From f1fdf2cd6d5c32524706438701ee03ff9f3914b2 Mon Sep 17 00:00:00 2001 From: Aaron Kaw Date: Sun, 25 Aug 2024 12:12:51 +1000 Subject: [PATCH] Migrated iteration 5 to branch --- .github/dependabot.yml | 7 + .github/workflows/CI.yml | 71 + .github/workflows/CompatHelper.yml | 16 + .github/workflows/TagBot.yml | 31 + .gitignore | 4 + .vscode/settings.json | 2 + CITATION.bib | 8 + Project.toml | 35 + benchmark/benchmarks.jl | 7 + docs/Project.toml | 4 + docs/make.jl | 86 + docs/src/acoustics/propagation/intro.md | 6 + .../propagation/parabolic/marcher.md | 43 + .../src/acoustics/propagation/tracing/beam.md | 5 + .../src/acoustics/propagation/tracing/grid.md | 30 + .../acoustics/propagation/tracing/intro.md | 5 + .../src/acoustics/propagation/tracing/rays.md | 23 + docs/src/acoustics/reflection/bottom.md | 81 + docs/src/acoustics/scenario.md | 5 + docs/src/general/implementation.md | 18 + docs/src/general/usage.md | 154 + docs/src/index.md | 3 + .../environment/boundary/altimetry.md | 6 + .../environment/boundary/bathymetry.md | 6 + docs/src/oceanography/environment/intro.md | 5 + .../environment/medium/atmosphere.md | 5 + .../oceanography/environment/medium/intro.md | 5 + .../oceanography/environment/medium/ocean.md | 5 + .../oceanography/environment/medium/seabed.md | 5 + .../parameters/attenuation/atmosphere.md | 6 + .../parameters/attenuation/ocean.md | 6 + .../attenuation/seabed/compressional.md | 6 + .../parameters/attenuation/seabed/shear.md | 6 + .../parameters/celerity/atmosphere.md | 6 + .../oceanography/parameters/celerity/ocean.md | 6 + .../celerity/seabed/compressional.md | 6 + .../parameters/celerity/seabed/shear.md | 6 + .../parameters/density/atmosphere.md | 6 + .../oceanography/parameters/density/ocean.md | 6 + .../oceanography/parameters/density/seabed.md | 6 + ext/OceanSonarMakieExt/OceanSonarMakieExt.jl | 31 + ext/OceanSonarMakieExt/bivariate.jl | 76 + ext/OceanSonarMakieExt/boundary.jl | 57 + ext/OceanSonarMakieExt/propagation.jl | 19 + ext/OceanSonarMakieExt/ray.jl | 32 + .../OceanSonarMakieExt_.jl | 40 + ext/OceanSonarMakieExt_/bivariate_.jl | 40 + ext/OceanSonarMakieExt_/boundary_.jl | 65 + ext/OceanSonarMakieExt_/environment_.jl | 37 + ext/OceanSonarMakieExt_/medium_.jl | 11 + ext/OceanSonarMakieExt_/propagation_.jl | 47 + ext/OceanSonarMakieExt_/ray_.jl | 39 + ext/OceanSonarMakieExt_/scenario_.jl | 9 + ext/OceanSonarPlotsExt/OceanSonarPlotsExt.jl | 21 + ext/OceanSonarPlotsExt/beam.jl | 32 + ext/OceanSonarPlotsExt/bivariate.jl | 16 + ext/OceanSonarPlotsExt/boundary.jl | 21 + ext/OceanSonarPlotsExt/medium.jl | 2 + ext/OceanSonarPlotsExt/propagation.jl | 26 + ext/OceanSonarPlotsExt/scenario.jl | 35 + ext/OceanSonarPlotsExt/slice.jl | 25 + license.md | 21 + notebooks/mtk.jl | 218 + notebooks/mtk2.jl | 2298 + readme.md | 323 + readme/Project.toml | 5 + readme/img/custom_celerity_profile.svg | 3485 ++ readme/img/index_squared_profile.svg | 2793 + readme/img/lloyd_mirror_freq_perturb.svg | 824 + readme/img/munk_profile.svg | 2795 + readme/img/munk_profile_3000.svg | 2814 + readme/img/munk_profile_eqn.svg | 1 + readme/img/munk_profile_rays.svg | 51129 +++++++++++++++ readme/img/parabolic_bathymetry_rays.svg | 51394 ++++++++++++++++ readme/readme.md | 19 + readme/refs/DifferentialEquations.bib | 13 + readme/refs/ForwardDiff.bib | 7 + readme/refs/IntervalArithmetic.bib | 7 + readme/refs/Julia.bib | 12 + readme/refs/ModelingToolkit.bib | 8 + readme/refs/Plots.bib | 10 + readme/scripts/lloyd_mirror_freq_perturb.jl | 49 + readme/scripts/lloyd_mirror_sqrt_approxers.jl | 12 + readme/scripts/main.jl | 180 + readme/scripts/munk_profile_eqn.jl | 5 + readme/scripts/munk_profile_rays.jl | 7 + readme/scripts/parabolic_bathymetry_rays.jl | 10 + readme/scripts/readme_images_old.jl | 92 + readme/texts/implementation.md | 39 + readme/texts/introduction.md | 20 + readme/texts/usage.md | 11 + src/OceanSonar.jl | 25 + src/acoustics/propagation/parabolic/config.jl | 12 + .../propagation/parabolic/marcher.jl | 54 + src/acoustics/propagation/parabolic/root.jl | 33 + .../propagation/parabolic/starter.jl | 37 + src/acoustics/propagation/root.jl | 38 + src/acoustics/propagation/trace/beam.jl | 305 + src/acoustics/propagation/trace/gridder.jl | 108 + src/acoustics/propagation/trace/ray.jl | 76 + src/acoustics/propagation/trace/root.jl | 58 + src/acoustics/reflection/bottom.jl | 25 + src/acoustics/reflection/root.jl | 66 + src/acoustics/reflection/surface.jl | 19 + src/acoustics/root.jl | 4 + src/acoustics/scenario.jl | 116 + src/macro/performance.jl | 120 + src/oceanography/attenuation/atmosphere.jl | 28 + src/oceanography/attenuation/ocean.jl | 36 + src/oceanography/attenuation/root.jl | 11 + .../attenuation/seabed/compressional.jl | 35 + src/oceanography/attenuation/seabed/root.jl | 2 + src/oceanography/attenuation/seabed/shear.jl | 35 + src/oceanography/boundary/altimetry.jl | 70 + src/oceanography/boundary/bathymetry.jl | 40 + src/oceanography/boundary/root.jl | 6 + src/oceanography/celerity/atmosphere.jl | 28 + src/oceanography/celerity/ocean.jl | 156 + src/oceanography/celerity/root.jl | 9 + .../celerity/seabed/compressional.jl | 33 + src/oceanography/celerity/seabed/root.jl | 2 + src/oceanography/celerity/seabed/shear.jl | 37 + src/oceanography/density/atmosphere.jl | 28 + src/oceanography/density/ocean.jl | 35 + src/oceanography/density/root.jl | 7 + src/oceanography/density/seabed.jl | 33 + src/oceanography/medium/atmosphere.jl | 29 + src/oceanography/medium/ocean.jl | 38 + src/oceanography/medium/root.jl | 10 + src/oceanography/medium/seabed.jl | 35 + src/oceanography/root.jl | 7 + src/oceanography/slice.jl | 59 + src/postliminary/get.jl | 21 + src/postliminary/modelling.jl | 4 + src/postliminary/precompile.jl | 9 + src/postliminary/root.jl | 5 + src/postliminary/variables.jl | 17 + src/postliminary/visualisation.jl | 120 + .../auxiliary/interpolation/bivariate.jl | 47 + .../auxiliary/interpolation/root.jl | 3 + .../auxiliary/interpolation/trivariate.jl | 4 + .../auxiliary/interpolation/univariate.jl | 46 + src/preliminary/auxiliary/modelling.jl | 144 + src/preliminary/auxiliary/root.jl | 18 + src/preliminary/auxiliary/series125.jl | 30 + src/preliminary/auxiliary/stringcases.jl | 73 + src/preliminary/auxiliary/units/decibels.jl | 20 + src/preliminary/auxiliary/units/root.jl | 1 + src/preliminary/base/abstract_supertypes.jl | 49 + src/preliminary/base/overloads.jl | 3 + src/preliminary/base/root.jl | 2 + src/preliminary/root.jl | 2 + src/processing/root.jl | 2 + src/processing/sonar.jl | 17 + src/processing/types.jl | 36 + test/Manifest.toml | 245 + test/Project.toml | 7 + test/auxiliary/interpolation/univariate.jl | 17 + test/auxiliary/series.jl | 48 + test/modelling/concreteness.jl | 19 + test/modelling/model_stability.jl | 101 + test/modelling/type_stability.jl | 21 + test/processing/sonar_types.jl | 103 + test/quality/ambiguities.jl | 5 + test/quality/aqua.jl | 4 + test/quality/docstrings.jl | 4 + test/quality/jet.jl | 4 + test/runtests.jl | 26 + 168 files changed, 123211 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/CI.yml create mode 100644 .github/workflows/CompatHelper.yml create mode 100644 .github/workflows/TagBot.yml create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 CITATION.bib create mode 100644 Project.toml create mode 100644 benchmark/benchmarks.jl create mode 100644 docs/Project.toml create mode 100644 docs/make.jl create mode 100644 docs/src/acoustics/propagation/intro.md create mode 100644 docs/src/acoustics/propagation/parabolic/marcher.md create mode 100644 docs/src/acoustics/propagation/tracing/beam.md create mode 100644 docs/src/acoustics/propagation/tracing/grid.md create mode 100644 docs/src/acoustics/propagation/tracing/intro.md create mode 100644 docs/src/acoustics/propagation/tracing/rays.md create mode 100644 docs/src/acoustics/reflection/bottom.md create mode 100644 docs/src/acoustics/scenario.md create mode 100644 docs/src/general/implementation.md create mode 100644 docs/src/general/usage.md create mode 100644 docs/src/index.md create mode 100644 docs/src/oceanography/environment/boundary/altimetry.md create mode 100644 docs/src/oceanography/environment/boundary/bathymetry.md create mode 100644 docs/src/oceanography/environment/intro.md create mode 100644 docs/src/oceanography/environment/medium/atmosphere.md create mode 100644 docs/src/oceanography/environment/medium/intro.md create mode 100644 docs/src/oceanography/environment/medium/ocean.md create mode 100644 docs/src/oceanography/environment/medium/seabed.md create mode 100644 docs/src/oceanography/parameters/attenuation/atmosphere.md create mode 100644 docs/src/oceanography/parameters/attenuation/ocean.md create mode 100644 docs/src/oceanography/parameters/attenuation/seabed/compressional.md create mode 100644 docs/src/oceanography/parameters/attenuation/seabed/shear.md create mode 100644 docs/src/oceanography/parameters/celerity/atmosphere.md create mode 100644 docs/src/oceanography/parameters/celerity/ocean.md create mode 100644 docs/src/oceanography/parameters/celerity/seabed/compressional.md create mode 100644 docs/src/oceanography/parameters/celerity/seabed/shear.md create mode 100644 docs/src/oceanography/parameters/density/atmosphere.md create mode 100644 docs/src/oceanography/parameters/density/ocean.md create mode 100644 docs/src/oceanography/parameters/density/seabed.md create mode 100644 ext/OceanSonarMakieExt/OceanSonarMakieExt.jl create mode 100644 ext/OceanSonarMakieExt/bivariate.jl create mode 100644 ext/OceanSonarMakieExt/boundary.jl create mode 100644 ext/OceanSonarMakieExt/propagation.jl create mode 100644 ext/OceanSonarMakieExt/ray.jl create mode 100644 ext/OceanSonarMakieExt_/OceanSonarMakieExt_.jl create mode 100644 ext/OceanSonarMakieExt_/bivariate_.jl create mode 100644 ext/OceanSonarMakieExt_/boundary_.jl create mode 100644 ext/OceanSonarMakieExt_/environment_.jl create mode 100644 ext/OceanSonarMakieExt_/medium_.jl create mode 100644 ext/OceanSonarMakieExt_/propagation_.jl create mode 100644 ext/OceanSonarMakieExt_/ray_.jl create mode 100644 ext/OceanSonarMakieExt_/scenario_.jl create mode 100644 ext/OceanSonarPlotsExt/OceanSonarPlotsExt.jl create mode 100644 ext/OceanSonarPlotsExt/beam.jl create mode 100644 ext/OceanSonarPlotsExt/bivariate.jl create mode 100644 ext/OceanSonarPlotsExt/boundary.jl create mode 100644 ext/OceanSonarPlotsExt/medium.jl create mode 100644 ext/OceanSonarPlotsExt/propagation.jl create mode 100644 ext/OceanSonarPlotsExt/scenario.jl create mode 100644 ext/OceanSonarPlotsExt/slice.jl create mode 100644 license.md create mode 100644 notebooks/mtk.jl create mode 100644 notebooks/mtk2.jl create mode 100644 readme.md create mode 100644 readme/Project.toml create mode 100644 readme/img/custom_celerity_profile.svg create mode 100644 readme/img/index_squared_profile.svg create mode 100644 readme/img/lloyd_mirror_freq_perturb.svg create mode 100644 readme/img/munk_profile.svg create mode 100644 readme/img/munk_profile_3000.svg create mode 100644 readme/img/munk_profile_eqn.svg create mode 100644 readme/img/munk_profile_rays.svg create mode 100644 readme/img/parabolic_bathymetry_rays.svg create mode 100644 readme/readme.md create mode 100644 readme/refs/DifferentialEquations.bib create mode 100644 readme/refs/ForwardDiff.bib create mode 100644 readme/refs/IntervalArithmetic.bib create mode 100644 readme/refs/Julia.bib create mode 100644 readme/refs/ModelingToolkit.bib create mode 100644 readme/refs/Plots.bib create mode 100644 readme/scripts/lloyd_mirror_freq_perturb.jl create mode 100644 readme/scripts/lloyd_mirror_sqrt_approxers.jl create mode 100644 readme/scripts/main.jl create mode 100644 readme/scripts/munk_profile_eqn.jl create mode 100644 readme/scripts/munk_profile_rays.jl create mode 100644 readme/scripts/parabolic_bathymetry_rays.jl create mode 100644 readme/scripts/readme_images_old.jl create mode 100644 readme/texts/implementation.md create mode 100644 readme/texts/introduction.md create mode 100644 readme/texts/usage.md create mode 100644 src/OceanSonar.jl create mode 100644 src/acoustics/propagation/parabolic/config.jl create mode 100644 src/acoustics/propagation/parabolic/marcher.jl create mode 100644 src/acoustics/propagation/parabolic/root.jl create mode 100644 src/acoustics/propagation/parabolic/starter.jl create mode 100644 src/acoustics/propagation/root.jl create mode 100644 src/acoustics/propagation/trace/beam.jl create mode 100644 src/acoustics/propagation/trace/gridder.jl create mode 100644 src/acoustics/propagation/trace/ray.jl create mode 100644 src/acoustics/propagation/trace/root.jl create mode 100644 src/acoustics/reflection/bottom.jl create mode 100644 src/acoustics/reflection/root.jl create mode 100644 src/acoustics/reflection/surface.jl create mode 100644 src/acoustics/root.jl create mode 100644 src/acoustics/scenario.jl create mode 100644 src/macro/performance.jl create mode 100644 src/oceanography/attenuation/atmosphere.jl create mode 100644 src/oceanography/attenuation/ocean.jl create mode 100644 src/oceanography/attenuation/root.jl create mode 100644 src/oceanography/attenuation/seabed/compressional.jl create mode 100644 src/oceanography/attenuation/seabed/root.jl create mode 100644 src/oceanography/attenuation/seabed/shear.jl create mode 100644 src/oceanography/boundary/altimetry.jl create mode 100644 src/oceanography/boundary/bathymetry.jl create mode 100644 src/oceanography/boundary/root.jl create mode 100644 src/oceanography/celerity/atmosphere.jl create mode 100644 src/oceanography/celerity/ocean.jl create mode 100644 src/oceanography/celerity/root.jl create mode 100644 src/oceanography/celerity/seabed/compressional.jl create mode 100644 src/oceanography/celerity/seabed/root.jl create mode 100644 src/oceanography/celerity/seabed/shear.jl create mode 100644 src/oceanography/density/atmosphere.jl create mode 100644 src/oceanography/density/ocean.jl create mode 100644 src/oceanography/density/root.jl create mode 100644 src/oceanography/density/seabed.jl create mode 100644 src/oceanography/medium/atmosphere.jl create mode 100644 src/oceanography/medium/ocean.jl create mode 100644 src/oceanography/medium/root.jl create mode 100644 src/oceanography/medium/seabed.jl create mode 100644 src/oceanography/root.jl create mode 100644 src/oceanography/slice.jl create mode 100644 src/postliminary/get.jl create mode 100644 src/postliminary/modelling.jl create mode 100644 src/postliminary/precompile.jl create mode 100644 src/postliminary/root.jl create mode 100644 src/postliminary/variables.jl create mode 100644 src/postliminary/visualisation.jl create mode 100644 src/preliminary/auxiliary/interpolation/bivariate.jl create mode 100644 src/preliminary/auxiliary/interpolation/root.jl create mode 100644 src/preliminary/auxiliary/interpolation/trivariate.jl create mode 100644 src/preliminary/auxiliary/interpolation/univariate.jl create mode 100644 src/preliminary/auxiliary/modelling.jl create mode 100644 src/preliminary/auxiliary/root.jl create mode 100644 src/preliminary/auxiliary/series125.jl create mode 100644 src/preliminary/auxiliary/stringcases.jl create mode 100644 src/preliminary/auxiliary/units/decibels.jl create mode 100644 src/preliminary/auxiliary/units/root.jl create mode 100644 src/preliminary/base/abstract_supertypes.jl create mode 100644 src/preliminary/base/overloads.jl create mode 100644 src/preliminary/base/root.jl create mode 100644 src/preliminary/root.jl create mode 100644 src/processing/root.jl create mode 100644 src/processing/sonar.jl create mode 100644 src/processing/types.jl create mode 100644 test/Manifest.toml create mode 100644 test/Project.toml create mode 100644 test/auxiliary/interpolation/univariate.jl create mode 100644 test/auxiliary/series.jl create mode 100644 test/modelling/concreteness.jl create mode 100644 test/modelling/model_stability.jl create mode 100644 test/modelling/type_stability.jl create mode 100644 test/processing/sonar_types.jl create mode 100644 test/quality/ambiguities.jl create mode 100644 test/quality/aqua.jl create mode 100644 test/quality/docstrings.jl create mode 100644 test/quality/jet.jl create mode 100644 test/runtests.jl diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..700707c --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml new file mode 100644 index 0000000..c329628 --- /dev/null +++ b/.github/workflows/CI.yml @@ -0,0 +1,71 @@ +name: CI +on: + push: + branches: + - main + tags: ['*'] + pull_request: + workflow_dispatch: +concurrency: + # Skip intermediate builds: always. + # Cancel intermediate builds: only if it is a pull request build. + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ startsWith(github.ref, 'refs/pull/') }} +jobs: + test: + name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + permissions: # needed to allow julia-actions/cache to proactively delete old caches that it has created + actions: write + contents: read + strategy: + fail-fast: false + matrix: + version: + - '1.10' + os: + - ubuntu-latest + - macOS-latest + - windows-latest + arch: + - x64 + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 + with: + version: ${{ matrix.version }} + arch: ${{ matrix.arch }} + - uses: julia-actions/cache@v2 + - uses: julia-actions/julia-buildpkg@v1 + - uses: julia-actions/julia-runtest@v1 + docs: + name: Documentation + runs-on: ubuntu-latest + permissions: + actions: write # needed to allow julia-actions/cache to proactively delete old caches that it has created + contents: write + statuses: write + steps: + - uses: actions/checkout@v4 + - uses: julia-actions/setup-julia@v2 + with: + version: '1' + - uses: julia-actions/cache@v2 + - name: Configure doc environment + shell: julia --project=docs --color=yes {0} + run: | + using Pkg + Pkg.develop(PackageSpec(path=pwd())) + Pkg.instantiate() + - uses: julia-actions/julia-buildpkg@v1 + - uses: julia-actions/julia-docdeploy@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Run doctests + shell: julia --project=docs --color=yes {0} + run: | + using Documenter: DocMeta, doctest + using OceanSonar + DocMeta.setdocmeta!(OceanSonar, :DocTestSetup, :(using OceanSonar); recursive=true) + doctest(OceanSonar) diff --git a/.github/workflows/CompatHelper.yml b/.github/workflows/CompatHelper.yml new file mode 100644 index 0000000..cba9134 --- /dev/null +++ b/.github/workflows/CompatHelper.yml @@ -0,0 +1,16 @@ +name: CompatHelper +on: + schedule: + - cron: 0 0 * * * + workflow_dispatch: +jobs: + CompatHelper: + runs-on: ubuntu-latest + steps: + - name: Pkg.add("CompatHelper") + run: julia -e 'using Pkg; Pkg.add("CompatHelper")' + - name: CompatHelper.main() + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + COMPATHELPER_PRIV: ${{ secrets.DOCUMENTER_KEY }} + run: julia -e 'using CompatHelper; CompatHelper.main()' diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml new file mode 100644 index 0000000..2bacdb8 --- /dev/null +++ b/.github/workflows/TagBot.yml @@ -0,0 +1,31 @@ +name: TagBot +on: + issue_comment: + types: + - created + workflow_dispatch: + inputs: + lookback: + default: 3 +permissions: + actions: read + checks: read + contents: write + deployments: read + issues: read + discussions: read + packages: read + pages: read + pull-requests: read + repository-projects: read + security-events: read + statuses: read +jobs: + TagBot: + if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' + runs-on: ubuntu-latest + steps: + - uses: JuliaRegistries/TagBot@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + ssh: ${{ secrets.DOCUMENTER_KEY }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bdf1626 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/Manifest.toml +/docs/Manifest.toml +/docs/build/ +/readme/Manifest.toml \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7a73a41 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/CITATION.bib b/CITATION.bib new file mode 100644 index 0000000..0db9e08 --- /dev/null +++ b/CITATION.bib @@ -0,0 +1,8 @@ +@misc{OceanSonar.jl, + author = {Aaron Kaw and contributors}, + title = {OceanSonar.jl}, + url = {https://github.com/kapple19/OceanSonar.jl}, + version = {v1.0.0-DEV}, + year = {2024}, + month = {3} +} \ No newline at end of file diff --git a/Project.toml b/Project.toml new file mode 100644 index 0000000..0d96792 --- /dev/null +++ b/Project.toml @@ -0,0 +1,35 @@ +name = "OceanSonar" +uuid = "606d67fd-65b6-4abb-b2f0-1946d248e4dc" +authors = ["Aaron Kaw and contributors"] +version = "1.0.0-DEV" + +[deps] +ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" +Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" +IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[weakdeps] +Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" + +[extensions] +OceanSonarMakieExt = "Makie" +OceanSonarPlotsExt = "Plots" + +[compat] +ForwardDiff = "0.10" +Interpolations = "0.15" +IntervalArithmetic = "0.22" +LinearAlgebra = "1.10" +Makie = "0.21" +NaNMath = "1.0" +OrdinaryDiffEq = "6.85" +Plots = "1.40" +PrecompileTools = "1.2" +Statistics = "1.10" +julia = "1.11" diff --git a/benchmark/benchmarks.jl b/benchmark/benchmarks.jl new file mode 100644 index 0000000..f5578b5 --- /dev/null +++ b/benchmark/benchmarks.jl @@ -0,0 +1,7 @@ +using OceanSonar +using BenchmarkTools + +SUITE = BenchmarkGroup() +SUITE["rand"] = @benchmarkable rand(10) + +# Write your benchmarks here. diff --git a/docs/Project.toml b/docs/Project.toml new file mode 100644 index 0000000..93cbb6e --- /dev/null +++ b/docs/Project.toml @@ -0,0 +1,4 @@ +[deps] +Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +OceanSonar = "606d67fd-65b6-4abb-b2f0-1946d248e4dc" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" diff --git a/docs/make.jl b/docs/make.jl new file mode 100644 index 0000000..c47564f --- /dev/null +++ b/docs/make.jl @@ -0,0 +1,86 @@ +using OceanSonar +using Documenter + +DocMeta.setdocmeta!(OceanSonar, :DocTestSetup, :(using OceanSonar); recursive=true) + +pages = [ + "Ocean Sonar" => "index.md" + "General" => [ + "Usage" => "general/usage.md" + "Implementation" => "general/implementation.md" + ] + "Oceanography" => [ + "Parameters" => [ + "Celerity" => [ + "Atmosphere" => "oceanography/parameters/celerity/atmosphere.md" + "Ocean" => "oceanography/parameters/celerity/ocean.md" + "Seabed" => [ + "Compressional" => "oceanography/parameters/celerity/seabed/compressional.md" + "Shear" => "oceanography/parameters/celerity/seabed/shear.md" + ] + ] + "Density" => [ + "Atmosphere" => "oceanography/parameters/density/atmosphere.md" + "Ocean" => "oceanography/parameters/density/ocean.md" + "Seabed" => "oceanography/parameters/density/seabed.md" + ] + "Attenuation" => [ + "Atmosphere" => "oceanography/parameters/attenuation/atmosphere.md" + "Ocean" => "oceanography/parameters/attenuation/ocean.md" + "Seabed" => [ + "Compressional" => "oceanography/parameters/attenuation/seabed/compressional.md" + "Shear" => "oceanography/parameters/attenuation/seabed/shear.md" + ] + ] + ] + "Slice" => [ + "Introduction" => "oceanography/environment/intro.md" + "Boundary" => [ + "Altimetry" => "oceanography/environment/boundary/altimetry.md" + "Bathymetry" => "oceanography/environment/boundary/bathymetry.md" + ] + "Medium" => [ + "Introduction" => "oceanography/environment/medium/intro.md" + "Atmosphere" => "oceanography/environment/medium/atmosphere.md" + "Ocean" => "oceanography/environment/medium/ocean.md" + "Seabed" => "oceanography/environment/medium/seabed.md" + ] + ] + ] + "Acoustics" => [ + "Scenario" => "acoustics/scenario.md" + "Reflection" => [ + "Bottom" => "acoustics/reflection/bottom.md" + ] + "Propagation" => [ + "Introduction" => "acoustics/propagation/intro.md" + "Tracing" => [ + "Introduction" => "acoustics/propagation/tracing/intro.md" + "Rays" => "acoustics/propagation/tracing/rays.md" + "Beams" => "acoustics/propagation/tracing/beam.md" + "Grid" => "acoustics/propagation/tracing/grid.md" + ] + "Parabolic" => [ + "Marchers" => "acoustics/propagation/parabolic/marcher.md" + ] + ] + ] +] + +makedocs(; + sitename="OceanSonar.jl", + modules=[OceanSonar], + authors="Aaron Kaw and contributors", + format = Documenter.HTML(; + canonical="https://kapple19.github.io/OceanSonar.jl", + edit_link = :commit, + collapselevel = 1, + assets = String[] + ), + pages = pages, +) + +deploydocs(; + repo="github.com/kapple19/OceanSonar.jl", + devbranch="main", +) diff --git a/docs/src/acoustics/propagation/intro.md b/docs/src/acoustics/propagation/intro.md new file mode 100644 index 0000000..33a5aea --- /dev/null +++ b/docs/src/acoustics/propagation/intro.md @@ -0,0 +1,6 @@ +# Acoustic Propagation + +```@docs +Propagation +PropagationConfig +``` diff --git a/docs/src/acoustics/propagation/parabolic/marcher.md b/docs/src/acoustics/propagation/parabolic/marcher.md new file mode 100644 index 0000000..2aa6228 --- /dev/null +++ b/docs/src/acoustics/propagation/parabolic/marcher.md @@ -0,0 +1,43 @@ +# Marchers + +To be renamed. + +```@example +using OceanSonar +using Plots + +θ_deg = range(0, 90, 301) +θ = deg2rad.(θ_deg) +q = -sin.(θ).^2 + +helmholtz(q) = √(1 + q) +helmholtz_q = helmholtz.(q) + +plot() + +for model = list_models(OceanSonar.RationalFunctionApproximation) + rfa = OceanSonar.RationalFunctionApproximation(model) + errs = helmholtz_q - rfa.(q) .|> abs + plot!(θ_deg, errs, + label = string(model, " (", length(rfa.a), ")") + ) +end +model = :pade +rfa = OceanSonar.RationalFunctionApproximation(model, m = 5) +errs = helmholtz_q - rfa.(q) .|> abs +plot!(θ_deg, errs, + label = string(model, " (", length(rfa.a), ")") +) + +plot!( + xlims = (0, 90), + ylims = (0, 0.001), + legend_position = :best +) + +savefig("phase_errors.svg") +``` + +Replication of Figure 6.1b of Jensen, et al (2011). + +![phase_errors.svg](phase_errors.svg) diff --git a/docs/src/acoustics/propagation/tracing/beam.md b/docs/src/acoustics/propagation/tracing/beam.md new file mode 100644 index 0000000..980372c --- /dev/null +++ b/docs/src/acoustics/propagation/tracing/beam.md @@ -0,0 +1,5 @@ +# Acoustic Beam Tracing + +```@docs +Beam +``` \ No newline at end of file diff --git a/docs/src/acoustics/propagation/tracing/grid.md b/docs/src/acoustics/propagation/tracing/grid.md new file mode 100644 index 0000000..d705ec9 --- /dev/null +++ b/docs/src/acoustics/propagation/tracing/grid.md @@ -0,0 +1,30 @@ +# Acoustic Tracing Interpolation to Grid + +```@example +using OceanSonar +using Plots +using .Threads + +@time "all" begin + begin + models = list_models(Scenario) + for m in eachindex(models) + model = models[m] + scen = Scenario(model) + prop = @time "$model" Propagation(:trace, scen, + angles = critical_angles(scen) + ) + fig = visual(prop) + savefig(fig, "prop_" * modelsnake(scen.model) * ".svg") + end + end +end +``` + +![prop_parabolic_bathymetry.svg](prop_parabolic_bathymetry.svg) + +![prop_index_squared_profile.svg](prop_index_squared_profile.svg) + +![prop_munk_profile.svg](prop_munk_profile.svg) + +![prop_lloyd_mirror.svg](prop_lloyd_mirror.svg) diff --git a/docs/src/acoustics/propagation/tracing/intro.md b/docs/src/acoustics/propagation/tracing/intro.md new file mode 100644 index 0000000..48a77ab --- /dev/null +++ b/docs/src/acoustics/propagation/tracing/intro.md @@ -0,0 +1,5 @@ +# Acoustic Tracing Models + +```@docs +TraceConfig +``` diff --git a/docs/src/acoustics/propagation/tracing/rays.md b/docs/src/acoustics/propagation/tracing/rays.md new file mode 100644 index 0000000..0f4800c --- /dev/null +++ b/docs/src/acoustics/propagation/tracing/rays.md @@ -0,0 +1,23 @@ +# Ray Tracing + +```@example +using OceanSonar +using Plots + +for model in list_models(Scenario) + scen = Scenario(model) + prop = @time "$model" Propagation(:trace, scen, + angles = critical_angles(scen, N = 21) + ) + fig = visual(Beam, prop) + savefig(fig, "rays_" * modelsnake(scen.model) * ".svg") +end +``` + +![rays_parabolic_bathymetry.svg](rays_parabolic_bathymetry.svg) + +![rays_index_squared_profile.svg](rays_index_squared_profile.svg) + +![rays_munk_profile.svg](rays_munk_profile.svg) + +![rays_lloyd_mirror.svg](rays_lloyd_mirror.svg) diff --git a/docs/src/acoustics/reflection/bottom.md b/docs/src/acoustics/reflection/bottom.md new file mode 100644 index 0000000..a686361 --- /dev/null +++ b/docs/src/acoustics/reflection/bottom.md @@ -0,0 +1,81 @@ +# Bottom Reflection + +```julia +using OceanSonar +using CairoMakie + +@kwdef struct Case + family::Symbol + axis::Axis + θ₁ = range(0, π/2, 301) + ρ₁ = [1e3] + c₁ = [1500.0] + α₁ = [0.0] + c₂ₚ = [1600.0] + c₂ₛ = [0.0] + α₂ₚ = [0.5] + α₂ₛ = [0.0] + ρ₂ = [2e3] +end + +fig = Figure() + +cases = [ + Case( + family = :c₂ₚ, + axis = Axis(fig[1, 1], title = "Celerity"), + c₂ₚ = Float64[1550 1600 1800], + ) + Case( + family = :α₂ₚ, + axis = Axis(fig[1, 2], title = "Attenuation"), + α₂ₚ = Float64[0 0.5 1], + ) + Case( + family = :ρ₂, + axis = Axis(fig[2, 1], title = "Density"), + ρ₂ = Float64[1500 2000 2500], + ) + Case( + family = :c₂ₛ, + axis = Axis(fig[2, 2], title = "Shear Celerity"), + c₂ₛ = Float64[0 200 400 600], + α₂ₚ = [0.0] + ) +] + +translate_inputs = ( + ρ_inc = :ρ₁, + ρ_rfr = :ρ₂, + c_inc = :c₁, + c_compr_rfr = :c₂ₚ, + c_shear_rfr = :c₂ₛ, + α_inc = :α₁, + α_compr_rfr = :α₂ₚ, + α_shear_rfr = :α₂ₛ, + θ_inc = :θ₁ +) + +model = :rayleigh_solid + +for case in cases + inputs = Tuple( + getproperty(case, translate_inputs[input]) + for input in list_inputs(reflection_coefficient, model) + ) + R = @. reflection_coefficient(model, inputs...) + BRLs = @. -20log10(R |> abs) + + for (n, BRL) in BRLs |> eachcol |> enumerate + lines!(case.axis, case.θ₁ .|> rad2deg, BRL, + label = getproperty(case, case.family)[n] |> string + ) + end + + ylims!(case.axis, 0, 15) + xlims!(case.axis, 0, 90) + axislegend(case.axis) +end + +save("jensen_fig_1_23.svg", fig) +``` diff --git a/docs/src/acoustics/scenario.md b/docs/src/acoustics/scenario.md new file mode 100644 index 0000000..e47c904 --- /dev/null +++ b/docs/src/acoustics/scenario.md @@ -0,0 +1,5 @@ +# Ocean Acoustics Scenario + +```@docs +Scenario +``` diff --git a/docs/src/general/implementation.md b/docs/src/general/implementation.md new file mode 100644 index 0000000..734cfd6 --- /dev/null +++ b/docs/src/general/implementation.md @@ -0,0 +1,18 @@ +# Ocean Sonar Models Implementation + +All data container types in OceanSonar.jl are subtypes of `OcnSon`. + +```@docs +OcnSon +``` + +## Internals + +The following is an automated printing of documentation +for OceanSonar.jl functions, variables, and types +that aren't exported. + +```@autodocs; canonical = true +Modules = [OceanSonar] +Public = false +``` diff --git a/docs/src/general/usage.md b/docs/src/general/usage.md new file mode 100644 index 0000000..06e4fad --- /dev/null +++ b/docs/src/general/usage.md @@ -0,0 +1,154 @@ +# OceanSonar.jl Usage + +TODO: Link OceanSonar.jl definition names to their documentation. + +## Installation + +As OceanSonar.jl is a Julia package, it requires the Julia programming language. + +1. Install Julia using the instructions [here](https://julialang.org/downloads/). +2. Open a Julia REPL (terminal). +3. Activate the `Pkg` mode by pressing `]` (at the beginning of the line). +4. Enter `add https://github.com/kapple19/OceanSonar.jl` which installs the `OceanSonar.jl` package. +5. Return to the `Julian` mode by backspacing (at the beginning of the line). +6. Enter `using OceanSonar` to load the package. + +Registered packages require only `add OceanSonar`, +which is not yet the case for this package under development. + +## Functions + +The functions defined by OceanSonar.jl are: + +* `atmosphere_celerity` +* `ocean_celerity` +* `seabed_celerity` +* `shear_seabed_celerity` +* TODO: programmatically produce this list. + +View their respective documentation for more details. + +## Containers + +Data containers available for storing information are: + +* `Medium` +* `Slice` +* TODO: programmatically produce this list. + +## Functors + +Functors are data containers that can be run like functions. +The functor types defined by OceanSonar.jl available for instantiation are: + +* `AtmosphereCelerity` +* `OceanCelerity` +* `SeabedCelerity` +* `ShearSeabedCelerity` +* TODO: programmatically produce this list. + +Their usage, for example: + +```julia +using OceanSonar + +models = list_models(OceanCelerity) +cel = OceanCelerity(models[1]) + +cel(0, 1e3) +``` + +## Built-In Models + +For any of the functions, containers, and functor types listed above, +run `list_models` on them to list the available models for usage. + +```@docs +list_models +``` + +## Custom User Models + +Models are implemented in Julia as methods signed with a [`Val{Symbol}`](https://docs.julialang.org/en/v1/base/base/#Base.Val) as the first input. +The `Symbol` instance must be snake-case. +For example, to add custom models for ocean sound speed: + +```julia +using OceanSonar +import OceanSonar: ocean_celerity + +function ocean_celerity(::Val{:sinusoidal}, x, z) + 1500 + sin(x) - cos(z) +end + +ocean_celerity(::Val{:depth_decreasing}, x, z) = 1500.0 + 20exp(-z) +``` + +which becomes available as + +```julia +ocean_celerity("Sinusoidal", 1e2, 1e3) +``` + +and + +```julia +ocean_celerity("Depth Decreasing", 0, 100) +``` + +Some models are interpolations of data points. + +```@docs +Univariate +Bivariate +Trivariate +``` + +For example, + +```julia +using OceanSonar +using CairoMakie + +ranges = 1e3 * [0, 5, 6, 7, 10] +depths = 1e3 * [5, 5, 2, 5, 5] + +itp = Univariate(ranges, depths) +bathymetry(::Val{:triangular_seamount}, x) = itp(x) + +bty = Bathymetry("Triangular Seamount") +visual(bty) +``` + +Note that the pascal-case `Bathymetry <: Univariate`, +but the `Univariate` instance is used to define the snake-case `bathymetry` method. + +## Visualisation + +OceanSonar.jl comes with [package extensions](https://docs.julialang.org/en/v1/manual/code-loading/#man-extensions) +for backends [Plots.jl](https://docs.juliaplots.org/stable/) +and [Makie.jl](https://docs.makie.org/stable/). +The extensions define recipes for: + +* `OceanCelerity` +* TODO: Programmatically produce this list. + +So you can use either plotting backend's plotting functions on instances of the above-listed types. + +OceanSonar.jl also provides `visual` which acts as a convenience function for plotting multiple features with one function call. +Its mutating version `visual!` is also provided. + +```@docs +visual! +visual +``` + +## Other Auxiliaries + +Formatting a string of the model's name has been wrapped into the following functions: + +```@docs +modelsnake +modeltitle +modelsymbol +``` diff --git a/docs/src/index.md b/docs/src/index.md new file mode 100644 index 0000000..8956adc --- /dev/null +++ b/docs/src/index.md @@ -0,0 +1,3 @@ +# OceanSonar.jl + +Documentation for OceanSonar.jl diff --git a/docs/src/oceanography/environment/boundary/altimetry.md b/docs/src/oceanography/environment/boundary/altimetry.md new file mode 100644 index 0000000..88a7c3f --- /dev/null +++ b/docs/src/oceanography/environment/boundary/altimetry.md @@ -0,0 +1,6 @@ +# Altimetry + +```@docs +altimetry +Altimetry +``` diff --git a/docs/src/oceanography/environment/boundary/bathymetry.md b/docs/src/oceanography/environment/boundary/bathymetry.md new file mode 100644 index 0000000..e83fb87 --- /dev/null +++ b/docs/src/oceanography/environment/boundary/bathymetry.md @@ -0,0 +1,6 @@ +# Bathymetry + +```@docs +bathymetry +Bathymetry +``` diff --git a/docs/src/oceanography/environment/intro.md b/docs/src/oceanography/environment/intro.md new file mode 100644 index 0000000..7f932cf --- /dev/null +++ b/docs/src/oceanography/environment/intro.md @@ -0,0 +1,5 @@ +# The Ocean Slice + +```@docs +Slice +``` \ No newline at end of file diff --git a/docs/src/oceanography/environment/medium/atmosphere.md b/docs/src/oceanography/environment/medium/atmosphere.md new file mode 100644 index 0000000..c4ca3aa --- /dev/null +++ b/docs/src/oceanography/environment/medium/atmosphere.md @@ -0,0 +1,5 @@ +# The Atmosphere Medium + +```@docs +Atmosphere +``` diff --git a/docs/src/oceanography/environment/medium/intro.md b/docs/src/oceanography/environment/medium/intro.md new file mode 100644 index 0000000..d3d3221 --- /dev/null +++ b/docs/src/oceanography/environment/medium/intro.md @@ -0,0 +1,5 @@ +# Acoustic Media + +```@docs +Medium +``` diff --git a/docs/src/oceanography/environment/medium/ocean.md b/docs/src/oceanography/environment/medium/ocean.md new file mode 100644 index 0000000..fd86f78 --- /dev/null +++ b/docs/src/oceanography/environment/medium/ocean.md @@ -0,0 +1,5 @@ +# The Ocean Medium + +```@docs +Ocean +``` diff --git a/docs/src/oceanography/environment/medium/seabed.md b/docs/src/oceanography/environment/medium/seabed.md new file mode 100644 index 0000000..f06f040 --- /dev/null +++ b/docs/src/oceanography/environment/medium/seabed.md @@ -0,0 +1,5 @@ +# The Seabed Medium + +```@docs +Seabed +``` diff --git a/docs/src/oceanography/parameters/attenuation/atmosphere.md b/docs/src/oceanography/parameters/attenuation/atmosphere.md new file mode 100644 index 0000000..ebfa9d4 --- /dev/null +++ b/docs/src/oceanography/parameters/attenuation/atmosphere.md @@ -0,0 +1,6 @@ +# Atmosphere Attenuation + +```@docs +atmosphere_attenuation +AtmosphereAttenuation +``` diff --git a/docs/src/oceanography/parameters/attenuation/ocean.md b/docs/src/oceanography/parameters/attenuation/ocean.md new file mode 100644 index 0000000..1630a57 --- /dev/null +++ b/docs/src/oceanography/parameters/attenuation/ocean.md @@ -0,0 +1,6 @@ +# Ocean Attenuation + +```@docs +OceanAttenuation +ocean_attenuation +``` diff --git a/docs/src/oceanography/parameters/attenuation/seabed/compressional.md b/docs/src/oceanography/parameters/attenuation/seabed/compressional.md new file mode 100644 index 0000000..3ab892f --- /dev/null +++ b/docs/src/oceanography/parameters/attenuation/seabed/compressional.md @@ -0,0 +1,6 @@ +# Compressional Seabed Attenuation + +```@docs +seabed_attenuation +SeabedAttenuation +``` diff --git a/docs/src/oceanography/parameters/attenuation/seabed/shear.md b/docs/src/oceanography/parameters/attenuation/seabed/shear.md new file mode 100644 index 0000000..fb67e74 --- /dev/null +++ b/docs/src/oceanography/parameters/attenuation/seabed/shear.md @@ -0,0 +1,6 @@ +# Shear Seabed Attenuation + +```@docs +ShearSeabedAttenuation +shear_seabed_attenuation +``` diff --git a/docs/src/oceanography/parameters/celerity/atmosphere.md b/docs/src/oceanography/parameters/celerity/atmosphere.md new file mode 100644 index 0000000..b695c10 --- /dev/null +++ b/docs/src/oceanography/parameters/celerity/atmosphere.md @@ -0,0 +1,6 @@ +# Atmosphere Celerity + +```@docs +atmosphere_celerity +AtmosphereCelerity +``` diff --git a/docs/src/oceanography/parameters/celerity/ocean.md b/docs/src/oceanography/parameters/celerity/ocean.md new file mode 100644 index 0000000..36eea83 --- /dev/null +++ b/docs/src/oceanography/parameters/celerity/ocean.md @@ -0,0 +1,6 @@ +# Ocean Celerity + +```@docs +ocean_celerity +OceanCelerity +``` diff --git a/docs/src/oceanography/parameters/celerity/seabed/compressional.md b/docs/src/oceanography/parameters/celerity/seabed/compressional.md new file mode 100644 index 0000000..58ea7c0 --- /dev/null +++ b/docs/src/oceanography/parameters/celerity/seabed/compressional.md @@ -0,0 +1,6 @@ +# Compressional Seabed Celerity + +```@docs +seabed_celerity +SeabedCelerity +``` diff --git a/docs/src/oceanography/parameters/celerity/seabed/shear.md b/docs/src/oceanography/parameters/celerity/seabed/shear.md new file mode 100644 index 0000000..dabc5e4 --- /dev/null +++ b/docs/src/oceanography/parameters/celerity/seabed/shear.md @@ -0,0 +1,6 @@ +# Shear Seabed Celerity + +```@docs +shear_seabed_celerity +ShearSeabedCelerity +``` diff --git a/docs/src/oceanography/parameters/density/atmosphere.md b/docs/src/oceanography/parameters/density/atmosphere.md new file mode 100644 index 0000000..e075b66 --- /dev/null +++ b/docs/src/oceanography/parameters/density/atmosphere.md @@ -0,0 +1,6 @@ +# Atmosphere Density + +```@docs +atmosphere_density +AtmosphereDensity +``` diff --git a/docs/src/oceanography/parameters/density/ocean.md b/docs/src/oceanography/parameters/density/ocean.md new file mode 100644 index 0000000..a3dcdbc --- /dev/null +++ b/docs/src/oceanography/parameters/density/ocean.md @@ -0,0 +1,6 @@ +# Ocean Density + +```@docs +ocean_density +OceanDensity +``` diff --git a/docs/src/oceanography/parameters/density/seabed.md b/docs/src/oceanography/parameters/density/seabed.md new file mode 100644 index 0000000..906e056 --- /dev/null +++ b/docs/src/oceanography/parameters/density/seabed.md @@ -0,0 +1,6 @@ +# Seabed Density + +```@docs +seabed_density +SeabedDensity +``` diff --git a/ext/OceanSonarMakieExt/OceanSonarMakieExt.jl b/ext/OceanSonarMakieExt/OceanSonarMakieExt.jl new file mode 100644 index 0000000..1f29acf --- /dev/null +++ b/ext/OceanSonarMakieExt/OceanSonarMakieExt.jl @@ -0,0 +1,31 @@ +module OceanSonarMakieExt + +using OceanSonar +using Makie + +import OceanSonar: visual!, visual, OceanAxis +import Makie: AbstractAxis, convert_arguments + +function OceanAxis(pos::GridPosition) + axis = Axis(pos[1, 1], + yreversed = true, + xlabel = "Range [m]", + ylabel = "Depth [m]" + ) + return axis +end + +function visual(args...) + fig = Figure() + pos = fig[1, 1] + OceanAxis(pos) + visual!(pos, args...) + return fig +end + +include("boundary.jl") +include("bivariate.jl") +include("ray.jl") +include("propagation.jl") + +end # module OceanSonarMakieExt \ No newline at end of file diff --git a/ext/OceanSonarMakieExt/bivariate.jl b/ext/OceanSonarMakieExt/bivariate.jl new file mode 100644 index 0000000..144edc1 --- /dev/null +++ b/ext/OceanSonarMakieExt/bivariate.jl @@ -0,0 +1,76 @@ +function convert_arguments(plot::GridBased, + biv::Bivariate, + x::AbstractVector{<:Real}, + z::AbstractVector{<:Real} +) + b = [biv(x̂, ẑ) for x̂ in x, ẑ in z] + convert_arguments(plot, x, z, b) +end + +function visual!(pos::GridPosition, + biv::Bivariate, + x::AbstractVector{<:Real}, + z::AbstractVector{<:Real} +) + plot = heatmap!(pos[1, 1], biv, x, z, + colormap = OceanSonar.colour(biv) + ) + axis = current_axis() + axis.title = modeltitle(biv) * " Model" + Colorbar(pos[1, 2], plot, + label = OceanSonar.label(biv) + ) + return axis +end + +function visual!(pos::GridPosition, + type::Type{<:Bivariate}, + med::Medium, + x::AbstractVector{<:Real}, + z::AbstractVector{<:Real} +) + return visual!(pos, get(med, type), x, z) +end + +get_medium(slc::Slice, ::Type{<:OceanCelerity}) = slc.ocn +get_medium(slc::Slice, ::Type{<:OceanDensity}) = slc.ocn + +function visual!(pos::GridPosition, + type::Type{<:Bivariate}, + slc::Slice, + x::AbstractVector{<:Real}, + z::AbstractVector{<:Real} +) + axis = visual!(pos, type, get_medium(slc, type), x, z) + visual!(pos, Boundary, slc, x) + return axis +end + +function visual!(pos::GridPosition, + type::Type{<:Bivariate}, + scen::Scenario, + x::AbstractVector{<:Real}, + z::AbstractVector{<:Real} +) + axis = visual!(pos, type, scen.slc, x, z) + axis.title = modeltitle(scen) + return axis +end + +function visual!(pos::GridPosition, + type::Type{<:Bivariate}, + scen::Scenario, + Nx::Integer, + Nz::Integer +) + x = OceanSonar.create_ranges(0.0, scen.x, Nx) + z = range(depth_extrema(scen)..., Nz) + return visual!(pos, type, scen.slc, x, z) +end + +function visual!(pos::GridPosition, + type::Type{<:Bivariate}, + prop::Propagation +) + return visual!(pos, type, prop.scen, prop.x, prop.z) +end diff --git a/ext/OceanSonarMakieExt/boundary.jl b/ext/OceanSonarMakieExt/boundary.jl new file mode 100644 index 0000000..1933d48 --- /dev/null +++ b/ext/OceanSonarMakieExt/boundary.jl @@ -0,0 +1,57 @@ +import OceanSonar: boundaryplot!, boundaryplot + +## Convert Boundary Instances to Plotting Data + +function convert_arguments(plot::PointBased, bnd::Boundary, x::AbstractVector{<:Real}) + return convert_arguments(plot, x, x .|> bnd) +end + +function convert_arguments(plot::Type{<:Band}, ati::Altimetry, x::AbstractVector{<:Real}) + x_lo, x_hi = extrema(x) + z_lo, _ = depth_extrema(ati, x_lo, x_hi) + z_hi = x .|> ati + return convert_arguments(plot, x, z_lo, z_hi) +end + +function convert_arguments(plot::Type{<:Band}, bty::Boundary, x::AbstractVector{<:Real}) + x_lo, x_hi = extrema(x) + _, z_hi = depth_extrema(bty, x_lo, x_hi) + z_lo = bty.(x) + return convert_arguments(plot, x, z_lo, z_hi) +end + +## Boundary Data Pipeline + +function visual!(pos::GridPosition, bnd::Boundary, x::AbstractVector{<:Real}) + band!(pos[1, 1], bnd, x, + color = OceanSonar.colour(bnd) + ) + return current_axis() +end + +function visual!(pos::GridPosition, ::Type{Altimetry}, slc::Slice, x::AbstractVector{<:Real}) + return visual!(pos, slc.ati, x) +end + +function visual!(pos::GridPosition, ::Type{Bathymetry}, slc::Slice, x::AbstractVector{<:Real}) + return visual!(pos, slc.bty, x) +end + +function visual!(pos::GridPosition, ::Type{Boundary}, slc::Slice, x::AbstractVector{<:Real}) + visual!(pos, Altimetry, slc, x) + visual!(pos, Bathymetry, slc, x) + return current_axis() +end + +function visual!(pos::GridPosition, type::Type{<:Boundary}, scen::Scenario, x::AbstractVector{<:Real}) + return visual!(pos, type, scen.slc, x) +end + +function visual!(pos::GridPosition, type::Type{<:Boundary}, scen::Scenario, Nx::Integer) + x = OceanSonar.create_ranges(0.0, scen.x, Nx) + return visual!(pos, type, scen, x) +end + +function visual!(pos::GridPosition, type::Type{<:Boundary}, prop::Propagation) + return visual!(pos, type, prop.scen, prop.x) +end \ No newline at end of file diff --git a/ext/OceanSonarMakieExt/propagation.jl b/ext/OceanSonarMakieExt/propagation.jl new file mode 100644 index 0000000..1193b82 --- /dev/null +++ b/ext/OceanSonarMakieExt/propagation.jl @@ -0,0 +1,19 @@ +function convert_arguments(::GridBased, prop::Propagation) + prop.x, prop.z, prop.PL +end + +colour(any::Any) = OceanSonar.colour(any) +colour(prop::Propagation) = OceanSonar.colour(prop) |> Reverse + +function visual!(pos::GridPosition, prop::Propagation) + plot = heatmap!(pos[1, 1], prop, + colormap = colour(prop), + colorrange = OceanSonar.colourrange(prop) + ) + axis = current_axis() + visual!(pos, Boundary, prop) + Colorbar(pos[1, 2], plot, + label = "Propagation Loss [dB re m²]" + ) + return axis +end \ No newline at end of file diff --git a/ext/OceanSonarMakieExt/ray.jl b/ext/OceanSonarMakieExt/ray.jl new file mode 100644 index 0000000..9cbb056 --- /dev/null +++ b/ext/OceanSonarMakieExt/ray.jl @@ -0,0 +1,32 @@ +function ray_series_data(beam::Beam) + arc = OceanSonar.default_arc_points(beam) + return [ + Point2(beam.x(s), beam.z(s)) + for s in arc + ] +end + +function convert_arguments(plot::Type{<:Series}, beams::AbstractVector{<:Beam}) + convert_arguments(plot, [ray_series_data(beam) for beam in beams]) +end + +function convert_arguments(plot::Type{<:Series}, beam::Beam) + convert_arguments(plot, [beam]) +end + +function visual!(pos::GridPosition, beams::AbstractVector{<:Beam}) + series!(pos[1, 1], beams, + solid_color = OceanSonar.colour(beams) + ) + return current_axis() +end + +visual!(pos::GridPosition, beam::Beam) = visual!(pos, [beam]) + +function visual!(pos::GridPosition, ::Type{Beam}, prop::Propagation) + visual!(pos, OceanCelerity, prop) + visual!(pos, Boundary, prop) + axis = visual!(pos, prop.beams) + axis.title = modeltitle(prop.scen) + return axis +end \ No newline at end of file diff --git a/ext/OceanSonarMakieExt_/OceanSonarMakieExt_.jl b/ext/OceanSonarMakieExt_/OceanSonarMakieExt_.jl new file mode 100644 index 0000000..ce9af21 --- /dev/null +++ b/ext/OceanSonarMakieExt_/OceanSonarMakieExt_.jl @@ -0,0 +1,40 @@ +module OceanSonarMakieExt + +using OceanSonar +using Makie +using Makie: AbstractAxis + +import OceanSonar: visual!, visual +import Makie: convert_arguments + +function get_plot_arguments(plot::Plot) + N = 0 + while true + try + N += 1 + plot[N].val + catch + N -= 1 + break + end + end + idxs = 1:N + return plot, (plot[n].val for n in idxs)... +end + +function visual(args...; kw...) + fig = Figure() + Axis(fig[1, 1]) + visual!(args...; kw...) + return fig +end + +include("boundary_.jl") +include("bivariate_.jl") +include("medium_.jl") +include("environment_.jl") +include("scenario_.jl") +include("ray_.jl") +include("propagation_.jl") + +end \ No newline at end of file diff --git a/ext/OceanSonarMakieExt_/bivariate_.jl b/ext/OceanSonarMakieExt_/bivariate_.jl new file mode 100644 index 0000000..35a99bd --- /dev/null +++ b/ext/OceanSonarMakieExt_/bivariate_.jl @@ -0,0 +1,40 @@ +import OceanSonar: bivariateplot!, bivariateplot + +@recipe(BivariatePlot) do scene + Theme() +end + +function bivariateplot_!( + plot::Plot, + biv::Bivariate, + x_lo::Real = 0.0, x_hi::Real = 1e3, + z_lo::Real = 0.0, z_hi::Real = 5e3 +) + x = range(x_lo, x_hi, 301) + z = range(z_lo, z_hi, 251) + + heatmap!(plot, + x, z, (x, z) -> biv(x, z), + colormap = OceanSonar.colour(biv), + axis = (yreversed = true,) # doesn't work in low-level Makie processing + ) +end + +bivariateplot_!(::Plot, args...) = error( + "No method matching desired signature for", args, ".\n", + "Try one of these:\n", + methods(bivariateplot_!) +) + +function Makie.plot!(plot::BivariatePlot) + get_plot_arguments(plot) |> splat(bivariateplot_!) +end + +function visual!(biv::Bivariate, args...; kw...) + plt = bivariateplot!(biv, args...; kw...) + ax = current_axis() + ax.yreversed = true + fig = current_figure() + Colorbar(fig[1, end+1], plt) + return current_figure() +end \ No newline at end of file diff --git a/ext/OceanSonarMakieExt_/boundary_.jl b/ext/OceanSonarMakieExt_/boundary_.jl new file mode 100644 index 0000000..bb27cb3 --- /dev/null +++ b/ext/OceanSonarMakieExt_/boundary_.jl @@ -0,0 +1,65 @@ +import OceanSonar: boundaryplot!, boundaryplot + +function ribbon_data(ati::Altimetry, x_lo::Real = 0.0, x_hi::Real = 1e3) + x = range(x_lo, x_hi, 301) + z_lo, _ = OceanSonar.depth_extrema(ati, x_lo, x_hi) + z_hi = ati.(x) + return x, z_lo, z_hi +end + +function ribbon_data(bty::Bathymetry, x_lo::Real = 0.0, x_hi::Real = 1e3) + x = range(x_lo, x_hi, 301) + _, z_hi = OceanSonar.depth_extrema(bty, x_lo, x_hi) + z_lo = bty.(x) + return x, z_lo, z_hi +end + +@recipe(BoundaryPlot) do scene + Theme() +end + +function boundaryplot_!( + plot::Plot, + bnd::Boundary, + x_lo::Real = 0.0, + x_hi::Real = 1e3 +) + band!(plot, + ribbon_data(bnd, x_lo, x_hi)..., + color = OceanSonar.colour(bnd), + axis = (yreversed = true,) # doesn't work in low-level Makie processing + ) + return plot +end + +function boundaryplot_!( + plot::Plot, + slc::Slice, + x_lo::Real = 0.0, + x_hi::Real = 1e3 +) + boundaryplot_!(plot, slc.bnd, x_lo, x_hi) +end + +function boundaryplot_!(plot::Plot, scen::Scenario) + x_lo = 0.0 + x_hi = scen.x + boundaryplot_!(plot, scen.slc, x_lo, x_hi) +end + +boundaryplot_!(::Plot, args...) = error( + "No method matching desired signature for", args, ".\n", + "Try one of these:\n", + methods(boundaryplot_!) +) + +function Makie.plot!(plot::BoundaryPlot) + get_plot_arguments(plot) |> splat(boundaryplot_!) +end + +function visual!(bnd::Boundary, args...; kw...) + plot = boundaryplot!(bnd, args...; kw...) + ax = current_axis() + ax.yreversed = true + return current_figure() +end \ No newline at end of file diff --git a/ext/OceanSonarMakieExt_/environment_.jl b/ext/OceanSonarMakieExt_/environment_.jl new file mode 100644 index 0000000..2c1d60c --- /dev/null +++ b/ext/OceanSonarMakieExt_/environment_.jl @@ -0,0 +1,37 @@ +function visual!(slc::Slice, x_lo::Real, x_hi::Real; kw...) + visual!(slc.ati, x_lo, x_hi; kw...) + visual!(slc.bty, x_lo, x_hi; kw...) + return current_figure() +end + +get_boundary(::Type{Altimetry}, slc::Slice) = slc.ati +get_boundary(::Type{Bathymetry}, slc::Slice) = slc.bty + +function visual!(type::Type{<:Boundary}, slc::Slice, + x_lo::Real = 0.0, x_hi::Real = 1e3; + kw... +) + @assert isconcretetype(type) "Expecting concrete type request." + visual!(get_boundary(type, slc), x_lo, x_hi) + return current_figure() +end + +function visual!(type::Type{<:Bivariate}, slc::Slice, + x_lo::Real = 0.0, x_hi::Real = 1e3; + kw... +) + super = supertype(type) + @assert super ≠ Bivariate + z_lo, z_hi = OceanSonar.depth_extrema(slc, x_lo, x_hi) + visual!(super, slc.ocn, x_lo, x_hi, z_lo, z_hi; kw...) + visual!(slc, x_lo, x_hi) + return current_figure() +end + +function visual!(::Type{Boundary}, slc::Slice, + x_lo::Real = 0.0, x_hi::Real = 1e3; + kw... +) + visual!(slc, x_lo, x_hi; kw...) + return current_figure() +end \ No newline at end of file diff --git a/ext/OceanSonarMakieExt_/medium_.jl b/ext/OceanSonarMakieExt_/medium_.jl new file mode 100644 index 0000000..018ad5d --- /dev/null +++ b/ext/OceanSonarMakieExt_/medium_.jl @@ -0,0 +1,11 @@ +get_bivariate(::Type{Celerity}, med::Medium) = med.cel +get_bivariate(::Type{OceanSonar.Density}, med::Medium) = med.den + +function visual!(type::Type{<:Bivariate}, med::Medium, + x_lo::Real, x_hi::Real, + z_lo::Real, z_hi::Real; + kw... +) + visual!(get_bivariate(type, med), x_lo, x_hi, z_lo, z_hi; kw...) + return current_figure() +end \ No newline at end of file diff --git a/ext/OceanSonarMakieExt_/propagation_.jl b/ext/OceanSonarMakieExt_/propagation_.jl new file mode 100644 index 0000000..c9bc963 --- /dev/null +++ b/ext/OceanSonarMakieExt_/propagation_.jl @@ -0,0 +1,47 @@ +import OceanSonar: propagationplot!, propagationplot + +@recipe(PropagationPlot) do scene + Theme() +end + +function propagationplot_!(plot::Plot, prop::Propagation) + heatmap!(plot, + prop.x, prop.z, prop.PL, + colormap = Makie.Reverse(:jet), + axis = (yreversed = true,) # doesn't work in low-level Makie processing + ) +end + +propagationplot_!(::Plot, args...) = error( + "No method matching desired signature for", args, ".\n", + "Try one of these:\n", + methods(propagationplot_!) +) + +function Makie.plot!(plot::PropagationPlot) + get_plot_arguments(plot) |> splat(propagationplot_!) +end + +function visual!(type::Type{<:OceanSonar.Functor}, prop::Propagation, args...; kw...) + visual!(type, prop.scen, args...; kw...) + return current_figure() +end + +function visual!(prop::Propagation; kw...) + plt = propagationplot!(prop; kw...) + ax = current_axis() + ax.yreversed = true + fig = current_figure() + Colorbar(fig[1, end+1], plt) + + visual!(Boundary, prop) + + return current_figure() +end + +function visual!(::Type{Beam}, prop::Propagation, args...; kw...) + visual!(prop.beams, args...; kw...) + visual!(Boundary, prop) + + return current_figure() +end \ No newline at end of file diff --git a/ext/OceanSonarMakieExt_/ray_.jl b/ext/OceanSonarMakieExt_/ray_.jl new file mode 100644 index 0000000..5bd4298 --- /dev/null +++ b/ext/OceanSonarMakieExt_/ray_.jl @@ -0,0 +1,39 @@ +import OceanSonar: rayplot!, rayplot + +@recipe(RayPlot) do scene + Theme() +end + +function ray_series_data(beam) + arc = OceanSonar.default_arc_points(beam) + return [ + Point2(beam.x(s), beam.z(s)) + for s in arc + ] +end + +function rayplot_!(plot::Plot, beams::Vector{Beam}) + rays = [ray_series_data(beam) for beam in beams] + series!(plot, + rays, + solid_color = :black, + ) + return plot +end + +rayplot_!(::Plot, args...) = error( + "No method matching desired signature for", args, ".\n", + "Try one of these:\n", + methods(rayplot_!) +) + +function Makie.plot!(plot::RayPlot) + get_plot_arguments(plot) |> splat(rayplot_!) +end + +function visual!(beams::Vector{Beam}; kw...) + rayplot!(beams; kw...) + return current_figure() +end + +visual!(beam::Beam; kw...) = visual!([beam]; kw...) \ No newline at end of file diff --git a/ext/OceanSonarMakieExt_/scenario_.jl b/ext/OceanSonarMakieExt_/scenario_.jl new file mode 100644 index 0000000..06ac291 --- /dev/null +++ b/ext/OceanSonarMakieExt_/scenario_.jl @@ -0,0 +1,9 @@ +function visual!(type::Type{<:OceanSonar.Functor}, scen::Scenario) + visual!(type, scen.slc, 0.0, scen.x) + return current_figure() +end + +function visual!(scen::Scenario) + visual!(OceanCelerity, scen) + return current_figure() +end \ No newline at end of file diff --git a/ext/OceanSonarPlotsExt/OceanSonarPlotsExt.jl b/ext/OceanSonarPlotsExt/OceanSonarPlotsExt.jl new file mode 100644 index 0000000..e822e1a --- /dev/null +++ b/ext/OceanSonarPlotsExt/OceanSonarPlotsExt.jl @@ -0,0 +1,21 @@ +module OceanSonarPlotsExt + +using OceanSonar +using Plots + +import OceanSonar: visual!, visual + +function visual(args...; kw...) + plot() + visual!(args...; kw...) +end + +include("boundary.jl") +include("bivariate.jl") +include("medium.jl") +include("slice.jl") +include("scenario.jl") +include("beam.jl") +include("propagation.jl") + +end \ No newline at end of file diff --git a/ext/OceanSonarPlotsExt/beam.jl b/ext/OceanSonarPlotsExt/beam.jl new file mode 100644 index 0000000..00ebd81 --- /dev/null +++ b/ext/OceanSonarPlotsExt/beam.jl @@ -0,0 +1,32 @@ +@recipe _(beam::Beam) = (([beam]),) + +# TODO: +# * Make more efficient +# * Truncate to x-limits +@recipe function _(beams::Vector{Beam}) + legend --> :none + yflip --> true + color --> :black + + x = [ + beam.x.( + [ + range(0, beam.s_max, 301); beam.s_srf; beam.s_bot; beam.s_hrz + ] |> uniquesort! + ) for beam in beams + ] + + z = [ + beam.z.( + [ + range(0, beam.s_max, 301); beam.s_srf; beam.s_bot; beam.s_hrz + ] |> uniquesort! + ) for beam in beams + ] + + ((x, z),) +end + +visual!(beam::Beam; kw...) = plot!(beam; kw...) + +visual!(beams::Vector{Beam}; kw...) = plot!(beams; kw...) \ No newline at end of file diff --git a/ext/OceanSonarPlotsExt/bivariate.jl b/ext/OceanSonarPlotsExt/bivariate.jl new file mode 100644 index 0000000..b32fa7a --- /dev/null +++ b/ext/OceanSonarPlotsExt/bivariate.jl @@ -0,0 +1,16 @@ +@recipe function _(biv::Bivariate; Nx = 301, Nz = 251) + x_lim = get(plotattributes, :xlims, (0.0, 1e3)) + z_lim = get(plotattributes, :ylims, (0.0, 1e3)) + + x = range(x_lim..., Nx) + z = range(z_lim..., Nz) + + seriestype --> :heatmap + legend --> :none + yflip --> true + colormap --> OceanSonar.colour(biv) + + x, z, (x, z) -> biv(x, z) +end + +visual!(biv::Bivariate; kw...) = plot!(biv; kw...) \ No newline at end of file diff --git a/ext/OceanSonarPlotsExt/boundary.jl b/ext/OceanSonarPlotsExt/boundary.jl new file mode 100644 index 0000000..4500f37 --- /dev/null +++ b/ext/OceanSonarPlotsExt/boundary.jl @@ -0,0 +1,21 @@ +boundary_outermost(::Altimetry, z_lo, z_hi) = z_lo +boundary_outermost(::Bathymetry, z_lo, z_hi) = z_hi + +@recipe function _(bnd::OceanSonar.Boundary) + seriestype := :path + x_lim = get(plotattributes, :xlims, (0.0, 1e3)) + z_lo, z_hi = OceanSonar.depth_extrema(bnd, x_lim...) + if z_lo == z_hi + nothing + else + legend --> :none + yflip --> true + color --> OceanSonar.colour(bnd) + + fillrange := boundary_outermost(bnd, z_lo, z_hi) + + x -> bnd(x) + end +end + +visual!(bnd::Boundary; kw...) = plot!(bnd; kw...) \ No newline at end of file diff --git a/ext/OceanSonarPlotsExt/medium.jl b/ext/OceanSonarPlotsExt/medium.jl new file mode 100644 index 0000000..b7f5393 --- /dev/null +++ b/ext/OceanSonarPlotsExt/medium.jl @@ -0,0 +1,2 @@ +visual!(::Type{Celerity}, med::Medium; kw...) = visual!(med.cel; kw...) +visual!(::Type{OceanSonar.Density}, med::Medium; kw...) = visual!(med.den; kw...) \ No newline at end of file diff --git a/ext/OceanSonarPlotsExt/propagation.jl b/ext/OceanSonarPlotsExt/propagation.jl new file mode 100644 index 0000000..a699648 --- /dev/null +++ b/ext/OceanSonarPlotsExt/propagation.jl @@ -0,0 +1,26 @@ +@recipe function _(prop::Propagation) + seriestype --> :heatmap + legend --> :none + yflip --> true + colormap --> cgrad(:jet, rev = true) + + prop.x, prop.z, prop.PL' +end + +function visual!(prop::Propagation; kw...) + plot!(prop; kw...) + visual!(Boundary, prop; kw...) +end + +visual!(type::Type{<:Boundary}, prop::Propagation; kw...) = visual!(type, prop.scen; kw...) + +visual!(type::Type{<:Bivariate}, prop::Propagation; kw...) = visual!(type, prop.scen; kw...) + +function visual!(::Type{Beam}, prop::Propagation; kw...) + visual!(OceanCelerity, prop; kw...) + visual!(prop.beams; kw...) + visual!(Boundary, prop) + plot!( + title = string("Ray Trace: ", prop.scen.model |> modeltitle) + ) +end \ No newline at end of file diff --git a/ext/OceanSonarPlotsExt/scenario.jl b/ext/OceanSonarPlotsExt/scenario.jl new file mode 100644 index 0000000..34c6b93 --- /dev/null +++ b/ext/OceanSonarPlotsExt/scenario.jl @@ -0,0 +1,35 @@ +@recipe function _(scen::Scenario; ownship_color = :green) + xlims --> (0.0, scen.x) + ylims --> OceanSonar.depth_extrema(scen) + yflip --> true + + seriestype --> :scatter + markershape --> :star8 + color --> ownship_color + ((0, scen.z),) +end + +function visual!(scen::Scenario; kw...) + plot!(scen; + xlims = (0, scen.x), + ylims = OceanSonar.depth_extrema(scen), + kw... + ) + visual!(Boundary, scen; kw...) +end + +function visual!(type::Type{<:Boundary}, scen::Scenario; kw...) + visual!(type, scen.slc; + xlims = (0, scen.x), + ylims = OceanSonar.depth_extrema(scen), + kw... + ) +end + +function visual!(type::Type{<:Bivariate}, scen::Scenario; kw...) + visual!(type, scen.slc; + xlims = (0, scen.x), + ylims = OceanSonar.depth_extrema(scen), + kw... + ) +end \ No newline at end of file diff --git a/ext/OceanSonarPlotsExt/slice.jl b/ext/OceanSonarPlotsExt/slice.jl new file mode 100644 index 0000000..85c2126 --- /dev/null +++ b/ext/OceanSonarPlotsExt/slice.jl @@ -0,0 +1,25 @@ +visual!(::Type{Altimetry}, slc::Slice; kw...) = visual!(slc.ati; kw...) +visual!(::Type{Bathymetry}, slc::Slice; kw...) = visual!(slc.bty; kw...) + +function visual!(::Type{Boundary}, slc::Slice; kw...) + visual!(slc.ati; kw...) + visual!(slc.bty; kw...) +end + +# TODO: Automate through `Bivariate`s. + +function visual!(::Type{OceanCelerity}, slc::Slice; kw...) + visual!(Celerity, slc.ocn; kw...) + visual!(Boundary, slc; kw...) + plot!( + colorbar_title = " \n" * "Ocean Sound Speed [m/s]", + colorbar_title_font_halign = :right + ) +end + +function visual!(::Type{OceanDensity}, slc::Slice; kw...) + visual!(OceanSonar.Density, slc.ocn; kw...) + visual!(Boundary, slc; kw...) +end + +visual!(slc::Slice; kw...) = visual!(OceanCelerity, slc) \ No newline at end of file diff --git a/license.md b/license.md new file mode 100644 index 0000000..192b8ed --- /dev/null +++ b/license.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Aaron Kaw and contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/notebooks/mtk.jl b/notebooks/mtk.jl new file mode 100644 index 0000000..1511fc1 --- /dev/null +++ b/notebooks/mtk.jl @@ -0,0 +1,218 @@ +### A Pluto.jl notebook ### +# v0.19.41 + +using Markdown +using InteractiveUtils + +# ╔═╡ f6f34400-dd3f-11ee-1a23-33af0a082239 +begin + using Pkg + + Pkg.add("ModelingToolkit") + Pkg.add("OrdinaryDiffEq") + Pkg.add("Plots") + Pkg.develop("OceanSonar") + + using ModelingToolkit + using OrdinaryDiffEq + using Plots + using OceanSonar + + Pkg.status() +end + +# ╔═╡ 7e349625-b3d6-4e6b-a9d7-7ac032ab4aa9 +md""" +# Modeling Toolkit Compatibility +The following code will become part of OceanSonar.jl once the needed features are implemented in ModelingToolkit.jl. + +E.g. +""" + +# ╔═╡ d429c4ad-50cc-47aa-a45e-b0df10d41b43 +@mtkmodel Eikonal begin + begin + s = only(@parameters s) + end + + @variables begin + x(s), [description = "Horizontal range"] + z(s), [description = "Downward depth"] + ξ(s), [description = "Normalised horizontal celerity gradient"] + ζ(s), [description = "Normalised vertical celerity gradient"] + end + + @structural_parameters begin + scen + end + + begin + D = Differential(s) + ∂c_∂z(x, z) = ModelingToolkit.derivative(c(x, z), z) + ∂c_∂x(x, z) = ModelingToolkit.derivative(c(x, z), x) + + c = scen.slc.ocn.cel + end + + @continuous_events begin + [x ~ scen.x] => ((t1, t2, t3, t4) -> terminate!(t1), [], [], []) + [z ~ 0] => [ζ ~ -ζ] + end + + @equations begin + D(x) ~ c(x, z) * ξ + D(z) ~ c(x, z) * ζ + D(ξ) ~ -∂c_∂x(x, z) / c(x, z)^2 + D(ζ) ~ -∂c_∂z(x, z) / c(x, z)^2 + end +end + +# ╔═╡ d9869488-44db-4a09-a030-1c707c484856 +function munk_profile(x, z; ϵ = 7.37e-3) + z̃ = 2(z - 1300)/1300 + 1500(1 + ϵ * (z̃ - 1 + exp(-z̃))) +end + +# ╔═╡ 8b79f49d-5486-4bd9-8e6f-c5f74c5579e2 +@mtkbuild eik = Eikonal(scen = scen) + +# ╔═╡ d32b532c-59c9-4f3c-aebe-4d5eabf69b10 +scen = Scenario("Munk Profile") + +# ╔═╡ 49b98d31-ce55-47ee-8b27-fed9365c6a6a +@mtkbuild eik_munk = Eikonal(scen = scen) + +# ╔═╡ ed059bda-f4a1-462d-91a8-39750ead7926 +sol_munk = let + angle = 0.0 + u0 = [ + 0.0 + 1e3 + cos(angle) / munk_profile(0.0, 1e3) + sin(angle) / munk_profile(0.0, 1e3) + ] + prob = ODEProblem(eik, u0, (0.0, 100e3)) + sol = solve(prob, Tsit5()) +end + +# ╔═╡ 830f3ff2-f62c-475e-bdd5-ba3772c67dcf +plot(sol_munk, idxs = (:x, :z), yflip = true) + +# ╔═╡ 20e37e67-7a97-4598-b6c3-92e021464a53 +# function trace(scen::Scenario, angle) +# @mtkbuild eik_scen = Eikonal(c = scen.slc.ocn.cel) +# x0 = 0.0 +# z0 = scen.z +# u0 = [ +# x0 +# z0 +# cos(angle) / scen.slc.ocn.cel(x0, z0) +# sin(angle) / scen.slc.ocn.cel(x0, z0) +# ] + +# # prob = ODEProblem(eik_scen, u0, OceanSonar.DEFAULT_RAY_ARC_SPAN) +# prob = ODEProblem(eik_scen, u0, (0.0, 100e3)) +# sol = solve(prob, Tsit5()) +# end + +# ╔═╡ 57041ca1-be9c-41b0-809b-c90dd3874f8b +function trace(scen::Scenario, angle) + @mtkbuild eik = Eikonal(scen = scen) + x0 = 0.0 + z0 = scen.z + u0 = [ + x0 + z0 + cos(angle) / scen.slc.ocn.cel(x0, z0) + sin(angle) / scen.slc.ocn.cel(x0, z0) + ] + + prob = ODEProblem(eik, u0, OceanSonar.DEFAULT_RAY_ARC_SPAN) + # prob = ODEProblem(eik, u0, (0.0, 250e3); + # continuous_events = [ + # [eik.x ~ scen.x] => (terminate!, [], [], [], nothing), + # [eik.z ~ 0] => [eik.ζ ~ -eik.ζ] + # ] + # ) + # prob = ODEProblem(eik, u0, (0.0, 250e3); + # continuous_events = [eik.z ~ 0] => [eik.ζ ~ -eik.ζ] + # ) + sol = solve(prob, Tsit5()) +end + +# ╔═╡ 3c6b2229-5ba7-43bf-8fef-f7600a3aba11 +sol = trace(scen, -π/4) + +# ╔═╡ 17c9a114-90a7-4eeb-a277-98945f289186 +plot(sol, idxs = (:x, :z), yflip = true) + +# ╔═╡ d9451565-7a71-4be6-90cc-85a1710f43f3 +sol2 = trace(scen, -0.25) + +# ╔═╡ 2a83e4a1-976e-4e52-8059-5bd0a01fb5e3 +plot(sol2, idxs = (:x, :z), yflip = true) + +# ╔═╡ 705b54ee-98a9-4df7-afba-43e3317423c9 +sols = trace.(scen, critical_angles(scen, N = 21)) + +# ╔═╡ faea319b-61fe-4f96-a7fc-eed6a2f2b2de +critical_angles(scen, N = 3) + +# ╔═╡ d3e843dd-86ab-4aee-b8f7-918055acbc0a +let + plot() + plot!.(sols, idxs = (:x, :z)) + plot!(yflip = true, legend = false) +end + +# ╔═╡ 7aec2d3d-1b7e-49ff-97b4-9e29d2ef9ae9 +let + plot() + plot!.(sols, idxs = (:x, :z)) + plot!(yflip = true, legend = false, xlim = (0, 250e3)) +end + +# ╔═╡ c18f392c-557e-43b3-8644-65aeb78ed837 +scen_lcz = Scenario("linearised Convergence Zones"); + +# ╔═╡ b61be131-2bf2-422f-8a81-fb5980999371 +sols_lcz = trace.(scen_lcz, critical_angles(scen_lcz, N = 21)); + +# ╔═╡ d6bd9ed2-d768-4ea3-beeb-e1aaa5d068c5 +let + plot() + plot!.(sols_lcz, idxs = (:x, :z)) + plot!(yflip = true, legend = false) +end + +# ╔═╡ 1aea1350-51b0-4dc0-a0d6-4f061b8cebb4 +names(Symbolics) + +# ╔═╡ 1ace5e8a-106c-4dae-a43c-9fcf625418b1 +@register_symbolic + +# ╔═╡ Cell order: +# ╟─7e349625-b3d6-4e6b-a9d7-7ac032ab4aa9 +# ╠═f6f34400-dd3f-11ee-1a23-33af0a082239 +# ╠═d429c4ad-50cc-47aa-a45e-b0df10d41b43 +# ╠═d9869488-44db-4a09-a030-1c707c484856 +# ╠═8b79f49d-5486-4bd9-8e6f-c5f74c5579e2 +# ╠═d32b532c-59c9-4f3c-aebe-4d5eabf69b10 +# ╠═49b98d31-ce55-47ee-8b27-fed9365c6a6a +# ╠═ed059bda-f4a1-462d-91a8-39750ead7926 +# ╠═830f3ff2-f62c-475e-bdd5-ba3772c67dcf +# ╠═20e37e67-7a97-4598-b6c3-92e021464a53 +# ╠═57041ca1-be9c-41b0-809b-c90dd3874f8b +# ╠═3c6b2229-5ba7-43bf-8fef-f7600a3aba11 +# ╠═17c9a114-90a7-4eeb-a277-98945f289186 +# ╠═d9451565-7a71-4be6-90cc-85a1710f43f3 +# ╠═2a83e4a1-976e-4e52-8059-5bd0a01fb5e3 +# ╠═705b54ee-98a9-4df7-afba-43e3317423c9 +# ╠═faea319b-61fe-4f96-a7fc-eed6a2f2b2de +# ╠═d3e843dd-86ab-4aee-b8f7-918055acbc0a +# ╠═7aec2d3d-1b7e-49ff-97b4-9e29d2ef9ae9 +# ╠═c18f392c-557e-43b3-8644-65aeb78ed837 +# ╠═b61be131-2bf2-422f-8a81-fb5980999371 +# ╠═d6bd9ed2-d768-4ea3-beeb-e1aaa5d068c5 +# ╠═1aea1350-51b0-4dc0-a0d6-4f061b8cebb4 +# ╠═1ace5e8a-106c-4dae-a43c-9fcf625418b1 diff --git a/notebooks/mtk2.jl b/notebooks/mtk2.jl new file mode 100644 index 0000000..a822897 --- /dev/null +++ b/notebooks/mtk2.jl @@ -0,0 +1,2298 @@ +### A Pluto.jl notebook ### +# v0.19.41 + +using Markdown +using InteractiveUtils + +# ╔═╡ 9439f2ed-1dc5-4333-934c-9e49a61e9915 +using Pkg + +# ╔═╡ c3ef64c0-03d8-11ef-38c5-035a60e72ba5 +using ModelingToolkit + +# ╔═╡ 018a6d5d-f7c9-4cba-a2e7-bc6d8dd6e24c +using OrdinaryDiffEq + +# ╔═╡ cf19a33d-f6b8-4db5-aa58-eed8b305c437 +using Plots + +# ╔═╡ 27930d05-f61d-4681-95a5-4cc3e3048476 +Pkg.status() + +# ╔═╡ 88fe0db6-58cb-4fe4-897f-20cb4bc91914 +@mtkmodel Eikonal begin + begin + s = only(@parameters s) + end + + @variables begin + x(s), [description = "Horizontal range"] + z(s), [description = "Downward depth"] + ξ(s), [description = "Normalised horizontal celerity gradient"] + ζ(s), [description = "Normalised vertical celerity gradient"] + end + + @structural_parameters begin + c + x_max + end + + begin + D = Differential(s) + ∂c_∂z(x, z) = ModelingToolkit.derivative(c(x, z), z) + ∂c_∂x(x, z) = ModelingToolkit.derivative(c(x, z), x) + end + + @continuous_events begin + [x ~ x_max] => ((t1, t2, t3, t4) -> terminate!(t1), [], [], []) + [z ~ 0] => [ζ ~ -ζ] + end + + @equations begin + D(x) ~ c(x, z) * ξ + D(z) ~ c(x, z) * ζ + D(ξ) ~ -∂c_∂x(x, z) / c(x, z)^2 + D(ζ) ~ -∂c_∂z(x, z) / c(x, z)^2 + end +end + +# ╔═╡ 9987b4d8-9c1a-4906-8c16-b492e6e57e28 +function munk_profile(x, z; ϵ = 7.37e-3) + z̃ = 2(z - 1300)/1300 + 1500(1 + ϵ * (z̃ - 1 + exp(-z̃))) +end + +# ╔═╡ 6123e783-bb7f-4719-a1b7-24e7cf1826d6 +c = munk_profile + +# ╔═╡ a0ccd3e8-91ca-4ee2-9717-a5540561ad46 +@mtkbuild eik = Eikonal(c = c, x_max = 10e3) + +# ╔═╡ f167af9b-3c38-4695-acdc-5a1643fcb549 +z_src = 1e3 + +# ╔═╡ cdf6730f-a8de-43d5-83ef-7c57c87ae4ea +angles = [-1.1, -1, 0, 1, 1.1] * acos(c(0.0, z_src) / c(0.0, 0.0)) + +# ╔═╡ d8f898a0-3f8c-4438-b868-6688d86c7328 +init_cond(θ₀) = [ + 0.0; z_src; + [cos(θ₀), sin(θ₀)] / c(0.0, z_src) +] + +# ╔═╡ 848f3025-a1fa-432c-8c1d-e569d93b6323 +prob = ODEProblem(eik, init_cond(0), (0, 200e3)) + +# ╔═╡ 9c372062-4f73-43a3-9018-c4d21f7d12dc +sol = solve(prob, Tsit5()) + +# ╔═╡ 6b5a9aa0-e31e-4af2-b16e-f6aca6e15350 +plot(sol, idxs = (:x, :z), yflip = true) + +# ╔═╡ d1cff8c1-8443-404a-825e-38d2ef06122f +function prob_func(prob, i, repeat) + remake(prob, u0 = init_cond(π * (rand() - 0.5))) +end + +# ╔═╡ 94a1ac29-1fbb-47f3-93d9-c5ca0b6a75ae +ens_prob = EnsembleProblem(prob, prob_func = prob_func) + +# ╔═╡ 87673d46-b120-40fa-b048-9ada54ea7768 +sim = solve(ens_prob, Tsit5(), EnsembleThreads(), trajectories = 5) + +# ╔═╡ 3b40d052-2a41-4e28-8537-928ebb93d55c +plot(sim, idxs = (:x, :z), yflip = true) + +# ╔═╡ 00000000-0000-0000-0000-000000000001 +PLUTO_PROJECT_TOML_CONTENTS = """ +[deps] +ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78" +OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" + +[compat] +ModelingToolkit = "~9.12.0" +OrdinaryDiffEq = "~6.74.1" +Plots = "~1.40.4" +""" + +# ╔═╡ 00000000-0000-0000-0000-000000000002 +PLUTO_MANIFEST_TOML_CONTENTS = """ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.10.2" +manifest_format = "2.0" +project_hash = "e9560e45a5c81ce4c0bc1ff3aeb93c7c4c152196" + +[[deps.ADTypes]] +git-tree-sha1 = "016833eb52ba2d6bea9fcb50ca295980e728ee24" +uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" +version = "0.2.7" + +[[deps.AbstractTrees]] +git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177" +uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" +version = "0.4.5" + +[[deps.Accessors]] +deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "LinearAlgebra", "MacroTools", "Markdown", "Test"] +git-tree-sha1 = "c0d491ef0b135fd7d63cbc6404286bc633329425" +uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" +version = "0.1.36" + + [deps.Accessors.extensions] + AccessorsAxisKeysExt = "AxisKeys" + AccessorsIntervalSetsExt = "IntervalSets" + AccessorsStaticArraysExt = "StaticArrays" + AccessorsStructArraysExt = "StructArrays" + AccessorsUnitfulExt = "Unitful" + + [deps.Accessors.weakdeps] + AxisKeys = "94b1ba4f-4ee9-5380-92f1-94cde586c3c5" + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + Requires = "ae029012-a4dd-5104-9daa-d747884805df" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.Adapt]] +deps = ["LinearAlgebra", "Requires"] +git-tree-sha1 = "6a55b747d1812e699320963ffde36f1ebdda4099" +uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" +version = "4.0.4" +weakdeps = ["StaticArrays"] + + [deps.Adapt.extensions] + AdaptStaticArraysExt = "StaticArrays" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.1" + +[[deps.ArnoldiMethod]] +deps = ["LinearAlgebra", "Random", "StaticArrays"] +git-tree-sha1 = "d57bd3762d308bded22c3b82d033bff85f6195c6" +uuid = "ec485272-7323-5ecc-a04f-4719b315124d" +version = "0.4.0" + +[[deps.ArrayInterface]] +deps = ["Adapt", "LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "44691067188f6bd1b2289552a23e4b7572f4528d" +uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" +version = "7.9.0" + + [deps.ArrayInterface.extensions] + ArrayInterfaceBandedMatricesExt = "BandedMatrices" + ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" + ArrayInterfaceCUDAExt = "CUDA" + ArrayInterfaceChainRulesExt = "ChainRules" + ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" + ArrayInterfaceReverseDiffExt = "ReverseDiff" + ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" + ArrayInterfaceTrackerExt = "Tracker" + + [deps.ArrayInterface.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + +[[deps.ArrayLayouts]] +deps = ["FillArrays", "LinearAlgebra"] +git-tree-sha1 = "33207a8be6267bc389d0701e97a9bce6a4de68eb" +uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" +version = "1.9.2" +weakdeps = ["SparseArrays"] + + [deps.ArrayLayouts.extensions] + ArrayLayoutsSparseArraysExt = "SparseArrays" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" + +[[deps.Bijections]] +git-tree-sha1 = "c9b163bd832e023571e86d0b90d9de92a9879088" +uuid = "e2ed5e7c-b2de-5872-ae92-c73ca462fb04" +version = "0.1.6" + +[[deps.BitFlags]] +git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" +uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" +version = "0.1.8" + +[[deps.BitTwiddlingConvenienceFunctions]] +deps = ["Static"] +git-tree-sha1 = "0c5f81f47bbbcf4aea7b2959135713459170798b" +uuid = "62783981-4cbd-42fc-bca8-16325de8dc4b" +version = "0.1.5" + +[[deps.Bzip2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "9e2a6b69137e6969bab0152632dcb3bc108c8bdd" +uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" +version = "1.0.8+1" + +[[deps.CPUSummary]] +deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] +git-tree-sha1 = "601f7e7b3d36f18790e2caf83a882d88e9b71ff1" +uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" +version = "0.2.4" + +[[deps.CSTParser]] +deps = ["Tokenize"] +git-tree-sha1 = "b544d62417a99d091c569b95109bc9d8c223e9e3" +uuid = "00ebfdb7-1f24-5e51-bd34-a7502290713f" +version = "3.4.2" + +[[deps.Cairo_jll]] +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "a4c43f59baa34011e303e76f5c8c91bf58415aaf" +uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" +version = "1.18.0+1" + +[[deps.Calculus]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" +uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" +version = "0.5.1" + +[[deps.ChainRulesCore]] +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "575cd02e080939a33b6df6c5853d14924c08e35b" +uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +version = "1.23.0" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" + +[[deps.CloseOpenIntervals]] +deps = ["Static", "StaticArrayInterface"] +git-tree-sha1 = "70232f82ffaab9dc52585e0dd043b5e0c6b714f1" +uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" +version = "0.1.12" + +[[deps.CodecZlib]] +deps = ["TranscodingStreams", "Zlib_jll"] +git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73" +uuid = "944b1d66-785c-5afd-91f1-9de20f533193" +version = "0.7.4" + +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.24.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "b10d0b65641d57b8b4d5e234446582de5047050d" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.11.5" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.10.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.12.10" + +[[deps.Combinatorics]] +git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" +uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" +version = "1.0.2" + +[[deps.CommonMark]] +deps = ["Crayons", "JSON", "PrecompileTools", "URIs"] +git-tree-sha1 = "532c4185d3c9037c0237546d817858b23cf9e071" +uuid = "a80b9123-70ca-4bc0-993e-6e3bcb318db6" +version = "0.8.12" + +[[deps.CommonSolve]] +git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" +uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" +version = "0.2.4" + +[[deps.CommonSubexpressions]] +deps = ["MacroTools", "Test"] +git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" +version = "0.3.0" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "c955881e3c981181362ae4088b35995446298b80" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.14.0" +weakdeps = ["Dates", "LinearAlgebra"] + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + +[[deps.CompilerSupportLibraries_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" +version = "1.1.0+0" + +[[deps.CompositeTypes]] +git-tree-sha1 = "bce26c3dab336582805503bed209faab1c279768" +uuid = "b152e2b5-7a66-4b01-a709-34e65c35f657" +version = "0.1.4" + +[[deps.CompositionsBase]] +git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" +uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" +version = "0.1.2" +weakdeps = ["InverseFunctions"] + + [deps.CompositionsBase.extensions] + CompositionsBaseInverseFunctionsExt = "InverseFunctions" + +[[deps.ConcreteStructs]] +git-tree-sha1 = "f749037478283d372048690eb3b5f92a79432b34" +uuid = "2569d6c7-a4a2-43d3-a901-331e8e4be471" +version = "0.2.3" + +[[deps.ConcurrentUtilities]] +deps = ["Serialization", "Sockets"] +git-tree-sha1 = "6cbbd4d241d7e6579ab354737f4dd95ca43946e1" +uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" +version = "2.4.1" + +[[deps.ConstructionBase]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "260fd2400ed2dab602a7c15cf10c1933c59930a2" +uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" +version = "1.5.5" +weakdeps = ["IntervalSets", "StaticArrays"] + + [deps.ConstructionBase.extensions] + ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseStaticArraysExt = "StaticArrays" + +[[deps.Contour]] +git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" +uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" +version = "0.6.3" + +[[deps.CpuId]] +deps = ["Markdown"] +git-tree-sha1 = "fcbb72b032692610bfbdb15018ac16a36cf2e406" +uuid = "adafc99b-e345-5852-983c-f28acb93d879" +version = "0.3.1" + +[[deps.Crayons]] +git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" +uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" +version = "4.1.1" + +[[deps.DataAPI]] +git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" +uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" +version = "1.16.0" + +[[deps.DataStructures]] +deps = ["Compat", "InteractiveUtils", "OrderedCollections"] +git-tree-sha1 = "1d0a14036acb104d9e89698bd408f63ab58cdc82" +uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" +version = "0.18.20" + +[[deps.DataValueInterfaces]] +git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" +uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" +version = "1.0.0" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" + +[[deps.DelimitedFiles]] +deps = ["Mmap"] +git-tree-sha1 = "9e2f36d3c96a820c678f2f1f1782582fcf685bae" +uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" +version = "1.9.1" + +[[deps.DiffEqBase]] +deps = ["ArrayInterface", "ConcreteStructs", "DataStructures", "DocStringExtensions", "EnumX", "EnzymeCore", "FastBroadcast", "FastClosures", "ForwardDiff", "FunctionWrappers", "FunctionWrappersWrappers", "LinearAlgebra", "Logging", "Markdown", "MuladdMacro", "Parameters", "PreallocationTools", "PrecompileTools", "Printf", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Static", "StaticArraysCore", "Statistics", "Tricks", "TruncatedStacktraces"] +git-tree-sha1 = "531c53fd0405716712a8b4960216c3b7b5ec89b9" +uuid = "2b5f629d-d688-5b77-993f-72d75c75574e" +version = "6.149.1" + + [deps.DiffEqBase.extensions] + DiffEqBaseChainRulesCoreExt = "ChainRulesCore" + DiffEqBaseDistributionsExt = "Distributions" + DiffEqBaseEnzymeExt = ["ChainRulesCore", "Enzyme"] + DiffEqBaseGeneralizedGeneratedExt = "GeneralizedGenerated" + DiffEqBaseMPIExt = "MPI" + DiffEqBaseMeasurementsExt = "Measurements" + DiffEqBaseMonteCarloMeasurementsExt = "MonteCarloMeasurements" + DiffEqBaseReverseDiffExt = "ReverseDiff" + DiffEqBaseTrackerExt = "Tracker" + DiffEqBaseUnitfulExt = "Unitful" + + [deps.DiffEqBase.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + GeneralizedGenerated = "6b9d7cbe-bcb9-11e9-073f-15a7a543e2eb" + MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" + Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" + MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.DiffEqCallbacks]] +deps = ["DataStructures", "DiffEqBase", "ForwardDiff", "Functors", "LinearAlgebra", "Markdown", "NonlinearSolve", "Parameters", "RecipesBase", "RecursiveArrayTools", "SciMLBase", "StaticArraysCore"] +git-tree-sha1 = "ec436ca77daad49b71147d873638c206543c2312" +uuid = "459566f4-90b8-5000-8ac3-15dfb0a30def" +version = "3.6.1" + + [deps.DiffEqCallbacks.weakdeps] + OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" + Sundials = "c3572dad-4567-51f8-b174-8c6c989267f4" + +[[deps.DiffResults]] +deps = ["StaticArraysCore"] +git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" +uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" +version = "1.1.0" + +[[deps.DiffRules]] +deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] +git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" +uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" +version = "1.15.1" + +[[deps.Distributed]] +deps = ["Random", "Serialization", "Sockets"] +uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" + +[[deps.Distributions]] +deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "7c302d7a5fec5214eb8a5a4c466dcf7a51fcf169" +uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" +version = "0.25.107" + + [deps.Distributions.extensions] + DistributionsChainRulesCoreExt = "ChainRulesCore" + DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" + + [deps.Distributions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.DocStringExtensions]] +deps = ["LibGit2"] +git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" +uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +version = "0.9.3" + +[[deps.DomainSets]] +deps = ["CompositeTypes", "IntervalSets", "LinearAlgebra", "Random", "StaticArrays"] +git-tree-sha1 = "a0c11553b6c58bfc0283d8279dd3798150b77ac5" +uuid = "5b8099bc-c8ec-5219-889f-1d9e522a28bf" +version = "0.7.12" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.DualNumbers]] +deps = ["Calculus", "NaNMath", "SpecialFunctions"] +git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" +uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" +version = "0.6.8" + +[[deps.DynamicPolynomials]] +deps = ["Future", "LinearAlgebra", "MultivariatePolynomials", "MutableArithmetics", "Pkg", "Reexport", "Test"] +git-tree-sha1 = "0c056035f7de73b203a5295a22137f96fc32ad46" +uuid = "7c1d4256-1411-5781-91ec-d7bc3513ac07" +version = "0.5.6" + +[[deps.DynamicQuantities]] +deps = ["Compat", "PackageExtensionCompat", "Tricks"] +git-tree-sha1 = "412b25c7d99ec6b06967d315c7b29bb8e484f092" +uuid = "06fc5a27-2a28-4c7c-a15d-362465fb6821" +version = "0.13.2" + + [deps.DynamicQuantities.extensions] + DynamicQuantitiesLinearAlgebraExt = "LinearAlgebra" + DynamicQuantitiesMeasurementsExt = "Measurements" + DynamicQuantitiesScientificTypesExt = "ScientificTypes" + DynamicQuantitiesUnitfulExt = "Unitful" + + [deps.DynamicQuantities.weakdeps] + LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" + ScientificTypes = "321657f4-b219-11e9-178b-2701a2544e81" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.EnumX]] +git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" +uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" +version = "1.0.4" + +[[deps.EnzymeCore]] +git-tree-sha1 = "1bc328eec34ffd80357f84a84bb30e4374e9bd60" +uuid = "f151be2c-9106-41f4-ab19-57ee4f262869" +version = "0.6.6" +weakdeps = ["Adapt"] + + [deps.EnzymeCore.extensions] + AdaptExt = "Adapt" + +[[deps.EpollShim_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8e9441ee83492030ace98f9789a654a6d0b1f643" +uuid = "2702e6a9-849d-5ed8-8c21-79e8b8f9ee43" +version = "0.0.20230411+0" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.10" + +[[deps.Expat_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" +uuid = "2e619515-83b5-522b-bb60-26c02a35a201" +version = "2.5.0+0" + +[[deps.ExponentialUtilities]] +deps = ["Adapt", "ArrayInterface", "GPUArraysCore", "GenericSchur", "LinearAlgebra", "PrecompileTools", "Printf", "SparseArrays", "libblastrampoline_jll"] +git-tree-sha1 = "8e18940a5ba7f4ddb41fe2b79b6acaac50880a86" +uuid = "d4d017d3-3776-5f7e-afef-a10c40355c18" +version = "1.26.1" + +[[deps.ExprTools]] +git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" +uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" +version = "0.1.10" + +[[deps.FFMPEG]] +deps = ["FFMPEG_jll"] +git-tree-sha1 = "b57e3acbe22f8484b4b5ff66a7499717fe1a9cc8" +uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" +version = "0.4.1" + +[[deps.FFMPEG_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "466d45dc38e15794ec7d5d63ec03d776a9aff36e" +uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" +version = "4.4.4+1" + +[[deps.FastBroadcast]] +deps = ["ArrayInterface", "LinearAlgebra", "Polyester", "Static", "StaticArrayInterface", "StrideArraysCore"] +git-tree-sha1 = "a6e756a880fc419c8b41592010aebe6a5ce09136" +uuid = "7034ab61-46d4-4ed7-9d0f-46aef9175898" +version = "0.2.8" + +[[deps.FastClosures]] +git-tree-sha1 = "acebe244d53ee1b461970f8910c235b259e772ef" +uuid = "9aa1b823-49e4-5ca5-8b0f-3971ec8bab6a" +version = "0.3.2" + +[[deps.FastLapackInterface]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "0a59c7d1002f3131de53dc4568a47d15a44daef7" +uuid = "29a986be-02c6-4525-aec4-84b980013641" +version = "2.0.2" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" + +[[deps.FillArrays]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "bfe82a708416cf00b73a3198db0859c82f741558" +uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" +version = "1.10.0" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" + +[[deps.FindFirstFunctions]] +git-tree-sha1 = "e90fef90f7d75e6a5b435b0fd65609759f99717a" +uuid = "64ca27bc-2ba2-4a57-88aa-44e436879224" +version = "1.2.0" + +[[deps.FiniteDiff]] +deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays"] +git-tree-sha1 = "2de436b72c3422940cbe1367611d137008af7ec3" +uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" +version = "2.23.1" + + [deps.FiniteDiff.extensions] + FiniteDiffBandedMatricesExt = "BandedMatrices" + FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" + FiniteDiffStaticArraysExt = "StaticArrays" + + [deps.FiniteDiff.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.4" + +[[deps.Fontconfig_jll]] +deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"] +git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03" +uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" +version = "2.13.93+0" + +[[deps.Format]] +git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" +uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" +version = "1.3.7" + +[[deps.ForwardDiff]] +deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] +git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" +uuid = "f6369f11-7733-5829-9624-2563aa707210" +version = "0.10.36" +weakdeps = ["StaticArrays"] + + [deps.ForwardDiff.extensions] + ForwardDiffStaticArraysExt = "StaticArrays" + +[[deps.FreeType2_jll]] +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" +uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" +version = "2.13.1+0" + +[[deps.FriBidi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "aa31987c2ba8704e23c6c8ba8a4f769d5d7e4f91" +uuid = "559328eb-81f9-559d-9380-de523a88c83c" +version = "1.0.10+0" + +[[deps.FunctionWrappers]] +git-tree-sha1 = "d62485945ce5ae9c0c48f124a84998d755bae00e" +uuid = "069b7b12-0de2-55c6-9aab-29f3d0a68a2e" +version = "1.1.3" + +[[deps.FunctionWrappersWrappers]] +deps = ["FunctionWrappers"] +git-tree-sha1 = "b104d487b34566608f8b4e1c39fb0b10aa279ff8" +uuid = "77dc65aa-8811-40c2-897b-53d922fa7daf" +version = "0.1.3" + +[[deps.Functors]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "d3e63d9fa13f8eaa2f06f64949e2afc593ff52c2" +uuid = "d9f16b24-f501-4c13-a1f2-28368ffc5196" +version = "0.4.10" + +[[deps.Future]] +deps = ["Random"] +uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" + +[[deps.GLFW_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"] +git-tree-sha1 = "ff38ba61beff76b8f4acad8ab0c97ef73bb670cb" +uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" +version = "3.3.9+0" + +[[deps.GPUArraysCore]] +deps = ["Adapt"] +git-tree-sha1 = "ec632f177c0d990e64d955ccc1b8c04c485a0950" +uuid = "46192b85-c4d5-4398-a991-12ede77f4527" +version = "0.1.6" + +[[deps.GR]] +deps = ["Artifacts", "Base64", "DelimitedFiles", "Downloads", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Pkg", "Preferences", "Printf", "Random", "Serialization", "Sockets", "TOML", "Tar", "Test", "UUIDs", "p7zip_jll"] +git-tree-sha1 = "3437ade7073682993e092ca570ad68a2aba26983" +uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" +version = "0.73.3" + +[[deps.GR_jll]] +deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "FreeType2_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt6Base_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "a96d5c713e6aa28c242b0d25c1347e258d6541ab" +uuid = "d2c73de3-f751-5644-a686-071e5b155ba9" +version = "0.73.3+0" + +[[deps.GenericSchur]] +deps = ["LinearAlgebra", "Printf"] +git-tree-sha1 = "af49a0851f8113fcfae2ef5027c6d49d0acec39b" +uuid = "c145ed77-6b09-5dd9-b285-bf645a82121e" +version = "0.5.4" + +[[deps.Gettext_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"] +git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046" +uuid = "78b55507-aeef-58d4-861c-77aaff3498b1" +version = "0.21.0+0" + +[[deps.Glib_jll]] +deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "359a1ba2e320790ddbe4ee8b4d54a305c0ea2aff" +uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" +version = "2.80.0+0" + +[[deps.Glob]] +git-tree-sha1 = "97285bbd5230dd766e9ef6749b80fc617126d496" +uuid = "c27321d9-0574-5035-807b-f59d2c89b15c" +version = "1.3.1" + +[[deps.Graphite2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011" +uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" +version = "1.3.14+0" + +[[deps.Graphs]] +deps = ["ArnoldiMethod", "Compat", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] +git-tree-sha1 = "3863330da5466410782f2bffc64f3d505a6a8334" +uuid = "86223c79-3864-5bf0-83f7-82e725a168b6" +version = "1.10.0" + +[[deps.Grisu]] +git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" +uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" +version = "1.0.2" + +[[deps.HTTP]] +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "8e59b47b9dc525b70550ca082ce85bcd7f5477cd" +uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" +version = "1.10.5" + +[[deps.HarfBuzz_jll]] +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] +git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" +uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" +version = "2.8.1+1" + +[[deps.HostCPUFeatures]] +deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] +git-tree-sha1 = "eb8fed28f4994600e29beef49744639d985a04b2" +uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" +version = "0.1.16" + +[[deps.HypergeometricFunctions]] +deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.23" + +[[deps.IfElse]] +git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" +uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" +version = "0.1.1" + +[[deps.Inflate]] +git-tree-sha1 = "ea8031dea4aff6bd41f1df8f2fdfb25b33626381" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.4" + +[[deps.IntelOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "5fdf2fe6724d8caabf43b557b84ce53f3b7e2f6b" +uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" +version = "2024.0.2+0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" + +[[deps.IntervalSets]] +git-tree-sha1 = "dba9ddf07f77f60450fe5d2e2beb9854d9a49bd0" +uuid = "8197267c-284f-5f27-9208-e0e47529a953" +version = "0.7.10" +weakdeps = ["Random", "RecipesBase", "Statistics"] + + [deps.IntervalSets.extensions] + IntervalSetsRandomExt = "Random" + IntervalSetsRecipesBaseExt = "RecipesBase" + IntervalSetsStatisticsExt = "Statistics" + +[[deps.InverseFunctions]] +deps = ["Test"] +git-tree-sha1 = "896385798a8d49a255c398bd49162062e4a4c435" +uuid = "3587e190-3f89-42d0-90ee-14403ec27112" +version = "0.1.13" +weakdeps = ["Dates"] + + [deps.InverseFunctions.extensions] + DatesExt = "Dates" + +[[deps.IrrationalConstants]] +git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" +uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" +version = "0.2.2" + +[[deps.IteratorInterfaceExtensions]] +git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" +uuid = "82899510-4779-5014-852e-03e436cf321d" +version = "1.0.0" + +[[deps.JLFzf]] +deps = ["Pipe", "REPL", "Random", "fzf_jll"] +git-tree-sha1 = "a53ebe394b71470c7f97c2e7e170d51df21b17af" +uuid = "1019f520-868f-41f5-a6de-eb00f4b6a39c" +version = "0.1.7" + +[[deps.JLLWrappers]] +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca" +uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" +version = "1.5.0" + +[[deps.JSON]] +deps = ["Dates", "Mmap", "Parsers", "Unicode"] +git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" +uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" +version = "0.21.4" + +[[deps.JpegTurbo_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3336abae9a713d2210bb57ab484b1e065edd7d23" +uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" +version = "3.0.2+0" + +[[deps.JuliaFormatter]] +deps = ["CSTParser", "CommonMark", "DataStructures", "Glob", "Pkg", "PrecompileTools", "Tokenize"] +git-tree-sha1 = "1c4880cb70a5c6c87ea36deccc3d7f9e7969c18c" +uuid = "98e50ef6-434e-11e9-1051-2b60c6c9e899" +version = "1.0.56" + +[[deps.JumpProcesses]] +deps = ["ArrayInterface", "DataStructures", "DiffEqBase", "DocStringExtensions", "FunctionWrappers", "Graphs", "LinearAlgebra", "Markdown", "PoissonRandom", "Random", "RandomNumbers", "RecursiveArrayTools", "Reexport", "SciMLBase", "StaticArrays", "SymbolicIndexingInterface", "UnPack"] +git-tree-sha1 = "ed08d89318be7d625613f3c435d1f6678fba4850" +uuid = "ccbc3e58-028d-4f4c-8cd5-9ae44345cda5" +version = "9.11.1" +weakdeps = ["FastBroadcast"] + + [deps.JumpProcesses.extensions] + JumpProcessFastBroadcastExt = "FastBroadcast" + +[[deps.KLU]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse_jll"] +git-tree-sha1 = "07649c499349dad9f08dde4243a4c597064663e9" +uuid = "ef3ab10e-7fda-4108-b977-705223b18434" +version = "0.6.0" + +[[deps.Krylov]] +deps = ["LinearAlgebra", "Printf", "SparseArrays"] +git-tree-sha1 = "8a6837ec02fe5fb3def1abc907bb802ef11a0729" +uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7" +version = "0.9.5" + +[[deps.LAME_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c" +uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" +version = "3.100.1+0" + +[[deps.LERC_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "bf36f528eec6634efc60d7ec062008f171071434" +uuid = "88015f11-f218-50d7-93a8-a6af411a945d" +version = "3.0.0+1" + +[[deps.LLVMOpenMP_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d986ce2d884d49126836ea94ed5bfb0f12679713" +uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" +version = "15.0.7+0" + +[[deps.LZO_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6" +uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" +version = "2.10.1+0" + +[[deps.LaTeXStrings]] +git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" +uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" +version = "1.3.1" + +[[deps.LabelledArrays]] +deps = ["ArrayInterface", "ChainRulesCore", "ForwardDiff", "LinearAlgebra", "MacroTools", "PreallocationTools", "RecursiveArrayTools", "StaticArrays"] +git-tree-sha1 = "d1f981fba6eb3ec393eede4821bca3f2b7592cd4" +uuid = "2ee39098-c373-598a-b85f-a56591580800" +version = "1.15.1" + +[[deps.LambertW]] +git-tree-sha1 = "c5ffc834de5d61d00d2b0e18c96267cffc21f648" +uuid = "984bce1d-4616-540c-a9ee-88d1112d94c9" +version = "0.4.6" + +[[deps.Latexify]] +deps = ["Format", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] +git-tree-sha1 = "e0b5cd21dc1b44ec6e64f351976f961e6f31d6c4" +uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" +version = "0.16.3" + + [deps.Latexify.extensions] + DataFramesExt = "DataFrames" + SymEngineExt = "SymEngine" + + [deps.Latexify.weakdeps] + DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" + SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" + +[[deps.LayoutPointers]] +deps = ["ArrayInterface", "LinearAlgebra", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface"] +git-tree-sha1 = "62edfee3211981241b57ff1cedf4d74d79519277" +uuid = "10f19ff3-798f-405d-979b-55457f8fc047" +version = "0.1.15" + +[[deps.LazyArrays]] +deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra", "MacroTools", "MatrixFactorizations", "SparseArrays"] +git-tree-sha1 = "30fc74040b7507231ba889e363fd1135f5067395" +uuid = "5078a376-72f3-5289-bfd5-ec5146d43c02" +version = "1.9.1" +weakdeps = ["StaticArrays"] + + [deps.LazyArrays.extensions] + LazyArraysStaticArraysExt = "StaticArrays" + +[[deps.LazyArtifacts]] +deps = ["Artifacts", "Pkg"] +uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.4.0+0" + +[[deps.LibGit2]] +deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.6.4+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.0+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" + +[[deps.Libffi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290" +uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" +version = "3.2.2+1" + +[[deps.Libgcrypt_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"] +git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae" +uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4" +version = "1.8.7+0" + +[[deps.Libglvnd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"] +git-tree-sha1 = "6f73d1dd803986947b2c750138528a999a6c7733" +uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" +version = "1.6.0+0" + +[[deps.Libgpg_error_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9" +uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" +version = "1.42.0+0" + +[[deps.Libiconv_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" +uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" +version = "1.17.0+0" + +[[deps.Libmount_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "dae976433497a2f841baadea93d27e68f1a12a97" +uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" +version = "2.39.3+0" + +[[deps.Libtiff_jll]] +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "2da088d113af58221c52828a80378e16be7d037a" +uuid = "89763e89-9b03-5906-acba-b20f662cd828" +version = "4.5.1+1" + +[[deps.Libuuid_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "0a04a1318df1bf510beb2562cf90fb0c386f58c4" +uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" +version = "2.39.3+1" + +[[deps.LineSearches]] +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] +git-tree-sha1 = "7bbea35cec17305fc70a0e5b4641477dc0789d9d" +uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" +version = "7.2.0" + +[[deps.LinearAlgebra]] +deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] +uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[deps.LinearSolve]] +deps = ["ArrayInterface", "ChainRulesCore", "ConcreteStructs", "DocStringExtensions", "EnumX", "FastLapackInterface", "GPUArraysCore", "InteractiveUtils", "KLU", "Krylov", "LazyArrays", "Libdl", "LinearAlgebra", "MKL_jll", "Markdown", "PrecompileTools", "Preferences", "RecursiveFactorization", "Reexport", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Sparspak", "StaticArraysCore", "UnPack"] +git-tree-sha1 = "775e5e5d9ace42ef8deeb236587abc69e70dc455" +uuid = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" +version = "2.28.0" + + [deps.LinearSolve.extensions] + LinearSolveBandedMatricesExt = "BandedMatrices" + LinearSolveBlockDiagonalsExt = "BlockDiagonals" + LinearSolveCUDAExt = "CUDA" + LinearSolveEnzymeExt = ["Enzyme", "EnzymeCore"] + LinearSolveFastAlmostBandedMatricesExt = ["FastAlmostBandedMatrices"] + LinearSolveHYPREExt = "HYPRE" + LinearSolveIterativeSolversExt = "IterativeSolvers" + LinearSolveKernelAbstractionsExt = "KernelAbstractions" + LinearSolveKrylovKitExt = "KrylovKit" + LinearSolveMetalExt = "Metal" + LinearSolvePardisoExt = "Pardiso" + LinearSolveRecursiveArrayToolsExt = "RecursiveArrayTools" + + [deps.LinearSolve.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockDiagonals = "0a1fb500-61f7-11e9-3c65-f5ef3456f9f0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + FastAlmostBandedMatrices = "9d29842c-ecb8-4973-b1e9-a27b1157504e" + HYPRE = "b5ffcf37-a2bd-41ab-a3da-4bd9bc8ad771" + IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153" + KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" + KrylovKit = "0b1a1467-8014-51b9-945f-bf0ae24f4b77" + Metal = "dde4c033-4e86-420c-a63e-0dd931031962" + Pardiso = "46dd5b70-b6fb-5a00-ae2d-e8fea33afaf2" + RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" + +[[deps.LogExpFunctions]] +deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] +git-tree-sha1 = "18144f3e9cbe9b15b070288eef858f71b291ce37" +uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" +version = "0.3.27" + + [deps.LogExpFunctions.extensions] + LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" + LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" + LogExpFunctionsInverseFunctionsExt = "InverseFunctions" + + [deps.LogExpFunctions.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" + InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" + +[[deps.LoggingExtras]] +deps = ["Dates", "Logging"] +git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075" +uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" +version = "1.0.3" + +[[deps.LoopVectorization]] +deps = ["ArrayInterface", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] +git-tree-sha1 = "a13f3be5d84b9c95465d743c82af0b094ef9c2e2" +uuid = "bdcacae8-1622-11e9-2a5c-532679323890" +version = "0.12.169" +weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] + + [deps.LoopVectorization.extensions] + ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.MKL_jll]] +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "72dc3cf284559eb8f53aa593fe62cb33f83ed0c0" +uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" +version = "2024.0.0+0" + +[[deps.MLStyle]] +git-tree-sha1 = "bc38dff0548128765760c79eb7388a4b37fae2c8" +uuid = "d8e11817-5142-5d16-987a-aa16d5891078" +version = "0.4.17" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.13" + +[[deps.ManualMemory]] +git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" +uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" +version = "0.1.8" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" + +[[deps.MatrixFactorizations]] +deps = ["ArrayLayouts", "LinearAlgebra", "Printf", "Random"] +git-tree-sha1 = "6731e0574fa5ee21c02733e397beb133df90de35" +uuid = "a3b82374-2e81-5b9e-98ce-41277c0e4c87" +version = "2.2.0" + +[[deps.MaybeInplace]] +deps = ["ArrayInterface", "LinearAlgebra", "MacroTools", "SparseArrays"] +git-tree-sha1 = "b1f2f92feb0bc201e91c155ef575bcc7d9cc3526" +uuid = "bb5d69b7-63fc-4a16-80bd-7e42200c7bdb" +version = "0.1.2" + +[[deps.MbedTLS]] +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +uuid = "739be429-bea8-5141-9913-cc70e7f3736d" +version = "1.1.9" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.2+1" + +[[deps.Measures]] +git-tree-sha1 = "c13304c81eec1ed3af7fc20e75fb6b26092a1102" +uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" +version = "0.3.2" + +[[deps.Missings]] +deps = ["DataAPI"] +git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" +uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" +version = "1.2.0" + +[[deps.Mmap]] +uuid = "a63ad114-7e13-5084-954f-fe012c677804" + +[[deps.ModelingToolkit]] +deps = ["AbstractTrees", "ArrayInterface", "Combinatorics", "Compat", "ConstructionBase", "DataStructures", "DiffEqBase", "DiffEqCallbacks", "DiffRules", "Distributed", "Distributions", "DocStringExtensions", "DomainSets", "DynamicQuantities", "ExprTools", "FindFirstFunctions", "ForwardDiff", "FunctionWrappersWrappers", "Graphs", "InteractiveUtils", "JuliaFormatter", "JumpProcesses", "LabelledArrays", "Latexify", "Libdl", "LinearAlgebra", "MLStyle", "NaNMath", "OrdinaryDiffEq", "PrecompileTools", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLBase", "SciMLStructures", "Serialization", "Setfield", "SimpleNonlinearSolve", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicIndexingInterface", "SymbolicUtils", "Symbolics", "URIs", "UnPack", "Unitful"] +git-tree-sha1 = "43f984aae6f3d2bee9832f14da78eb965f6765e8" +uuid = "961ee093-0014-501f-94e3-6117800e7a78" +version = "9.12.0" + + [deps.ModelingToolkit.extensions] + MTKBifurcationKitExt = "BifurcationKit" + MTKDeepDiffsExt = "DeepDiffs" + + [deps.ModelingToolkit.weakdeps] + BifurcationKit = "0f109fa4-8a5d-4b75-95aa-f515264e7665" + DeepDiffs = "ab62b9b5-e342-54a8-a765-a90f495de1a6" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2023.1.10" + +[[deps.MuladdMacro]] +git-tree-sha1 = "cac9cc5499c25554cba55cd3c30543cff5ca4fab" +uuid = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" +version = "0.2.4" + +[[deps.MultivariatePolynomials]] +deps = ["ChainRulesCore", "DataStructures", "LinearAlgebra", "MutableArithmetics"] +git-tree-sha1 = "769c9175942d91ed9b83fa929eee4fe6a1d128ad" +uuid = "102ac46a-7ee4-5c85-9060-abc95bfdeaa3" +version = "0.5.4" + +[[deps.MutableArithmetics]] +deps = ["LinearAlgebra", "SparseArrays", "Test"] +git-tree-sha1 = "c2e2d748aea87f006a87c1654878349baa04aaf0" +uuid = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" +version = "1.4.3" + +[[deps.NLSolversBase]] +deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] +git-tree-sha1 = "a0b464d183da839699f4c79e7606d9d186ec172c" +uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" +version = "7.8.3" + +[[deps.NaNMath]] +deps = ["OpenLibm_jll"] +git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" +uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" +version = "1.0.2" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.2.0" + +[[deps.NonlinearSolve]] +deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "DiffEqBase", "FastBroadcast", "FastClosures", "FiniteDiff", "ForwardDiff", "LazyArrays", "LineSearches", "LinearAlgebra", "LinearSolve", "MaybeInplace", "PrecompileTools", "Preferences", "Printf", "RecursiveArrayTools", "Reexport", "SciMLBase", "SimpleNonlinearSolve", "SparseArrays", "SparseDiffTools", "StaticArraysCore", "SymbolicIndexingInterface", "TimerOutputs"] +git-tree-sha1 = "4891b745bd621f88aac661f2504d014931b443ba" +uuid = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" +version = "3.10.0" + + [deps.NonlinearSolve.extensions] + NonlinearSolveBandedMatricesExt = "BandedMatrices" + NonlinearSolveFastLevenbergMarquardtExt = "FastLevenbergMarquardt" + NonlinearSolveFixedPointAccelerationExt = "FixedPointAcceleration" + NonlinearSolveLeastSquaresOptimExt = "LeastSquaresOptim" + NonlinearSolveMINPACKExt = "MINPACK" + NonlinearSolveNLSolversExt = "NLSolvers" + NonlinearSolveNLsolveExt = "NLsolve" + NonlinearSolveSIAMFANLEquationsExt = "SIAMFANLEquations" + NonlinearSolveSpeedMappingExt = "SpeedMapping" + NonlinearSolveSymbolicsExt = "Symbolics" + NonlinearSolveZygoteExt = "Zygote" + + [deps.NonlinearSolve.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + FastLevenbergMarquardt = "7a0df574-e128-4d35-8cbd-3d84502bf7ce" + FixedPointAcceleration = "817d07cb-a79a-5c30-9a31-890123675176" + LeastSquaresOptim = "0fc2ff8b-aaa3-5acd-a817-1944a5e08891" + MINPACK = "4854310b-de5a-5eb6-a2a5-c1dee2bd17f9" + NLSolvers = "337daf1e-9722-11e9-073e-8b9effe078ba" + NLsolve = "2774e3e8-f4cf-5e23-947b-6d7e65073b56" + SIAMFANLEquations = "084e46ad-d928-497d-ad5e-07fa361a48c4" + SpeedMapping = "f1835b91-879b-4a3f-a438-e4baacf14412" + Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" + Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" + +[[deps.OffsetArrays]] +git-tree-sha1 = "e64b4f5ea6b7389f6f046d13d4896a8f9c1ba71e" +uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" +version = "1.14.0" +weakdeps = ["Adapt"] + + [deps.OffsetArrays.extensions] + OffsetArraysAdaptExt = "Adapt" + +[[deps.Ogg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "887579a3eb005446d514ab7aeac5d1d027658b8f" +uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" +version = "1.3.5+1" + +[[deps.OpenBLAS_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] +uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" +version = "0.3.23+4" + +[[deps.OpenLibm_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "05823500-19ac-5b8b-9628-191a04bc5112" +version = "0.8.1+2" + +[[deps.OpenSSL]] +deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] +git-tree-sha1 = "af81a32750ebc831ee28bdaaba6e1067decef51e" +uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" +version = "1.4.2" + +[[deps.OpenSSL_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "3da7367955dcc5c54c1ba4d402ccdc09a1a3e046" +uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" +version = "3.0.13+1" + +[[deps.OpenSpecFun_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" +uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" +version = "0.5.5+0" + +[[deps.Opus_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720" +uuid = "91d4177d-7536-5919-b921-800302f37372" +version = "1.3.2+0" + +[[deps.OrderedCollections]] +git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" +uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" +version = "1.6.3" + +[[deps.OrdinaryDiffEq]] +deps = ["ADTypes", "Adapt", "ArrayInterface", "DataStructures", "DiffEqBase", "DocStringExtensions", "ExponentialUtilities", "FastBroadcast", "FastClosures", "FillArrays", "FiniteDiff", "ForwardDiff", "FunctionWrappersWrappers", "IfElse", "InteractiveUtils", "LineSearches", "LinearAlgebra", "LinearSolve", "Logging", "MacroTools", "MuladdMacro", "NonlinearSolve", "Polyester", "PreallocationTools", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "SimpleNonlinearSolve", "SimpleUnPack", "SparseArrays", "SparseDiffTools", "StaticArrayInterface", "StaticArrays", "TruncatedStacktraces"] +git-tree-sha1 = "91079af18db922354197eeae2a17b177079e24c1" +uuid = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" +version = "6.74.1" + +[[deps.PCRE2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" +version = "10.42.0+1" + +[[deps.PDMats]] +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] +git-tree-sha1 = "949347156c25054de2db3b166c52ac4728cbad65" +uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" +version = "0.11.31" + +[[deps.PackageExtensionCompat]] +git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" +uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" +version = "1.0.2" +weakdeps = ["Requires", "TOML"] + +[[deps.Parameters]] +deps = ["OrderedCollections", "UnPack"] +git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" +uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" +version = "0.12.3" + +[[deps.Parsers]] +deps = ["Dates", "PrecompileTools", "UUIDs"] +git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" +uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +version = "2.8.1" + +[[deps.Pipe]] +git-tree-sha1 = "6842804e7867b115ca9de748a0cf6b364523c16d" +uuid = "b98c9c47-44ae-5843-9183-064241ee97a0" +version = "1.3.0" + +[[deps.Pixman_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] +git-tree-sha1 = "64779bc4c9784fee475689a1752ef4d5747c5e87" +uuid = "30392449-352a-5448-841d-b1acce4e97dc" +version = "0.42.2+0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.10.0" + +[[deps.PlotThemes]] +deps = ["PlotUtils", "Statistics"] +git-tree-sha1 = "1f03a2d339f42dca4a4da149c7e15e9b896ad899" +uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a" +version = "3.1.0" + +[[deps.PlotUtils]] +deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "Statistics"] +git-tree-sha1 = "7b1a9df27f072ac4c9c7cbe5efb198489258d1f5" +uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" +version = "1.4.1" + +[[deps.Plots]] +deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "JLFzf", "JSON", "LaTeXStrings", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "PrecompileTools", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "RelocatableFolders", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "UUIDs", "UnicodeFun", "UnitfulLatexify", "Unzip"] +git-tree-sha1 = "442e1e7ac27dd5ff8825c3fa62fbd1e86397974b" +uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +version = "1.40.4" + + [deps.Plots.extensions] + FileIOExt = "FileIO" + GeometryBasicsExt = "GeometryBasics" + IJuliaExt = "IJulia" + ImageInTerminalExt = "ImageInTerminal" + UnitfulExt = "Unitful" + + [deps.Plots.weakdeps] + FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" + GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" + IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" + ImageInTerminal = "d8c32880-2388-543b-8c61-d9f865259254" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + +[[deps.PoissonRandom]] +deps = ["Random"] +git-tree-sha1 = "a0f1159c33f846aa77c3f30ebbc69795e5327152" +uuid = "e409e4f3-bfea-5376-8464-e040bb5c01ab" +version = "0.4.4" + +[[deps.Polyester]] +deps = ["ArrayInterface", "BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "ManualMemory", "PolyesterWeave", "Requires", "Static", "StaticArrayInterface", "StrideArraysCore", "ThreadingUtilities"] +git-tree-sha1 = "2ba5f33cbb51a85ef58a850749492b08f9bf2193" +uuid = "f517fe37-dbe3-4b94-8317-1923a5111588" +version = "0.7.13" + +[[deps.PolyesterWeave]] +deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] +git-tree-sha1 = "240d7170f5ffdb285f9427b92333c3463bf65bf6" +uuid = "1d0040c9-8b98-4ee7-8388-3f51789ca0ad" +version = "0.2.1" + +[[deps.PreallocationTools]] +deps = ["Adapt", "ArrayInterface", "ForwardDiff"] +git-tree-sha1 = "a660e9daab5db07adf3dedfe09b435cc530d855e" +uuid = "d236fae5-4411-538c-8e31-a6e3d9e00b46" +version = "0.4.21" + + [deps.PreallocationTools.extensions] + PreallocationToolsReverseDiffExt = "ReverseDiff" + + [deps.PreallocationTools.weakdeps] + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.1" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.4.3" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.Qt6Base_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libSM_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_cursor_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "libinput_jll", "xkbcommon_jll"] +git-tree-sha1 = "37b7bb7aabf9a085e0044307e1717436117f2b3b" +uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" +version = "6.5.3+1" + +[[deps.QuadGK]] +deps = ["DataStructures", "LinearAlgebra"] +git-tree-sha1 = "9b23c31e76e333e6fb4c1595ae6afa74966a729e" +uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" +version = "2.9.4" + +[[deps.REPL]] +deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] +uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.RandomNumbers]] +deps = ["Random", "Requires"] +git-tree-sha1 = "043da614cc7e95c703498a491e2c21f58a2b8111" +uuid = "e6cf234a-135c-5ec9-84dd-332b85af5143" +version = "1.5.3" + +[[deps.RecipesBase]] +deps = ["PrecompileTools"] +git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" +uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" +version = "1.3.4" + +[[deps.RecipesPipeline]] +deps = ["Dates", "NaNMath", "PlotUtils", "PrecompileTools", "RecipesBase"] +git-tree-sha1 = "45cf9fd0ca5839d06ef333c8201714e888486342" +uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c" +version = "0.6.12" + +[[deps.RecursiveArrayTools]] +deps = ["Adapt", "ArrayInterface", "DocStringExtensions", "GPUArraysCore", "IteratorInterfaceExtensions", "LinearAlgebra", "RecipesBase", "SparseArrays", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"] +git-tree-sha1 = "d8f131090f2e44b145084928856a561c83f43b27" +uuid = "731186ca-8d62-57ce-b412-fbd966d074cd" +version = "3.13.0" + + [deps.RecursiveArrayTools.extensions] + RecursiveArrayToolsFastBroadcastExt = "FastBroadcast" + RecursiveArrayToolsForwardDiffExt = "ForwardDiff" + RecursiveArrayToolsMeasurementsExt = "Measurements" + RecursiveArrayToolsMonteCarloMeasurementsExt = "MonteCarloMeasurements" + RecursiveArrayToolsReverseDiffExt = ["ReverseDiff", "Zygote"] + RecursiveArrayToolsTrackerExt = "Tracker" + RecursiveArrayToolsZygoteExt = "Zygote" + + [deps.RecursiveArrayTools.weakdeps] + FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" + MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" + +[[deps.RecursiveFactorization]] +deps = ["LinearAlgebra", "LoopVectorization", "Polyester", "PrecompileTools", "StrideArraysCore", "TriangularSolve"] +git-tree-sha1 = "6db1a75507051bc18bfa131fbc7c3f169cc4b2f6" +uuid = "f2c3362d-daeb-58d1-803e-2bc74f2840b4" +version = "0.2.23" + +[[deps.Reexport]] +git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" +uuid = "189a3867-3050-52da-a836-e630ba90ab69" +version = "1.2.2" + +[[deps.RelocatableFolders]] +deps = ["SHA", "Scratch"] +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" +uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" +version = "1.0.1" + +[[deps.Requires]] +deps = ["UUIDs"] +git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" +uuid = "ae029012-a4dd-5104-9daa-d747884805df" +version = "1.3.0" + +[[deps.Rmath]] +deps = ["Random", "Rmath_jll"] +git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" +uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" +version = "0.7.1" + +[[deps.Rmath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "6ed52fdd3382cf21947b15e8870ac0ddbff736da" +uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" +version = "0.4.0+0" + +[[deps.RuntimeGeneratedFunctions]] +deps = ["ExprTools", "SHA", "Serialization"] +git-tree-sha1 = "04c968137612c4a5629fa531334bb81ad5680f00" +uuid = "7e49a35a-f44a-4d26-94aa-eba1b4ca6b47" +version = "0.5.13" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.SIMDTypes]] +git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c" +uuid = "94e857df-77ce-4151-89e5-788b33177be4" +version = "0.1.0" + +[[deps.SLEEFPirates]] +deps = ["IfElse", "Static", "VectorizationBase"] +git-tree-sha1 = "3aac6d68c5e57449f5b9b865c9ba50ac2970c4cf" +uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" +version = "0.6.42" + +[[deps.SciMLBase]] +deps = ["ADTypes", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PrecompileTools", "Preferences", "Printf", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "SciMLStructures", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"] +git-tree-sha1 = "816176bca8a93f8f50a33853e0933d6c4ec116d0" +uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" +version = "2.33.1" + + [deps.SciMLBase.extensions] + SciMLBaseChainRulesCoreExt = "ChainRulesCore" + SciMLBaseMakieExt = "Makie" + SciMLBasePartialFunctionsExt = "PartialFunctions" + SciMLBasePyCallExt = "PyCall" + SciMLBasePythonCallExt = "PythonCall" + SciMLBaseRCallExt = "RCall" + SciMLBaseZygoteExt = "Zygote" + + [deps.SciMLBase.weakdeps] + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" + PartialFunctions = "570af359-4316-4cb7-8c74-252c00c2016b" + PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" + PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d" + RCall = "6f49c342-dc21-5d91-9882-a32aef131414" + Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" + +[[deps.SciMLOperators]] +deps = ["ArrayInterface", "DocStringExtensions", "LinearAlgebra", "MacroTools", "Setfield", "SparseArrays", "StaticArraysCore"] +git-tree-sha1 = "10499f619ef6e890f3f4a38914481cc868689cd5" +uuid = "c0aeaf25-5076-4817-a8d5-81caf7dfa961" +version = "0.3.8" + +[[deps.SciMLStructures]] +git-tree-sha1 = "5833c10ce83d690c124beedfe5f621b50b02ba4d" +uuid = "53ae85a6-f571-4167-b2af-e1d143709226" +version = "1.1.0" + +[[deps.Scratch]] +deps = ["Dates"] +git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" +uuid = "6c6a2e73-6563-6170-7368-637461726353" +version = "1.2.1" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.Setfield]] +deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] +git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" +uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" +version = "1.1.1" + +[[deps.SharedArrays]] +deps = ["Distributed", "Mmap", "Random", "Serialization"] +uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" + +[[deps.Showoff]] +deps = ["Dates", "Grisu"] +git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" +uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" +version = "1.0.3" + +[[deps.SimpleBufferStream]] +git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1" +uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" +version = "1.1.0" + +[[deps.SimpleNonlinearSolve]] +deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "DiffEqBase", "DiffResults", "FastClosures", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "MaybeInplace", "PrecompileTools", "Reexport", "SciMLBase", "StaticArraysCore"] +git-tree-sha1 = "d4c17fc60bf5f8f2be02777c4836878f27ac7b9b" +uuid = "727e6d20-b764-4bd8-a329-72de5adea6c7" +version = "1.7.0" + + [deps.SimpleNonlinearSolve.extensions] + SimpleNonlinearSolveChainRulesCoreExt = "ChainRulesCore" + SimpleNonlinearSolvePolyesterForwardDiffExt = "PolyesterForwardDiff" + SimpleNonlinearSolveReverseDiffExt = "ReverseDiff" + SimpleNonlinearSolveStaticArraysExt = "StaticArrays" + SimpleNonlinearSolveTrackerExt = "Tracker" + SimpleNonlinearSolveZygoteExt = "Zygote" + + [deps.SimpleNonlinearSolve.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + PolyesterForwardDiff = "98d1487c-24ca-40b6-b7ab-df2af84e126b" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" + +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.4" + +[[deps.SimpleUnPack]] +git-tree-sha1 = "58e6353e72cde29b90a69527e56df1b5c3d8c437" +uuid = "ce78b400-467f-4804-87d8-8f486da07d0a" +version = "1.1.0" + +[[deps.Sockets]] +uuid = "6462fe0b-24de-5631-8697-dd941f90decc" + +[[deps.SortingAlgorithms]] +deps = ["DataStructures"] +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" +uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" +version = "1.2.1" + +[[deps.SparseArrays]] +deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] +uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.10.0" + +[[deps.SparseDiffTools]] +deps = ["ADTypes", "Adapt", "ArrayInterface", "Compat", "DataStructures", "FiniteDiff", "ForwardDiff", "Graphs", "LinearAlgebra", "PackageExtensionCompat", "Random", "Reexport", "SciMLOperators", "Setfield", "SparseArrays", "StaticArrayInterface", "StaticArrays", "Tricks", "UnPack", "VertexSafeGraphs"] +git-tree-sha1 = "e2a3d8dfaffce3d3b8b5a0967c0cfcc89d34e425" +uuid = "47a9eef4-7e08-11e9-0b38-333d64bd3804" +version = "2.17.1" + + [deps.SparseDiffTools.extensions] + SparseDiffToolsEnzymeExt = "Enzyme" + SparseDiffToolsPolyesterExt = "Polyester" + SparseDiffToolsPolyesterForwardDiffExt = "PolyesterForwardDiff" + SparseDiffToolsSymbolicsExt = "Symbolics" + SparseDiffToolsZygoteExt = "Zygote" + + [deps.SparseDiffTools.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + Polyester = "f517fe37-dbe3-4b94-8317-1923a5111588" + PolyesterForwardDiff = "98d1487c-24ca-40b6-b7ab-df2af84e126b" + Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" + Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" + +[[deps.Sparspak]] +deps = ["Libdl", "LinearAlgebra", "Logging", "OffsetArrays", "Printf", "SparseArrays", "Test"] +git-tree-sha1 = "342cf4b449c299d8d1ceaf00b7a49f4fbc7940e7" +uuid = "e56a9233-b9d6-4f03-8d0f-1825330902ac" +version = "0.3.9" + +[[deps.SpecialFunctions]] +deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] +git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" +uuid = "276daf66-3868-5448-9aa4-cd146d93841b" +version = "2.3.1" +weakdeps = ["ChainRulesCore"] + + [deps.SpecialFunctions.extensions] + SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" + +[[deps.Static]] +deps = ["IfElse"] +git-tree-sha1 = "d2fdac9ff3906e27f7a618d47b676941baa6c80c" +uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" +version = "0.8.10" + +[[deps.StaticArrayInterface]] +deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] +git-tree-sha1 = "5d66818a39bb04bf328e92bc933ec5b4ee88e436" +uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" +version = "1.5.0" +weakdeps = ["OffsetArrays", "StaticArrays"] + + [deps.StaticArrayInterface.extensions] + StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" + StaticArrayInterfaceStaticArraysExt = "StaticArrays" + +[[deps.StaticArrays]] +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "bf074c045d3d5ffd956fa0a461da38a44685d6b2" +uuid = "90137ffa-7385-5640-81b9-e52037218182" +version = "1.9.3" +weakdeps = ["ChainRulesCore", "Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" + +[[deps.StaticArraysCore]] +git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" +uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" +version = "1.4.2" + +[[deps.Statistics]] +deps = ["LinearAlgebra", "SparseArrays"] +uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +version = "1.10.0" + +[[deps.StatsAPI]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" +uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" +version = "1.7.0" + +[[deps.StatsBase]] +deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] +git-tree-sha1 = "5cf7606d6cef84b543b483848d4ae08ad9832b21" +uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" +version = "0.34.3" + +[[deps.StatsFuns]] +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "cef0472124fab0695b58ca35a77c6fb942fdab8a" +uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" +version = "1.3.1" +weakdeps = ["ChainRulesCore", "InverseFunctions"] + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" + +[[deps.StrideArraysCore]] +deps = ["ArrayInterface", "CloseOpenIntervals", "IfElse", "LayoutPointers", "LinearAlgebra", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface", "ThreadingUtilities"] +git-tree-sha1 = "b518da45c50dfab8384125ba829f1739bda41034" +uuid = "7792a7ef-975c-4747-a70f-980b88e8d1da" +version = "0.5.5" + +[[deps.SuiteSparse]] +deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] +uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" + +[[deps.SuiteSparse_jll]] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] +uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" +version = "7.2.1+1" + +[[deps.SymbolicIndexingInterface]] +deps = ["Accessors", "ArrayInterface", "MacroTools", "RuntimeGeneratedFunctions", "StaticArraysCore"] +git-tree-sha1 = "40ea524431a92328cd73582d1820a5b08247a40f" +uuid = "2efcf032-c050-4f8e-a9bb-153293bab1f5" +version = "0.3.16" + +[[deps.SymbolicLimits]] +deps = ["SymbolicUtils"] +git-tree-sha1 = "89aa6b25a75418c8fffc42073b2e7dce69847394" +uuid = "19f23fe9-fdab-4a78-91af-e7b7767979c3" +version = "0.2.0" + +[[deps.SymbolicUtils]] +deps = ["AbstractTrees", "Bijections", "ChainRulesCore", "Combinatorics", "ConstructionBase", "DataStructures", "DocStringExtensions", "DynamicPolynomials", "IfElse", "LabelledArrays", "LinearAlgebra", "MultivariatePolynomials", "NaNMath", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicIndexingInterface", "TimerOutputs", "Unityper"] +git-tree-sha1 = "669e43e90df46fcee4aa859b587da7a7948272ac" +uuid = "d1185830-fcd6-423d-90d6-eec64667417b" +version = "1.5.1" + +[[deps.Symbolics]] +deps = ["ArrayInterface", "Bijections", "ConstructionBase", "DataStructures", "DiffRules", "Distributions", "DocStringExtensions", "DomainSets", "DynamicPolynomials", "ForwardDiff", "IfElse", "LaTeXStrings", "LambertW", "Latexify", "Libdl", "LinearAlgebra", "LogExpFunctions", "MacroTools", "Markdown", "NaNMath", "PrecompileTools", "RecipesBase", "Reexport", "Requires", "RuntimeGeneratedFunctions", "SciMLBase", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicIndexingInterface", "SymbolicLimits", "SymbolicUtils"] +git-tree-sha1 = "4104548fff14d7370b278ee767651d6ec61eb195" +uuid = "0c5d862f-8b57-4792-8d23-62f2024744c7" +version = "5.28.0" + + [deps.Symbolics.extensions] + SymbolicsGroebnerExt = "Groebner" + SymbolicsLuxCoreExt = "LuxCore" + SymbolicsPreallocationToolsExt = "PreallocationTools" + SymbolicsSymPyExt = "SymPy" + + [deps.Symbolics.weakdeps] + Groebner = "0b43b601-686d-58a3-8a1c-6623616c7cd4" + LuxCore = "bb33d45b-7691-41d6-9220-0943567d0623" + PreallocationTools = "d236fae5-4411-538c-8e31-a6e3d9e00b46" + SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.TableTraits]] +deps = ["IteratorInterfaceExtensions"] +git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" +uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" +version = "1.0.1" + +[[deps.Tables]] +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" +uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +version = "1.11.1" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.TensorCore]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" +uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" +version = "0.1.1" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.ThreadingUtilities]] +deps = ["ManualMemory"] +git-tree-sha1 = "eda08f7e9818eb53661b3deb74e3159460dfbc27" +uuid = "8290d209-cae3-49c0-8002-c8c24d57dab5" +version = "0.5.2" + +[[deps.TimerOutputs]] +deps = ["ExprTools", "Printf"] +git-tree-sha1 = "f548a9e9c490030e545f72074a41edfd0e5bcdd7" +uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" +version = "0.5.23" + +[[deps.Tokenize]] +git-tree-sha1 = "5b5a892ba7704c0977013bd0f9c30f5d962181e0" +uuid = "0796e94c-ce3b-5d07-9a54-7f471281c624" +version = "0.5.28" + +[[deps.TranscodingStreams]] +git-tree-sha1 = "71509f04d045ec714c4748c785a59045c3736349" +uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" +version = "0.10.7" +weakdeps = ["Random", "Test"] + + [deps.TranscodingStreams.extensions] + TestExt = ["Test", "Random"] + +[[deps.TriangularSolve]] +deps = ["CloseOpenIntervals", "IfElse", "LayoutPointers", "LinearAlgebra", "LoopVectorization", "Polyester", "Static", "VectorizationBase"] +git-tree-sha1 = "66c68a20907800c0b7c04ff8a6164115e8747de2" +uuid = "d5829a12-d9aa-46ab-831f-fb7c9ab06edf" +version = "0.2.0" + +[[deps.Tricks]] +git-tree-sha1 = "eae1bb484cd63b36999ee58be2de6c178105112f" +uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" +version = "0.1.8" + +[[deps.TruncatedStacktraces]] +deps = ["InteractiveUtils", "MacroTools", "Preferences"] +git-tree-sha1 = "ea3e54c2bdde39062abf5a9758a23735558705e1" +uuid = "781d530d-4396-4725-bb49-402e4bee1e77" +version = "1.4.0" + +[[deps.URIs]] +git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b" +uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" +version = "1.5.1" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" + +[[deps.UnPack]] +git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" +uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" +version = "1.0.2" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" + +[[deps.UnicodeFun]] +deps = ["REPL"] +git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" +uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" +version = "0.4.1" + +[[deps.Unitful]] +deps = ["Dates", "LinearAlgebra", "Random"] +git-tree-sha1 = "3c793be6df9dd77a0cf49d80984ef9ff996948fa" +uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" +version = "1.19.0" +weakdeps = ["ConstructionBase", "InverseFunctions"] + + [deps.Unitful.extensions] + ConstructionBaseUnitfulExt = "ConstructionBase" + InverseFunctionsUnitfulExt = "InverseFunctions" + +[[deps.UnitfulLatexify]] +deps = ["LaTeXStrings", "Latexify", "Unitful"] +git-tree-sha1 = "e2d817cc500e960fdbafcf988ac8436ba3208bfd" +uuid = "45397f5d-5981-4c77-b2b3-fc36d6e9b728" +version = "1.6.3" + +[[deps.Unityper]] +deps = ["ConstructionBase"] +git-tree-sha1 = "25008b734a03736c41e2a7dc314ecb95bd6bbdb0" +uuid = "a7c27f48-0311-42f6-a7f8-2c11e75eb415" +version = "0.1.6" + +[[deps.Unzip]] +git-tree-sha1 = "ca0969166a028236229f63514992fc073799bb78" +uuid = "41fe7b60-77ed-43a1-b4f0-825fd5a5650d" +version = "0.2.0" + +[[deps.VectorizationBase]] +deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] +git-tree-sha1 = "ac377f0a248753a1b1d58bbc92a64f5a726dfb71" +uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" +version = "0.21.66" + +[[deps.VertexSafeGraphs]] +deps = ["Graphs"] +git-tree-sha1 = "8351f8d73d7e880bfc042a8b6922684ebeafb35c" +uuid = "19fa3120-7c27-5ec5-8db8-b0b0aa330d6f" +version = "0.2.0" + +[[deps.Vulkan_Loader_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Wayland_jll", "Xorg_libX11_jll", "Xorg_libXrandr_jll", "xkbcommon_jll"] +git-tree-sha1 = "2f0486047a07670caad3a81a075d2e518acc5c59" +uuid = "a44049a8-05dd-5a78-86c9-5fde0876e88c" +version = "1.3.243+0" + +[[deps.Wayland_jll]] +deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg", "XML2_jll"] +git-tree-sha1 = "7558e29847e99bc3f04d6569e82d0f5c54460703" +uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89" +version = "1.21.0+1" + +[[deps.Wayland_protocols_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "93f43ab61b16ddfb2fd3bb13b3ce241cafb0e6c9" +uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91" +version = "1.31.0+0" + +[[deps.XML2_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "532e22cf7be8462035d092ff21fada7527e2c488" +uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" +version = "2.12.6+0" + +[[deps.XSLT_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] +git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" +uuid = "aed1982a-8fda-507f-9586-7b0439959a61" +version = "1.1.34+0" + +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "ac88fb95ae6447c8dda6a5503f3bafd496ae8632" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.4.6+0" + +[[deps.Xorg_libICE_jll]] +deps = ["Libdl", "Pkg"] +git-tree-sha1 = "e5becd4411063bdcac16be8b66fc2f9f6f1e8fe5" +uuid = "f67eecfb-183a-506d-b269-f58e52b52d7c" +version = "1.0.10+1" + +[[deps.Xorg_libSM_jll]] +deps = ["Libdl", "Pkg", "Xorg_libICE_jll"] +git-tree-sha1 = "4a9d9e4c180e1e8119b5ffc224a7b59d3a7f7e18" +uuid = "c834827a-8449-5923-a945-d239c165b7dd" +version = "1.2.3+0" + +[[deps.Xorg_libX11_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "afead5aba5aa507ad5a3bf01f58f82c8d1403495" +uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" +version = "1.8.6+0" + +[[deps.Xorg_libXau_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6035850dcc70518ca32f012e46015b9beeda49d8" +uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" +version = "1.0.11+0" + +[[deps.Xorg_libXcursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "12e0eb3bc634fa2080c1c37fccf56f7c22989afd" +uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" +version = "1.2.0+4" + +[[deps.Xorg_libXdmcp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "34d526d318358a859d7de23da945578e8e8727b7" +uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" +version = "1.1.4+0" + +[[deps.Xorg_libXext_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3" +uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" +version = "1.3.4+4" + +[[deps.Xorg_libXfixes_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "0e0dc7431e7a0587559f9294aeec269471c991a4" +uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" +version = "5.0.3+4" + +[[deps.Xorg_libXi_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] +git-tree-sha1 = "89b52bc2160aadc84d707093930ef0bffa641246" +uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" +version = "1.7.10+4" + +[[deps.Xorg_libXinerama_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll"] +git-tree-sha1 = "26be8b1c342929259317d8b9f7b53bf2bb73b123" +uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" +version = "1.1.4+4" + +[[deps.Xorg_libXrandr_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll"] +git-tree-sha1 = "34cea83cb726fb58f325887bf0612c6b3fb17631" +uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" +version = "1.5.2+4" + +[[deps.Xorg_libXrender_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] +git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96" +uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" +version = "0.9.10+4" + +[[deps.Xorg_libpthread_stubs_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8fdda4c692503d44d04a0603d9ac0982054635f9" +uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74" +version = "0.1.1+0" + +[[deps.Xorg_libxcb_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] +git-tree-sha1 = "b4bfde5d5b652e22b9c790ad00af08b6d042b97d" +uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" +version = "1.15.0+0" + +[[deps.Xorg_libxkbfile_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "730eeca102434283c50ccf7d1ecdadf521a765a4" +uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a" +version = "1.1.2+0" + +[[deps.Xorg_xcb_util_cursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_jll", "Xorg_xcb_util_renderutil_jll"] +git-tree-sha1 = "04341cb870f29dcd5e39055f895c39d016e18ccd" +uuid = "e920d4aa-a673-5f3a-b3d7-f755a4d47c43" +version = "0.1.4+0" + +[[deps.Xorg_xcb_util_image_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"] +git-tree-sha1 = "0fab0a40349ba1cba2c1da699243396ff8e94b97" +uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b" +version = "0.4.0+1" + +[[deps.Xorg_xcb_util_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll"] +git-tree-sha1 = "e7fd7b2881fa2eaa72717420894d3938177862d1" +uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5" +version = "0.4.0+1" + +[[deps.Xorg_xcb_util_keysyms_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"] +git-tree-sha1 = "d1151e2c45a544f32441a567d1690e701ec89b00" +uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7" +version = "0.4.0+1" + +[[deps.Xorg_xcb_util_renderutil_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"] +git-tree-sha1 = "dfd7a8f38d4613b6a575253b3174dd991ca6183e" +uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e" +version = "0.3.9+1" + +[[deps.Xorg_xcb_util_wm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"] +git-tree-sha1 = "e78d10aab01a4a154142c5006ed44fd9e8e31b67" +uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361" +version = "0.4.1+1" + +[[deps.Xorg_xkbcomp_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxkbfile_jll"] +git-tree-sha1 = "330f955bc41bb8f5270a369c473fc4a5a4e4d3cb" +uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4" +version = "1.4.6+0" + +[[deps.Xorg_xkeyboard_config_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xkbcomp_jll"] +git-tree-sha1 = "691634e5453ad362044e2ad653e79f3ee3bb98c3" +uuid = "33bec58e-1273-512f-9401-5d533626f822" +version = "2.39.0+0" + +[[deps.Xorg_xtrans_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e92a1a012a10506618f10b7047e478403a046c77" +uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" +version = "1.5.0+0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.2.13+1" + +[[deps.Zstd_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e678132f07ddb5bfa46857f0d7620fb9be675d3b" +uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" +version = "1.5.6+0" + +[[deps.eudev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "gperf_jll"] +git-tree-sha1 = "431b678a28ebb559d224c0b6b6d01afce87c51ba" +uuid = "35ca27e7-8b34-5b7f-bca9-bdc33f59eb06" +version = "3.2.9+0" + +[[deps.fzf_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a68c9655fbe6dfcab3d972808f1aafec151ce3f8" +uuid = "214eeab7-80f7-51ab-84ad-2988db7cef09" +version = "0.43.0+0" + +[[deps.gperf_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "3516a5630f741c9eecb3720b1ec9d8edc3ecc033" +uuid = "1a1c6b14-54f6-533d-8383-74cd7377aa70" +version = "3.1.1+0" + +[[deps.libaom_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "3a2ea60308f0996d26f1e5354e10c24e9ef905d4" +uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" +version = "3.4.0+0" + +[[deps.libass_jll]] +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] +git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47" +uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" +version = "0.15.1+0" + +[[deps.libblastrampoline_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" +version = "5.8.0+1" + +[[deps.libevdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "141fe65dc3efabb0b1d5ba74e91f6ad26f84cc22" +uuid = "2db6ffa8-e38f-5e21-84af-90c45d0032cc" +version = "1.11.0+0" + +[[deps.libfdk_aac_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" +uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" +version = "2.0.2+0" + +[[deps.libinput_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "eudev_jll", "libevdev_jll", "mtdev_jll"] +git-tree-sha1 = "ad50e5b90f222cfe78aa3d5183a20a12de1322ce" +uuid = "36db933b-70db-51c0-b978-0f229ee0e533" +version = "1.18.0+0" + +[[deps.libpng_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d7015d2e18a5fd9a4f47de711837e980519781a4" +uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" +version = "1.6.43+1" + +[[deps.libvorbis_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] +git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" +uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" +version = "1.3.7+1" + +[[deps.mtdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "814e154bdb7be91d78b6802843f76b6ece642f11" +uuid = "009596ad-96f7-51b1-9f1b-5ce2d5e8a71e" +version = "1.1.6+0" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.52.0+1" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" + +[[deps.x264_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" +uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" +version = "2021.5.5+0" + +[[deps.x265_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" +uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" +version = "3.5.0+0" + +[[deps.xkbcommon_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll", "Wayland_protocols_jll", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"] +git-tree-sha1 = "9c304562909ab2bab0262639bd4f444d7bc2be37" +uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd" +version = "1.4.1+1" +""" + +# ╔═╡ Cell order: +# ╠═c3ef64c0-03d8-11ef-38c5-035a60e72ba5 +# ╠═018a6d5d-f7c9-4cba-a2e7-bc6d8dd6e24c +# ╠═cf19a33d-f6b8-4db5-aa58-eed8b305c437 +# ╠═9439f2ed-1dc5-4333-934c-9e49a61e9915 +# ╠═27930d05-f61d-4681-95a5-4cc3e3048476 +# ╠═88fe0db6-58cb-4fe4-897f-20cb4bc91914 +# ╠═9987b4d8-9c1a-4906-8c16-b492e6e57e28 +# ╠═6123e783-bb7f-4719-a1b7-24e7cf1826d6 +# ╠═a0ccd3e8-91ca-4ee2-9717-a5540561ad46 +# ╠═f167af9b-3c38-4695-acdc-5a1643fcb549 +# ╠═cdf6730f-a8de-43d5-83ef-7c57c87ae4ea +# ╠═d8f898a0-3f8c-4438-b868-6688d86c7328 +# ╠═848f3025-a1fa-432c-8c1d-e569d93b6323 +# ╠═9c372062-4f73-43a3-9018-c4d21f7d12dc +# ╠═6b5a9aa0-e31e-4af2-b16e-f6aca6e15350 +# ╠═d1cff8c1-8443-404a-825e-38d2ef06122f +# ╠═94a1ac29-1fbb-47f3-93d9-c5ca0b6a75ae +# ╠═87673d46-b120-40fa-b048-9ada54ea7768 +# ╠═3b40d052-2a41-4e28-8537-928ebb93d55c +# ╟─00000000-0000-0000-0000-000000000001 +# ╟─00000000-0000-0000-0000-000000000002 diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..4a4c3cf --- /dev/null +++ b/readme.md @@ -0,0 +1,323 @@ +# OceanSonar.jl + +[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://kapple19.github.io/OceanSonar.jl/stable/) +[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://kapple19.github.io/OceanSonar.jl/dev/) +[![Build Status](https://github.com/kapple19/OceanSonar.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/kapple19/OceanSonar.jl/actions/workflows/CI.yml?query=branch%3Amain) +[![Aqua](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl) + +[Aqua.jl]: https://docs.juliahub.com/Aqua +[Documenter.jl]: https://documenter.juliadocs.org/stable +[JET.jl]: https://aviatesk.github.io/JET.jl +[Julia]: https://docs.julialang.org/en +[Latexify.jl]: https://korsbo.github.io/Latexify.jl/stable +[LiveServer.jl]: https://tlienart.github.io/LiveServer.jl +[Makie.jl]: https://docs.makie.org/stable/ +[ModelingToolkit.jl]: https://docs.sciml.ai/ModelingToolkit/stable +[Plots.jl]: https://docs.juliaplots.org/stable +[PropCheck.jl]: https://seelengrab.github.io/PropCheck.jl/stable +[Symbolics.jl]: https://docs.sciml.ai/Symbolics/stable + +This [Julia] package is in development. + +The purpose of this package is to implement ocean acoustics and sonar models. +Its goal is an open source community-developed acoustics package that enables: + +* Performance like C++ and Fortran with legible syntax like MATLAB and Python. +* Distributed and parallel computing provided by Julia. +* Reproducibility of literature books and papers. +* Composability and modularity of models. +* Documented verbosities of mathematical results. +* Ease of collaboration. +* Code implementations that can be introspected mathematically, compiler-wise, and visualisation functionalities are built-in. +* Reliance and use of community-developed and tested equation solver libraries for differential equations, root finders, etc. + +Motivations of the primary author: + +* Mastery of field. +* Community engagement. +* Julia programming enjoyment and learning. +* Demonstration of Julia as next generation scientific software tool for analysis and deployment. + +## Usage + +Installation requires the [Julia] programming language. + +This package is still under development, +thus the repository address is required for installation. + +1. Install Julia using the instructions [here](https://julialang.org/downloads/). +2. Open a Julia REPL (terminal). +3. Activate the `Pkg` mode by pressing `]`. +4. Enter `add https://github.com/kapple19/OceanSonar.jl` which installs the `OceanSonar.jl` package. +5. Return to the `Julian` mode by backspacing. +6. Enter `using OceanSonar`. + +## Demonstration + +Acoustic ray tracing + +```julia +using OceanSonar +using CairoMakie + +scen = Scenario("Munk Profile") +prop = Propagation("Trace", scen, angles = critical_angles(scen, N = 21)) + +visual(Beam, prop) +``` + +![readme/img/munk_profile_rays.svg](readme/img/munk_profile_rays.svg) + +```julia +using OceanSonar +using CairoMakie + +scen = Scenario("Parabolic Bathymetry") +lowest_angle = atan(1, 5) +highest_angle = atan(5, 2) +angles = angles = range(lowest_angle, highest_angle, 31) +prop = Propagation("Trace", scen, angles = angles) + +visual(Beam, prop) +``` + +![readme/img/parabolic_bathymetry_rays.svg](readme/img/parabolic_bathymetry_rays.svg) + +Visualise frequency changes (issues with CairoMakie image saving) + +```julia +using OceanSonar +using CairoMakie +using Statistics + +model = "Lloyd Mirror" + +function run_prop(f) + scen = Scenario(model) + scen.f = f + return Propagation("Trace", scen) +end + +props = [run_prop(f) for f in series125(5e3)] + +bounds(data) = mean(data) .+ (3std(data) * [-1, 1]) +clims = [prop.PL for prop in props] |> splat(vcat) |> bounds + +fig = Figure() +num_rows, num_cols = OceanSonar.rect_or_square_gridsize(props |> length) +heatmaps = Makie.Plot[] +for row in 1:num_rows, col in 1:num_cols + lin = LinearIndices((num_cols, num_rows)) + + idx_prop = lin[col, row] + prop = props[idx_prop] + + pos = fig[row, col] + axis = Axis(pos, + yreversed = true, + title = string(prop.scen.f, " Hz") + ) + hidedecorations!(axis) + + hm = heatmap!(axis, + prop, + colormap = Reverse(:jet), + colorrange = clims, + interpolate = true # https://github.com/MakieOrg/Makie.jl/issues/2514 + ) + push!(heatmaps, hm) +end +Colorbar(fig[:, end+1], heatmaps[1], + label = OceanSonar.label(Propagation) +) +Label(fig[0, :], model, + fontsize = 25 +) + +fig +``` + +![readme/img/lloyd_mirror_freq_perturb.svg](readme/img/lloyd_mirror_freq_perturb.svg) + +Compare square root operator approximations for the parabolic equation + +```julia +using OceanSonar +using CairoMakie + +scen = Scenario("Lloyd Mirror") +config = ParabolicConfig() +for model = list_models(RationalFunctionApproximation) + # config.marcher = marcher + # prop = Propagation(config, scen) + # visual!(prop) # TODO: tile +end + +nothing +``` + +In development. + +Visualise the equation for an OceanSonar.jl model + +```julia +using OceanSonar +using Symbolics + +@variables x z +ocean_celerity("Munk", x, z) |> string +``` + +1500(1 + 0.00737(-1 + 2(-1 + (1//1300)*z) + exp(-2(-1 + (1//1300)*z)))) +## Implementation & Roadmap Summary + +* Sonar oceanography + * Conceptually-structured hierarchical containers + * Convenience uni/multivariate interpolators + * Inbuilt extensive suite of environments from literature + +* Underwater acoustics + * Reflection dynamics and losses + * Scattering and reverberation + * Propagation solution methods + * Ray methods + * Wavenumber integration + * Normal modes + * Parabolic equations + * Finite difference and finite element methods + * Replication of literature results + +* Signal processing + * Sonar types hierarchy enumeration + * Efficiently implemented sonar type-sensitive sonar equation term calculations + +* Statistical detection theory + * ROC curves + * Signal detector design + * Detection metrics e.g. signal excess, transition detection probability, etc. + +* Documentation + * Book publishing of ocean sonar theory with executable, reproducible implementation examples + * Mathematical formulations accompany implementation, reducing vagueness + * Pushing frontiers of ocean acoustics and sonar with reproducible publications + +* Computational performance + * Removing allocations + * Parallel and distributed computing + +* Front-end compatibility + * [ModelingToolkit.jl] compatibility + * Ocean sonar GUI + +## Citation + +Cite this work with [`citation.bib`](citation.bib): + +```verbatim +@misc{OceanSonar.jl, + author = {Aaron Kaw and contributors}, + title = {OceanSonar.jl}, + url = {https://github.com/kapple19/OceanSonar.jl}, + version = {v1.0.0-DEV}, + year = {2024}, + month = {3} +} +``` + +### Academic Bibliography + +> Abraham, D. A. (2019). _Underwater Acoustic Signal Processing: Modeling, Detection, and Estimation_. Springer. + +> Ainslie, M. A. (2010). _Principles of Sonar Performance Modelling_. Springer. + +> Jensen, F. B., Kuperman, W. A., Porter, M. B., & Schmidt, H. (2011). _Computational Ocean Acoustics_ (2nd Ed.). Springer. + +> Lurton, X. (2016). _An Introduction to Underwater Acoustics: Principles and Applications_ (2nd Ed.). Springer. + +### Software Bibliography + +No citation provided: + +* [Aqua.jl] +* [Documenter.jl] +* [JET.jl] +* [Latexify.jl] +* [LiveServer.jl] +* [PropCheck.jl] + +Provided citations: + +```bibtex +@article{DifferentialEquations.jl-2017, + author = {Rackauckas, Christopher and Nie, Qing}, + doi = {10.5334/jors.151}, + journal = {The Journal of Open Research Software}, + keywords = {Applied Mathematics}, + note = {Exported from https://app.dimensions.ai on 2019/05/05}, + number = {1}, + pages = {}, + title = {DifferentialEquations.jl – A Performant and Feature-Rich Ecosystem for Solving Differential Equations in Julia}, + url = {https://app.dimensions.ai/details/publication/pub.1085583166 and http://openresearchsoftware.metajnl.com/articles/10.5334/jors.151/galley/245/download/}, + volume = {5}, + year = {2017} +} +``` + +```bibtex +@article{RevelsLubinPapamarkou2016, + title = {Forward-Mode Automatic Differentiation in {J}ulia}, + author = {{Revels}, J. and {Lubin}, M. and {Papamarkou}, T.}, + journal = {arXiv:1607.07892 [cs.MS]}, + year = {2016}, + url = {https://arxiv.org/abs/1607.07892} +} +``` + +```bibtex +@software{IntervalArithmetic.jl, + author = {David P. Sanders and Luis Benet}, + title = {IntervalArithmetic.jl}, + url = {https://github.com/JuliaIntervals/IntervalArithmetic.jl}, + year = {2014}, + doi = {10.5281/zenodo.3336308} +} +``` + +```bibtex +@article{Julia-2017, + title={Julia: A fresh approach to numerical computing}, + author={Bezanson, Jeff and Edelman, Alan and Karpinski, Stefan and Shah, Viral B}, + journal={SIAM {R}eview}, + volume={59}, + number={1}, + pages={65--98}, + year={2017}, + publisher={SIAM}, + doi={10.1137/141000671}, + url={https://epubs.siam.org/doi/10.1137/141000671} +} +``` + +```bibtex +@misc{ma2021modelingtoolkit, + title={ModelingToolkit: A Composable Graph Transformation System For Equation-Based Modeling}, + author={Yingbo Ma and Shashi Gowda and Ranjan Anantharaman and Chris Laughman and Viral Shah and Chris Rackauckas}, + year={2021}, + eprint={2103.05244}, + archivePrefix={arXiv}, + primaryClass={cs.MS} +} +``` + +```bibtex +@article{PlotsJL, + doi = {https://doi.org/10.5334/jors.431}, + url = {https://openresearchsoftware.metajnl.com/articles/10.5334/jors.431/}, + author = {Christ, Simon and Schwabeneder, Daniel and Rackauckas, Christopher and Borregaard, Michael Krabbe and Breloff, Thomas}, + keywords = {Graphics (cs.GR), FOS: Computer and information sciences, FOS: Computer and information sciences, I.3.3}, + title = {Plots.jl -- a user extendable plotting API for the julia programming language}, + publisher = {Journal of Open Research Software}, + year = {2023}, + copyright = {Creative Commons Attribution 4.0 International} +} +``` diff --git a/readme/Project.toml b/readme/Project.toml new file mode 100644 index 0000000..f56404a --- /dev/null +++ b/readme/Project.toml @@ -0,0 +1,5 @@ +[deps] +CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" +Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" +OceanSonar = "606d67fd-65b6-4abb-b2f0-1946d248e4dc" +Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" diff --git a/readme/img/custom_celerity_profile.svg b/readme/img/custom_celerity_profile.svg new file mode 100644 index 0000000..99b0293 --- /dev/null +++ b/readme/img/custom_celerity_profile.svg @@ -0,0 +1,3485 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/readme/img/index_squared_profile.svg b/readme/img/index_squared_profile.svg new file mode 100644 index 0000000..6df6194 --- /dev/null +++ b/readme/img/index_squared_profile.svg @@ -0,0 +1,2793 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/readme/img/lloyd_mirror_freq_perturb.svg b/readme/img/lloyd_mirror_freq_perturb.svg new file mode 100644 index 0000000..5c33bde --- /dev/null +++ b/readme/img/lloyd_mirror_freq_perturb.svg @@ -0,0 +1,824 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/readme/img/munk_profile.svg b/readme/img/munk_profile.svg new file mode 100644 index 0000000..73b8e9c --- /dev/null +++ b/readme/img/munk_profile.svg @@ -0,0 +1,2795 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/readme/img/munk_profile_3000.svg b/readme/img/munk_profile_3000.svg new file mode 100644 index 0000000..43c47ac --- /dev/null +++ b/readme/img/munk_profile_3000.svg @@ -0,0 +1,2814 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/readme/img/munk_profile_eqn.svg b/readme/img/munk_profile_eqn.svg new file mode 100644 index 0000000..d6d5f91 --- /dev/null +++ b/readme/img/munk_profile_eqn.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/readme/img/munk_profile_rays.svg b/readme/img/munk_profile_rays.svg new file mode 100644 index 0000000..fcb3f0a --- /dev/null +++ b/readme/img/munk_profile_rays.svg @@ -0,0 +1,51129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/readme/img/parabolic_bathymetry_rays.svg b/readme/img/parabolic_bathymetry_rays.svg new file mode 100644 index 0000000..2354998 --- /dev/null +++ b/readme/img/parabolic_bathymetry_rays.svg @@ -0,0 +1,51394 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/readme/readme.md b/readme/readme.md new file mode 100644 index 0000000..7715749 --- /dev/null +++ b/readme/readme.md @@ -0,0 +1,19 @@ +# OceanSonar.jl + +[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://kapple19.github.io/OceanSonar.jl/stable/) +[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://kapple19.github.io/OceanSonar.jl/dev/) +[![Build Status](https://github.com/kapple19/OceanSonar.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/kapple19/OceanSonar.jl/actions/workflows/CI.yml?query=branch%3Amain) +[![Aqua](https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl) + +[Aqua.jl]: https://docs.juliahub.com/Aqua +[Documenter.jl]: https://documenter.juliadocs.org/stable +[JET.jl]: https://aviatesk.github.io/JET.jl +[Julia]: https://docs.julialang.org/en +[Latexify.jl]: https://korsbo.github.io/Latexify.jl/stable +[LiveServer.jl]: https://tlienart.github.io/LiveServer.jl +[Makie.jl]: https://docs.makie.org/stable/ +[ModelingToolkit.jl]: https://docs.sciml.ai/ModelingToolkit/stable +[Plots.jl]: https://docs.juliaplots.org/stable +[PropCheck.jl]: https://seelengrab.github.io/PropCheck.jl/stable +[Symbolics.jl]: https://docs.sciml.ai/Symbolics/stable + diff --git a/readme/refs/DifferentialEquations.bib b/readme/refs/DifferentialEquations.bib new file mode 100644 index 0000000..53c488a --- /dev/null +++ b/readme/refs/DifferentialEquations.bib @@ -0,0 +1,13 @@ +@article{DifferentialEquations.jl-2017, + author = {Rackauckas, Christopher and Nie, Qing}, + doi = {10.5334/jors.151}, + journal = {The Journal of Open Research Software}, + keywords = {Applied Mathematics}, + note = {Exported from https://app.dimensions.ai on 2019/05/05}, + number = {1}, + pages = {}, + title = {DifferentialEquations.jl – A Performant and Feature-Rich Ecosystem for Solving Differential Equations in Julia}, + url = {https://app.dimensions.ai/details/publication/pub.1085583166 and http://openresearchsoftware.metajnl.com/articles/10.5334/jors.151/galley/245/download/}, + volume = {5}, + year = {2017} +} \ No newline at end of file diff --git a/readme/refs/ForwardDiff.bib b/readme/refs/ForwardDiff.bib new file mode 100644 index 0000000..1652e05 --- /dev/null +++ b/readme/refs/ForwardDiff.bib @@ -0,0 +1,7 @@ +@article{RevelsLubinPapamarkou2016, + title = {Forward-Mode Automatic Differentiation in {J}ulia}, + author = {{Revels}, J. and {Lubin}, M. and {Papamarkou}, T.}, + journal = {arXiv:1607.07892 [cs.MS]}, + year = {2016}, + url = {https://arxiv.org/abs/1607.07892} +} \ No newline at end of file diff --git a/readme/refs/IntervalArithmetic.bib b/readme/refs/IntervalArithmetic.bib new file mode 100644 index 0000000..ccca379 --- /dev/null +++ b/readme/refs/IntervalArithmetic.bib @@ -0,0 +1,7 @@ +@software{IntervalArithmetic.jl, + author = {David P. Sanders and Luis Benet}, + title = {IntervalArithmetic.jl}, + url = {https://github.com/JuliaIntervals/IntervalArithmetic.jl}, + year = {2014}, + doi = {10.5281/zenodo.3336308} +} \ No newline at end of file diff --git a/readme/refs/Julia.bib b/readme/refs/Julia.bib new file mode 100644 index 0000000..cfb613f --- /dev/null +++ b/readme/refs/Julia.bib @@ -0,0 +1,12 @@ +@article{Julia-2017, + title={Julia: A fresh approach to numerical computing}, + author={Bezanson, Jeff and Edelman, Alan and Karpinski, Stefan and Shah, Viral B}, + journal={SIAM {R}eview}, + volume={59}, + number={1}, + pages={65--98}, + year={2017}, + publisher={SIAM}, + doi={10.1137/141000671}, + url={https://epubs.siam.org/doi/10.1137/141000671} +} \ No newline at end of file diff --git a/readme/refs/ModelingToolkit.bib b/readme/refs/ModelingToolkit.bib new file mode 100644 index 0000000..9bc3e64 --- /dev/null +++ b/readme/refs/ModelingToolkit.bib @@ -0,0 +1,8 @@ +@misc{ma2021modelingtoolkit, + title={ModelingToolkit: A Composable Graph Transformation System For Equation-Based Modeling}, + author={Yingbo Ma and Shashi Gowda and Ranjan Anantharaman and Chris Laughman and Viral Shah and Chris Rackauckas}, + year={2021}, + eprint={2103.05244}, + archivePrefix={arXiv}, + primaryClass={cs.MS} +} \ No newline at end of file diff --git a/readme/refs/Plots.bib b/readme/refs/Plots.bib new file mode 100644 index 0000000..c7e21ac --- /dev/null +++ b/readme/refs/Plots.bib @@ -0,0 +1,10 @@ +@article{PlotsJL, + doi = {https://doi.org/10.5334/jors.431}, + url = {https://openresearchsoftware.metajnl.com/articles/10.5334/jors.431/}, + author = {Christ, Simon and Schwabeneder, Daniel and Rackauckas, Christopher and Borregaard, Michael Krabbe and Breloff, Thomas}, + keywords = {Graphics (cs.GR), FOS: Computer and information sciences, FOS: Computer and information sciences, I.3.3}, + title = {Plots.jl -- a user extendable plotting API for the julia programming language}, + publisher = {Journal of Open Research Software}, + year = {2023}, + copyright = {Creative Commons Attribution 4.0 International} +} \ No newline at end of file diff --git a/readme/scripts/lloyd_mirror_freq_perturb.jl b/readme/scripts/lloyd_mirror_freq_perturb.jl new file mode 100644 index 0000000..ea1dc92 --- /dev/null +++ b/readme/scripts/lloyd_mirror_freq_perturb.jl @@ -0,0 +1,49 @@ +using OceanSonar +using CairoMakie +using Statistics + +model = "Lloyd Mirror" + +function run_prop(f) + scen = Scenario(model) + scen.f = f + return Propagation("Trace", scen) +end + +props = [run_prop(f) for f in series125(5e3)] + +bounds(data) = mean(data) .+ (3std(data) * [-1, 1]) +clims = [prop.PL for prop in props] |> splat(vcat) |> bounds + +fig = Figure() +num_rows, num_cols = OceanSonar.rect_or_square_gridsize(props |> length) +heatmaps = Makie.Plot[] +for row in 1:num_rows, col in 1:num_cols + lin = LinearIndices((num_cols, num_rows)) + + idx_prop = lin[col, row] + prop = props[idx_prop] + + pos = fig[row, col] + axis = Axis(pos, + yreversed = true, + title = string(prop.scen.f, " Hz") + ) + hidedecorations!(axis) + + hm = heatmap!(axis, + prop, + colormap = Reverse(:jet), + colorrange = clims, + interpolate = true # https://github.com/MakieOrg/Makie.jl/issues/2514 + ) + push!(heatmaps, hm) +end +Colorbar(fig[:, end+1], heatmaps[1], + label = OceanSonar.label(Propagation) +) +Label(fig[0, :], model, + fontsize = 25 +) + +fig \ No newline at end of file diff --git a/readme/scripts/lloyd_mirror_sqrt_approxers.jl b/readme/scripts/lloyd_mirror_sqrt_approxers.jl new file mode 100644 index 0000000..a287c6f --- /dev/null +++ b/readme/scripts/lloyd_mirror_sqrt_approxers.jl @@ -0,0 +1,12 @@ +using OceanSonar +using CairoMakie + +scen = Scenario("Lloyd Mirror") +config = ParabolicConfig() +for model = list_models(RationalFunctionApproximation) + # config.marcher = marcher + # prop = Propagation(config, scen) + # visual!(prop) # TODO: tile +end + +nothing \ No newline at end of file diff --git a/readme/scripts/main.jl b/readme/scripts/main.jl new file mode 100644 index 0000000..c554293 --- /dev/null +++ b/readme/scripts/main.jl @@ -0,0 +1,180 @@ +# This script generates the `readme.md` file for the OceanSonar.jl package. + +using CairoMakie + +badges = [ + "Stable" => "https://img.shields.io/badge/docs-stable-blue.svg)](https://kapple19.github.io/OceanSonar.jl/stable/" + "Dev" => "https://img.shields.io/badge/docs-dev-blue.svg)](https://kapple19.github.io/OceanSonar.jl/dev/" + "Build Status" => "https://github.com/kapple19/OceanSonar.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/kapple19/OceanSonar.jl/actions/workflows/CI.yml?query=branch%3Amain" + "Aqua" => "https://raw.githubusercontent.com/JuliaTesting/Aqua.jl/master/badge.svg)](https://github.com/JuliaTesting/Aqua.jl" +] + +link_definitions = [ + "Aqua.jl" => "https://docs.juliahub.com/Aqua" + "Documenter.jl" => "https://documenter.juliadocs.org/stable" + "JET.jl" => "https://aviatesk.github.io/JET.jl" + "Julia" => "https://docs.julialang.org/en" + "Latexify.jl" => "https://korsbo.github.io/Latexify.jl/stable" + "LiveServer.jl" => "https://tlienart.github.io/LiveServer.jl" + "Makie.jl" => "https://docs.makie.org/stable/" + "ModelingToolkit.jl" => "https://docs.sciml.ai/ModelingToolkit/stable" + "Plots.jl" => "https://docs.juliaplots.org/stable" + "PropCheck.jl" => "https://seelengrab.github.io/PropCheck.jl/stable" + "Symbolics.jl" => "https://docs.sciml.ai/Symbolics/stable" +] |> sort! + +academics = [ + "Abraham, D. A. (2019). _Underwater Acoustic Signal Processing: Modeling, Detection, and Estimation_. Springer." + "Ainslie, M. A. (2010). _Principles of Sonar Performance Modelling_. Springer." + "Jensen, F. B., Kuperman, W. A., Porter, M. B., & Schmidt, H. (2011). _Computational Ocean Acoustics_ (2nd Ed.). Springer." + "Lurton, X. (2016). _An Introduction to Underwater Acoustics: Principles and Applications_ (2nd Ed.). Springer." +] |> sort! + +software = [ + "Documenter" + "LiveServer" + "Aqua" + "JET" + "PropCheck" + "Latexify" +] |> sort! + +struct Demo + desc::String + filenames::Vector{String} +end + +Demo(desc::String, filename::String) = Demo(desc, [filename]) + +function present(io::IO, demo::Demo) + println(io, demo.desc) + println(io) + + for filebarename in demo.filenames + codename = filebarename * ".jl" + codepath = joinpath("readme", "scripts", codename) + code_string = read(codepath, String) + + println(io, "```julia") + println(io, code_string) + println(io, "```") + println(io) + + sym = Symbol(codename) + m = Module(sym) + # Core.eval(m, :(eval(x) = Core.eval($m, x))) + Core.eval(m, :(include(x) = Base.include($m, abspath(x)))) + # codefullpath = abspath(codepath) + # output = invokelatest(m.include, codefullpath) + output = @eval m include($codepath) + + if output isa Nothing + println(io, "In development.") + elseif output isa AbstractString + print(io, output) + elseif output isa Figure + outputpath = "readme/img/" * filebarename * ".svg" + save(outputpath, output) + println(io, "![", outputpath, "](", outputpath, ")") + else + error(""" + Unrecognised expression evaluation output + from file $codename: + $(output |> typeof). + """) + end + println(io) + end +end + +demos = [ + Demo( + "Acoustic ray tracing", [ + "munk_profile_rays", "parabolic_bathymetry_rays" + ] + ) + Demo( + "Visualise frequency changes (issues with CairoMakie image saving)", + "lloyd_mirror_freq_perturb" + ) + Demo( + "Compare square root operator approximations for the parabolic equation", + "lloyd_mirror_sqrt_approxers" + ) + Demo( + "Visualise the equation for an OceanSonar.jl model", + "munk_profile_eqn" + ) +] + +function write_readme_file() + open("readme.md"; write = true) do file + println(file, "# OceanSonar.jl") + println(file) + + for badge in badges + println(file, "[![", badge.first, "](", badge.second, ")") + end + println(file) + + for link in link_definitions + println(file, "[", link.first, "]: ", link.second) + end + println(file) + + println(file, read("readme/texts/introduction.md", String)) + println(file) + + println(file, "## Usage") + println(file) + println(file, read("readme/texts/usage.md", String)) + println(file) + + println(file, "## Demonstration") + println(file) + + for demo in demos + present(file, demo) + end + + println(file, read("readme/texts/implementation.md", String)) + + println(file, "## Citation") + println(file) + + println(file, "Cite this work with [`citation.bib`](citation.bib):") + println(file) + println(file, "```verbatim") + println(file, read("citation.bib", String)) + println(file, "```") + println(file) + + println(file, "### Academic Bibliography") + println(file) + + for ref in academics + println(file, "> ", ref) + println(file) + end + + println(file, "### Software Bibliography") + println(file) + + println(file, "No citation provided:") + println(file) + for ref in software + println(file, "* [", ref, ".jl]") + end + println(file) + + println(file, "Provided citations:") + for ref in readdir("readme/refs") + println(file) + println(file, "```bibtex") + println(file, read("readme/refs/" * ref, String)) + println(file, "```") + end + end +end + +write_readme_file() diff --git a/readme/scripts/munk_profile_eqn.jl b/readme/scripts/munk_profile_eqn.jl new file mode 100644 index 0000000..71d003d --- /dev/null +++ b/readme/scripts/munk_profile_eqn.jl @@ -0,0 +1,5 @@ +using OceanSonar +using Symbolics + +@variables x z +ocean_celerity("Munk", x, z) |> string \ No newline at end of file diff --git a/readme/scripts/munk_profile_rays.jl b/readme/scripts/munk_profile_rays.jl new file mode 100644 index 0000000..ebbcedc --- /dev/null +++ b/readme/scripts/munk_profile_rays.jl @@ -0,0 +1,7 @@ +using OceanSonar +using CairoMakie + +scen = Scenario("Munk Profile") +prop = Propagation("Trace", scen, angles = critical_angles(scen, N = 21)) + +visual(Beam, prop) \ No newline at end of file diff --git a/readme/scripts/parabolic_bathymetry_rays.jl b/readme/scripts/parabolic_bathymetry_rays.jl new file mode 100644 index 0000000..3f70f45 --- /dev/null +++ b/readme/scripts/parabolic_bathymetry_rays.jl @@ -0,0 +1,10 @@ +using OceanSonar +using CairoMakie + +scen = Scenario("Parabolic Bathymetry") +lowest_angle = atan(1, 5) +highest_angle = atan(5, 2) +angles = angles = range(lowest_angle, highest_angle, 31) +prop = Propagation("Trace", scen, angles = angles) + +visual(Beam, prop) \ No newline at end of file diff --git a/readme/scripts/readme_images_old.jl b/readme/scripts/readme_images_old.jl new file mode 100644 index 0000000..0460f96 --- /dev/null +++ b/readme/scripts/readme_images_old.jl @@ -0,0 +1,92 @@ +# TODO: Automate readme.md generation + +## +using OceanSonar +using Plots + +scen = Scenario("Munk Profile") +prop = Propagation("Trace", scen, angles = critical_angles(scen)) +fig = visual(prop) +savefig(fig, "img/vis_munk_profile.svg") + +## +using OceanSonar +using Symbolics +using Latexify + +@variables x z + +c_eqn = ocean_celerity("Munk", x, z) + +c_eqn |> latexify |> render + +## +using OceanSonar + +@code_lowered bathymetry("Parabolic", 0) + +## +using OceanSonar +using Plots + +scen = Scenario("Munk Profile") +scen.z = 3000.0 +prop = Propagation("Trace", scen, angles = critical_angles(scen)) + +fig = visual(prop) + +savefig(fig, "img/vis_munk_profile_3000.svg") + +## +using OceanSonar +using Plots + +scen = Scenario("Munk Profile") +prop = Propagation("Trace", scen, angles = critical_angles(scen, N = 21)) + +fig = visual(Beam, prop) + +savefig(fig, "img/munk_profile_rays.svg") + +## +using OceanSonar +using Plots + +scen = Scenario("Parabolic Bathymetry") +lowest_angle = atan(1, 5) +highest_angle = atan(5, 2) +angles = angles = range(lowest_angle, highest_angle, 31) +prop = Propagation("Trace", scen, angles = angles) + +fig = visual(Beam, prop) + +savefig(fig, "img/parabolic_bathymetry_rays.svg") + +## +using OceanSonar +import OceanSonar: ocean_celerity + +ocean_celerity(::Val{:custom_profile}, x, z) = 1500.0 + sin(x*z/1e6) + +cel = OceanCelerity("Custom Profile") + +fig = visual(cel, xlim = (0, 10e3), ylim = (0, 5e3)) + +savefig(fig, "img/custom_celerity_profile.svg") + +## +using OceanSonar +using Base.Threads + +@info "Number of threads: $(nthreads())" + +@time "All" begin + models = list_models(Scenario) + @threads for m in eachindex(models) + model = models[m] + scen = Scenario(model) + prop = @time "$model" Propagation("Trace", scen, + angles = critical_angles(scen) + ) + end +end diff --git a/readme/texts/implementation.md b/readme/texts/implementation.md new file mode 100644 index 0000000..95e303f --- /dev/null +++ b/readme/texts/implementation.md @@ -0,0 +1,39 @@ +## Implementation & Roadmap Summary + +* Sonar oceanography + * Conceptually-structured hierarchical containers + * Convenience uni/multivariate interpolators + * Inbuilt extensive suite of environments from literature + +* Underwater acoustics + * Reflection dynamics and losses + * Scattering and reverberation + * Propagation solution methods + * Ray methods + * Wavenumber integration + * Normal modes + * Parabolic equations + * Finite difference and finite element methods + * Replication of literature results + +* Signal processing + * Sonar types hierarchy enumeration + * Efficiently implemented sonar type-sensitive sonar equation term calculations + +* Statistical detection theory + * ROC curves + * Signal detector design + * Detection metrics e.g. signal excess, transition detection probability, etc. + +* Documentation + * Book publishing of ocean sonar theory with executable, reproducible implementation examples + * Mathematical formulations accompany implementation, reducing vagueness + * Pushing frontiers of ocean acoustics and sonar with reproducible publications + +* Computational performance + * Removing allocations + * Parallel and distributed computing + +* Front-end compatibility + * [ModelingToolkit.jl] compatibility + * Ocean sonar GUI diff --git a/readme/texts/introduction.md b/readme/texts/introduction.md new file mode 100644 index 0000000..dd37b38 --- /dev/null +++ b/readme/texts/introduction.md @@ -0,0 +1,20 @@ +This [Julia] package is in development. + +The purpose of this package is to implement ocean acoustics and sonar models. +Its goal is an open source community-developed acoustics package that enables: + +* Performance like C++ and Fortran with legible syntax like MATLAB and Python. +* Distributed and parallel computing provided by Julia. +* Reproducibility of literature books and papers. +* Composability and modularity of models. +* Documented verbosities of mathematical results. +* Ease of collaboration. +* Code implementations that can be introspected mathematically, compiler-wise, and visualisation functionalities are built-in. +* Reliance and use of community-developed and tested equation solver libraries for differential equations, root finders, etc. + +Motivations of the primary author: + +* Mastery of field. +* Community engagement. +* Julia programming enjoyment and learning. +* Demonstration of Julia as next generation scientific software tool for analysis and deployment. \ No newline at end of file diff --git a/readme/texts/usage.md b/readme/texts/usage.md new file mode 100644 index 0000000..73f4663 --- /dev/null +++ b/readme/texts/usage.md @@ -0,0 +1,11 @@ +Installation requires the [Julia] programming language. + +This package is still under development, +thus the repository address is required for installation. + +1. Install Julia using the instructions [here](https://julialang.org/downloads/). +2. Open a Julia REPL (terminal). +3. Activate the `Pkg` mode by pressing `]`. +4. Enter `add https://github.com/kapple19/OceanSonar.jl` which installs the `OceanSonar.jl` package. +5. Return to the `Julian` mode by backspacing. +6. Enter `using OceanSonar`. \ No newline at end of file diff --git a/src/OceanSonar.jl b/src/OceanSonar.jl new file mode 100644 index 0000000..0af1cad --- /dev/null +++ b/src/OceanSonar.jl @@ -0,0 +1,25 @@ +module OceanSonar + +import Base: show, length, iterate, get +using NaNMath +using IntervalArithmetic: Interval, interval +using LinearAlgebra: dot +using Interpolations: linear_interpolation, Flat +using Statistics: mean, std +using ForwardDiff: derivative +using OrdinaryDiffEq: + ODEProblem, + solve, + CallbackSet, + ContinuousCallback, + Tsit5, + terminate! +using PrecompileTools: @setup_workload, @compile_workload + +include("preliminary/root.jl") +include("oceanography/root.jl") +include("acoustics/root.jl") +include("processing/root.jl") +include("postliminary/root.jl") + +end \ No newline at end of file diff --git a/src/acoustics/propagation/parabolic/config.jl b/src/acoustics/propagation/parabolic/config.jl new file mode 100644 index 0000000..4ec823a --- /dev/null +++ b/src/acoustics/propagation/parabolic/config.jl @@ -0,0 +1,12 @@ +@kwdef struct ParabolicConfig <: Config + field_starter::Symbol = :gaussian + marcher::Symbol = :elastic + surface::Symbol = :release + bottom::Symbol = :halfspace +end + +function Config(::Val{:parabolic}, args...; kwargs...) + ParabolicConfig(args...; kwargs...) +end + +const default_parabolic_config = ParabolicConfig() \ No newline at end of file diff --git a/src/acoustics/propagation/parabolic/marcher.jl b/src/acoustics/propagation/parabolic/marcher.jl new file mode 100644 index 0000000..732d4b7 --- /dev/null +++ b/src/acoustics/propagation/parabolic/marcher.jl @@ -0,0 +1,54 @@ +export RationalFunctionApproximation + +struct RationalFunctionApproximation{N} <: Functor + model::Val + a::NTuple{N, NTuple{2, Float64}} + b::NTuple{N, Float64} +end + +function (rfa::RationalFunctionApproximation)(q::Real) + numerators = [a[1] + q*a[2] for a in rfa.a] + denominators = [1.0 + b*q for b in rfa.b] + return 1.0 + sum(numerators ./ denominators) +end + +@parse_models_w_args_kwargs RationalFunctionApproximation + +function pade_rfa(m::Integer) + a_eqn(j, m) = 2 / (2m + 1) * sin(j*π / (2m + 1))^2 + b_eqn(j, m) = cos(j*π / (2m + 1))^2 + return ( + Tuple((0.0, a_eqn(j, m)) for j in 1:m), + Tuple(b_eqn(j, m) for j in 1:m) + ) +end + +function RationalFunctionApproximation(model::Val{:pade}; m::Integer = 2) + RationalFunctionApproximation( + model, + pade_rfa(m)... + ) +end + +function RationalFunctionApproximation(model::Val{:tappert}) + RationalFunctionApproximation( + model, + ((0.0, 0.5),), + (0.0,) + ) +end + +function RationalFunctionApproximation(model::Val{:claerbout}) + RationalFunctionApproximation( + model, + pade_rfa(1)... + ) +end + +function RationalFunctionApproximation(model::Val{:greene}) + RationalFunctionApproximation( + model, + ((0.99987 - 1, 0.79624 - 0.30102),), + (0.30102,) + ) +end \ No newline at end of file diff --git a/src/acoustics/propagation/parabolic/root.jl b/src/acoustics/propagation/parabolic/root.jl new file mode 100644 index 0000000..58ebd28 --- /dev/null +++ b/src/acoustics/propagation/parabolic/root.jl @@ -0,0 +1,33 @@ +export ParabolicConfig + +include("config.jl") +include("starter.jl") +include("marcher.jl") + +# Starter: 6.4.1.2 + +struct Parabolic <: Propagation + x + z + p + PL + + function Parabolic(scen::Scenario, + config::ParabolicConfig = ParabolicConfig(); + ranges::AbstractVector{<:AbstractFloat} = default_ranges(scen), + depths::AbstractVector{<:AbstractFloat} = default_depths(scen) + ) + starter = FieldStarter(config.field_starter, scen) + ψ = [starter.(depths)] + + k₀ = 2π * scen.f / scen.slc.ocn.cel(0, scen.z) + p = [ + [ + ψel/√(x) * cis(k₀*x - π/4) + for ψel in ψcol + ] for ψcol in ψ, x in ranges + ] + PL = @. -20log10(p |> abs) + new(ranges, depths, p, PL) + end +end \ No newline at end of file diff --git a/src/acoustics/propagation/parabolic/starter.jl b/src/acoustics/propagation/parabolic/starter.jl new file mode 100644 index 0000000..1927604 --- /dev/null +++ b/src/acoustics/propagation/parabolic/starter.jl @@ -0,0 +1,37 @@ +export field_starter +export FieldStarter + +function field_starter(::Val{:gaussian}, k₀::Real, z₀::Real, z::Real) + return √(k₀) * exp( + (-k₀ * (z - z₀))^2 / 2 + ) +end + +function field_starter(::Val{:green}, k₀::Real, z₀::Real, z::Real) + k₀² = k₀^2 + return √(k₀) * ( + 1.4467 - 0.4201k₀² * (z - z₀)^2 + ) * exp( + -k₀² * (z - z₀) / 3.0512 + ) +end + +@parse_models_w_args field_starter + +struct FieldStarter <: Univariate + model::Val + k₀::Real + z₀::Real + + function FieldStarter(model::Val, scen::Scenario) + k₀ = 2π * scen.f / scen.slc.ocn.cel(0, scen.z) + + new(model, k₀, scen.z) + end +end + +function (starter::FieldStarter)(z::Real) + field_starter(starter.model, starter.k₀, starter.z₀, z) +end + +@parse_models_w_args FieldStarter \ No newline at end of file diff --git a/src/acoustics/propagation/root.jl b/src/acoustics/propagation/root.jl new file mode 100644 index 0000000..448f78a --- /dev/null +++ b/src/acoustics/propagation/root.jl @@ -0,0 +1,38 @@ +export Propagation +export PropagationConfig +export default_ranges +export default_depths +export propagationplot! +export propagationplot + +""" +TODO. +""" +abstract type PropagationConfig <: Config end + +@parse_models_w_args_kwargs PropagationConfig + +""" +TODO. +""" +abstract type Propagation <: Result end + +@parse_models_w_args_kwargs Propagation + +const DEFAULT_NUM_RANGES = 251 +const DEFAULT_NUM_DEPTHS = 201 + +default_ranges(scen, N = DEFAULT_NUM_RANGES) = range(0, scen.x, N) +default_depths(scen, N = DEFAULT_NUM_DEPTHS) = range(depth_extrema(scen)..., N) + +include("trace/root.jl") +include("parabolic/root.jl") + +PropagationConfig(::Val{:trace}; kwargs...) = TraceConfig(; kwargs...) +PropagationConfig(::Val{:parabolic}; kwargs...) = ParabolicConfig(; kwargs...) + +Propagation(::Val{:trace}, args...; kwargs...) = Trace(args...; kwargs...) +Propagation(::Val{:parabolic}, args...; kwargs...) = Parabolic(args...; kwargs...) + +function propagationplot! end +function propagationplot end \ No newline at end of file diff --git a/src/acoustics/propagation/trace/beam.jl b/src/acoustics/propagation/trace/beam.jl new file mode 100644 index 0000000..5eaeb9b --- /dev/null +++ b/src/acoustics/propagation/trace/beam.jl @@ -0,0 +1,305 @@ +export Beam +export Beams + +""" +TODO. +""" +struct Beam <: Result + s_max::Float64 + s_srf::Vector{Float64} + s_bot::Vector{Float64} + s_hrz::Vector{Float64} + + x::Function + z::Function + ξ::Function + ζ::Function + p::Function + θ::Function + c::Function +end + +(beam::Beam)(s::Real, n::Real = 0.0) = beam.p(s, n) + +@parse_models_w_args_kwargs Beam + +function Beam(model::Val, scen::Scenario; angle) + beams = Beams(model, scen; angles = [angle]) + return beams[1] +end + +list_model_symbols(::Type{Beam}) = list_model_symbols(Beams) + +show(io::IO, beam::Beam) = show(io, "$(beam |> typeof)(θ₀ = $(beam.θ(0.0)))") + +function Beams( + ::Val{:ray}, + scen::Scenario; + angles = default_angles(scen) +) + c_func(x::Real, z::Real) = scen.slc.ocn.cel(x, z) + ∂c_∂x_func(x::Real, z::Real) = derivative(x -> c_func(x, z), x) + ∂c_∂z_func(x::Real, z::Real) = derivative(z -> c_func(x, z), z) + + function trace!(du, u, _, s) + x, z, ξ, ζ = u + + c = c_func(x, z) + c² = c^2 + ∂c_∂x = ∂c_∂x_func(x, z) + ∂c_∂z = ∂c_∂z_func(x, z) + + du[1] = dx_ds = c * ξ + du[2] = dz_ds = c * ζ + du[3] = dξ_ds = -∂c_∂x / c² + du[4] = dζ_ds = -∂c_∂z / c² + end + + x₀::Float64 = 0.0 + z₀::Float64 = scen.z + c₀::Float64 = c_func(x₀, z₀) + + R_func(::Altimetry, x, z, θ) = SurfaceReflectionCoefficient(:rayleigh_fluid, scen.slc)(x, z, scen.f, θ |> abs) + R_func(::Bathymetry, x, z, θ) = BottomReflectionCoefficient(:rayleigh_solid, scen.slc)(x, z, scen.f, θ |> abs) + + beams = Beam[] + u₀ = [x₀, z₀, NaN64, NaN64] + u = fill(NaN64, length(u₀)) + + for θ₀ in angles + u₀[3] = ξ₀ = cos(θ₀) / c₀ + u₀[4] = ζ₀ = sin(θ₀) / c₀ + + s_srf = Float64[] + s_bot = Float64[] + s_hrz = Float64[] + R_rfl = ComplexF64[] + + record_reflection!(::Altimetry, s) = push!(s_srf, s) + record_reflection!(::Bathymetry, s) = push!(s_bot, s) + + function reflect!(ntg, bnd::Boundary) + x, z, ξ, ζ = ntg.u[1:4] + c = c_func(x, z) + θ = atan(ζ, ξ) + + θ_bnd_deg = derivative(bnd, x) |> atand + θ_inc_deg = atand(ζ, ξ) + θ_rfl_deg = reflection_angle_degrees(θ_bnd_deg, θ_inc_deg) + + record_reflection!(bnd, ntg.t) + push!(R_rfl, R_func(bnd, x, z, θ)) + + ntg.u[3] = cosd(θ_rfl_deg) / c + ntg.u[4] = sind(θ_rfl_deg) / c + + nothing + end + + cb_rng = ContinuousCallback( + (u, _, _) -> u[1] - scen.x, + terminate! + ) + + cb_ati = ContinuousCallback( + (u, _, _) -> u[2] - scen.slc.ati(u[1]), + ntg -> reflect!(ntg, scen.slc.ati) + ) + + cb_bty = ContinuousCallback( + (u, _, _) -> u[2] - scen.slc.bty(u[1]), + ntg -> reflect!(ntg, scen.slc.bty) + ) + + # cb_hrz = ContinuousCallback( + # (u, _, _) -> u[4], + # ntg -> push!(s_hrz, ntg.t) + # ) # "Larger maxiters is needed" message from OrdinaryDiffEq.jl + + # cb = CallbackSet(cb_rng, cb_ati, cb_bty, cb_hrz) + cb = CallbackSet(cb_rng, cb_ati, cb_bty) + + prob = ODEProblem(trace!, u₀, DEFAULT_RAY_ARC_SPAN) + sol = solve(prob, Tsit5(), callback = cb, + reltol = 1e-50 + ) + + s_max = sol.t[end] + + x(s) = sol(s, idxs = 1) + z(s) = sol(s, idxs = 2) + ξ(s) = sol(s, idxs = 3) + ζ(s) = sol(s, idxs = 4) + θ(s) = atan(ζ(s), ξ(s)) + c(s) = scen.slc.ocn.cel(x(s), z(s)) + + @assert θ(0.0) ≈ θ₀ + + pressure(s::Real, n::Real) = ComplexF64(0.0) + + beam = Beam(s_max, s_srf, s_bot, s_hrz, x, z, ξ, ζ, pressure, θ, c) + + push!(beams, beam) + end + + return beams +end + +function Beams( + ::Val{:gaussian}, + scen::Scenario; + angles = default_angles(scen) +) + δθ₀ = length(angles) == 1 ? 1.0 : angles |> diff |> mean + + ω = 2π * scen.f + + c_func(x::Real, z::Real) = scen.slc.ocn.cel(x, z) + ∂c_∂x_func(x::Real, z::Real) = derivative(x -> c_func(x, z), x) + ∂c_∂z_func(x::Real, z::Real) = derivative(z -> c_func(x, z), z) + ∂²c_∂x²_func(x::Real, z::Real) = derivative(x -> ∂c_∂x_func(x, z), x) + ∂²c_∂z²_func(x::Real, z::Real) = derivative(z -> ∂c_∂z_func(x, z), z) + ∂²c_∂x∂z_func(x::Real, z::Real) = derivative(z -> ∂c_∂x_func(x, z), z) + ∂²c_∂n²_func(x::Real, z::Real, ξ::Real, ζ::Real) = c_func(x, z)^2 * ( + ∂²c_∂x²_func(x, z) * ζ^2 + - 2∂²c_∂x∂z_func(x, z) * ξ * ζ + + ∂²c_∂z²_func(x, z) * ξ^2 + ) + + function trace!(du, u, _, s) + x, z, ξ, ζ, pRe, pIm, qRe, qIm, τ = u + + c = c_func(x, z) + c² = c^2 + ∂c_∂x = ∂c_∂x_func(x, z) + ∂c_∂z = ∂c_∂z_func(x, z) + ∂²c_∂n² = ∂²c_∂n²_func(x, z, ξ, ζ) + + du[1] = dx_ds = c * ξ + du[2] = dz_ds = c * ζ + du[3] = dξ_ds = -∂c_∂x / c² + du[4] = dζ_ds = -∂c_∂z / c² + du[5] = dpRe_ds = -∂²c_∂n² * qRe / c² + du[6] = dpIm_ds = -∂²c_∂n² * qIm / c² + du[7] = dqRe_ds = c * pRe + du[8] = dqIm_ds = c * pIm + du[9] = dτ_ds = 1 / c + end + + x₀::Float64 = 0.0 + z₀::Float64 = scen.z + c₀::Float64 = c_func(x₀, z₀) + λ₀::Float64 = c₀ / scen.f + W₀::Float64 = 30λ₀ + p₀::ComplexF64 = 1.0 + 0.0im + q₀::ComplexF64 = 0.0 + im * pi * scen.f * W₀^2 + τ₀::Float64 = 0.0 + + R_func(::Altimetry, x, z, θ) = SurfaceReflectionCoefficient(:rayleigh_fluid, scen.slc)(x, z, scen.f, θ |> abs) + R_func(::Bathymetry, x, z, θ) = BottomReflectionCoefficient(:rayleigh_solid, scen.slc)(x, z, scen.f, θ |> abs) + + beams = Beam[] + u₀ = [x₀, z₀, NaN64, NaN64, reim(p₀)..., reim(q₀)..., τ₀] + u = fill(NaN64, length(u₀)) + + for θ₀ in angles + u₀[3] = ξ₀ = cos(θ₀) / c₀ + u₀[4] = ζ₀ = sin(θ₀) / c₀ + + s_srf = Float64[] + s_bot = Float64[] + s_hrz = Float64[] + R_rfl = ComplexF64[] + + record_reflection!(::Altimetry, s) = push!(s_srf, s) + record_reflection!(::Bathymetry, s) = push!(s_bot, s) + + function reflect!(ntg, bnd::Boundary) + x, z, ξ, ζ = ntg.u[1:4] + c = c_func(x, z) + θ = atan(ζ, ξ) + + θ_bnd_deg = derivative(bnd, x) |> atand + θ_inc_deg = atand(ζ, ξ) + θ_rfl_deg = reflection_angle_degrees(θ_bnd_deg, θ_inc_deg) + + record_reflection!(bnd, ntg.t) + push!(R_rfl, R_func(bnd, x, z, θ)) + + ntg.u[3] = cosd(θ_rfl_deg) / c + ntg.u[4] = sind(θ_rfl_deg) / c + + nothing + end + + cb_rng = ContinuousCallback( + (u_sol, _, _) -> u_sol[1] - scen.x, + terminate! + ) + + cb_ati = ContinuousCallback( + (u_sol, _, _) -> u_sol[2] - scen.slc.ati(u_sol[1]), + ntg -> reflect!(ntg, scen.slc.ati) + ) + + cb_bty = ContinuousCallback( + (u_sol, _, _) -> u_sol[2] - scen.slc.bty(u_sol[1]), + ntg -> reflect!(ntg, scen.slc.bty) + ) + + # cb_hrz = ContinuousCallback( + # (u_sol, _, _) -> u_sol[4], + # ntg -> push!(s_hrz, ntg.t) + # ) # "Larger maxiters is needed" message from OrdinaryDiffEq.jl + + # cb = CallbackSet(cb_rng, cb_ati, cb_bty, cb_hrz) + cb = CallbackSet(cb_rng, cb_ati, cb_bty) + + prob = ODEProblem(trace!, u₀, DEFAULT_RAY_ARC_SPAN) + sol = solve(prob, Tsit5(), callback = cb, + reltol = 1e-100 + ) + + s_max = sol.t[end] + + x(s) = sol(s, idxs = 1) + z(s) = sol(s, idxs = 2) + ξ(s) = sol(s, idxs = 3) + ζ(s) = sol(s, idxs = 4) + θ(s) = atan(ζ(s), ξ(s)) + c(s) = scen.slc.ocn.cel(x(s), z(s)) + + s_rfl = [s_srf; s_bot] |> uniquesort! + cumul_refl_coeff(s) = prod(@views R_rfl[s .≤ s_rfl]) + function pressure(s::Real, n::Real) + !(0 ≤ s ≤ s_max) && return ComplexF64(0.0) + + sol(u, s) + + xVal = u[1] + + xVal < 0 && return ComplexF64(0.0) + + zVal = u[2] + pVal = complex(u[5], u[6]) + qVal = complex(u[7], u[8]) + τVal = u[9] + + sqrt_arg = c_func(xVal, zVal) / (xVal * qVal) + exp_arg = -im * ω * (τVal + pVal / 2qVal * n^2) + A = δθ₀ / c₀ * sqrt( + q₀ * scen.f * cos(θ₀) + ) * exp(im * π / 4) + R = cumul_refl_coeff(s) + return R * A * sqrt(sqrt_arg) * exp(exp_arg) ::ComplexF64 + end + + beam = Beam(s_max, s_srf, s_bot, s_hrz, x, z, ξ, ζ, pressure, θ, c) + + push!(beams, beam) + end + + return beams +end + +@parse_models_w_args_kwargs Beams diff --git a/src/acoustics/propagation/trace/gridder.jl b/src/acoustics/propagation/trace/gridder.jl new file mode 100644 index 0000000..b25b4b3 --- /dev/null +++ b/src/acoustics/propagation/trace/gridder.jl @@ -0,0 +1,108 @@ +export trace_gridder! +export trace_gridder + +function trace_gridder!(model::Val, + p::AbstractMatrix{<:Complex}, + beams::Vector{Beam}, + scen::Scenario; + ranges::AbstractVector{<:Real} = default_ranges(scen), + depths::AbstractVector{<:Real} = default_depths(scen) +) + trace_gridder!(model, p, beams; + ranges = ranges, + depths = depths + ) +end + +@parse_models_w_args_kwargs trace_gridder! + +function trace_gridder(model::Val, + beams::Vector{Beam}; + ranges::AbstractVector{<:Real}, + depths::AbstractVector{<:Real} +) + Nx = length(ranges) + Nz = length(depths) + p = fill(ComplexF64(0.0), (Nx, Nz)) + + trace_gridder!(model, p, beams; + ranges = ranges, + depths = depths + ) +end + +function trace_gridder(model::Val, + beams::Vector{Beam}, + scen::Scenario; + ranges::AbstractVector{<:Real} = default_ranges(scen), + depths::AbstractVector{<:Real} = default_depths(scen) +) + trace_gridder(model, beams; + ranges = ranges, + depths = depths + ) +end + +@parse_models_w_args_kwargs trace_gridder + +## Models + +function trace_gridder!(::Val{:segments}, + p::AbstractMatrix{<:Complex}, + beams::AbstractVector{<:Beam}; + ranges::AbstractVector{<:Real}, + depths::AbstractVector{<:Real}, +) + Nx = length(ranges) + + Xrcv = fill(NaN, 2) + Xray = fill(NaN, 2) + Tray = fill(NaN, 2) + Nray = fill(NaN, 2) + dX = fill(NaN, 2) + + for beam in beams + s = [ + range(0.0, beam.s_max, max(101, Nx ÷ 3)); + beam.s_srf; + beam.s_bot; + beam.s_hrz + ] |> uniquesort! + # s = range(0.0, beam.s_max, max(101, Nx ÷ 3)) + + for i = eachindex(s)[begin+1 : end] + sᵢ₋₁ = s[i-1] + sᵢ = s[i] + xᵢ₋₁ = beam.x(sᵢ₋₁) + xᵢ = beam.x(sᵢ) + zᵢ = beam.z(sᵢ) + ξᵢ₋₁ = beam.ξ(sᵢ₋₁) + ζᵢ₋₁ = beam.ζ(sᵢ₋₁) + cᵢ₋₁ = beam.c(sᵢ₋₁) + + for nx in findall(xᵢ₋₁ .≤ ranges .< xᵢ) + x_grid = ranges[nx] + @views for (nz, z_grid) in enumerate(depths) + Xrcv[1] = x_grid + Xrcv[2] = z_grid + Xray[1] = xᵢ + Xray[2] = zᵢ + Tray[1] = cᵢ₋₁ * ξᵢ₋₁ + Tray[2] = cᵢ₋₁ * ζᵢ₋₁ + Nray[1] = cᵢ₋₁ * -ζᵢ₋₁ + Nray[2] = cᵢ₋₁ * ξᵢ₋₁ + dX[1] = Xrcv[1] - Xray[1] + dX[2] = Xrcv[2] - Xray[2] + arc = sᵢ₋₁ + dot(dX, Tray) + nrm = dot(dX, Nray) |> abs + p̂ = beam(arc, nrm) + if !isnan(p̂) && !isinf(p̂) + p[nx, nz] = p[nx, nz] + p̂ + end + end + end + end + end + + return p +end \ No newline at end of file diff --git a/src/acoustics/propagation/trace/ray.jl b/src/acoustics/propagation/trace/ray.jl new file mode 100644 index 0000000..55fbcf2 --- /dev/null +++ b/src/acoustics/propagation/trace/ray.jl @@ -0,0 +1,76 @@ +export default_angles +export steepest_angle +export minimum_angle +export maximum_angle +export critical_angle +export critical_angles +export rayplot! +export rayplot + +const DEFAULT_RAY_ARC_SPAN = (0.0, 1e6) + +function shallowest_angle(scen::Scenario) + dz = scen |> depth_extrema |> reverse |> splat(-) + atan(dz, 200scen.x) +end + +function steepest_angle(scen) + dz = scen |> depth_extrema |> reverse |> splat(-) + atan(200dz, scen.x) |> abs +end + +const DEFAULT_NUM_RAYS = 101 + +tangent_angle(bnd::Boundary) = derivative(x -> bnd(x), 0) |> atan + +function minimum_angle(scen::Scenario) + if scen.z == scen.slc.ati(0) + tangent_angle(scen.slc.ati) + shallowest_angle(scen) + else + -steepest_angle(scen) + end +end + +function maximum_angle(scen::Scenario) + if scen.z == scen.slc.bty(0) + tangent_angle(scen.slc.bty) - shallowest_angle(scen) + else + steepest_angle(scen) + end +end + +function default_angles( + scen::Scenario; + θ_min::Real = minimum_angle(scen), + θ_max::Real = maximum_angle(scen), + N::Integer = DEFAULT_NUM_RAYS +) + return range(θ_min, θ_max, N) +end + +critical_angle(c_from, c_to) = snells_law(c_to, 0.0, c_from) + +function critical_angles(scen::Scenario; N::Integer = DEFAULT_NUM_RAYS) + z_srf = scen.slc.ati(0) + z_bot = scen.slc.bty(0) + c_srf = scen.slc.ocn.cel(0.0, z_srf) + c_bot = scen.slc.ocn.cel(0.0, z_bot) + c_own = scen.slc.ocn.cel(0.0, scen.z) + + θ_min = if scen.z == z_srf || c_own ≥ c_srf + minimum_angle(scen) + else + -critical_angle(c_own, c_srf) + end + + θ_max = if scen.z == z_bot || c_own ≥ c_bot + maximum_angle(scen) + else + critical_angle(c_own, c_bot) + end + + return range(θ_min, θ_max, N) +end + +function rayplot! end +function rayplot end \ No newline at end of file diff --git a/src/acoustics/propagation/trace/root.jl b/src/acoustics/propagation/trace/root.jl new file mode 100644 index 0000000..6dd5b78 --- /dev/null +++ b/src/acoustics/propagation/trace/root.jl @@ -0,0 +1,58 @@ +export Trace +export TraceConfig + +include("ray.jl") +include("beam.jl") +include("gridder.jl") + +""" +TODO. +""" +@kwdef mutable struct TraceConfig <: PropagationConfig + beam = list_models(Beam)[1] + gridder = list_models(trace_gridder!)[1] +end + +struct Trace <: Propagation + scen::Scenario + config::TraceConfig + beams::Vector{<:Beam} + x::Vector{<:Float64} + z::Vector{<:Float64} + p::Array{<:ComplexF64, 2} + PL::Array{<:Float64, 2} + + function Trace( + scen::Scenario, + beams::Vector{Beam}, + config::TraceConfig = TraceConfig(); + ranges::AbstractVector{<:Real} = default_ranges(scen), + depths::AbstractVector{<:Real} = default_depths(scen), + ) + validate(scen) + + p = trace_gridder(config.gridder, beams; + ranges = ranges, + depths = depths + ) + + PL = @. -20log10(4π * p |> abs) + PL = max.(PL, 0.0) + PL = min.(PL, 100.0) + + new(scen, config, beams, ranges |> collect, depths |> collect, p, PL) + end +end + +function Trace(scen::Scenario, config::TraceConfig = TraceConfig(); + ranges::AbstractVector{<:Real} = default_ranges(scen), + depths::AbstractVector{<:Real} = default_depths(scen), + angles::AbstractVector{<:Real} = default_angles(scen) +) + validate(scen) + beams = Beams(config.beam, scen; angles = angles) + Trace(scen, beams, config; + ranges = ranges, + depths = depths + ) +end \ No newline at end of file diff --git a/src/acoustics/reflection/bottom.jl b/src/acoustics/reflection/bottom.jl new file mode 100644 index 0000000..1359401 --- /dev/null +++ b/src/acoustics/reflection/bottom.jl @@ -0,0 +1,25 @@ +# struct BottomReflectionCoefficient <: ReflectionCoefficient +# model::Val +# end + +function BottomReflectionCoefficient(::Val{:rayleigh_solid}, slc::Slice) + function func(x::Real, z::Real, f::Real, θ_inc::Real) + reflection_coefficient(:rayleigh_solid, + slc.ocn.den(x, z), + slc.sbd.den(x, 0), + slc.ocn.cel(x, z), + slc.sbd.cel(x, 0), + slc.sbd.shear_cel(x, 0), + slc.ocn.atn(x, z, f), + slc.sbd.atn(x, 0, f), + slc.sbd.shear_atn(x, 0, f), + θ_inc + ) + end +end + +@parse_models_w_args BottomReflectionCoefficient + +# function list_models(::Type{BottomReflectionCoefficient}) +# list_models(reflection_coefficient) +# end \ No newline at end of file diff --git a/src/acoustics/reflection/root.jl b/src/acoustics/reflection/root.jl new file mode 100644 index 0000000..9241690 --- /dev/null +++ b/src/acoustics/reflection/root.jl @@ -0,0 +1,66 @@ +export reflection_coefficient + +reflection_angle_degrees( + θ_bnd_deg::Real, θ_inc_deg::Real +) = mod(2θ_bnd_deg - θ_inc_deg + 180, 360) - 180 + +specific_impedance(ρ::Real, c::Number) = ρ * c + +snells_law(c_inc::Number, θ_inc::Number, c_rfr::Number) = c_rfr / c_inc * cos(θ_inc) |> acos + +function reflection_coefficient end + +@parse_models_w_args reflection_coefficient + +function reflection_coefficient(::Val{:rayleigh_fluid}, + ρ_inc::Real, ρ_rfr::Real, + c_inc::Number, c_rfr::Number, + α_inc::Number, α_rfr::Number, + θ_inc::Number +) + ς_inc = complex_celerity(c_inc, α_inc) + ς_rfr = complex_celerity(c_rfr, α_rfr) + + θ_rfr = snells_law(ς_inc, θ_inc, ς_rfr) + + 𝓏_inc = specific_impedance(ρ_inc, ς_inc) + 𝓏_rfr = specific_impedance(ρ_rfr, ς_rfr) + + _rfr = 𝓏_rfr * sin(θ_inc) + _inc = 𝓏_inc * sin(θ_rfr) + + return (_rfr - _inc) / (_rfr + _inc) +end + +function reflection_coefficient(::Val{:rayleigh_solid}, + ρ_inc::Real, ρ_rfr::Real, + c_inc::Number, c_compr_rfr::Number, c_shear_rfr::Number, + α_inc::Number, α_compr_rfr::Number, α_shear_rfr::Number, + θ_inc::Number +) + ς_inc = complex_celerity(c_inc, α_inc) + ς_compr_rfr = complex_celerity(c_compr_rfr, α_compr_rfr) + ς_shear_rfr = complex_celerity(c_shear_rfr, α_shear_rfr) + + θ_compr_rfr = snells_law(ς_inc, θ_inc, ς_compr_rfr) + θ_shear_rfr = snells_law(ς_inc, θ_inc, ς_shear_rfr) + + 𝓏_inc = specific_impedance(ρ_inc, ς_inc) + 𝓏_compr_rfr = specific_impedance(ρ_rfr, ς_compr_rfr) + 𝓏_shear_rfr = specific_impedance(ρ_rfr, ς_shear_rfr) + + sin_shear_rfr = sin(θ_shear_rfr) + sin_compr_rfr = sin(θ_compr_rfr) + + _inc = 𝓏_inc * sin_compr_rfr * sin_shear_rfr + _compr_rfr = 𝓏_compr_rfr * sin_shear_rfr * cos(2θ_shear_rfr)^2 + _shear_rfr = 𝓏_shear_rfr * sin_compr_rfr * sin(2θ_shear_rfr)^2 + _rfr = sin(θ_inc) * (_compr_rfr + _shear_rfr) + + return (_rfr - _inc) / (_rfr + _inc) +end + +abstract type ReflectionCoefficient <: Functor end + +include("surface.jl") +include("bottom.jl") \ No newline at end of file diff --git a/src/acoustics/reflection/surface.jl b/src/acoustics/reflection/surface.jl new file mode 100644 index 0000000..6892c2b --- /dev/null +++ b/src/acoustics/reflection/surface.jl @@ -0,0 +1,19 @@ +function SurfaceReflectionCoefficient(::Val{:rayleigh_fluid}, slc::Slice) + function func(x::Real, z::Real, f::Real, θ_inc::Real) + reflection_coefficient(:rayleigh_fluid, + slc.ocn.den(x, z), + slc.atm.den(x, z), + slc.ocn.cel(x, z), + slc.atm.cel(x, z), + slc.ocn.atn(x, z, f), + slc.atm.atn(x, z, f), + θ_inc + ) + end +end + +@parse_models_w_args SurfaceReflectionCoefficient + +# function list_models(::Type{SurfaceReflectionCoefficient}) +# list_models(reflection_coefficient) +# end \ No newline at end of file diff --git a/src/acoustics/root.jl b/src/acoustics/root.jl new file mode 100644 index 0000000..8a2686b --- /dev/null +++ b/src/acoustics/root.jl @@ -0,0 +1,4 @@ +include("scenario.jl") + +include("reflection/root.jl") +include("propagation/root.jl") \ No newline at end of file diff --git a/src/acoustics/scenario.jl b/src/acoustics/scenario.jl new file mode 100644 index 0000000..d471c29 --- /dev/null +++ b/src/acoustics/scenario.jl @@ -0,0 +1,116 @@ +export Scenario +export depth_extrema + +""" +TODO. +""" +@kwdef mutable struct Scenario <: Container + model::Val + + slc::Slice + + x::Float64 + z::Float64 + f::Float64 +end + +Scenario(model::Val{:lloyd_mirror}) = Scenario( + model = model, + slc = Slice(:lloyd_mirror), + x = 500.0, + z = 25.0, + f = 150.0 +) + +Scenario(model::Val{:munk_profile}) = Scenario( + model = model, + slc = Slice(:munk_profile), + x = 100e3, + z = 1e3, + f = 500.0 +) + +Scenario(model::Val{:index_squared_profile}) = Scenario( + model = model, + slc = Slice(:index_squared_profile), + x = 3.5e3, + z = 1e3, + f = 100.0 +) + +Scenario(model::Val{:parabolic_bathymetry}) = Scenario( + model = model, + slc = Slice(:parabolic_bathymetry), + x = 20e3, + z = 0.0, + f = 1e2 +) + +Scenario(model::Val{:linearised_convergence_zones}) = Scenario( + model = model, + slc = Slice(:linearised_convergence_zones), + x = 250e3, + z = 0.0, + f = 1e3 +) + +Scenario(model::Val{:norwegian_sea_sound_channel}) = Scenario( + model = model, + slc = Slice(:norwegian_sea), + x = 250e3, + z = 500.0, + f = 1e3 +) + +Scenario(model::Val{:norwegian_sea_surface_duct}) = Scenario( + model = model, + slc = Slice(:norwegian_sea), + x = 40e3, + z = 40.0, + f = 1e3 +) + +@parse_models Scenario + +function depth_extrema(bnd::Boundary, x_lo::Real, x_hi::Real) + x_lo + x_hi + z_rng = bnd(x_lo .. x_hi) + return if z_rng isa Interval + ( + z_rng.bareinterval.lo, + z_rng.bareinterval.hi + ) + else + (z_rng, z_rng) + end +end + +depth_extrema( + ati::Altimetry, + bty::Bathymetry, + x_lo::Real, + x_hi::Real +) = ( + depth_extrema(ati, x_lo, x_hi)[1], + depth_extrema(bty, x_lo, x_hi)[2] +) + +depth_extrema( + slc::Slice, + x_lo::Real, + x_hi::Real +) = depth_extrema(slc.ati, slc.bty, x_lo, x_hi) + +depth_extrema( + scen::Scenario, + x_lo::Real = 0.0, + x_hi::Real = scen.x +) = depth_extrema(scen.slc, x_lo, x_hi) + +depth_minimum(args...) = depth_extrema(args...) |> splat(min) +depth_maximum(args...) = depth_extrema(args...) |> splat(max) + +function validate(scen::Scenario) + @assert scen.slc.ati(0) ≤ scen.z ≤ scen.slc.bty(0) +end \ No newline at end of file diff --git a/src/macro/performance.jl b/src/macro/performance.jl new file mode 100644 index 0000000..3538602 --- /dev/null +++ b/src/macro/performance.jl @@ -0,0 +1,120 @@ +struct Ownship + z +end + +struct Target + SL + NL +end + +struct Processing + f + B + t +end + +struct Environment + NL +end + +struct Reverberation + RL +end + +struct Performance + SNR + DT + SE + POD + + function Performance( + sonar_type::Type{<:SonarType}, + scen::Scenario, + own::Ownship, + proc::Processing, + env::Environment, + tgt::Target, + r::AbstractFloat, + z::AbstractFloat + ) + + SL = if sonar_type <: Exposure + tgt.NL + elseif any(sonar_type .<: (Intercept, Active)) + tgt.SL + end + + PL = propagation_loss(scen) + + NL = own.NL ⊕ env.NL + + RL = if sonar_type <: Passive + -Inf + elseif sonar_type <: Active + reverberation_level(sonar_type, scen) + end + + BIL = NL ⊕ RL + + SNR = if sonar_type <: Passive + signal_to_noise_ratio(sonar_type, SL, prop.PL, NL, own.DI) + elseif sonar_type <: Monostatic + signal_to_noise_ratio(sonar_type, SL, prop.PL, NL, rvb.RL, own.DI) + elseif sonar_type <: Bistatic + prop_b = Propagation(prop.model, prop.scen, prop.config) + signal_to_noise_ratio(sonar_type, SL, prop.PL, prob_b) + end + + new(SL, BIL, SNR, DT, SE, POD) + end +end + +function performance(sonar_type::Type{<:Exposure}, + + ) + +end + +function performance(sonar_type::Type{<:Intercept}, + + ) + +end + +function performance(sonar_type::Type{<:Monostatic}, + slc::Slice, + txr::Entity, + rxr::Entity, + tgt::Entity, + + ) + +end + +function performance(sonar_type::Type{<:Bistatic}, + slc::Slice, + txr::Entity, + rxr::Entity, + tgt::Entity, + env::Environment, + proc::Processing, + ranges::AbstractVector{<:AbstractFloat}, + depths::AbstractVector{<:AbstractFloat} + ) + scen_txr = Scenario(slc = slc, x = txr.x, z = txr.z, f = proc.f) + scen_rxr = Scenario(slc = slc, x = rxr.x, z = rxr.z, f = proc.f) + + prop_txr = Propagation(scen_txr, ranges, depths) + prop_rxr = Propagation(scen_rxr, ranges, depths) + + SL = txr.SL + PLa = prop_txr.PL + PLb = prop_rxr.PL + TS = tgt.TS + NL = rxr.NL ⊕ env.NL + RL = reverberation_level(sonar_type, prop_txr, prop_rxr) + SNR = signal_to_noise_ratio(sonar_type, SL, PLa, PLb, TS, NL, RL, DI) + DT = detection_threshold(sonar_type, d, proc.B, proc.t) + SE = SNR - DT + tPd = transition_detection_probability(sonar_type, SE, Pf) +end \ No newline at end of file diff --git a/src/oceanography/attenuation/atmosphere.jl b/src/oceanography/attenuation/atmosphere.jl new file mode 100644 index 0000000..e59f1a1 --- /dev/null +++ b/src/oceanography/attenuation/atmosphere.jl @@ -0,0 +1,28 @@ +export atmosphere_attenuation +export AtmosphereAttenuation + +""" +TODO. +""" +function atmosphere_attenuation end + +atmosphere_attenuation(::Val{:standard}, x::Real, z::Real, f::Real) = 0.0 + +@parse_models_w_args atmosphere_attenuation + +""" +TODO. +""" +struct AtmosphereAttenuation <: Attenuation + model::Val +end + +function (atn::AtmosphereAttenuation)(x::Real, z::Real, f::Real) + atmosphere_attenuation(atn.model, x, z, f) +end + +@parse_models AtmosphereAttenuation + +AtmosphereAttenuation() = AtmosphereAttenuation(:standard) + +list_model_symbols(::Type{AtmosphereAttenuation}) = list_model_symbols(atmosphere_attenuation) \ No newline at end of file diff --git a/src/oceanography/attenuation/ocean.jl b/src/oceanography/attenuation/ocean.jl new file mode 100644 index 0000000..1083425 --- /dev/null +++ b/src/oceanography/attenuation/ocean.jl @@ -0,0 +1,36 @@ +export ocean_attenuation +export OceanAttenuation + +""" +TODO. +""" +function ocean_attenuation end + +""" +dB/m + +Equation 1.47 of Jensen, et al (2011). +""" +function ocean_attenuation(::Val{:jensen}, x::Real, z::Real, f::Real) + f² = f^2 + 3.3 + 110f² / (1 + f²) + 44000f² / (4100 + f²) + 0.3f² +end + +@parse_models_w_args ocean_attenuation + +""" +TODO. +""" +struct OceanAttenuation <: Attenuation + model::Val +end + +function (atn::OceanAttenuation)(x::Real, z::Real, f::Real) + ocean_attenuation(atn.model, x, z, f) +end + +@parse_models OceanAttenuation + +OceanAttenuation() = OceanAttenuation(:jensen) + +list_model_symbols(::Type{OceanAttenuation}) = list_model_symbols(ocean_attenuation) \ No newline at end of file diff --git a/src/oceanography/attenuation/root.jl b/src/oceanography/attenuation/root.jl new file mode 100644 index 0000000..d448a3b --- /dev/null +++ b/src/oceanography/attenuation/root.jl @@ -0,0 +1,11 @@ +export attenuationplot! +export attenuationplot + +abstract type Attenuation <: Trivariate end + +include("atmosphere.jl") +include("ocean.jl") +include("seabed/root.jl") + +function attenuationplot! end +function attenuationplot end \ No newline at end of file diff --git a/src/oceanography/attenuation/seabed/compressional.jl b/src/oceanography/attenuation/seabed/compressional.jl new file mode 100644 index 0000000..643e597 --- /dev/null +++ b/src/oceanography/attenuation/seabed/compressional.jl @@ -0,0 +1,35 @@ +export seabed_attenuation +export SeabedAttenuation + +""" +TODO. +""" +function seabed_attenuation end + +seabed_attenuation(::Val{:jensen_clay}, x::Real, z::Real, f::Real) = 0.2 +seabed_attenuation(::Val{:jensen_silt}, x::Real, z::Real, f::Real) = 1.0 +seabed_attenuation(::Val{:jensen_sand}, x::Real, z::Real, f::Real) = 0.8 +seabed_attenuation(::Val{:jensen_gravel}, x::Real, z::Real, f::Real) = 0.6 +seabed_attenuation(::Val{:jensen_moraine}, x::Real, z::Real, f::Real) = 0.4 +seabed_attenuation(::Val{:jensen_chalk}, x::Real, z::Real, f::Real) = 0.2 +seabed_attenuation(::Val{:jensen_limestone}, x::Real, z::Real, f::Real) = 0.1 +seabed_attenuation(::Val{:jensen_basalt}, x::Real, z::Real, f::Real) = 0.1 + +@parse_models_w_args seabed_attenuation + +""" +TODO. +""" +struct SeabedAttenuation <: Attenuation + model::Val +end + +function (den::SeabedAttenuation)(x::Real, z::Real, f::Real) + seabed_attenuation(den.model, x, z, f) +end + +@parse_models SeabedAttenuation + +SeabedAttenuation() = SeabedAttenuation(Symbol()) + +list_model_symbols(::Type{SeabedAttenuation}) = list_model_symbols(seabed_attenuation) \ No newline at end of file diff --git a/src/oceanography/attenuation/seabed/root.jl b/src/oceanography/attenuation/seabed/root.jl new file mode 100644 index 0000000..cc08993 --- /dev/null +++ b/src/oceanography/attenuation/seabed/root.jl @@ -0,0 +1,2 @@ +include("compressional.jl") +include("shear.jl") \ No newline at end of file diff --git a/src/oceanography/attenuation/seabed/shear.jl b/src/oceanography/attenuation/seabed/shear.jl new file mode 100644 index 0000000..c10af54 --- /dev/null +++ b/src/oceanography/attenuation/seabed/shear.jl @@ -0,0 +1,35 @@ +export shear_seabed_attenuation +export ShearSeabedAttenuation + +""" +TODO. +""" +function shear_seabed_attenuation end + +shear_seabed_attenuation(::Val{:jensen_clay}, x::Real, z::Real, f::Real) = 1.0 +shear_seabed_attenuation(::Val{:jensen_silt}, x::Real, z::Real, f::Real) = 1.5 +shear_seabed_attenuation(::Val{:jensen_sand}, x::Real, z::Real, f::Real) = 2.5 +shear_seabed_attenuation(::Val{:jensen_gravel}, x::Real, z::Real, f::Real) = 1.5 +shear_seabed_attenuation(::Val{:jensen_moraine}, x::Real, z::Real, f::Real) = 1.0 +shear_seabed_attenuation(::Val{:jensen_chalk}, x::Real, z::Real, f::Real) = 0.5 +shear_seabed_attenuation(::Val{:jensen_limestone}, x::Real, z::Real, f::Real) = 0.2 +shear_seabed_attenuation(::Val{:jensen_basalt}, x::Real, z::Real, f::Real) = 0.2 + +@parse_models_w_args shear_seabed_attenuation + +""" +TODO. +""" +struct ShearSeabedAttenuation <: Trivariate + model::Val +end + +function (shear_atn::ShearSeabedAttenuation)(x::Real, z::Real, f::Real) + shear_seabed_attenuation(shear_atn.model, x, z, f) +end + +@parse_models ShearSeabedAttenuation + +ShearSeabedAttenuation() = ShearSeabedAttenuation(Symbol()) + +list_model_symbols(::Type{ShearSeabedAttenuation}) = list_model_symbols(shear_seabed_attenuation) \ No newline at end of file diff --git a/src/oceanography/boundary/altimetry.jl b/src/oceanography/boundary/altimetry.jl new file mode 100644 index 0000000..b53ca52 --- /dev/null +++ b/src/oceanography/boundary/altimetry.jl @@ -0,0 +1,70 @@ +export altimetry +export Altimetry + +@doc """ +``` +z::Float64 = altimetry(model::Val, x::Real) +``` + +* `x` (m) horizontal range +* `model` name of model +* `z` (m) ocean surface height + +Built-in models are: + +$(altimetry |> doc_models) + +Examples: + +```julia +altimetry(:sine, 1e3) +altimetry(:sine, 1e2) +``` +""" +function altimetry end + +altimetry(::Val{:flat}, x::Real) = 0.0 + +sine_default = ( + a = 500.0, + f = 1e-4, + s = 0.0 +) + +ocnson_sin(x::Real) = NaNMath.sin(x) +ocnson_sin(x::Interval) = sin(x) + +function altimetry(::Val{:sine}, + x::Real; + a::Real = sine_default.a, + f::Real = -sine_default.f, + s::Real = sine_default.s +) + a * ocnson_sin(2π * f*(x - s)) +end + +# function altimetry(::Val{:sine}, +# x::Interval; +# a::Real = sine_default.a, +# f::Real = sine_default.f, +# s::Real = sine_default.s +# ) +# a * sin(2π * f*(x - s)) +# end + +@parse_models_w_args_kwargs altimetry + +""" +TODO. +""" +struct Altimetry <: Boundary + model::Val +end + +(ati::Altimetry)(x::Real; kwargs...) = altimetry(ati.model, x; kwargs...) + +@parse_models Altimetry + +Altimetry() = Altimetry(:flat) + +list_model_symbols(::Type{Altimetry}) = list_model_symbols(altimetry) \ No newline at end of file diff --git a/src/oceanography/boundary/bathymetry.jl b/src/oceanography/boundary/bathymetry.jl new file mode 100644 index 0000000..d96f5e2 --- /dev/null +++ b/src/oceanography/boundary/bathymetry.jl @@ -0,0 +1,40 @@ +export bathymetry +export Bathymetry + +@doc """ +TODO. +""" +function bathymetry end + +bathymetry(::Val{:shallow}, x::Real) = 1e2 +bathymetry(::Val{:half_kilometre}, x::Real) = 5e2 +bathymetry(::Val{:mesopelagic}, x::Real) = 1e3 +bathymetry(::Val{:four_kilometers}, x::Real) = 4e3 +bathymetry(::Val{:deep}, x::Real) = 5e3 + +bathymetry(::Val{:parabolic}, + x::Real; + b = 250e3, c = 250.0 +) = 2e-3b * NaNMath.sqrt(1 + x/c) + +bathymetry(::Val{:parabolic}, + x::Interval; + b = 250e3, c = 250.0 +) = 2e-3b * sqrt(1 + x/c) + +@parse_models_w_args_kwargs bathymetry + +""" +TODO. +""" +struct Bathymetry <: Boundary + model::Val +end + +(bty::Bathymetry)(x::Real; kwargs...) = bathymetry(bty.model, x; kwargs...) + +@parse_models Bathymetry + +Bathymetry() = Bathymetry(Symbol()) + +list_model_symbols(::Type{Bathymetry}) = list_model_symbols(bathymetry) \ No newline at end of file diff --git a/src/oceanography/boundary/root.jl b/src/oceanography/boundary/root.jl new file mode 100644 index 0000000..a2f6ce5 --- /dev/null +++ b/src/oceanography/boundary/root.jl @@ -0,0 +1,6 @@ +export Boundary + +abstract type Boundary <: Univariate end + +include("altimetry.jl") +include("bathymetry.jl") \ No newline at end of file diff --git a/src/oceanography/celerity/atmosphere.jl b/src/oceanography/celerity/atmosphere.jl new file mode 100644 index 0000000..dffea8d --- /dev/null +++ b/src/oceanography/celerity/atmosphere.jl @@ -0,0 +1,28 @@ +export atmosphere_celerity +export AtmosphereCelerity + +""" +TODO. +""" +function atmosphere_celerity end + +atmosphere_celerity(::Val{:standard}, x::Real, z::Real) = 343.0 + +@parse_models_w_args atmosphere_celerity + +""" +TODO. +""" +struct AtmosphereCelerity <: Celerity + model::Val +end + +function (cel::AtmosphereCelerity)(x::Real, z::Real) + atmosphere_celerity(cel.model, x, z) +end + +@parse_models AtmosphereCelerity + +AtmosphereCelerity() = AtmosphereCelerity(:standard) + +list_model_symbols(::Type{AtmosphereCelerity}) = list_model_symbols(atmosphere_celerity) \ No newline at end of file diff --git a/src/oceanography/celerity/ocean.jl b/src/oceanography/celerity/ocean.jl new file mode 100644 index 0000000..0a52c61 --- /dev/null +++ b/src/oceanography/celerity/ocean.jl @@ -0,0 +1,156 @@ +export ocean_celerity +export OceanCelerity + +@doc """ +``` +c::Float64 = ocean_celerity(model, x::Real, z::Real; kwargs...) +``` + +Calculation of sound speed in the ocean. + +* `model` name of celerity model +* `x` horizontal range (m) +* `z` depth (m), positive downwards +* `c` celerity (m/s) of sound in the ocean for the specified `model` +* `kwargs...` keyword arguments, see specific `model` documentations. + +Example: + +``` +c = ocean_celerity(:munk, 1e3, 1e2; ϵ = 1e-3) +``` +""" +function ocean_celerity end + +@parse_models_w_args_kwargs ocean_celerity + +""" +``` +c::Float64 = ocean_celerity(::Val{:homogeneous}, x::Real, z::Real) +``` + +Returns a constant sound speed value `c == 1500.0` for all ranges and depths. +""" +ocean_celerity(::Val{:homogeneous}, x::Real, z::Real) = 1500.0 + +""" +``` +c::Float64 = ocean_celerity(:munk, x::Real, z::Real; ϵ = 7.37e-3) +``` + +Calculation of ocean sound speed by Equation 5.83 of Jensen, et al (2011). +This model is range independent and depth dependent. + +* `ϵ` A factor (unitless) for variation with depth, +e.g. `ϵ = 0` gives a homogenous sound speed of 1500 m/s. +""" +function ocean_celerity(::Val{:munk}, x::Real, z::Real; ϵ = 7.37e-3) + z̃ = 2(z/1300 - 1) + return 1500( + 1 + ϵ * ( + z̃ - 1 + exp(-z̃) + ) + ) +end + +""" +``` +c::Float64 = ocean_celerity(:index_squared, x::Real, z::Real; c₀ = 1550.0) +``` + +Calculation of ocean sound speed by Equation 3.77 of Jensen, et al (2011). +This model is range independent and depth dependent. + +* `c₀` Sound speed at `z = 0`. +""" +function ocean_celerity(::Val{:index_squared}, x::Real, z::Real; c₀ = 1550.0) + c₀ / NaNMath.sqrt(1 + 2.4z / c₀) +end + +data_linearised_convergence_zones = ( + z = Float64[0, 300, 1200, 2000, 5000], + c = Float64[1522, 1501, 1514, 1496, 1545] +) + +itp_linearised_convergence_zones = Bivariate( + nothing, + data_linearised_convergence_zones.z, + data_linearised_convergence_zones.c +) + +""" +``` +c::Float64 = ocean_celerity("Linearised Convergence Zones", x::Real, z::Real) +``` + +Calculation of ocean sound speed by table 1.1 of Jensen, et al (2011). +This model is range (`x` [m]) independent and depth (`z` [m]) dependent. +""" +function ocean_celerity(::Val{:linearised_convergence_zones}, + x::Real, z::Real +) + return itp_linearised_convergence_zones(x, z) +end + +data_norwegian_sea = ( + z = [0, 145, 250, 500, 750, 1000, 2000, 4000], + c = [1495, 1500, 1485, 1475, 1477, 1485, 1500, 1525] +) + +itp_norwegian_sea = Bivariate( + nothing, + data_norwegian_sea.z, + data_norwegian_sea.c +) + +""" +Fig 1.12 of Jensen, et al (2011). +""" +function ocean_celerity(::Val{:norwegian_sea}, + x::Real, z::Real +) + return itp_norwegian_sea(x, z) +end + +data_north_atlantic = ( + z = Float64[0, 300, 1200, 2e3, 5e3], + c = Float64[1522.0, 1502, 1514, 1496, 1545] +) + +itp_north_atlantic = Bivariate( + nothing, + data_north_atlantic.z, + data_north_atlantic.c +) + +""" +TODO of Jensen, et al (2011). +""" +function ocean_celerity(::Val{:north_atlantic}, + x::Real, z::Real +) + return itp_north_atlantic(x, z) +end + +""" +``` +OceanCelerity(model::Val) +``` + +Construction of a data container for storing the desired `model`. + +Built-in models are: TODO +""" +struct OceanCelerity <: Celerity + model::Val +end + +function (cel::OceanCelerity)(x::Real, z::Real; kwargs...) + ocean_celerity(cel.model, x, z; kwargs...) +end + +@parse_models OceanCelerity + +OceanCelerity() = OceanCelerity(Symbol()) + +list_model_symbols(::Type{OceanCelerity}) = list_model_symbols(ocean_celerity) \ No newline at end of file diff --git a/src/oceanography/celerity/root.jl b/src/oceanography/celerity/root.jl new file mode 100644 index 0000000..e7c0dbb --- /dev/null +++ b/src/oceanography/celerity/root.jl @@ -0,0 +1,9 @@ +export Celerity + +abstract type Celerity <: Bivariate end + +include("atmosphere.jl") +include("ocean.jl") +include("seabed/root.jl") + +# Discussion point: Should I implement a celerity parser that takes a scenario and returns a function that returns the appropriate medium celerity for the range and depth inputted? I don't know any use cases but it's an interesting idea if it's ever useful. That applies to the other volumetric, multi-media parameters also, like density. \ No newline at end of file diff --git a/src/oceanography/celerity/seabed/compressional.jl b/src/oceanography/celerity/seabed/compressional.jl new file mode 100644 index 0000000..4c1fdbd --- /dev/null +++ b/src/oceanography/celerity/seabed/compressional.jl @@ -0,0 +1,33 @@ +export seabed_celerity +export SeabedCelerity + +""" +TODO. +""" +function seabed_celerity end + +seabed_celerity(::Val{:jensen_clay}, x::Real, z::Real) = 1500.0 +seabed_celerity(::Val{:jensen_silt}, x::Real, z::Real) = 1575.0 +seabed_celerity(::Val{:jensen_sand}, x::Real, z::Real) = 1650.0 +seabed_celerity(::Val{:jensen_gravel}, x::Real, z::Real) = 1800.0 +seabed_celerity(::Val{:jensen_moraine}, x::Real, z::Real) = 1950.0 +seabed_celerity(::Val{:jensen_chalk}, x::Real, z::Real) = 2400.0 +seabed_celerity(::Val{:jensen_limestone}, x::Real, z::Real) = 3000.0 +seabed_celerity(::Val{:jensen_basalt}, x::Real, z::Real) = 5250.0 + +@parse_models_w_args seabed_celerity + +""" +TODO. +""" +struct SeabedCelerity <: Celerity + model::Val +end + +(cel::SeabedCelerity)(x::Real, z::Real) = seabed_celerity(cel.model, x, z) + +@parse_models SeabedCelerity + +SeabedCelerity() = SeabedCelerity(Symbol()) + +list_model_symbols(::Type{SeabedCelerity}) = list_model_symbols(seabed_celerity) \ No newline at end of file diff --git a/src/oceanography/celerity/seabed/root.jl b/src/oceanography/celerity/seabed/root.jl new file mode 100644 index 0000000..cc08993 --- /dev/null +++ b/src/oceanography/celerity/seabed/root.jl @@ -0,0 +1,2 @@ +include("compressional.jl") +include("shear.jl") \ No newline at end of file diff --git a/src/oceanography/celerity/seabed/shear.jl b/src/oceanography/celerity/seabed/shear.jl new file mode 100644 index 0000000..2cff16d --- /dev/null +++ b/src/oceanography/celerity/seabed/shear.jl @@ -0,0 +1,37 @@ +export shear_seabed_celerity +export ShearSeabedCelerity + + + +""" +TODO. +""" +function shear_seabed_celerity end + +shear_seabed_celerity(::Val{:jensen_clay}, x::Real, z::Real) = 50.0 +shear_seabed_celerity(::Val{:jensen_silt}, x::Real, z::Real) = 80∛(z) +shear_seabed_celerity(::Val{:jensen_sand}, x::Real, z::Real) = 110∛(z) +shear_seabed_celerity(::Val{:jensen_gravel}, x::Real, z::Real) = 180∛(z) +shear_seabed_celerity(::Val{:jensen_moraine}, x::Real, z::Real) = 600.0 +shear_seabed_celerity(::Val{:jensen_chalk}, x::Real, z::Real) = 1000.0 +shear_seabed_celerity(::Val{:jensen_limestone}, x::Real, z::Real) = 1500.0 +shear_seabed_celerity(::Val{:jensen_basalt}, x::Real, z::Real) = 2500.0 + +@parse_models_w_args shear_seabed_celerity + +""" +TODO. +""" +struct ShearSeabedCelerity <: Celerity + model::Val +end + +function (shear_atn::ShearSeabedCelerity)(x::Real, z::Real) + shear_seabed_celerity(shear_atn.model, x, z) +end + +@parse_models ShearSeabedCelerity + +ShearSeabedCelerity() = ShearSeabedCelerity(Symbol()) + +list_model_symbols(::Type{ShearSeabedCelerity}) = list_model_symbols(shear_seabed_celerity) \ No newline at end of file diff --git a/src/oceanography/density/atmosphere.jl b/src/oceanography/density/atmosphere.jl new file mode 100644 index 0000000..8adccdc --- /dev/null +++ b/src/oceanography/density/atmosphere.jl @@ -0,0 +1,28 @@ +export atmosphere_density +export AtmosphereDensity + +""" +TODO. +""" +function atmosphere_density end + +atmosphere_density(::Val{:standard}, x::Real, z::Real) = 1.225 + +@parse_models_w_args atmosphere_density + +""" +TODO. +""" +struct AtmosphereDensity <: Density + model::Val +end + +function (den::AtmosphereDensity)(x::Real, z::Real) + atmosphere_density(den.model, x, z) +end + +@parse_models AtmosphereDensity + +AtmosphereDensity() = AtmosphereDensity(:standard) + +list_model_symbols(::Type{AtmosphereDensity}) = list_model_symbols(atmosphere_density) \ No newline at end of file diff --git a/src/oceanography/density/ocean.jl b/src/oceanography/density/ocean.jl new file mode 100644 index 0000000..93853ca --- /dev/null +++ b/src/oceanography/density/ocean.jl @@ -0,0 +1,35 @@ +export ocean_density +export OceanDensity + +""" +TODO. +""" +function ocean_density end + +""" +``` +ρ::Real = ocean_density(:homogeneous, x::Real, z::Real) +``` + +Section 2.1.1.2 of Ainslie (2010). +""" +ocean_density(::Val{:homogeneous}, x::Real, z::Real) = 1027.0 + +@parse_models_w_args ocean_density + +""" +TODO. +""" +struct OceanDensity <: Density + model::Val +end + +function (den::OceanDensity)(x::Real, z::Real) + ocean_density(den.model, x, z) +end + +@parse_models OceanDensity + +OceanDensity() = OceanDensity(:homogeneous) + +list_model_symbols(::Type{OceanDensity}) = list_model_symbols(ocean_density) \ No newline at end of file diff --git a/src/oceanography/density/root.jl b/src/oceanography/density/root.jl new file mode 100644 index 0000000..48368a6 --- /dev/null +++ b/src/oceanography/density/root.jl @@ -0,0 +1,7 @@ +export Density + +abstract type Density <: Bivariate end + +include("atmosphere.jl") +include("ocean.jl") +include("seabed.jl") \ No newline at end of file diff --git a/src/oceanography/density/seabed.jl b/src/oceanography/density/seabed.jl new file mode 100644 index 0000000..0b47959 --- /dev/null +++ b/src/oceanography/density/seabed.jl @@ -0,0 +1,33 @@ +export seabed_density +export SeabedDensity + +""" +TODO. +""" +function seabed_density end + +seabed_density(::Val{:jensen_clay}, x::Real, z::Real) = 1500.0 +seabed_density(::Val{:jensen_silt}, x::Real, z::Real) = 1700.0 +seabed_density(::Val{:jensen_sand}, x::Real, z::Real) = 1900.0 +seabed_density(::Val{:jensen_gravel}, x::Real, z::Real) = 2000.0 +seabed_density(::Val{:jensen_moraine}, x::Real, z::Real) = 2100.0 +seabed_density(::Val{:jensen_chalk}, x::Real, z::Real) = 2200.0 +seabed_density(::Val{:jensen_limestone}, x::Real, z::Real) = 2400.0 +seabed_density(::Val{:jensen_basalt}, x::Real, z::Real) = 2700.0 + +@parse_models_w_args seabed_density + +""" +TODO. +""" +struct SeabedDensity <: Density + model::Val +end + +(den::SeabedDensity)(x::Real, z::Real) = seabed_density(den.model, x, z) + +@parse_models SeabedDensity + +SeabedDensity() = SeabedDensity(Symbol()) + +list_model_symbols(::Type{SeabedDensity}) = list_model_symbols(seabed_density) \ No newline at end of file diff --git a/src/oceanography/medium/atmosphere.jl b/src/oceanography/medium/atmosphere.jl new file mode 100644 index 0000000..efeefc7 --- /dev/null +++ b/src/oceanography/medium/atmosphere.jl @@ -0,0 +1,29 @@ +export Atmosphere + +""" +TODO. +""" +mutable struct Atmosphere <: Medium + model::Val + cel::AtmosphereCelerity + den::AtmosphereDensity + atn::AtmosphereAttenuation +end + +function Atmosphere(; kwargs...) + length(kwargs) == 0 && return Atmosphere(:standard) + atm = Atmosphere() + for (key, val) in kwargs + setfield!(atm, key, val) + end + return atm +end + +Atmosphere(model::Val{:standard}) = Atmosphere( + model, + AtmosphereCelerity(:standard), + AtmosphereDensity(:standard), + AtmosphereAttenuation(:standard) +) + +@parse_models Atmosphere \ No newline at end of file diff --git a/src/oceanography/medium/ocean.jl b/src/oceanography/medium/ocean.jl new file mode 100644 index 0000000..9925898 --- /dev/null +++ b/src/oceanography/medium/ocean.jl @@ -0,0 +1,38 @@ +export Ocean + +""" +TODO. +""" +@kwdef mutable struct Ocean <: Medium + model::Val = Val(Symbol()) + cel::OceanCelerity = OceanCelerity() + den::OceanDensity = OceanDensity() + atn::OceanAttenuation = OceanAttenuation() +end + +Ocean(model::Val{:homogeneous}) = Ocean( + model = model, + cel = OceanCelerity(:homogeneous) +) + +Ocean(model::Val{:munk_profile}) = Ocean( + model = model, + cel = OceanCelerity(:munk) +) + +Ocean(model::Val{:index_squared_profile}) = Ocean( + model = model, + cel = OceanCelerity(:index_squared) +) + +Ocean(model::Val{:linearised_convergence_zones}) = Ocean( + model = model, + cel = OceanCelerity(:linearised_convergence_zones) +) + +Ocean(model::Val{:norwegian_sea}) = Ocean( + model = model, + cel = OceanCelerity(:norwegian_sea) +) + +@parse_models Ocean \ No newline at end of file diff --git a/src/oceanography/medium/root.jl b/src/oceanography/medium/root.jl new file mode 100644 index 0000000..b047c5e --- /dev/null +++ b/src/oceanography/medium/root.jl @@ -0,0 +1,10 @@ +export Medium + +""" +Generic medium container. +""" +abstract type Medium <: Container end + +include("atmosphere.jl") +include("ocean.jl") +include("seabed.jl") \ No newline at end of file diff --git a/src/oceanography/medium/seabed.jl b/src/oceanography/medium/seabed.jl new file mode 100644 index 0000000..d818407 --- /dev/null +++ b/src/oceanography/medium/seabed.jl @@ -0,0 +1,35 @@ +export Seabed + +""" +TODO. +""" +@kwdef mutable struct Seabed <: Medium + model::Val = Val(Symbol()) + cel::SeabedCelerity = SeabedCelerity() + den::SeabedDensity = SeabedDensity() + atn::SeabedAttenuation = SeabedAttenuation() + shear_cel::ShearSeabedCelerity = ShearSeabedCelerity() + shear_atn::ShearSeabedAttenuation = ShearSeabedAttenuation() +end + +function Seabed(model::Val) + model |> modelsymbol ∉ list_model_symbols(Seabed) && error( + "Invalid Seabed model. Try one of: ", + list_models(Seabed) + ) + Seabed( + model = model, + cel = SeabedCelerity(model), + den = SeabedDensity(model), + atn = SeabedAttenuation(model), + shear_cel = ShearSeabedCelerity(model), + shear_atn = ShearSeabedAttenuation(model) + ) +end + +@parse_models Seabed + +function list_model_symbols(::Type{Seabed}) + components = [SeabedCelerity, SeabedDensity, SeabedAttenuation, ShearSeabedCelerity, ShearSeabedAttenuation] + list_model_symbols.(components) |> splat(intersect) +end \ No newline at end of file diff --git a/src/oceanography/root.jl b/src/oceanography/root.jl new file mode 100644 index 0000000..b703969 --- /dev/null +++ b/src/oceanography/root.jl @@ -0,0 +1,7 @@ +include("boundary/root.jl") +include("celerity/root.jl") +include("density/root.jl") +include("attenuation/root.jl") + +include("medium/root.jl") +include("slice.jl") \ No newline at end of file diff --git a/src/oceanography/slice.jl b/src/oceanography/slice.jl new file mode 100644 index 0000000..c70641a --- /dev/null +++ b/src/oceanography/slice.jl @@ -0,0 +1,59 @@ +export Slice + +""" +TODO. +""" +@kwdef mutable struct Slice <: Container + model::Val = Val(Symbol()) + + atm::Atmosphere = Atmosphere() + ocn::Ocean = Ocean() + sbd::Seabed = Seabed() + + ati::Altimetry = Altimetry() + bty::Bathymetry = Bathymetry() +end + +Slice(model::Val{:lloyd_mirror}) = Slice( + model = model, + ocn = Ocean(:homogeneous), + sbd = Seabed(:jensen_clay), + bty = Bathymetry(:half_kilometre) +) + +Slice(model::Val{:munk_profile}) = Slice( + model = model, + ocn = Ocean(:munk_profile), + sbd = Seabed(:jensen_clay), + bty = Bathymetry(:deep) +) + +Slice(model::Val{:index_squared_profile}) = Slice( + model = model, + ocn = Ocean(:index_squared_profile), + sbd = Seabed(:jensen_clay), + bty = Bathymetry(:mesopelagic) +) + +Slice(model::Val{:parabolic_bathymetry}) = Slice( + model = model, + ocn = Ocean(:homogeneous), + sbd = Seabed(:jensen_basalt), + bty = Bathymetry(:parabolic) +) + +Slice(model::Val{:linearised_convergence_zones}) = Slice( + model = model, + ocn = Ocean(:linearised_convergence_zones), + sbd = Seabed(:jensen_basalt), + bty = Bathymetry(:deep) +) + +Slice(model::Val{:norwegian_sea}) = Slice( + model = model, + ocn = Ocean(:norwegian_sea), + sbd = Seabed(:jensen_basalt), + bty = Bathymetry(:four_kilometers) +) + +@parse_models Slice \ No newline at end of file diff --git a/src/postliminary/get.jl b/src/postliminary/get.jl new file mode 100644 index 0000000..1f3b174 --- /dev/null +++ b/src/postliminary/get.jl @@ -0,0 +1,21 @@ +export get + +# TODO: automate + +get(med::Medium, ::Type{<:Celerity}) = med.cel +get(med::Medium, ::Type{<:Density}) = med.den + +get(slc::Slice, ::Type{<:Altimetry}) = slc.ati +get(slc::Slice, ::Type{<:Bathymetry}) = slc.bty +get(slc::Slice, ::Type{<:OceanCelerity}) = get(slc.ocn, Celerity) +get(slc::Slice, ::Type{<:OceanDensity}) = get(slc.ocn, Density) + +get(scen::Scenario, ::Type{<:Altimetry}) = get(scen.slc, Altimetry) +get(scen::Scenario, ::Type{<:Bathymetry}) = get(scen.slc, Bathymetry) +get(scen::Scenario, ::Type{<:OceanCelerity}) = get(scen.slc, OceanCelerity) +get(scen::Scenario, ::Type{<:OceanDensity}) = get(scen.slc, OceanDensity) + +get(prop::Propagation, ::Type{<:Altimetry}) = get(prop.scen, Altimetry) +get(prop::Propagation, ::Type{<:Bathymetry}) = get(prop.scen, Bathymetry) +get(prop::Propagation, ::Type{<:OceanCelerity}) = get(prop.scen, OceanCelerity) +get(prop::Propagation, ::Type{<:OceanDensity}) = get(prop.scen, OceanDensity) \ No newline at end of file diff --git a/src/postliminary/modelling.jl b/src/postliminary/modelling.jl new file mode 100644 index 0000000..2fc65f6 --- /dev/null +++ b/src/postliminary/modelling.jl @@ -0,0 +1,4 @@ +function modeltitle(ocnson::OcnSon) + @assert hasproperty(ocnson, :model) "Structure is not a model instance." + return ocnson.model |> modeltitle +end \ No newline at end of file diff --git a/src/postliminary/precompile.jl b/src/postliminary/precompile.jl new file mode 100644 index 0000000..51d2316 --- /dev/null +++ b/src/postliminary/precompile.jl @@ -0,0 +1,9 @@ +@setup_workload begin + scen = Scenario("Munk Profile") + + @compile_workload begin + beam = Beam("Gaussian", scen, angle = 0.0) + beams = Beams("Gaussian", scen) + prop = Propagation("Trace", scen) # TODO: loop through `Propagation` models + end +end \ No newline at end of file diff --git a/src/postliminary/root.jl b/src/postliminary/root.jl new file mode 100644 index 0000000..59912d2 --- /dev/null +++ b/src/postliminary/root.jl @@ -0,0 +1,5 @@ +include("get.jl") +include("modelling.jl") +include("variables.jl") +include("visualisation.jl") +include("precompile.jl") \ No newline at end of file diff --git a/src/postliminary/variables.jl b/src/postliminary/variables.jl new file mode 100644 index 0000000..42b709f --- /dev/null +++ b/src/postliminary/variables.jl @@ -0,0 +1,17 @@ +name(type::Type{<:OcnSon}) = title_case(type |> string) + +name(ocnson::OcnSon) = ocnson |> typeof |> name + +name(type::Type{<:Propagation}) = "Propagation Loss" + +# TODO: Supercede `unit` with a package like Unitful.jl. + +unit(::Type{<:Boundary}) = "m" +unit(::Type{<:Celerity}) = "m/s" +unit(::Type{<:Density}) = "kg/m³" +unit(::Type{<:Propagation}) = "dB re m²" + +unit(ocnson::OcnSon) = ocnson |> typeof |> unit + +label(type::Type{<:OcnSon}) = name(type) * " (" * unit(type) * ")" +label(ocnson::OcnSon) = ocnson |> typeof |> label \ No newline at end of file diff --git a/src/postliminary/visualisation.jl b/src/postliminary/visualisation.jl new file mode 100644 index 0000000..2729b72 --- /dev/null +++ b/src/postliminary/visualisation.jl @@ -0,0 +1,120 @@ +export visual! +export visual +export boundaryplot! +export boundaryplot +export bivariateplot! +export bivariateplot + +""" +``` +visual!(pos::Makie.GridPosition, args...) +``` +Adds the plotting of `args...` to `pos::Makie.GridPosition`, +where `args...` is the same as in `visual`. + +See `@doc visual`. +""" +function visual! end + +""" +``` +visual(args...) +``` + +Performs the following: + +* Creates a `Makie.Figure` with a single `Makie.GridPosition`. +* Plots according to `args...` +* Flips the y-axis positive-downwards for representing depth. +* Plots the boundaries if such information is available (`Slice` and upward). +* Adds a colorbar if 2D data (`<:Bivariate`) is plotted. +* Adds labels and units. +* Applies a default colouring for distinguishing between the different plots on the axis. + +The first argument always specifies what the plotting target is. +There are two ways to specify the plotting target: +instances or types. + +Plottable instances are: + +* `Altimetry` +* `Bathymetry` +* `<:Celerity` (e.g. `OceanCelerity` instances) +* `<:Density` +* `Slice` +* `Scenario` +* `Beam` +* `Vector{Beam}` +* `Propagation` + +The second way to specify the plotting target +is by `arg[2]` an instance of any of the above, +and `arg[1]` an appropriate type contained by the instance inputted as `arg[2]`. + +* `Altimetry` +* `Bathymetry` +* `Boundary` plots both the `Altimetry` and `Bathymetry` +* `OceanCelerity` +* `OceanDensity` +* `Beam` + +See documentation of the above-listed types for specific `visual` usage documentation. +""" +function visual end + +function OceanAxis end + +colour(ocnson::OcnSon) = ocnson |> typeof |> colour + +function boundaryplot! end +function boundaryplot end + +colour(::Type{Altimetry}) = :slateblue1 +colour(::Type{Bathymetry}) = :sienna +# colour(::Type{<:Boundary}) = :gray + +function bivariateplot! end +function bivariateplot end + +colour(::Type{<:Celerity}) = :Blues +colour(::Type{<:Bivariate}) = :jet +colour(::Type{<:Propagation}) = :jet + +function rayplot! end +function rayplot end + +colour(::Type{<:Beam}) = :black +colour(::Type{<:AbstractVector{<:Beam}}) = colour(Beam) +colour(beams::AbstractVector{<:Beam}) = beams |> typeof |> colour + +default_arc_points(beam::Beam) = [ + range(0, beam.s_max, 301); beam.s_srf; beam.s_bot; beam.s_hrz +] |> uniquesort! + +function propagationplot! end +function propagationplot end + +create_ranges(x1::Real, x2::Real, Nx::Integer) = range(x1, x2, Nx) +create_ranges(scen::Scenario, Nx::Integer) = create_ranges(0.0, scen.x, Nx) +create_ranges(prop::Propagation) = prop.x + +create_depths(z1::Real, z2::Real, Nz::Integer) = range(z1, z2, Nz) +create_depths(slc::Slice, xlo::Real, xhi::Real, Nz::Integer) = create_depths(depth_extrema(slc, xlo, xhi)..., Nz) +create_depths(scen::Scenario, Nz::Integer) = create_depths(scen.slc, 0.0, scen.x, Nz) +create_depths(prop::Propagation) = prop.z + +square_numbers = [(n, n, n^2) for n in 1:25] +rect_numbers = [(n, n+1, n * (n+1)) for n in 1:25] +rect_and_square_numbers = sort( + [rect_numbers; square_numbers], + by = nums -> nums[3] +) + +function rect_or_square_gridsize(N::Integer) + rect_and_square_nums = [numbers[3] for numbers in rect_and_square_numbers] + idx = findfirst(rect_and_square_nums .≥ N) + return rect_and_square_numbers[idx][1:2] +end + +colourrange(data) = mean(data) .+ 2std(data) * [-1, 1] +colourrange(prop::Propagation) = prop.PL |> colourrange \ No newline at end of file diff --git a/src/preliminary/auxiliary/interpolation/bivariate.jl b/src/preliminary/auxiliary/interpolation/bivariate.jl new file mode 100644 index 0000000..f1f612d --- /dev/null +++ b/src/preliminary/auxiliary/interpolation/bivariate.jl @@ -0,0 +1,47 @@ +""" +``` +Bivariate <: Functor +``` + +`Bivariate` is both an abstract type and a function that produces an interpolation-extrapolation object. + +``` +itp::Bivariate = Univariate(args...; kwargs...) +``` + +Returns a bivariate interpolator-extrapolator object +whose behaviour is specified by TODO. + +TODO: Implement. + +For example, + +```julia +itp = Bivariate(1:10, 1:20, rand(10, 20)) +itp(2.4, 11.5) +``` +""" +function Bivariate end + +function Bivariate(func::Function) + try + func(0.0, 0.0) + catch + error("Inputted function not bivariate") + end + return func +end + +function Bivariate(F_val::Real) + func(a::Real, b::Real) = F_val + return Bivariate(func) +end + +function Bivariate( + ::Nothing, + b_vec::AbstractVector{<:Real}, + F_vec::AbstractVector{<:Real} +) + itp = Univariate(b_vec, F_vec) + func(a::Real, b::Real) = itp(b) +end \ No newline at end of file diff --git a/src/preliminary/auxiliary/interpolation/root.jl b/src/preliminary/auxiliary/interpolation/root.jl new file mode 100644 index 0000000..08c3dee --- /dev/null +++ b/src/preliminary/auxiliary/interpolation/root.jl @@ -0,0 +1,3 @@ +include("univariate.jl") +include("bivariate.jl") +include("trivariate.jl") \ No newline at end of file diff --git a/src/preliminary/auxiliary/interpolation/trivariate.jl b/src/preliminary/auxiliary/interpolation/trivariate.jl new file mode 100644 index 0000000..f7641cc --- /dev/null +++ b/src/preliminary/auxiliary/interpolation/trivariate.jl @@ -0,0 +1,4 @@ +""" +`Trivariate` is both an abstract type and a function that produces an interpolation-extrapolation object. +""" +function Trivariate end \ No newline at end of file diff --git a/src/preliminary/auxiliary/interpolation/univariate.jl b/src/preliminary/auxiliary/interpolation/univariate.jl new file mode 100644 index 0000000..e0c0265 --- /dev/null +++ b/src/preliminary/auxiliary/interpolation/univariate.jl @@ -0,0 +1,46 @@ +""" +`Univariate` is both an abstract type and a function that produces an interpolation-extrapolation object. + +``` +itp::Univariate = Univariate(args...; kwargs...) +``` + +Returns univariate interpolator-extrapolator object +whose behaviour is specified by TODO. + +TODO: Implement. + +For example, + +```julia +itp = Univariate(1:10, rand(10)) +itp(2.4) +``` +""" +function Univariate end + +function Univariate(func::Function) + try + func(0.0) + catch + error("Inputted function not univariate.") + end + return func +end + +function Univariate(F_val::Real) + func(a::Real) = F_val + return Univariate(func) +end + +function Univariate( + a_vec::AbstractVector{<:Real}, + F_vec::AbstractVector{<:Real} +) + itp = linear_interpolation( + a_vec, F_vec, + extrapolation_bc = Flat() + ) + func(a::Real) = itp(a) + return Univariate(func) +end \ No newline at end of file diff --git a/src/preliminary/auxiliary/modelling.jl b/src/preliminary/auxiliary/modelling.jl new file mode 100644 index 0000000..9ccd641 --- /dev/null +++ b/src/preliminary/auxiliary/modelling.jl @@ -0,0 +1,144 @@ +export list_models +export list_inputs +export modelsnake +export modelsymbol +export modeltitle + +""" +`modelsnake(model::Union{String, Symbol, Val})` + +Converts `model` as a `String`, `Symbol`, or `Val` +into a snake-case `String` for `OceanSonar` model parsing. +""" +function modelsnake end +modelsnake(model::String) = model |> snake_case +modelsnake(model::Symbol) = model |> string |> modelsnake +modelsnake(::Val{model}) where model = model |> modelsnake + +""" +`modelsymbol(model::Union{String, Symbol, Val})` + +Converts `model` as a `String`, `Symbol`, or `Val` +into a `Symbol` for `OceanSonar` model parsing. +""" +function modelsymbol(model::Union{String, Symbol, Val}) + model |> modelsnake |> Symbol +end + +""" +`modelval(model::Union{String, Symbol, Val})` + +Converts `model` as a `String`, `Symbol`, or `Val` +into a `Val` for `OceanSonar` model parsing. +""" +function modelval(model::Union{String, Symbol, Val}) + model |> modelsymbol |> Val +end + +""" +`modeltitle(model::Union{String, Symbol, Val})` + +Converts `model` as a `String`, `Symbol`, or `Val` +into a title-case `String` for `OceanSonar` model parsing. +""" +function modeltitle(model::Union{String, Symbol, Val}) + model |> modelsnake |> title_case +end + +function list_model_symbols( + func::Union{Function, Type{<:OcnSon}} +) + @assert parentmodule(func) == OceanSonar "`list_models` only for OceanSonar.jl objects." + + func_methods = methods(func) + func_sigs = [func_method.sig for func_method in func_methods] + func_pars = [ + func_sig.parameters + for func_sig in func_sigs + if hasproperty(func_sig, :parameters) + ] + func_vals = [ + [ + par + for par in func_par + if par isa Type && par <: Val + ] for func_par in func_pars + ] + for func_val in func_vals + if length(func_val) > 1 + error(func, " method has more than one `Val` specification: ", func_val...) + end + end + condition(func_val) = length(func_val) == 1 && func_val[1] ≠ Val && func_val[1] ≠ Val{Symbol("")} + func_vals2 = [ + func_val[1]() + for func_val in func_vals + if condition(func_val) + ] + return func_vals2 .|> modelsymbol |> unique +end + +""" +``` +models::Symbol = list_models( + func::Union{ + Function, + Type{<:Container}, + Type{<:Result} + } +) +``` +""" +list_models(func::Union{Function, Type{<:OcnSon}}) = list_model_symbols(func) .|> modeltitle + +function doc_models(func::Union{Function, Type{<:OcnSon}}) + parentmodule(func) ≠ OceanSonar && error("`doc_models` only defined for `OceanSonar.jl` definitions.") + return [ + "* `\"" * string(model) * "\"`\n" for model in list_models(func) + ] |> join +end + +function list_inputs(func, model::Val) + func_methods = [ + func_method + for func_method in methods(func) + if typeof(model) in func_method.sig.parameters + ] + func_method = func_methods[1] # will fix later + return Base.method_argnames(func_method)[3:end] +end + +list_inputs(func) = list_inputs(func, func.model) + +list_inputs(func, model::Symbol) = list_inputs(func, model |> Val) + +macro parse_models(con_name_sym::Symbol) + name = esc(con_name_sym) + quote + function $name(model::Val{Symbol()}) + error("Default ", $name, " is intentionally invalid.") + end + + function $name(model::Union{Symbol, String}) + $name(model |> modelval) + end + end +end + +macro parse_models_w_args(func_name_sym::Symbol) + name = esc(func_name_sym) + quote + function $name(model::Union{Symbol, String}, args...) + $name(model |> modelval, args...) + end + end +end + +macro parse_models_w_args_kwargs(func_name_sym::Symbol) + name = esc(func_name_sym) + quote + function $name(model::Union{Symbol, String}, args...; kwargs...) + $name(model |> modelval, args...; kwargs...) + end + end +end \ No newline at end of file diff --git a/src/preliminary/auxiliary/root.jl b/src/preliminary/auxiliary/root.jl new file mode 100644 index 0000000..173d333 --- /dev/null +++ b/src/preliminary/auxiliary/root.jl @@ -0,0 +1,18 @@ +export uniquesort! + +(..)(lo, hi) = interval(lo, hi) +uniquesort! = unique! ∘ sort! + +# series125(n::Integer) = (1 + (n % 3)^2) * 10^(n ÷ 3) + +# function series125(; max::Real = NaN, length::Real = NaN) + +# end + +include("series125.jl") + +include("stringcases.jl") +include("modelling.jl") + +include("interpolation/root.jl") +include("units/root.jl") \ No newline at end of file diff --git a/src/preliminary/auxiliary/series125.jl b/src/preliminary/auxiliary/series125.jl new file mode 100644 index 0000000..15136ec --- /dev/null +++ b/src/preliminary/auxiliary/series125.jl @@ -0,0 +1,30 @@ +export series125 + +series125_(::Val{0}, type::Type{<:Integer} = Int) = 1 |> type +series125_(::Val{1}, type::Type{<:Integer} = Int) = 2 |> type +series125_(::Val{2}, type::Type{<:Integer} = Int) = 5 |> type +series125_(::Val{N}, type::Type{<:Integer} = Int) where N = 10series125_(N-3 |> Val, type) + +series125_(N::Integer, type::Type{<:Integer} = Int) = series125_(N |> Val, type) + +function series125(N::Integer, type::Type{<:Integer} = Int) + series = series125_.(0:N-1, type) + if any(series .< 0) + error("Integer overflow, try `series125(N, BigInt)`.") + end + return series +end + +function series125(M::AbstractFloat, type::Type{<:Integer} = Int) + series = Float64[] + n = -1 + while true + n += 1 + S = series125_(n, type) + if S ≤ M + push!(series, S) + else + return series + end + end +end \ No newline at end of file diff --git a/src/preliminary/auxiliary/stringcases.jl b/src/preliminary/auxiliary/stringcases.jl new file mode 100644 index 0000000..355b9a7 --- /dev/null +++ b/src/preliminary/auxiliary/stringcases.jl @@ -0,0 +1,73 @@ +export title_case +export snake_case + +# Temporary solution before I fix StringCases.jl +# Copying and editing files from StringCases.jl + +const downcase = lowercase + +function _purgecase(cur_string::AbstractString) + cur_string = replace(cur_string, "-" => " ") + cur_string = replace(cur_string, "_" => " ") + + cur_string +end + +function _defaultcase(cur_string::AbstractString) + cur_string = _purgecase(cur_string) + + cur_string = join(split(cur_string), " ") + cur_string = downcase(cur_string) + + cur_string +end + +function _delimcase(cur_string::AbstractString, cur_delim::AbstractString) + replace( + _defaultcase(cur_string), + " " => cur_delim + ) +end + +function snakecase(cur_string::AbstractString) + _delimcase(cur_string, "_") +end + +function spacecase(cur_string::AbstractString) + _defaultcase(cur_string) +end + +function decamelize(cur_string::AbstractString) + capital_letters = collect(m.match for m in eachmatch(r"[A-Z]+", cur_string)) + capital_letters = map(x -> downcase(x), capital_letters) + + lowercase_phrases = split(cur_string, r"([A-Z]+)") + + cur_array = vcat( + map( + x -> join(x, "_"), + [zip(lowercase_phrases, capital_letters)...] + )... + ) + + cur_string = join(cur_array) + + if length(lowercase_phrases) > length(capital_letters) + cur_string *= lowercase_phrases[end] + end + + if length(lowercase_phrases) < length(capital_letters) + error("Improperly handled string on decamelize: $cur_string") + end + + ( startswith(cur_string, "_") ) && ( cur_string = cur_string[2:end] ) + ( startswith(cur_string, "-") ) && ( cur_string = cur_string[2:end] ) + + cur_string +end + +defaultcase(text::String) = text |> decamelize |> spacecase + +title_case(text::String) = text |> defaultcase |> titlecase + +snake_case = snakecase \ No newline at end of file diff --git a/src/preliminary/auxiliary/units/decibels.jl b/src/preliminary/auxiliary/units/decibels.jl new file mode 100644 index 0000000..9c65069 --- /dev/null +++ b/src/preliminary/auxiliary/units/decibels.jl @@ -0,0 +1,20 @@ +export complex_celerity +export db2pow +export pow2db +export ⊕ + +decibels_per_wavelength_to_nepers(α::Real) = α / (2π * 20log10(ℯ)) + +complex_celerity(c::Real, α::Real) = c * (1 - im * decibels_per_wavelength_to_nepers(α)) + +# [dB / m / kHz] = [dB / m / Hz] / 1000 +# [dB / m / kHz] = [Np / m] * 1000 * 20log10(ℯ) / f +# [dB / m / Hz] / 1000 = [Np / m] * 1000 * 20log10(ℯ) / f +# [dB / m / Hz] = 10⁶ * [Np / m] * 20log10(ℯ) / f +# [dB / m] = [Np / m] * 20log10(ℯ) +# [dB / λ] = [Np / m] * λ * 20log10(ℯ) +# [dB / λ] = δ * 20log10(ℯ) * 2π + +db2pow(L) = 10^(L/10) +pow2db(P) = 10log10(P) +⊕(args...) = args .|> db2pow |> sum |> pow2db \ No newline at end of file diff --git a/src/preliminary/auxiliary/units/root.jl b/src/preliminary/auxiliary/units/root.jl new file mode 100644 index 0000000..bedadd3 --- /dev/null +++ b/src/preliminary/auxiliary/units/root.jl @@ -0,0 +1 @@ +include("decibels.jl") \ No newline at end of file diff --git a/src/preliminary/base/abstract_supertypes.jl b/src/preliminary/base/abstract_supertypes.jl new file mode 100644 index 0000000..441a200 --- /dev/null +++ b/src/preliminary/base/abstract_supertypes.jl @@ -0,0 +1,49 @@ +export OcnSon + +export Univariate +export Bivariate +export Trivariate + +abstract type OcnSon end +abstract type Functor <: OcnSon end +abstract type Univariate <: Functor end +abstract type Bivariate <: Functor end +abstract type Trivariate <: Functor end +abstract type Container <: OcnSon end +abstract type Result <: OcnSon end +abstract type Config <: OcnSon end + +@doc """ +`OceanSonar.OcnSon` + +Supertype for OceanSonar.jl containers and functors. +""" +OcnSon + +@doc """ +`OceanSonar.Functor` + +Supertype for OceanSonar.jl functors. +""" +Functor + +@doc """ +`OceanSonar.Container` + +Supertype for OceanSonar.jl containers for data. +""" +Container + +@doc """ +`OceanSonar.Result` + +Supertype for OceanSonar.jl containers for results and data. +""" +Result + +@doc """ +`OceanSonar.Config` + +Supertype for OceanSonar.jl configuration structures. +""" +Config \ No newline at end of file diff --git a/src/preliminary/base/overloads.jl b/src/preliminary/base/overloads.jl new file mode 100644 index 0000000..e02c809 --- /dev/null +++ b/src/preliminary/base/overloads.jl @@ -0,0 +1,3 @@ +show(io::IO, ocnson::OcnSon) = show(io, ocnson |> typeof) +length(::OcnSon) = 1 +iterate(ocnson::OcnSon, state = 1) = state > 1 ? nothing : (ocnson, state + 1) \ No newline at end of file diff --git a/src/preliminary/base/root.jl b/src/preliminary/base/root.jl new file mode 100644 index 0000000..3d20ef9 --- /dev/null +++ b/src/preliminary/base/root.jl @@ -0,0 +1,2 @@ +include("abstract_supertypes.jl") +include("overloads.jl") \ No newline at end of file diff --git a/src/preliminary/root.jl b/src/preliminary/root.jl new file mode 100644 index 0000000..91e92e4 --- /dev/null +++ b/src/preliminary/root.jl @@ -0,0 +1,2 @@ +include("base/root.jl") +include("auxiliary/root.jl") \ No newline at end of file diff --git a/src/processing/root.jl b/src/processing/root.jl new file mode 100644 index 0000000..c8b5e71 --- /dev/null +++ b/src/processing/root.jl @@ -0,0 +1,2 @@ +include("types.jl") +include("sonar.jl") \ No newline at end of file diff --git a/src/processing/sonar.jl b/src/processing/sonar.jl new file mode 100644 index 0000000..1a0d59e --- /dev/null +++ b/src/processing/sonar.jl @@ -0,0 +1,17 @@ +function signal_to_noise_ratio(::Type{<:Passive}, + SL::Real, PL::Real, NL::Real, DI::Real +) + SL - PL - NL + DI +end + +function signal_to_noise_ratio(::Type{<:Monostatic}, + SL::Real, PL::Real, TS::Real, NL::Real, RL::Real, DI::Real +) + SL - 2PL + TS - (NL ⊕ RL) + DI +end + +function signal_to_noise_ratio(::Type{<:Bistatic}, + SL::Real, PLa::Real, PLb::Real, TS::Real, NL::Real, RL::Real, DI::Real +) + SL - PLa + TS - PLb - (NL ⊕ RL) + DI +end \ No newline at end of file diff --git a/src/processing/types.jl b/src/processing/types.jl new file mode 100644 index 0000000..41a5878 --- /dev/null +++ b/src/processing/types.jl @@ -0,0 +1,36 @@ +export SpectralContent +export BandSize +export WaveForm +export NB +export BB +export CW +export FM +export NBorCW +export BBorFM + +export SonarType +export Passive +export Active +export Exposure +export Intercept +export Monostatic +export Bistatic + +abstract type SpectralContent end +abstract type BandSize <: SpectralContent end +abstract type NB <: BandSize end +abstract type BB <: BandSize end +abstract type WaveForm <: SpectralContent end +abstract type CW <: WaveForm end +abstract type FM <: WaveForm end + +NBorCW = Union{NB, CW} +BBorFM = Union{BB, FM} + +abstract type SonarType{SC <: SpectralContent} end +abstract type Passive{SC <: SpectralContent} <: SonarType{SC} end +abstract type Exposure{BS <: BandSize} <: Passive{BS} end +abstract type Intercept{WF <: WaveForm} <: Passive{WF} end +abstract type Active{WF <: WaveForm} <: SonarType{WF} end +abstract type Monostatic{WF <: WaveForm} <: Active{WF} end +abstract type Bistatic{WF <: WaveForm} <: Active{WF} end \ No newline at end of file diff --git a/test/Manifest.toml b/test/Manifest.toml new file mode 100644 index 0000000..86e0592 --- /dev/null +++ b/test/Manifest.toml @@ -0,0 +1,245 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.11.0-rc1" +manifest_format = "2.0" +project_hash = "0982de2fa10213520b37032d78b5ec17d46180ea" + +[[deps.Aqua]] +deps = ["Compat", "Pkg", "Test"] +git-tree-sha1 = "12e575f31a6f233ba2485ed86b9325b85df37c61" +uuid = "4c88cf16-eb10-579e-8560-4a9242c79595" +version = "0.8.7" + +[[deps.ArgTools]] +uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" +version = "1.1.2" + +[[deps.Artifacts]] +uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" +version = "1.11.0" + +[[deps.Base64]] +uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" +version = "1.11.0" + +[[deps.CodeTracking]] +deps = ["InteractiveUtils", "UUIDs"] +git-tree-sha1 = "c0216e792f518b39b22212127d4a84dc31e4e386" +uuid = "da1fd8a2-8d9e-5ec2-8556-3022fb5608a2" +version = "1.3.5" + +[[deps.Compat]] +deps = ["TOML", "UUIDs"] +git-tree-sha1 = "b1c55339b7c6c350ee89f2c1604299660525b248" +uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" +version = "4.15.0" + + [deps.Compat.extensions] + CompatLinearAlgebraExt = "LinearAlgebra" + + [deps.Compat.weakdeps] + Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" + LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + +[[deps.Dates]] +deps = ["Printf"] +uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" +version = "1.11.0" + +[[deps.Downloads]] +deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] +uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" +version = "1.6.0" + +[[deps.FileWatching]] +uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" +version = "1.11.0" + +[[deps.InteractiveUtils]] +deps = ["Markdown"] +uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +version = "1.11.0" + +[[deps.JET]] +deps = ["CodeTracking", "InteractiveUtils", "JuliaInterpreter", "LoweredCodeUtils", "MacroTools", "Pkg", "PrecompileTools", "Preferences", "Test"] +git-tree-sha1 = "8dc1a7e850cbcbb28d5beecc3816c16acd3f7452" +uuid = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" +version = "0.9.5" + + [deps.JET.extensions] + ReviseExt = "Revise" + + [deps.JET.weakdeps] + Revise = "295af30f-e4ad-537b-8983-00126c2a3abe" + +[[deps.JuliaInterpreter]] +deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"] +git-tree-sha1 = "a6adc2dcfe4187c40dc7c2c9d2128e326360e90a" +uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" +version = "0.9.32" + +[[deps.LibCURL]] +deps = ["LibCURL_jll", "MozillaCACerts_jll"] +uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" +version = "0.6.4" + +[[deps.LibCURL_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] +uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" +version = "8.6.0+0" + +[[deps.LibGit2]] +deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] +uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +version = "1.11.0" + +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.7.2+0" + +[[deps.LibSSH2_jll]] +deps = ["Artifacts", "Libdl", "MbedTLS_jll"] +uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" +version = "1.11.0+1" + +[[deps.Libdl]] +uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +version = "1.11.0" + +[[deps.Logging]] +uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" +version = "1.11.0" + +[[deps.LoweredCodeUtils]] +deps = ["JuliaInterpreter"] +git-tree-sha1 = "eeaedcf337f33c039f9f3a209a8db992deefd7e9" +uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b" +version = "2.4.8" + +[[deps.MacroTools]] +deps = ["Markdown", "Random"] +git-tree-sha1 = "2fa9ee3e63fd3a4f7a9a4f4744a52f4856de82df" +uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" +version = "0.5.13" + +[[deps.Markdown]] +deps = ["Base64"] +uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" +version = "1.11.0" + +[[deps.MbedTLS_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" +version = "2.28.6+0" + +[[deps.MozillaCACerts_jll]] +uuid = "14a3606d-f60d-562e-9121-12d972cd8159" +version = "2023.12.12" + +[[deps.NetworkOptions]] +uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" +version = "1.2.0" + +[[deps.Pkg]] +deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] +uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +version = "1.11.0" + + [deps.Pkg.extensions] + REPLExt = "REPL" + + [deps.Pkg.weakdeps] + REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" + +[[deps.PrecompileTools]] +deps = ["Preferences"] +git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" +uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" +version = "1.2.1" + +[[deps.Preferences]] +deps = ["TOML"] +git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" +uuid = "21216c6a-2e73-6563-6e65-726566657250" +version = "1.4.3" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" +version = "1.11.0" + +[[deps.PropCheck]] +deps = ["Compat", "InteractiveUtils", "Logging", "Random", "RequiredInterfaces", "Test"] +git-tree-sha1 = "859234e2490881f049d52998cbcc52281381b258" +uuid = "ca382230-33be-11e9-0059-d981d03070e4" +version = "0.10.1" + + [deps.PropCheck.extensions] + ATExt = "AbstractTrees" + + [deps.PropCheck.weakdeps] + AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" + +[[deps.Random]] +deps = ["SHA"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" +version = "1.11.0" + +[[deps.RequiredInterfaces]] +deps = ["InteractiveUtils", "Logging", "Test"] +git-tree-sha1 = "c3250333ea2894237ed015baf7d5fcb8a1ea3169" +uuid = "97f35ef4-7bc5-4ec1-a41a-dcc69c7308c6" +version = "0.1.6" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.SafeTestsets]] +git-tree-sha1 = "81ec49d645af090901120a1542e67ecbbe044db3" +uuid = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +version = "0.1.0" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" +version = "1.11.0" + +[[deps.TOML]] +deps = ["Dates"] +uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" +version = "1.0.3" + +[[deps.Tar]] +deps = ["ArgTools", "SHA"] +uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" +version = "1.10.0" + +[[deps.Test]] +deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] +uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +version = "1.11.0" + +[[deps.UUIDs]] +deps = ["Random", "SHA"] +uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +version = "1.11.0" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" +version = "1.11.0" + +[[deps.Zlib_jll]] +deps = ["Libdl"] +uuid = "83775a58-1f1d-513f-b197-d71354ab007a" +version = "1.2.13+1" + +[[deps.nghttp2_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" +version = "1.59.0+0" + +[[deps.p7zip_jll]] +deps = ["Artifacts", "Libdl"] +uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" +version = "17.4.0+2" diff --git a/test/Project.toml b/test/Project.toml new file mode 100644 index 0000000..44cf981 --- /dev/null +++ b/test/Project.toml @@ -0,0 +1,7 @@ +[deps] +Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" +InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" +JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" +PropCheck = "ca382230-33be-11e9-0059-d981d03070e4" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" \ No newline at end of file diff --git a/test/auxiliary/interpolation/univariate.jl b/test/auxiliary/interpolation/univariate.jl new file mode 100644 index 0000000..81a168c --- /dev/null +++ b/test/auxiliary/interpolation/univariate.jl @@ -0,0 +1,17 @@ +using OceanSonar +using Test +using PropCheck + +function wrap_check(prop::Function, gen::Integrated) + chk = check(splat(prop), gen) + chk isa Bool && return chk + @info chk + return prop(chk[1]...) +end + +function constant_univariate(F_val, a) + uni = Univariate(F_val) + return uni(a) == F_val +end + +@test wrap_check(constant_univariate, itype(NTuple{2, Float64})) \ No newline at end of file diff --git a/test/auxiliary/series.jl b/test/auxiliary/series.jl new file mode 100644 index 0000000..56282ff --- /dev/null +++ b/test/auxiliary/series.jl @@ -0,0 +1,48 @@ +using OceanSonar +using Test + +@test series125(1) == [1] +@test series125(2) == [1, 2] +@test series125(3) == [1, 2, 5] +@test series125(4) == [1, 2, 5, 10] +@test series125(5) == [1, 2, 5, 10, 20] +@test series125(6) == [1, 2, 5, 10, 20, 50] +@test series125(7) == [1, 2, 5, 10, 20, 50, 100] +@test series125(8) == [1, 2, 5, 10, 20, 50, 100, 200] +@test series125(9) == [1, 2, 5, 10, 20, 50, 100, 200, 500] +@test series125(10) == [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000] +@test series125(11) == [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000] +@test series125(12) == [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000] +@test series125(13) == [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000] +@test series125(14) == [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000] +@test series125(15) == [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000] +@test series125(16) == [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000] +@test series125(17) == [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000] +@test series125(18) == [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000] +@test series125(19) == [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000] +@test series125(20) == [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000] +@test series125(21) == [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000, 5000000] +@test series125(22) == [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000, 5000000, 10000000] +@test series125(23) == [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000, 5000000, 10000000, 20000000] +@test series125(24) == [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000, 2000000, 5000000, 10000000, 20000000, 50000000] + +@test series125(1.0) == [1.0] +@test series125(2.0) == [1.0, 2.0] +@test series125(3.0) == [1.0, 2.0] +@test series125(4.0) == [1.0, 2.0] +@test series125(5.0) == [1.0, 2.0, 5.0] +@test series125(6.0) == [1.0, 2.0, 5.0] +@test series125(7.0) == [1.0, 2.0, 5.0] +@test series125(8.0) == [1.0, 2.0, 5.0] +@test series125(9.0) == [1.0, 2.0, 5.0] +@test series125(10.0) == [1.0, 2.0, 5.0, 10.0] +@test series125(11.0) == [1.0, 2.0, 5.0, 10.0] +@test series125(12.0) == [1.0, 2.0, 5.0, 10.0] +@test series125(13.0) == [1.0, 2.0, 5.0, 10.0] +@test series125(14.0) == [1.0, 2.0, 5.0, 10.0] +@test series125(15.0) == [1.0, 2.0, 5.0, 10.0] +@test series125(16.0) == [1.0, 2.0, 5.0, 10.0] +@test series125(17.0) == [1.0, 2.0, 5.0, 10.0] +@test series125(18.0) == [1.0, 2.0, 5.0, 10.0] +@test series125(19.0) == [1.0, 2.0, 5.0, 10.0] +@test series125(20.0) == [1.0, 2.0, 5.0, 10.0, 20.0] diff --git a/test/modelling/concreteness.jl b/test/modelling/concreteness.jl new file mode 100644 index 0000000..66167d5 --- /dev/null +++ b/test/modelling/concreteness.jl @@ -0,0 +1,19 @@ +using OceanSonar +using Test + +exclusions = [ + RationalFunctionApproximation +] + +for name in names(OceanSonar) + property = getproperty(OceanSonar, name) + + property in exclusions && continue + !(property isa Type) && continue + !(property <: OceanSonar.OcnSon) && continue + isabstracttype(property) && continue + + @testset "$name" begin + @test isconcretetype(property) + end +end \ No newline at end of file diff --git a/test/modelling/model_stability.jl b/test/modelling/model_stability.jl new file mode 100644 index 0000000..f6e70b0 --- /dev/null +++ b/test/modelling/model_stability.jl @@ -0,0 +1,101 @@ +using OceanSonar +using Test +using PropCheck +using InteractiveUtils + +function wrap_check(prop::Function, gen::Integrated) + chk = check(splat(prop), gen) + chk isa Bool && return chk + @info chk + return prop(chk[1]...) +end + +function model_parsers_equal( + type::Type{<:OceanSonar.Functor}, model::String, inputs... +) + vals = [ + type(model |> modeltitle)(inputs...) + type(model |> modelsnake)(inputs...) + type(model |> modelsymbol)(inputs...) + ] + val = type(model |> OceanSonar.modelval)(inputs...) + return if isnan(val) + isnan.(vals) |> all + else + all(val .== vals) + end +end + +function test_model_stability( + type::Type{<:OceanSonar.Functor}, gen::Integrated +) + for model in list_models(type) + @testset "$model" verbose = true begin + model_parsing_equality(args...) = model_parsers_equal( + type, model, args... + ) + + @test wrap_check(model_parsing_equality, gen) + end + end +end + +function construct_generator(::Type{T}) where T <: OceanSonar.Univariate + itype(Float64) +end + +function construct_generator(::Type{T}) where T <: OceanSonar.Bivariate + itype(NTuple{2, Float64}) +end + +function construct_generator(::Type{T}) where T <: OceanSonar.Trivariate + itype(NTuple{3, Float64}) +end + + +function test_functor_model_stability(type::Type{<:OceanSonar.Functor}) + if isconcretetype(type) + @testset "$type" verbose = true test_model_stability( + type, construct_generator(type) + ) + else + for subtype in subtypes(type) + test_functor_model_stability(subtype) + end + end +end + +test_functor_model_stability(OceanSonar.Functor) + +# for type in subtypes(OceanSonar.Functor) +# if isconcretetype(type) +# @testset "$type" verbose = true test_type_stability(type) +# else +# for subtype in subtypes(type) +# @testset "$subtype" verbose = true test_type_stability(subtype) +# end +# end +# end + +# univariate_types = ( +# altimetry, +# bathymetry +# ) + +# @testset "Univariates" begin +# for type in univariate_types +# @testset "$type" test_model_stability(type, itype(Float64)) +# end +# end + +# bivariate_types = ( +# atmosphere_celerity, +# ocean_celerity, +# seabed_celerity +# ) + +# @testset "Bivariates" begin +# for type in bivariate_types +# @testset "$type" test_model_stability(type, itype(Tuple{Float64, Float64})) +# end +# end \ No newline at end of file diff --git a/test/modelling/type_stability.jl b/test/modelling/type_stability.jl new file mode 100644 index 0000000..12cf802 --- /dev/null +++ b/test/modelling/type_stability.jl @@ -0,0 +1,21 @@ +using OceanSonar +using Test +using InteractiveUtils + +function test_type_stability(::Type{T}) where T <: OceanSonar.OcnSon + for model in list_models(T) + @testset "$model" begin + @test T(model) isa T + end + end +end + +for type in subtypes(OceanSonar.Functor) + if isconcretetype(type) + @testset "$type" verbose = true test_type_stability(type) + else + for subtype in subtypes(type) + @testset "$subtype" verbose = true test_type_stability(subtype) + end + end +end \ No newline at end of file diff --git a/test/processing/sonar_types.jl b/test/processing/sonar_types.jl new file mode 100644 index 0000000..f8573b9 --- /dev/null +++ b/test/processing/sonar_types.jl @@ -0,0 +1,103 @@ +using OceanSonar +using Test + +@testset "Subtypes" begin + @test Exposure <: Passive + @test Intercept <: Passive + @test Monostatic <: Active + @test Bistatic <: Active + + @test Passive <: SonarType + @test Active <: SonarType + + @test Exposure <: SonarType + @test Intercept <: SonarType + @test Monostatic <: SonarType + @test Bistatic <: SonarType +end + +@testset "Invalid Spectral Parameterisations" begin + @test_throws TypeError Exposure{CW} + @test_throws TypeError Exposure{FM} + @test_throws TypeError Intercept{NB} + @test_throws TypeError Intercept{BB} + @test_throws TypeError Monostatic{NB} + @test_throws TypeError Monostatic{BB} + @test_throws TypeError Bistatic{NB} + @test_throws TypeError Bistatic{BB} + + @test_throws TypeError Exposure{NBorCW} + @test_throws TypeError Intercept{NBorCW} + + @test_throws TypeError Active{NBorCW} + @test_throws TypeError Active{BBorFM} +end + +@testset "Specific Subtyping" begin + @test Exposure{NB} <: Passive + @test Exposure{BB} <: Passive + @test Intercept{CW} <: Passive + @test Intercept{FM} <: Passive + @test Monostatic{CW} <: Active + @test Monostatic{FM} <: Active + @test Bistatic{CW} <: Active + @test Bistatic{FM} <: Active + + @test Exposure{NB} <: Passive{NB} + @test Exposure{BB} <: Passive{BB} + @test Intercept{CW} <: Passive{CW} + @test Intercept{FM} <: Passive{FM} + @test Monostatic{CW} <: Active{CW} + @test Monostatic{FM} <: Active{FM} + @test Bistatic{CW} <: Active{CW} + @test Bistatic{FM} <: Active{FM} + + @test !(Exposure{NB} <: Passive{NBorCW}) + @test !(Exposure{BB} <: Passive{BBorFM}) + @test !(Intercept{CW} <: Passive{NBorCW}) + @test !(Intercept{FM} <: Passive{BBorFM}) + + @test Exposure{NB} <: Passive{<:NBorCW} + @test Exposure{BB} <: Passive{<:BBorFM} + @test Intercept{CW} <: Passive{<:NBorCW} + @test Intercept{FM} <: Passive{<:BBorFM} +end + +@testset "Generic Subtyping" begin + @test Passive{NBorCW} <: SonarType + @test Passive{BBorFM} <: SonarType + + @test Passive{NBorCW} <: SonarType{NBorCW} + @test Passive{BBorFM} <: SonarType{BBorFM} + + @test Passive{NBorCW} <: SonarType{<:NBorCW} + @test Passive{BBorFM} <: SonarType{<:BBorFM} + + @test Exposure{NB} <: SonarType + @test Exposure{BB} <: SonarType + @test Intercept{CW} <: SonarType + @test Intercept{FM} <: SonarType + @test Monostatic{CW} <: SonarType + @test Monostatic{FM} <: SonarType + @test Bistatic{CW} <: SonarType + @test Bistatic{FM} <: SonarType + + @test Exposure{NB} <: SonarType{NB} + @test Exposure{BB} <: SonarType{BB} + @test Intercept{CW} <: SonarType{CW} + @test Intercept{FM} <: SonarType{FM} + @test Monostatic{CW} <: SonarType{CW} + @test Monostatic{FM} <: SonarType{FM} + @test Bistatic{CW} <: SonarType{CW} + @test Bistatic{FM} <: SonarType{FM} + + @test !(Exposure{NB} <: SonarType{NBorCW}) + @test !(Exposure{BB} <: SonarType{BBorFM}) + @test !(Intercept{CW} <: SonarType{NBorCW}) + @test !(Intercept{FM} <: SonarType{BBorFM}) + + @test Exposure{NB} <: SonarType{<:NBorCW} + @test Exposure{BB} <: SonarType{<:BBorFM} + @test Intercept{CW} <: SonarType{<:NBorCW} + @test Intercept{FM} <: SonarType{<:BBorFM} +end \ No newline at end of file diff --git a/test/quality/ambiguities.jl b/test/quality/ambiguities.jl new file mode 100644 index 0000000..27ee7a5 --- /dev/null +++ b/test/quality/ambiguities.jl @@ -0,0 +1,5 @@ +using OceanSonar +using Test + +ambiguities = Test.detect_ambiguities(OceanSonar) +@test length(ambiguities) == 0 \ No newline at end of file diff --git a/test/quality/aqua.jl b/test/quality/aqua.jl new file mode 100644 index 0000000..c45c2af --- /dev/null +++ b/test/quality/aqua.jl @@ -0,0 +1,4 @@ +using OceanSonar +using Aqua + +Aqua.test_all(OceanSonar, ambiguities = false) \ No newline at end of file diff --git a/test/quality/docstrings.jl b/test/quality/docstrings.jl new file mode 100644 index 0000000..25be7c7 --- /dev/null +++ b/test/quality/docstrings.jl @@ -0,0 +1,4 @@ +using OceanSonar +using Base.Docs + +@test_broken Docs.undocumented_names(OceanSonar) |> isempty \ No newline at end of file diff --git a/test/quality/jet.jl b/test/quality/jet.jl new file mode 100644 index 0000000..cb29e54 --- /dev/null +++ b/test/quality/jet.jl @@ -0,0 +1,4 @@ +using OceanSonar +using JET + +JET.test_package(OceanSonar; target_defined_modules = true) \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl new file mode 100644 index 0000000..f9a5369 --- /dev/null +++ b/test/runtests.jl @@ -0,0 +1,26 @@ +using Test +using SafeTestsets + +@testset "OceanSonar.jl" verbose = true begin + @testset "Code Quality" verbose = true begin + @safetestset "Aqua.jl" include("quality/aqua.jl") + @safetestset "JET.jl" include("quality/jet.jl") + @safetestset "Ambiguities" include("quality/ambiguities.jl") + @safetestset "Docstrings" include("quality/docstrings.jl") + end + + @testset "Auxiliary" verbose = true begin + @safetestset "Series" include("auxiliary/series.jl") + @safetestset "Univariate" include("auxiliary/interpolation/univariate.jl") + end + + @testset "Modelling" verbose = true begin + @safetestset "Concreteness" include("modelling/concreteness.jl") + @safetestset "Type Stability" include("modelling/type_stability.jl") + @safetestset "Model Stability" include("modelling/model_stability.jl") + end + + @testset "Processing" verbose = true begin + @safetestset "Sonar Types" include("processing/sonar_types.jl") + end +end \ No newline at end of file