From ddc4454dcdbecf7f53d5ec59071f781ef38ec33b Mon Sep 17 00:00:00 2001 From: Taylor Denouden Date: Mon, 2 Dec 2024 13:48:50 -0800 Subject: [PATCH 01/11] Update linter, lint fixes --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 3ba50dc..8fe3839 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,6 +32,9 @@ ruff = "^0.8.1" [tool.ruff.lint.isort] combine-as-imports = true +[tool.ruff.lint.isort] +combine-as-imports = true + [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" From 70e1714764070cff544aba01cb1b34cd48b2f0dc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Oct 2023 00:55:35 +0000 Subject: [PATCH 02/11] Bump pillow from 9.3.0 to 10.0.1 Bumps [pillow](https://github.com/python-pillow/Pillow) from 9.3.0 to 10.0.1. - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) - [Commits](https://github.com/python-pillow/Pillow/compare/9.3.0...10.0.1) --- updated-dependencies: - dependency-name: pillow dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- pyproject.toml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 8fe3839..3ba50dc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,9 +32,6 @@ ruff = "^0.8.1" [tool.ruff.lint.isort] combine-as-imports = true -[tool.ruff.lint.isort] -combine-as-imports = true - [build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" From cda7227edac0927ddb2e4f4d284aeece3eb00204 Mon Sep 17 00:00:00 2001 From: Taylor Denouden Date: Mon, 2 Dec 2024 13:58:15 -0800 Subject: [PATCH 03/11] Add deps --- poetry.lock | 744 ++++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 5 + 2 files changed, 748 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index cad3b49..cf6009b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -11,6 +11,31 @@ files = [ {file = "altgraph-0.17.4.tar.gz", hash = "sha256:1b5afbb98f6c4dcadb2e2ae6ab9fa994bbb8c1d75f4fa96d340f9437ae454406"}, ] +[[package]] +name = "babel" +version = "2.16.0" +description = "Internationalization utilities" +optional = false +python-versions = ">=3.8" +files = [ + {file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"}, + {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, +] + +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] + +[[package]] +name = "certifi" +version = "2024.8.30" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, +] + [[package]] name = "cfgv" version = "3.4.0" @@ -22,6 +47,134 @@ files = [ {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, ] +[[package]] +name = "charset-normalizer" +version = "3.4.0" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc"}, + {file = "charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99"}, + {file = "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7"}, + {file = "charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"}, + {file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win32.whl", hash = "sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149"}, + {file = "charset_normalizer-3.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win32.whl", hash = "sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613"}, + {file = "charset_normalizer-3.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win32.whl", hash = "sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2"}, + {file = "charset_normalizer-3.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca"}, + {file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"}, + {file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"}, +] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + [[package]] name = "colorama" version = "0.4.6" @@ -88,6 +241,37 @@ files = [ six = "*" termcolor = "*" +[[package]] +name = "ghp-import" +version = "2.1.0" +description = "Copy your docs directly to the gh-pages branch." +optional = false +python-versions = "*" +files = [ + {file = "ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343"}, + {file = "ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619"}, +] + +[package.dependencies] +python-dateutil = ">=2.8.1" + +[package.extras] +dev = ["flake8", "markdown", "twine", "wheel"] + +[[package]] +name = "griffe" +version = "1.5.1" +description = "Signatures for entire Python programs. Extract the structure, the frame, the skeleton of your project, to generate API documentation or find breaking changes in your API." +optional = false +python-versions = ">=3.9" +files = [ + {file = "griffe-1.5.1-py3-none-any.whl", hash = "sha256:ad6a7980f8c424c9102160aafa3bcdf799df0e75f7829d75af9ee5aef656f860"}, + {file = "griffe-1.5.1.tar.gz", hash = "sha256:72964f93e08c553257706d6cd2c42d1c172213feb48b2be386f243380b405d4b"}, +] + +[package.dependencies] +colorama = ">=0.4" + [[package]] name = "identify" version = "2.6.3" @@ -102,6 +286,20 @@ files = [ [package.extras] license = ["ukkonen"] +[[package]] +name = "idna" +version = "3.10" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.6" +files = [ + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, +] + +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + [[package]] name = "importlib-metadata" version = "8.5.0" @@ -136,6 +334,23 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] +[[package]] +name = "jinja2" +version = "3.1.4" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"}, + {file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + [[package]] name = "loguru" version = "0.7.2" @@ -168,6 +383,253 @@ files = [ [package.dependencies] altgraph = ">=0.17" +[[package]] +name = "markdown" +version = "3.7" +description = "Python implementation of John Gruber's Markdown." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803"}, + {file = "markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} + +[package.extras] +docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] +testing = ["coverage", "pyyaml"] + +[[package]] +name = "markupsafe" +version = "3.0.2" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.9" +files = [ + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, +] + +[[package]] +name = "mergedeep" +version = "1.3.4" +description = "A deep merge function for 🐍." +optional = false +python-versions = ">=3.6" +files = [ + {file = "mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307"}, + {file = "mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8"}, +] + +[[package]] +name = "mkdocs" +version = "1.6.1" +description = "Project documentation with Markdown." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e"}, + {file = "mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2"}, +] + +[package.dependencies] +click = ">=7.0" +colorama = {version = ">=0.4", markers = "platform_system == \"Windows\""} +ghp-import = ">=1.0" +importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} +jinja2 = ">=2.11.1" +markdown = ">=3.3.6" +markupsafe = ">=2.0.1" +mergedeep = ">=1.3.4" +mkdocs-get-deps = ">=0.2.0" +packaging = ">=20.5" +pathspec = ">=0.11.1" +pyyaml = ">=5.1" +pyyaml-env-tag = ">=0.1" +watchdog = ">=2.0" + +[package.extras] +i18n = ["babel (>=2.9.0)"] +min-versions = ["babel (==2.9.0)", "click (==7.0)", "colorama (==0.4)", "ghp-import (==1.0)", "importlib-metadata (==4.4)", "jinja2 (==2.11.1)", "markdown (==3.3.6)", "markupsafe (==2.0.1)", "mergedeep (==1.3.4)", "mkdocs-get-deps (==0.2.0)", "packaging (==20.5)", "pathspec (==0.11.1)", "pyyaml (==5.1)", "pyyaml-env-tag (==0.1)", "watchdog (==2.0)"] + +[[package]] +name = "mkdocs-autorefs" +version = "1.2.0" +description = "Automatically link across pages in MkDocs." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_autorefs-1.2.0-py3-none-any.whl", hash = "sha256:d588754ae89bd0ced0c70c06f58566a4ee43471eeeee5202427da7de9ef85a2f"}, + {file = "mkdocs_autorefs-1.2.0.tar.gz", hash = "sha256:a86b93abff653521bda71cf3fc5596342b7a23982093915cb74273f67522190f"}, +] + +[package.dependencies] +Markdown = ">=3.3" +markupsafe = ">=2.0.1" +mkdocs = ">=1.1" + +[[package]] +name = "mkdocs-get-deps" +version = "0.2.0" +description = "MkDocs extension that lists all dependencies according to a mkdocs.yml file" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134"}, + {file = "mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=4.3", markers = "python_version < \"3.10\""} +mergedeep = ">=1.3.4" +platformdirs = ">=2.2.0" +pyyaml = ">=5.1" + +[[package]] +name = "mkdocs-material" +version = "9.5.47" +description = "Documentation that simply works" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_material-9.5.47-py3-none-any.whl", hash = "sha256:53fb9c9624e7865da6ec807d116cd7be24b3cb36ab31b1d1d1a9af58c56009a2"}, + {file = "mkdocs_material-9.5.47.tar.gz", hash = "sha256:fc3b7a8e00ad896660bd3a5cc12ca0cb28bdc2bcbe2a946b5714c23ac91b0ede"}, +] + +[package.dependencies] +babel = ">=2.10,<3.0" +colorama = ">=0.4,<1.0" +jinja2 = ">=3.0,<4.0" +markdown = ">=3.2,<4.0" +mkdocs = ">=1.6,<2.0" +mkdocs-material-extensions = ">=1.3,<2.0" +paginate = ">=0.5,<1.0" +pygments = ">=2.16,<3.0" +pymdown-extensions = ">=10.2,<11.0" +regex = ">=2022.4" +requests = ">=2.26,<3.0" + +[package.extras] +git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2.4,<2.0)"] +imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=10.2,<11.0)"] +recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2.0)", "mkdocs-rss-plugin (>=1.6,<2.0)"] + +[[package]] +name = "mkdocs-material-extensions" +version = "1.3.1" +description = "Extension pack for Python Markdown and MkDocs Material." +optional = false +python-versions = ">=3.8" +files = [ + {file = "mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31"}, + {file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"}, +] + +[[package]] +name = "mkdocstrings" +version = "0.27.0" +description = "Automatic documentation from sources, for MkDocs." +optional = false +python-versions = ">=3.9" +files = [ + {file = "mkdocstrings-0.27.0-py3-none-any.whl", hash = "sha256:6ceaa7ea830770959b55a16203ac63da24badd71325b96af950e59fd37366332"}, + {file = "mkdocstrings-0.27.0.tar.gz", hash = "sha256:16adca6d6b0a1f9e0c07ff0b02ced8e16f228a9d65a37c063ec4c14d7b76a657"}, +] + +[package.dependencies] +click = ">=7.0" +importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} +Jinja2 = ">=2.11.1" +Markdown = ">=3.6" +MarkupSafe = ">=1.1" +mkdocs = ">=1.4" +mkdocs-autorefs = ">=1.2" +platformdirs = ">=2.2" +pymdown-extensions = ">=6.3" +typing-extensions = {version = ">=4.1", markers = "python_version < \"3.10\""} + +[package.extras] +crystal = ["mkdocstrings-crystal (>=0.3.4)"] +python = ["mkdocstrings-python (>=0.5.2)"] +python-legacy = ["mkdocstrings-python-legacy (>=0.2.1)"] + +[[package]] +name = "mkdocstrings-python" +version = "1.12.2" +description = "A Python handler for mkdocstrings." +optional = false +python-versions = ">=3.9" +files = [ + {file = "mkdocstrings_python-1.12.2-py3-none-any.whl", hash = "sha256:7f7d40d6db3cb1f5d19dbcd80e3efe4d0ba32b073272c0c0de9de2e604eda62a"}, + {file = "mkdocstrings_python-1.12.2.tar.gz", hash = "sha256:7a1760941c0b52a2cd87b960a9e21112ffe52e7df9d0b9583d04d47ed2e186f3"}, +] + +[package.dependencies] +griffe = ">=0.49" +mkdocs-autorefs = ">=1.2" +mkdocstrings = ">=0.26" + [[package]] name = "nodeenv" version = "1.9.1" @@ -224,6 +686,32 @@ files = [ {file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"}, ] +[[package]] +name = "paginate" +version = "0.5.7" +description = "Divides large result sets into pages for easier browsing" +optional = false +python-versions = "*" +files = [ + {file = "paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591"}, + {file = "paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945"}, +] + +[package.extras] +dev = ["pytest", "tox"] +lint = ["black"] + +[[package]] +name = "pathspec" +version = "0.12.1" +description = "Utility library for gitignore style pattern matching of file paths." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, +] + [[package]] name = "pefile" version = "2024.8.26" @@ -381,6 +869,20 @@ nodeenv = ">=0.11.1" pyyaml = ">=5.1" virtualenv = ">=20.10.0" +[[package]] +name = "pygments" +version = "2.18.0" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, + {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + [[package]] name = "pyinstaller" version = "5.13.2" @@ -430,6 +932,24 @@ importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} packaging = ">=22.0" setuptools = ">=42.0.0" +[[package]] +name = "pymdown-extensions" +version = "10.12" +description = "Extension pack for Python Markdown." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pymdown_extensions-10.12-py3-none-any.whl", hash = "sha256:49f81412242d3527b8b4967b990df395c89563043bc51a3d2d7d500e52123b77"}, + {file = "pymdown_extensions-10.12.tar.gz", hash = "sha256:b0ee1e0b2bef1071a47891ab17003bfe5bf824a398e13f49f8ed653b699369a7"}, +] + +[package.dependencies] +markdown = ">=3.6" +pyyaml = "*" + +[package.extras] +extra = ["pygments (>=2.12)"] + [[package]] name = "pyqt6" version = "6.7.1" @@ -516,6 +1036,20 @@ tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + [[package]] name = "pywin32-ctypes" version = "0.2.3" @@ -589,6 +1123,144 @@ files = [ {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, ] +[[package]] +name = "pyyaml-env-tag" +version = "0.1" +description = "A custom YAML tag for referencing environment variables in YAML files. " +optional = false +python-versions = ">=3.6" +files = [ + {file = "pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069"}, + {file = "pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb"}, +] + +[package.dependencies] +pyyaml = "*" + +[[package]] +name = "regex" +version = "2024.11.6" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.8" +files = [ + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ff590880083d60acc0433f9c3f713c51f7ac6ebb9adf889c79a261ecf541aa91"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:658f90550f38270639e83ce492f27d2c8d2cd63805c65a13a14d36ca126753f0"}, + {file = "regex-2024.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:164d8b7b3b4bcb2068b97428060b2a53be050085ef94eca7f240e7947f1b080e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d22326fcdef5e08c154280b71163ced384b428343ae16a5ab2b3354aed12436e"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac758ef6aebfc8943560194e9fd0fa18bcb34d89fd8bd2af18183afd8da3a2"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:997d6a487ff00807ba810e0f8332c18b4eb8d29463cfb7c820dc4b6e7562d0cf"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:02a02d2bb04fec86ad61f3ea7f49c015a0681bf76abb9857f945d26159d2968c"}, + {file = "regex-2024.11.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f02f93b92358ee3f78660e43b4b0091229260c5d5c408d17d60bf26b6c900e86"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:06eb1be98df10e81ebaded73fcd51989dcf534e3c753466e4b60c4697a003b67"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:040df6fe1a5504eb0f04f048e6d09cd7c7110fef851d7c567a6b6e09942feb7d"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabbfc59f2c6edba2a6622c647b716e34e8e3867e0ab975412c5c2f79b82da2"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8447d2d39b5abe381419319f942de20b7ecd60ce86f16a23b0698f22e1b70008"}, + {file = "regex-2024.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:da8f5fc57d1933de22a9e23eec290a0d8a5927a5370d24bda9a6abe50683fe62"}, + {file = "regex-2024.11.6-cp310-cp310-win32.whl", hash = "sha256:b489578720afb782f6ccf2840920f3a32e31ba28a4b162e13900c3e6bd3f930e"}, + {file = "regex-2024.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:5071b2093e793357c9d8b2929dfc13ac5f0a6c650559503bb81189d0a3814519"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5478c6962ad548b54a591778e93cd7c456a7a29f8eca9c49e4f9a806dcc5d638"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c89a8cc122b25ce6945f0423dc1352cb9593c68abd19223eebbd4e56612c5b7"}, + {file = "regex-2024.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94d87b689cdd831934fa3ce16cc15cd65748e6d689f5d2b8f4f4df2065c9fa20"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1062b39a0a2b75a9c694f7a08e7183a80c63c0d62b301418ffd9c35f55aaa114"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:167ed4852351d8a750da48712c3930b031f6efdaa0f22fa1933716bfcd6bf4a3"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d548dafee61f06ebdb584080621f3e0c23fff312f0de1afc776e2a2ba99a74f"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a19f302cd1ce5dd01a9099aaa19cae6173306d1302a43b627f62e21cf18ac0"}, + {file = "regex-2024.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bec9931dfb61ddd8ef2ebc05646293812cb6b16b60cf7c9511a832b6f1854b55"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9714398225f299aa85267fd222f7142fcb5c769e73d7733344efc46f2ef5cf89"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:202eb32e89f60fc147a41e55cb086db2a3f8cb82f9a9a88440dcfc5d37faae8d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:4181b814e56078e9b00427ca358ec44333765f5ca1b45597ec7446d3a1ef6e34"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:068376da5a7e4da51968ce4c122a7cd31afaaec4fccc7856c92f63876e57b51d"}, + {file = "regex-2024.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ac10f2c4184420d881a3475fb2c6f4d95d53a8d50209a2500723d831036f7c45"}, + {file = "regex-2024.11.6-cp311-cp311-win32.whl", hash = "sha256:c36f9b6f5f8649bb251a5f3f66564438977b7ef8386a52460ae77e6070d309d9"}, + {file = "regex-2024.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:02e28184be537f0e75c1f9b2f8847dc51e08e6e171c6bde130b2687e0c33cf60"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:52fb28f528778f184f870b7cf8f225f5eef0a8f6e3778529bdd40c7b3920796a"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:fdd6028445d2460f33136c55eeb1f601ab06d74cb3347132e1c24250187500d9"}, + {file = "regex-2024.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:805e6b60c54bf766b251e94526ebad60b7de0c70f70a4e6210ee2891acb70bf2"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b85c2530be953a890eaffde05485238f07029600e8f098cdf1848d414a8b45e4"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb26437975da7dc36b7efad18aa9dd4ea569d2357ae6b783bf1118dabd9ea577"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:abfa5080c374a76a251ba60683242bc17eeb2c9818d0d30117b4486be10c59d3"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b7fa6606c2881c1db9479b0eaa11ed5dfa11c8d60a474ff0e095099f39d98e"}, + {file = "regex-2024.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c32f75920cf99fe6b6c539c399a4a128452eaf1af27f39bce8909c9a3fd8cbe"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:982e6d21414e78e1f51cf595d7f321dcd14de1f2881c5dc6a6e23bbbbd68435e"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a7c2155f790e2fb448faed6dd241386719802296ec588a8b9051c1f5c481bc29"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:149f5008d286636e48cd0b1dd65018548944e495b0265b45e1bffecce1ef7f39"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e5364a4502efca094731680e80009632ad6624084aff9a23ce8c8c6820de3e51"}, + {file = "regex-2024.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0a86e7eeca091c09e021db8eb72d54751e527fa47b8d5787caf96d9831bd02ad"}, + {file = "regex-2024.11.6-cp312-cp312-win32.whl", hash = "sha256:32f9a4c643baad4efa81d549c2aadefaeba12249b2adc5af541759237eee1c54"}, + {file = "regex-2024.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:a93c194e2df18f7d264092dc8539b8ffb86b45b899ab976aa15d48214138e81b"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"}, + {file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"}, + {file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"}, + {file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"}, + {file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"}, + {file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a51ccc315653ba012774efca4f23d1d2a8a8f278a6072e29c7147eee7da446b"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ad182d02e40de7459b73155deb8996bbd8e96852267879396fb274e8700190e3"}, + {file = "regex-2024.11.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba9b72e5643641b7d41fa1f6d5abda2c9a263ae835b917348fc3c928182ad467"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40291b1b89ca6ad8d3f2b82782cc33807f1406cf68c8d440861da6304d8ffbbd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cdf58d0e516ee426a48f7b2c03a332a4114420716d55769ff7108c37a09951bf"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a36fdf2af13c2b14738f6e973aba563623cb77d753bbbd8d414d18bfaa3105dd"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cee317bfc014c2419a76bcc87f071405e3966da434e03e13beb45f8aced1a6"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50153825ee016b91549962f970d6a4442fa106832e14c918acd1c8e479916c4f"}, + {file = "regex-2024.11.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea1bfda2f7162605f6e8178223576856b3d791109f15ea99a9f95c16a7636fb5"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:df951c5f4a1b1910f1a99ff42c473ff60f8225baa1cdd3539fe2819d9543e9df"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:072623554418a9911446278f16ecb398fb3b540147a7828c06e2011fa531e773"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:f654882311409afb1d780b940234208a252322c24a93b442ca714d119e68086c"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:89d75e7293d2b3e674db7d4d9b1bee7f8f3d1609428e293771d1a962617150cc"}, + {file = "regex-2024.11.6-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:f65557897fc977a44ab205ea871b690adaef6b9da6afda4790a2484b04293a5f"}, + {file = "regex-2024.11.6-cp38-cp38-win32.whl", hash = "sha256:6f44ec28b1f858c98d3036ad5d7d0bfc568bdd7a74f9c24e25f41ef1ebfd81a4"}, + {file = "regex-2024.11.6-cp38-cp38-win_amd64.whl", hash = "sha256:bb8f74f2f10dbf13a0be8de623ba4f9491faf58c24064f32b65679b021ed0001"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5704e174f8ccab2026bd2f1ab6c510345ae8eac818b613d7d73e785f1310f839"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:220902c3c5cc6af55d4fe19ead504de80eb91f786dc102fbd74894b1551f095e"}, + {file = "regex-2024.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7e351589da0850c125f1600a4c4ba3c722efefe16b297de54300f08d734fbf"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056b185ca113c88e18223183aa1a50e66507769c9640a6ff75859619d73957b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e34b51b650b23ed3354b5a07aab37034d9f923db2a40519139af34f485f77d0"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5670bce7b200273eee1840ef307bfa07cda90b38ae56e9a6ebcc9f50da9c469b"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:08986dce1339bc932923e7d1232ce9881499a0e02925f7402fb7c982515419ef"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93c0b12d3d3bc25af4ebbf38f9ee780a487e8bf6954c115b9f015822d3bb8e48"}, + {file = "regex-2024.11.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:764e71f22ab3b305e7f4c21f1a97e1526a25ebdd22513e251cf376760213da13"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f056bf21105c2515c32372bbc057f43eb02aae2fda61052e2f7622c801f0b4e2"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69ab78f848845569401469da20df3e081e6b5a11cb086de3eed1d48f5ed57c95"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:86fddba590aad9208e2fa8b43b4c098bb0ec74f15718bb6a704e3c63e2cef3e9"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:684d7a212682996d21ca12ef3c17353c021fe9de6049e19ac8481ec35574a70f"}, + {file = "regex-2024.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a03e02f48cd1abbd9f3b7e3586d97c8f7a9721c436f51a5245b3b9483044480b"}, + {file = "regex-2024.11.6-cp39-cp39-win32.whl", hash = "sha256:41758407fc32d5c3c5de163888068cfee69cb4c2be844e7ac517a52770f9af57"}, + {file = "regex-2024.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:b2837718570f95dd41675328e111345f9b7095d821bac435aac173ac80b19983"}, + {file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"}, +] + +[[package]] +name = "requests" +version = "2.32.3" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +files = [ + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + [[package]] name = "ruff" version = "0.8.1" @@ -765,6 +1437,34 @@ notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] +[[package]] +name = "typing-extensions" +version = "4.12.2" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] + +[[package]] +name = "urllib3" +version = "2.2.3" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"}, + {file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + [[package]] name = "virtualenv" version = "20.28.0" @@ -785,6 +1485,48 @@ platformdirs = ">=3.9.1,<5" docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.2,!=7.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=23.6)"] test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23.1)", "pytest (>=7.4)", "pytest-env (>=0.8.2)", "pytest-freezer (>=0.4.8)", "pytest-mock (>=3.11.1)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)", "setuptools (>=68)", "time-machine (>=2.10)"] +[[package]] +name = "watchdog" +version = "6.0.0" +description = "Filesystem events monitoring" +optional = false +python-versions = ">=3.9" +files = [ + {file = "watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26"}, + {file = "watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112"}, + {file = "watchdog-6.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3"}, + {file = "watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c"}, + {file = "watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2"}, + {file = "watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c"}, + {file = "watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948"}, + {file = "watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860"}, + {file = "watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0"}, + {file = "watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c"}, + {file = "watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134"}, + {file = "watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b"}, + {file = "watchdog-6.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e6f0e77c9417e7cd62af82529b10563db3423625c5fce018430b249bf977f9e8"}, + {file = "watchdog-6.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:90c8e78f3b94014f7aaae121e6b909674df5b46ec24d6bebc45c44c56729af2a"}, + {file = "watchdog-6.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e7631a77ffb1f7d2eefa4445ebbee491c720a5661ddf6df3498ebecae5ed375c"}, + {file = "watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881"}, + {file = "watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11"}, + {file = "watchdog-6.0.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7a0e56874cfbc4b9b05c60c8a1926fedf56324bb08cfbc188969777940aef3aa"}, + {file = "watchdog-6.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:e6439e374fc012255b4ec786ae3c4bc838cd7309a540e5fe0952d03687d8804e"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c"}, + {file = "watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2"}, + {file = "watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a"}, + {file = "watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680"}, + {file = "watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f"}, + {file = "watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282"}, +] + +[package.extras] +watchmedo = ["PyYAML (>=3.10)"] + [[package]] name = "win32-setctime" version = "1.1.0" @@ -821,4 +1563,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "34c7a6f5ce7ff0a284d3864aec17f8119ee39b27aa07f623341d55b478fd7289" +content-hash = "093598959b4b845a20734a44a74e6cd449f06d2b8263378905f52ebcfad8c682" diff --git a/pyproject.toml b/pyproject.toml index 3ba50dc..5d8e03b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,6 +29,11 @@ pyinstaller = "^5.6.2" pre-commit = "^3.3.3" ruff = "^0.8.1" +[tool.poetry.group.docs.dependencies] +mkdocs = "^1.6.1" +mkdocs-material = "^9.5.47" +mkdocstrings-python = "^1.12.2" + [tool.ruff.lint.isort] combine-as-imports = true From da510aae328ac5d259ef77b6adc0267cb6a85f3f Mon Sep 17 00:00:00 2001 From: Taylor Denouden Date: Mon, 2 Dec 2024 14:39:51 -0800 Subject: [PATCH 04/11] Add basic skeleton --- docs/cli.md | 0 docs/getting_started.md | 0 docs/index.md | 5 ++++ docs/installation.md | 0 mkdocs.yml | 66 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 71 insertions(+) create mode 100644 docs/cli.md create mode 100644 docs/getting_started.md create mode 100644 docs/index.md create mode 100644 docs/installation.md create mode 100644 mkdocs.yml diff --git a/docs/cli.md b/docs/cli.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/getting_started.md b/docs/getting_started.md new file mode 100644 index 0000000..e69de29 diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..a10c385 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,5 @@ +# Glint Mask Generator + +Glint Mask Generator is a simple utility for generating mask images from some source imagery. These masks correspond to +areas of glint and can used by structure-from-motion (SfM) software to replace non-useful glint areas with data from +overlapping imagery that are not glinty. \ No newline at end of file diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 0000000..e69de29 diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..fe654e9 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,66 @@ +site_name: GlintMaskGenerator +site_url: https://glint-mask-generator.readthedocs.io +repo_url: https://github.com/HakaiInstitute/GlintMaskGenerator +repo_name: HakaiInstitue/GlintMaskGenerator + +nav: + - Home: index.md + - Installation: installation.md + - Getting Started: getting_started.md + - Command Line Interface: cli.md + - Issue Tracker: 'https://github.com/HakaiInstitute/GlintMaskGenerator/issues' + +theme: + name: material + palette: + primary: yellow + icon: + logo: material/weather-sunny-off + features: + - navigation.indexes + +extra: + social: + - icon: fontawesome/brands/x-twitter + link: https://x.com/HakaiGeospatial + - icon: fontawesome/brands/instagram + link: https://www.instagram.com/hakaiinstitute + - icon: fontawesome/brands/linkedin + link: https://ca.linkedin.com/company/hakai-institute + + +watch: + - glint_mask_generator + +markdown_extensions: + - admonition + - attr_list + - def_list + - footnotes + - md_in_html + - pymdownx.caret + - pymdownx.details + - pymdownx.keys + - pymdownx.tilde + - tables + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg + - pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:pymdownx.superfences.fence_code_format + - pymdownx.tabbed: + alternate_style: true + - pymdownx.tasklist: + custom_checkbox: true + +plugins: + - search: + lang: en + - mkdocstrings: + handlers: + python: + options: + docstring_style: google From b5adff066c005f4f71ece779bdcc6e52c8bd61f6 Mon Sep 17 00:00:00 2001 From: Taylor Denouden Date: Mon, 2 Dec 2024 15:46:11 -0800 Subject: [PATCH 05/11] Use typer for CLI instead of fire --- .github/dependabot.yml | 2 +- glint_mask_generator/cli.py | 339 +++++++++++++++++++----------------- poetry.lock | 112 +++++++++--- pyproject.toml | 2 +- 4 files changed, 264 insertions(+), 191 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 2f1ffd2..bc50666 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -15,4 +15,4 @@ updates: - "*" update-types: - "minor" - - "patch" \ No newline at end of file + - "patch" diff --git a/glint_mask_generator/cli.py b/glint_mask_generator/cli.py index 43379f7..1118610 100644 --- a/glint_mask_generator/cli.py +++ b/glint_mask_generator/cli.py @@ -7,9 +7,10 @@ import os import sys -from typing import List +from pathlib import Path +from typing import Annotated, List -import fire +import typer from tqdm import tqdm from .maskers import ( @@ -20,168 +21,186 @@ RGBThresholdMasker, ) +app = typer.Typer() -class CLI(object): - def __init__(self, max_workers: int = min(4, os.cpu_count())): - """Command Line Interface Class for glint mask generators. - - Parameters - ---------- - max_workers - The maximum number of threads to use for processing. - """ - self.max_workers = max_workers - - @staticmethod - def _err_callback(path, exception): - tqdm.write(f"{path} failed with err:\n{exception}", file=sys.stderr) - - def _process(self, masker: Masker): - with tqdm(total=len(masker)) as progress: - masker( - max_workers=self.max_workers, - callback=lambda _: progress.update(1), - err_callback=self._err_callback, - ) - - def rgb_threshold( - self, - img_dir: str, - out_dir: str, - thresholds: List[float] = (1, 1, 0.875), - pixel_buffer: int = 0, - ) -> None: - """Generate masks for glint regions in RGB imagery using Tom Bell's binning - algorithm. - - Parameters - ---------- - img_dir - The path to a named input image or directory containing images. If img_dir - is a directory, all tif, jpg, jpeg, and png images in that directory will - be processed. - out_dir - The path to send your out image including the file name and type. - e.g. "/path/to/mask.png". out_dir must be a directory if img_dir is - specified as a directory. - thresholds - The pixel band thresholds indicating glint. Domain for values is (0.0, 1.0). - Default is [1, 1, 0.875]. - pixel_buffer - The pixel distance to buffer out the mask. Defaults to 0 (off). - - Returns - ------- - None - Side effects are that the mask is saved to the specified out_dir location. - """ - self._process(RGBThresholdMasker(img_dir, out_dir, thresholds, pixel_buffer)) - - def cir_threshold( - self, - img_dir: str, - out_dir: str, - thresholds: List[float] = (1, 1, 0.875, 1), - pixel_buffer: int = 0, - ) -> None: - """Generate masks for glint regions in 4 Band CIR imagery using Tom Bell's - binning algorithm. - - Parameters - ---------- - img_dir - The path to a named input image or directory containing images. If img_dir - is a directory, all tif, jpg, jpeg, and png images in that directory will - be processed. - out_dir - The path to send your out image including the file name and type. - e.g. "/path/to/mask.png". out_dir must be a directory if img_dir is - specified as a directory. - thresholds - The pixel band thresholds indicating glint. Domain for values is (0.0, 1.0). - Default is [1, 1, 0.875]. - pixel_buffer - The pixel distance to buffer out the mask. Defaults to 0 (off). - - Returns - ------- - None - Side effects are that the mask is saved to the specified out_dir location. - """ - self._process(CIRThresholdMasker(img_dir, out_dir, thresholds, pixel_buffer)) - - def p4ms_threshold( - self, - img_dir: str, - out_dir: str, - thresholds: List[float] = (0.875, 1, 1, 1, 1), - pixel_buffer: int = 0, - ) -> None: - """Generate masks for glint regions in multispectral imagery from the DJI camera - using Tom Bell's algorithm on the Blue image band. - - Parameters - ---------- - img_dir - The path to a named input image or directory containing images. If img_dir - is a directory, all tif, jpg, jpeg, and png images in that directory will - be processed. - out_dir - The path to send your out image including the file name and type. - e.g. "/path/to/mask.png". out_dir must be a directory if img_dir is - specified as a directory. - thresholds - The pixel band thresholds indicating glint. Domain for values is (0.0, 1.0). - Default is [0.875, 1, 1, 1, 1]. - pixel_buffer - The pixel distance to buffer out the mask. Defaults to 0 (off). - - Returns - ------- - None - Side effects are that the mask is saved to the specified out_dir location. - """ - self._process(P4MSThresholdMasker(img_dir, out_dir, thresholds, pixel_buffer)) - - def micasense_threshold( - self, - img_dir: str, - out_dir: str, - thresholds: List[float] = (0.875, 1, 1, 1, 1), - pixel_buffer: int = 0, - ) -> None: - """Generate masks for glint regions in multispectral imagery from the - Micasense camera using Tom Bell's algorithm on the blue image band. - - Parameters - ---------- - img_dir - The path to a named input image or directory containing images. - If img_dir is a directory, all tif, jpg, jpeg, and png images in that - directory will be processed. - out_dir - The path to send your out image including the file name and type. - e.g. "/path/to/mask.png". out_dir must be a directory if img_dir is - specified as a directory. - thresholds - The pixel band thresholds indicating glint. Domain for values is (0.0, 1.0). - Default is [0.875, 1, 1, 1, 1]. - pixel_buffer - The pixel distance to buffer out the mask. Defaults to 0 (off). - - Returns - ------- - None - Side effects are that the mask is saved to the specified out_dir location. - """ - self._process( - MicasenseRedEdgeThresholdMasker(img_dir, out_dir, thresholds, pixel_buffer) + +def _err_callback(path, exception): + tqdm.write(f"{path} failed with err:\n{exception}", file=sys.stderr) + + +def _process(masker: Masker, max_workers: int): + with tqdm(total=len(masker)) as progress: + masker( + max_workers=self.max_workers, + callback=lambda _: progress.update(1), + err_callback=_err_callback, ) -def main(): - fire.Fire(CLI) +@app.command() +def rgb_threshold( + img_dir: Annotated[ + Path, + typer.Argument( + exists=True, + file_okay=True, + dir_okay=True, + help="The path to a named input image or directory containing images. If img_dir is a directory, all tif, jpg, jpeg, and png images in that directory will be processed.", + ), + ], + out_dir: Annotated[ + Path, + typer.Argument( + exists=True, + file_okay=True, + dir_okay=True, + help='The path to send your out image including the file name and type. e.g. "/path/to/mask.png". out_dir must be a directory if img_dir is specified as a directory.', + ), + ], + thresholds: Annotated[ + List[float], + typer.Option( + help="The pixel band thresholds indicating glint. Domain for values is (0.0, 1.0)." + ), + ] = (0.875, 1, 1, 1, 1), + pixel_buffer: Annotated[ + int, typer.Option(help="The pixel distance to buffer out the mask.") + ] = 0, + max_workers: Annotated[ + int, typer.Option(help="The maximum number of threads to use for processing.") + ] = min(4, os.cpu_count()), +) -> None: + """ + Generate masks for glint regions in RGB imagery using Tom Bell's binning algorithm. + """ + _process( + RGBThresholdMasker(img_dir, out_dir, thresholds, pixel_buffer), max_workers + ) + + +@app.command() +def cir_threshold( + img_dir: Annotated[ + Path, + typer.Argument( + exists=True, + file_okay=True, + dir_okay=True, + help="The path to a named input image or directory containing images. If img_dir is a directory, all tif, jpg, jpeg, and png images in that directory will be processed.", + ), + ], + out_dir: Annotated[ + Path, + typer.Argument( + exists=True, + file_okay=True, + dir_okay=True, + help='The path to send your out image including the file name and type. e.g. "/path/to/mask.png". out_dir must be a directory if img_dir is specified as a directory.', + ), + ], + thresholds: Annotated[ + List[float], + typer.Option( + help="The pixel band thresholds indicating glint. Domain for values is (0.0, 1.0)." + ), + ] = (0.875, 1, 1, 1, 1), + pixel_buffer: Annotated[ + int, typer.Option(help="The pixel distance to buffer out the mask.") + ] = 0, + max_workers: Annotated[ + int, typer.Option(help="The maximum number of threads to use for processing.") + ] = min(4, os.cpu_count()), +) -> None: + """ + Generate masks for glint regions in 4 Band CIR imagery using Tom Bell's binning algorithm. + """ + _process( + CIRThresholdMasker(img_dir, out_dir, thresholds, pixel_buffer), max_workers + ) + + +@app.command() +def p4ms_threshold( + img_dir: Annotated[ + Path, + typer.Argument( + exists=True, + file_okay=True, + dir_okay=True, + help="The path to a named input image or directory containing images. If img_dir is a directory, all tif, jpg, jpeg, and png images in that directory will be processed.", + ), + ], + out_dir: Annotated[ + Path, + typer.Argument( + exists=True, + file_okay=True, + dir_okay=True, + help='The path to send your out image including the file name and type. e.g. "/path/to/mask.png". out_dir must be a directory if img_dir is specified as a directory.', + ), + ], + thresholds: Annotated[ + List[float], + typer.Option( + help="The pixel band thresholds indicating glint. Domain for values is (0.0, 1.0)." + ), + ] = (0.875, 1, 1, 1, 1), + pixel_buffer: Annotated[ + int, typer.Option(help="The pixel distance to buffer out the mask.") + ] = 0, + max_workers: Annotated[ + int, typer.Option(help="The maximum number of threads to use for processing.") + ] = min(4, os.cpu_count()), +) -> None: + """ + Generate masks for glint regions in multispectral imagery from the DJI camera using Tom Bell's algorithm on the Blue image band. + """ + _process( + P4MSThresholdMasker(img_dir, out_dir, thresholds, pixel_buffer), max_workers + ) + + +@app.command() +def micasense_threshold( + img_dir: Annotated[ + Path, + typer.Argument( + exists=True, + file_okay=True, + dir_okay=True, + help="The path to a named input image or directory containing images. If img_dir is a directory, all tif, jpg, jpeg, and png images in that directory will be processed.", + ), + ], + out_dir: Annotated[ + Path, + typer.Argument( + exists=True, + file_okay=True, + dir_okay=True, + help='The path to send your out image including the file name and type. e.g. "/path/to/mask.png". out_dir must be a directory if img_dir is specified as a directory.', + ), + ], + thresholds: Annotated[ + List[float], + typer.Option( + help="The pixel band thresholds indicating glint. Domain for values is (0.0, 1.0)." + ), + ] = (0.875, 1, 1, 1, 1), + pixel_buffer: Annotated[ + int, typer.Option(help="The pixel distance to buffer out the mask.") + ] = 0, + max_workers: Annotated[ + int, typer.Option(help="The maximum number of threads to use for processing.") + ] = min(4, os.cpu_count()), +) -> None: + """ + Generate masks for glint regions in multispectral imagery from the Micasense camera using Tom Bell's algorithm on the blue image band. + """ + _process( + MicasenseRedEdgeThresholdMasker(img_dir, out_dir, thresholds, pixel_buffer), + max_workers, + ) if __name__ == "__main__": - main() + app() diff --git a/poetry.lock b/poetry.lock index cf6009b..69de51c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -227,20 +227,6 @@ docs = ["furo (>=2024.8.6)", "sphinx (>=8.0.2)", "sphinx-autodoc-typehints (>=2. testing = ["covdefaults (>=2.3)", "coverage (>=7.6.1)", "diff-cover (>=9.2)", "pytest (>=8.3.3)", "pytest-asyncio (>=0.24)", "pytest-cov (>=5)", "pytest-mock (>=3.14)", "pytest-timeout (>=2.3.1)", "virtualenv (>=20.26.4)"] typing = ["typing-extensions (>=4.12.2)"] -[[package]] -name = "fire" -version = "0.5.0" -description = "A library for automatically generating command line interfaces." -optional = false -python-versions = "*" -files = [ - {file = "fire-0.5.0.tar.gz", hash = "sha256:a6b0d49e98c8963910021f92bba66f65ab440da2982b78eb1bbf95a0a34aacc6"}, -] - -[package.dependencies] -six = "*" -termcolor = "*" - [[package]] name = "ghp-import" version = "2.1.0" @@ -401,6 +387,30 @@ importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] testing = ["coverage", "pyyaml"] +[[package]] +name = "markdown-it-py" +version = "3.0.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = false +python-versions = ">=3.8" +files = [ + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, +] + +[package.dependencies] +mdurl = ">=0.1,<1.0" + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +code-style = ["pre-commit (>=3.0,<4.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins"] +profiling = ["gprof2dot"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + [[package]] name = "markupsafe" version = "3.0.2" @@ -471,6 +481,17 @@ files = [ {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, ] +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + [[package]] name = "mergedeep" version = "1.3.4" @@ -1261,6 +1282,25 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "rich" +version = "13.9.4" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"}, + {file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"}, +] + +[package.dependencies] +markdown-it-py = ">=2.2.0" +pygments = ">=2.13.0,<3.0.0" +typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.11\""} + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<9)"] + [[package]] name = "ruff" version = "0.8.1" @@ -1350,6 +1390,17 @@ enabler = ["pytest-enabler (>=2.2)"] test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] type = ["importlib_metadata (>=7.0.2)", "jaraco.develop (>=7.21)", "mypy (>=1.12,<1.14)", "pytest-mypy"] +[[package]] +name = "shellingham" +version = "1.5.4" +description = "Tool to Detect Surrounding Shell" +optional = false +python-versions = ">=3.7" +files = [ + {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, + {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, +] + [[package]] name = "six" version = "1.16.0" @@ -1361,20 +1412,6 @@ files = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] -[[package]] -name = "termcolor" -version = "2.5.0" -description = "ANSI color formatting for output in terminal" -optional = false -python-versions = ">=3.9" -files = [ - {file = "termcolor-2.5.0-py3-none-any.whl", hash = "sha256:37b17b5fc1e604945c2642c872a3764b5d547a48009871aea3edd3afa180afb8"}, - {file = "termcolor-2.5.0.tar.gz", hash = "sha256:998d8d27da6d48442e8e1f016119076b690d962507531df4890fcd2db2ef8a6f"}, -] - -[package.extras] -tests = ["pytest", "pytest-cov"] - [[package]] name = "tomli" version = "2.2.1" @@ -1437,6 +1474,23 @@ notebook = ["ipywidgets (>=6)"] slack = ["slack-sdk"] telegram = ["requests"] +[[package]] +name = "typer" +version = "0.14.0" +description = "Typer, build great CLIs. Easy to code. Based on Python type hints." +optional = false +python-versions = ">=3.7" +files = [ + {file = "typer-0.14.0-py3-none-any.whl", hash = "sha256:f476233a25770ab3e7b2eebf7c68f3bc702031681a008b20167573a4b7018f09"}, + {file = "typer-0.14.0.tar.gz", hash = "sha256:af58f737f8d0c0c37b9f955a6d39000b9ff97813afcbeef56af5e37cf743b45a"}, +] + +[package.dependencies] +click = ">=8.0.0" +rich = ">=10.11.0" +shellingham = ">=1.3.0" +typing-extensions = ">=3.7.4.3" + [[package]] name = "typing-extensions" version = "4.12.2" @@ -1563,4 +1617,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "093598959b4b845a20734a44a74e6cd449f06d2b8263378905f52ebcfad8c682" +content-hash = "20b9df3fccce61e8de9c0c49e804ca7096ef3acd8c6d238d726b8dd04d97fff5" diff --git a/pyproject.toml b/pyproject.toml index 5d8e03b..d0ca176 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,12 +16,12 @@ glint-mask = 'glint_mask_generator.cli:main' [tool.poetry.dependencies] python = ">=3.9,<3.13" numpy = "~=1.25.1" -fire = "~=0.5.0" Pillow = "~=10.4" scipy = "~=1.11.1" tqdm = "~=4.65" loguru = "~=0.7.0" pyqt6 = "^6.4.0" +typer = "^0.14.0" [tool.poetry.group.dev.dependencies] pytest = "^7.2.0" From bc2ca3970b7f6666bac2eb2a88ab4e7f8aadae64 Mon Sep 17 00:00:00 2001 From: Taylor Denouden Date: Mon, 2 Dec 2024 15:46:20 -0800 Subject: [PATCH 06/11] Fill in some docs info --- docs/cli.md | 0 docs/getting_started.md | 0 docs/index.md | 33 ++++++++++- docs/installation.md | 28 +++++++++ docs/usage.md | 126 ++++++++++++++++++++++++++++++++++++++++ mkdocs.yml | 3 +- 6 files changed, 185 insertions(+), 5 deletions(-) delete mode 100644 docs/cli.md delete mode 100644 docs/getting_started.md create mode 100644 docs/usage.md diff --git a/docs/cli.md b/docs/cli.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/getting_started.md b/docs/getting_started.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/index.md b/docs/index.md index a10c385..e5d36d4 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,5 +1,32 @@ # Glint Mask Generator -Glint Mask Generator is a simple utility for generating mask images from some source imagery. These masks correspond to -areas of glint and can used by structure-from-motion (SfM) software to replace non-useful glint areas with data from -overlapping imagery that are not glinty. \ No newline at end of file +Glint Mask Generator is a utility for generating mask images that correspond to the area of spectral glint in some +source imagery. Once generated, the masks can used by 3rd party structure-from-motion (SfM) software to replace glint +areas with data from overlapping imagery that are not glinty. + +
+ Glint +
+ + +## Features + +* Support for single and multi-file sensors. + * RGB, PhaseOne 4-band CIRs, MicaSense RedEdge, and Phantom 4 MS images currently supported. +* Pixel buffering around glint areas. +* Parallel processing. + +## License + +GlintMaskGenerator is released under +the [MIT license](https://raw.githubusercontent.com/tayden/GlintMaskGenerator/main/LICENSE.txt). + +## Contribute + +Please file a bug report using our +[GitHub Issue Tracker :material-github:](https://github.com/HakaiInstitute/GlintMaskGenerator/issues) if +you encounter any problems or would like to help add additional functionality. + +
+ Hakai +
diff --git a/docs/installation.md b/docs/installation.md index e69de29..cbd0fe3 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -0,0 +1,28 @@ +# Installation and Updating + +The library is currently available for Python versions 3.9 through 3.12. Support for +future versions will be added when possible. + +## GUI Tool + +1. Go to the [releases page](https://github.com/HakaiInstitute/glint-mask-tools/releases) +2. Download the latest release file for your operating system. +3. Extract the compressed binary files from the gzipped archive. +4. This archive contains a file named GlintMaskGenerator-v*.\*.\*.exe that provides a GUI interface to the glint mask generation program. +5. You can copy these files to any location that is convenient for you. + +## CLI Tool / Python Package + +Installation of the CLI and Python tool are achieved using the Python package manager PIP. + +### Installing + +```bash +pip install glint-mask-tools +``` + +### Update + +```bash +pip install --upgrade glint-mask-tools +``` diff --git a/docs/usage.md b/docs/usage.md new file mode 100644 index 0000000..12516fc --- /dev/null +++ b/docs/usage.md @@ -0,0 +1,126 @@ +# Usage + +## GUI + +In Windows, launch the GUI by double clicking the executable file. In Linux, you'll have to launch the GUI from the +terminal, e.g. `./GlintMaskGenerator`. + +For now, generating masks by passing directory paths containing images is the supported workflow. Be sure to change the +image type option when processing imagery for cameras other than RGB cameras (e.g. Micasense RedEdge or DJI P4MS +cameras). You will be notified of any +processing errors via a pop-up dialog. + +## CLI + +For information about the parameters expected by the CLI, run glint-mask --help in a bash terminal or command line +interface. All the functionality of the CLI is documented there. + +```bash +glint-mask --help + +# NAME +# glint-mask-v*.*.* +# +# SYNOPSIS +# glint-mask-v*.*.* - COMMAND | VALUE +# +# COMMANDS +# COMMAND is one of the following: +# +# cir_threshold +# Generate masks for glint regions in 4 Band CIR imagery using Tom Bell's binning algorithm. +# +# micasense_threshold +# Generate masks for glint regions in multispectral imagery from the Micasense camera using Tom Bell's algorithm on the blue image band. +# +# p4ms_threshold +# Generate masks for glint regions in multispectral imagery from the DJI camera using Tom Bell's algorithm on the Blue image band. +# +# process +# +# rgb_threshold +# Generate masks for glint regions in RGB imagery using Tom Bell's binning algorithm. +# +# VALUES +# VALUE is one of the following: +# +# max_workers +# The maximum number of threads to use for processing. +``` + +```bash +# Get addition parameters for one of the cameras/methods available +glint-mask-v*.*.* rgb_threshold --help + +# NAME +# glint-mask-v*.*.* rgb_threshold - Generate masks for glint regions in RGB imagery using Tom Bell's binning algorithm. +# +# SYNOPSIS +# glint-mask-v*.*.* rgb_threshold IMG_DIR OUT_DIR +# +# DESCRIPTION +# Generate masks for glint regions in RGB imagery using Tom Bell's binning algorithm. +# +# POSITIONAL ARGUMENTS +# IMG_DIR +# The path to a named input image or directory containing images. If img_dir is a directory, all tif, jpg, jpeg, and png images in that directory will be # processed. +# OUT_DIR +# The path to send your out image including the file name and type. e.g. "/path/to/mask.png". out_dir must be a directory if img_dir is specified as a # # # directory. +# +# FLAGS +# --thresholds=THRESHOLDS +# The pixel band thresholds indicating glint. Domain for values is (0.0, 1.0). Default is [1, 1, 0.875]. +# --pixel_buffer=PIXEL_BUFFER +# The pixel distance to buffer out the mask. Defaults to 0 (off). +# +# NOTES +# You can also use flags syntax for POSITIONAL ARGUMENTS +``` + +### Examples + +```bash +# Process rgb imagery directory with default parameters +glint-mask-v*.*.* rgb_threshold /path/to/dir/with/images/ /path/to/out_masks/dir/ + +# Process PhaseONE camera imagery with image bands split over multiple files +glint-mask-v*.*.* aco_threshold /path/to/dir/with/images/ /path/to/out_masks/dir/ + +# Process DJI P4MS imagery +glint-mask-v*.*.* p4ms_threshold /path/to/dir/with/images/ /path/to/out_masks/dir/ + +# Process Micasense RedEdge imagery +glint-mask-v*.*.* micasense_threshold /path/to/dir/with/images/ /path/to/out_masks/dir/ +``` + +## Python Package + +Installing the PyPi package allows integrating the mask generation workflow into existing python scripts with ease. + +```python +from glint_mask_generator import MicasenseRedEdgeThresholdMasker + +# Also available: P4MSThresholdMasker, RGBIntensityRatioMasker, RGBThresholdMasker + +masker = MicasenseRedEdgeThresholdMasker(img_dir="path/to/micasense/images/", mask_dir="path/to/output/dir/", + thresholds=(0.875, 1, 1, 1, 1), pixel_buffer=5) +masker.process(max_workers=5, callback=print, err_callback=print) +``` + +## Notes + +### Directory of images processing + +- All files with "jpg", "jpeg", "tif", "tiff" and "png" extensions will be processed. This can be extended as needed. + File extension matching is case-insensitive. +- Output mask files with be in the specified directory, and have the same name as the input file with "_mask" appended + to the end of the file name stem. The file type will match the input type. + +### Multi-band image processing + +- For imagery types where each band is spread over multiple files, a mask will be generated for all the sibling band + images. + - For example, if a mask is generated using a threshold on the blue band image, identical masks are saved for + sibling red, green, blue, nir, and red_edge bands as well. + - If thresholds are passed for multiple bands, these mask outputs combined with a union operator before being saved + for all the sibling bands associated with that capture event. diff --git a/mkdocs.yml b/mkdocs.yml index fe654e9..6e683c6 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -6,8 +6,7 @@ repo_name: HakaiInstitue/GlintMaskGenerator nav: - Home: index.md - Installation: installation.md - - Getting Started: getting_started.md - - Command Line Interface: cli.md + - Usage: usage.md - Issue Tracker: 'https://github.com/HakaiInstitute/GlintMaskGenerator/issues' theme: From 573e3603545f1ea69f8e27875f2042deb606f26e Mon Sep 17 00:00:00 2001 From: Taylor Denouden Date: Mon, 2 Dec 2024 16:40:50 -0800 Subject: [PATCH 07/11] Update CLI usage --- docs/usage.md | 91 +++++++++++++++++++------------------------------- pyproject.toml | 2 +- 2 files changed, 35 insertions(+), 58 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index 12516fc..1db666f 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -18,79 +18,56 @@ interface. All the functionality of the CLI is documented there. ```bash glint-mask --help -# NAME -# glint-mask-v*.*.* -# -# SYNOPSIS -# glint-mask-v*.*.* - COMMAND | VALUE -# -# COMMANDS -# COMMAND is one of the following: -# -# cir_threshold -# Generate masks for glint regions in 4 Band CIR imagery using Tom Bell's binning algorithm. -# -# micasense_threshold -# Generate masks for glint regions in multispectral imagery from the Micasense camera using Tom Bell's algorithm on the blue image band. -# -# p4ms_threshold -# Generate masks for glint regions in multispectral imagery from the DJI camera using Tom Bell's algorithm on the Blue image band. -# -# process -# -# rgb_threshold -# Generate masks for glint regions in RGB imagery using Tom Bell's binning algorithm. -# -# VALUES -# VALUE is one of the following: -# -# max_workers -# The maximum number of threads to use for processing. + Usage: glint-mask [OPTIONS] COMMAND [ARGS]... + +╭─ Options ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ --install-completion Install completion for the current shell. │ +│ --show-completion Show completion for the current shell, to copy it or customize the installation. │ +│ --help Show this message and exit. │ +╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭─ Commands ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ rgb-threshold Generate masks for glint regions in RGB imagery using Tom Bell's binning algorithm. │ +│ cir-threshold Generate masks for glint regions in 4 Band CIR imagery using Tom Bell's binning algorithm. │ +│ p4ms-threshold Generate masks for glint regions in multispectral imagery from the DJI camera using Tom Bell's algorithm on the Blue image band. │ +│ micasense-threshold Generate masks for glint regions in multispectral imagery from the Micasense camera using Tom Bell's algorithm on the blue image band. │ +╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ``` ```bash # Get addition parameters for one of the cameras/methods available -glint-mask-v*.*.* rgb_threshold --help - -# NAME -# glint-mask-v*.*.* rgb_threshold - Generate masks for glint regions in RGB imagery using Tom Bell's binning algorithm. -# -# SYNOPSIS -# glint-mask-v*.*.* rgb_threshold IMG_DIR OUT_DIR -# -# DESCRIPTION -# Generate masks for glint regions in RGB imagery using Tom Bell's binning algorithm. -# -# POSITIONAL ARGUMENTS -# IMG_DIR -# The path to a named input image or directory containing images. If img_dir is a directory, all tif, jpg, jpeg, and png images in that directory will be # processed. -# OUT_DIR -# The path to send your out image including the file name and type. e.g. "/path/to/mask.png". out_dir must be a directory if img_dir is specified as a # # # directory. -# -# FLAGS -# --thresholds=THRESHOLDS -# The pixel band thresholds indicating glint. Domain for values is (0.0, 1.0). Default is [1, 1, 0.875]. -# --pixel_buffer=PIXEL_BUFFER -# The pixel distance to buffer out the mask. Defaults to 0 (off). -# -# NOTES -# You can also use flags syntax for POSITIONAL ARGUMENTS +glint-mask rgb_threshold --help +❯ glint-mask rgb-threshold --help + + Usage: glint-mask rgb-threshold [OPTIONS] IMG_DIR OUT_DIR + + Generate masks for glint regions in RGB imagery using Tom Bell's binning algorithm. + +╭─ Arguments ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ * img_dir PATH The path to a named input image or directory containing images. If img_dir is a directory, all tif, jpg, jpeg, and png images in that directory will be processed. [default: None] [required] │ +│ * out_dir PATH The path to send your out image including the file name and type. e.g. "/path/to/mask.png". out_dir must be a directory if img_dir is specified as a directory. [default: None] [required] │ +╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭─ Options ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ --thresholds FLOAT The pixel band thresholds indicating glint. Domain for values is (0.0, 1.0). [default: 0.875, 1, 1, 1, 1] │ +│ --pixel-buffer INTEGER The pixel distance to buffer out the mask. [default: 0] │ +│ --max-workers INTEGER The maximum number of threads to use for processing. [default: 4] │ +│ --help Show this message and exit. │ +╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ``` ### Examples ```bash # Process rgb imagery directory with default parameters -glint-mask-v*.*.* rgb_threshold /path/to/dir/with/images/ /path/to/out_masks/dir/ +glint-mask rgb_threshold /path/to/dir/with/images/ /path/to/out_masks/dir/ # Process PhaseONE camera imagery with image bands split over multiple files -glint-mask-v*.*.* aco_threshold /path/to/dir/with/images/ /path/to/out_masks/dir/ +glint-mask aco_threshold /path/to/dir/with/images/ /path/to/out_masks/dir/ # Process DJI P4MS imagery -glint-mask-v*.*.* p4ms_threshold /path/to/dir/with/images/ /path/to/out_masks/dir/ +glint-mask p4ms_threshold /path/to/dir/with/images/ /path/to/out_masks/dir/ # Process Micasense RedEdge imagery -glint-mask-v*.*.* micasense_threshold /path/to/dir/with/images/ /path/to/out_masks/dir/ +glint-mask micasense_threshold /path/to/dir/with/images/ /path/to/out_masks/dir/ ``` ## Python Package diff --git a/pyproject.toml b/pyproject.toml index d0ca176..5c800f2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ packages = [ ] [tool.poetry.scripts] -glint-mask = 'glint_mask_generator.cli:main' +glint-mask = 'glint_mask_generator.cli:app' [tool.poetry.dependencies] python = ">=3.9,<3.13" From fe576b428e73d3c67784a61091ce931c9587402b Mon Sep 17 00:00:00 2001 From: Taylor Denouden Date: Tue, 3 Dec 2024 11:56:18 -0800 Subject: [PATCH 08/11] Add "How it works" --- docs/index.md | 20 ++++++++++++++++++-- mkdocs.yml | 34 +++++++++------------------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/docs/index.md b/docs/index.md index e5d36d4..94b1d16 100644 --- a/docs/index.md +++ b/docs/index.md @@ -8,14 +8,30 @@ areas with data from overlapping imagery that are not glinty. Glint - ## Features * Support for single and multi-file sensors. - * RGB, PhaseOne 4-band CIRs, MicaSense RedEdge, and Phantom 4 MS images currently supported. + * RGB, PhaseOne 4-band CIRs, MicaSense RedEdge, and Phantom 4 MS images currently supported. * Pixel buffering around glint areas. * Parallel processing. +## How it works + +Structure from Motion (SfM) photogrammetry offers an effective solution for handling masked or obscured areas in imagery +through its multi-image processing capabilities. As illustrated in the diagram, when two overlapping images contain +masks identifying problematic areas (such as glints or data gaps), SfM can leverage the complementary information from +both images during the alignment and mosaicking process. Where Image 1 contains masked regions, corresponding areas in +Image 2 may be unobstructed, and vice versa. + +This technique requires sufficient overlap between images to function effectively - typically >50% overlap is +recommended. During processing, SfM algorithms identify matching features between the images and can preferentially +select pixel data from unmasked regions when constructing the final output. However, in cases where all overlapping +images have masked regions in the same location, or where image overlap is insufficient, gaps may remain in the final +composite image. Despite these limitations, when properly executed with adequate image overlap, this approach can +produce a complete, artifact-free composite image. + +![How it works](images/howitdo.png) + ## License GlintMaskGenerator is released under diff --git a/mkdocs.yml b/mkdocs.yml index 6e683c6..3f672cb 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -16,7 +16,8 @@ theme: icon: logo: material/weather-sunny-off features: - - navigation.indexes + - navigation.instant + - navigation.instant.prefetch extra: social: @@ -26,40 +27,23 @@ extra: link: https://www.instagram.com/hakaiinstitute - icon: fontawesome/brands/linkedin link: https://ca.linkedin.com/company/hakai-institute - + consent: + title: Cookie consent + description: >- + We use cookies to recognize your repeated visits and preferences, as well + as to measure the effectiveness of our documentation and whether users + find what they're searching for. With your consent, you're helping us to + make our documentation better. watch: - glint_mask_generator markdown_extensions: - admonition - - attr_list - - def_list - - footnotes - - md_in_html - - pymdownx.caret - - pymdownx.details - - pymdownx.keys - - pymdownx.tilde - - tables - pymdownx.emoji: emoji_index: !!python/name:material.extensions.emoji.twemoji emoji_generator: !!python/name:material.extensions.emoji.to_svg - - pymdownx.superfences: - custom_fences: - - name: mermaid - class: mermaid - format: !!python/name:pymdownx.superfences.fence_code_format - - pymdownx.tabbed: - alternate_style: true - - pymdownx.tasklist: - custom_checkbox: true plugins: - search: lang: en - - mkdocstrings: - handlers: - python: - options: - docstring_style: google From 002457bfdcb981b2ded6ce816e37354d731818e5 Mon Sep 17 00:00:00 2001 From: Taylor Denouden Date: Tue, 3 Dec 2024 13:05:54 -0800 Subject: [PATCH 09/11] Fix code styling --- docs/usage.md | 17 ++++++++++------- mkdocs.yml | 12 ++++++++---- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/docs/usage.md b/docs/usage.md index 1db666f..d64c886 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -15,8 +15,8 @@ processing errors via a pop-up dialog. For information about the parameters expected by the CLI, run glint-mask --help in a bash terminal or command line interface. All the functionality of the CLI is documented there. -```bash -glint-mask --help +``` +❯ glint-mask --help Usage: glint-mask [OPTIONS] COMMAND [ARGS]... @@ -33,9 +33,8 @@ glint-mask --help ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ``` -```bash +``` # Get addition parameters for one of the cameras/methods available -glint-mask rgb_threshold --help ❯ glint-mask rgb-threshold --help Usage: glint-mask rgb-threshold [OPTIONS] IMG_DIR OUT_DIR @@ -74,13 +73,17 @@ glint-mask micasense_threshold /path/to/dir/with/images/ /path/to/out_masks/dir/ Installing the PyPi package allows integrating the mask generation workflow into existing python scripts with ease. -```python +```py from glint_mask_generator import MicasenseRedEdgeThresholdMasker # Also available: P4MSThresholdMasker, RGBIntensityRatioMasker, RGBThresholdMasker -masker = MicasenseRedEdgeThresholdMasker(img_dir="path/to/micasense/images/", mask_dir="path/to/output/dir/", - thresholds=(0.875, 1, 1, 1, 1), pixel_buffer=5) +masker = MicasenseRedEdgeThresholdMasker( + img_dir="path/to/micasense/images/", + mask_dir="path/to/output/dir/", + thresholds=(0.875, 1, 1, 1, 1), + pixel_buffer=5 +) masker.process(max_workers=5, callback=print, err_callback=print) ``` diff --git a/mkdocs.yml b/mkdocs.yml index 3f672cb..1c3d8fa 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -18,6 +18,7 @@ theme: features: - navigation.instant - navigation.instant.prefetch + - content.code.copy extra: social: @@ -43,7 +44,10 @@ markdown_extensions: - pymdownx.emoji: emoji_index: !!python/name:material.extensions.emoji.twemoji emoji_generator: !!python/name:material.extensions.emoji.to_svg - -plugins: - - search: - lang: en + - pymdownx.highlight: + anchor_linenums: true + line_spans: __span + pygments_lang_class: true + - pymdownx.inlinehilite + - pymdownx.snippets + - pymdownx.superfences From 2b0ecc713181fedbbdceda86bb3354118eaad889 Mon Sep 17 00:00:00 2001 From: Taylor Denouden Date: Tue, 3 Dec 2024 15:56:37 -0800 Subject: [PATCH 10/11] Add and improve docs --- docs/faq.md | 16 +++++ docs/how_it_works.md | 15 ++++ docs/index.md | 72 ++++++++++++++------ docs/usage.md | 159 ++++++++++++++++++++++++++++++++----------- mkdocs.yml | 6 ++ 5 files changed, 205 insertions(+), 63 deletions(-) create mode 100644 docs/faq.md create mode 100644 docs/how_it_works.md diff --git a/docs/faq.md b/docs/faq.md new file mode 100644 index 0000000..d0c0bc9 --- /dev/null +++ b/docs/faq.md @@ -0,0 +1,16 @@ +# Common Questions + +Here are some answers to the questions we get most often + +**What settings do you recommend?** + +The current threshold defaults in all interfaces are what we found works best, in our own testing. We recommend +starting there and making small adjustments as needed. It may be useful to process just a subset of your images for +testing purposes for the sake of quickly iterating and finding what works best for you. + +We typically use a pixel buffer of 2 to slightly expand our masked areas. + +**What number of workers should I use?** + +We typically use the default of 4. If you have a really powerful machine with a lot of memory, you might benefit from +increasing this value. If you're machine is grinding to a halt, lower it. \ No newline at end of file diff --git a/docs/how_it_works.md b/docs/how_it_works.md new file mode 100644 index 0000000..9d1f428 --- /dev/null +++ b/docs/how_it_works.md @@ -0,0 +1,15 @@ +# How it works + +Structure from Motion (SfM) photogrammetry offers an effective solution for handling masked or obscured areas in imagery +through its multi-image processing capabilities. As illustrated in the diagram, when two overlapping images contain +masks identifying problematic areas (such as glints or data gaps), SfM can leverage the complementary information from +both images during the alignment and mosaicking process. + +![How it works](images/howitdo.png) + +**Key Requirements for Optimal Results:** + +- Image overlap >50% recommended +- Consistent lighting conditions +- Proper camera settings +- Quality source imagery diff --git a/docs/index.md b/docs/index.md index 94b1d16..8575b89 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,36 +1,65 @@ # Glint Mask Generator Glint Mask Generator is a utility for generating mask images that correspond to the area of spectral glint in some -source imagery. Once generated, the masks can used by 3rd party structure-from-motion (SfM) software to replace glint +source imagery. Once generated, the masks can be used by 3rd party structure-from-motion (SfM) software to replace glint areas with data from overlapping imagery that are not glinty. +## Quick Start + +1. Download the [latest release](https://github.com/HakaiInstitute/glint-mask-tools/releases) for your platform +2. Launch the GUI application +3. Select your imagery type and input directory +4. Click Run to generate masks +
Glint
## Features -* Support for single and multi-file sensors. - * RGB, PhaseOne 4-band CIRs, MicaSense RedEdge, and Phantom 4 MS images currently supported. -* Pixel buffering around glint areas. -* Parallel processing. +### Multiple interfaces to suit your workflow: + - User-friendly GUI for interactive use + - CLI for automation and scripting + - Python package for integration into existing pipelines + +### Support for various camera types: + - RGB cameras + - PhaseOne 4-band CIRs + - MicaSense RedEdge + - DJI Phantom 4 MS + +### Advanced processing capabilities: + - Configurable band thresholds + - Pixel buffering around glint areas + - Parallel processing for improved performance + - Batch processing of multiple images -## How it works +## System Requirements -Structure from Motion (SfM) photogrammetry offers an effective solution for handling masked or obscured areas in imagery -through its multi-image processing capabilities. As illustrated in the diagram, when two overlapping images contain -masks identifying problematic areas (such as glints or data gaps), SfM can leverage the complementary information from -both images during the alignment and mosaicking process. Where Image 1 contains masked regions, corresponding areas in -Image 2 may be unobstructed, and vice versa. +- Operating Systems: + - Windows 10 or later + - Linux (modern distributions) +- Python 3.9 - 3.12 (for CLI/Python package) +- Minimum 4GB RAM +- Storage space: 100MB + space for your imagery -This technique requires sufficient overlap between images to function effectively - typically >50% overlap is -recommended. During processing, SfM algorithms identify matching features between the images and can preferentially -select pixel data from unmasked regions when constructing the final output. However, in cases where all overlapping -images have masked regions in the same location, or where image overlap is insufficient, gaps may remain in the final -composite image. Despite these limitations, when properly executed with adequate image overlap, this approach can -produce a complete, artifact-free composite image. +## Interface Comparison -![How it works](images/howitdo.png) +| Feature | GUI | CLI | Python Package | +|--------------------------|------------------|--------------------|------------------| +| Ease of Use | ★★★★★ | ★★★ | ★★★ | +| Automation Support | ★ | ★★★★★ | ★★★★★ | +| Integration Capabilities | ★ | ★★★★ | ★★★★★ | +| Customization | ★ | ★★★ | ★★★★★ | +| Learning Curve | Minimal | Moderate | Moderate | +| Best For | Individual users | Automation/Scripts | Custom workflows | + +## Next Steps + +- [How it Works](how_it_works.md) - How glint masking works +- [Installation Guide](installation.md) - Get started with installation +- [Usage Guide](usage.md) - Learn how to use the tool +- [FAQs](faq.md) - Answers to common questions ## License @@ -39,10 +68,9 @@ the [MIT license](https://raw.githubusercontent.com/tayden/GlintMaskGenerator/ma ## Contribute -Please file a bug report using our -[GitHub Issue Tracker :material-github:](https://github.com/HakaiInstitute/GlintMaskGenerator/issues) if -you encounter any problems or would like to help add additional functionality. +We welcome contributions! Please file bug reports, feature requests, or propose improvements using +our [GitHub Issue Tracker :material-github:](https://github.com/HakaiInstitute/GlintMaskGenerator/issues).
Hakai -
+ \ No newline at end of file diff --git a/docs/usage.md b/docs/usage.md index d64c886..4b0a61e 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -1,16 +1,89 @@ # Usage -## GUI +## General usage notes -In Windows, launch the GUI by double clicking the executable file. In Linux, you'll have to launch the GUI from the -terminal, e.g. `./GlintMaskGenerator`. +### Accepted file types -For now, generating masks by passing directory paths containing images is the supported workflow. Be sure to change the -image type option when processing imagery for cameras other than RGB cameras (e.g. Micasense RedEdge or DJI P4MS -cameras). You will be notified of any -processing errors via a pop-up dialog. +- Supported file types are currently .jpg, .jpeg, .tif, .tiff, and .png (all are case-insensitive). -## CLI +### Output files: + +- Saved in the specified output directory +- Named as original filename + "_mask" suffix and maintain the same file type as the input file + - Example: `image1.jpg` → `image1_mask.jpg` +- When processing multi-band imagery (e.g., Micasense RedEdge or P4MS), masks will be generated for all sibling band + images. + - This caters to the expectations of SfM software like Agisoft Metashape. + +### Understanding Pixel Thresholds + +Pixel thresholds determine how the software identifies glint in your imagery. The thresholds are specified as decimal +values between 0.0 and 1.0, which are then applied to the full range of possible pixel values in your image. + +#### How Thresholds Work + +For example, in an 8-bit image (pixel values 0-255): + +- A threshold of 0.5 means: pixel value > (0.5 × 255) = 127 +- A threshold of 0.875 means: pixel value > (0.875 × 255) = 223 + +#### Multiple Band Behavior + +When multiple bands are present (like in RGB images): + +1. Each band is checked against its respective threshold +2. If ANY band exceeds its threshold, that pixel is marked as glint +3. The resulting masks are combined using a union operation + +#### Example + +For an RGB image with thresholds: + +- Blue: 0.875 (triggers at values > 223) +- Green: 1.000 (never triggers) +- Red: 1.000 (never triggers) + +A pixel will be marked as glint if its blue value exceeds 223, regardless of its red and green values. + +## Interfaces + +### GUI + +The GUI version provides an intuitive interface for generating glint masks from imagery. Launch the application by +double-clicking the executable file on Windows, or running `./GlintMaskGenerator` from the terminal on Linux. + +#### Main Options + +1. **Imagery Type Selection** + - Choose the appropriate camera/sensor type for your imagery: + - RGB: Standard RGB camera imagery + - CIR: 4-band Color Infrared imagery + - P4MS: DJI Phantom 4 Multispectral camera imagery + - MicasenseRedEdge: Micasense RedEdge multispectral camera imagery + +2. **Directory Selection** + - Image Directory: Select the input folder containing your imagery files using the "..." button + - Output Directory: Choose where the generated mask files will be saved + +3. **Band Thresholds** + - Adjust thresholds for each available band using the sliders + - Range: 0.0 to 1.0 (higher values = less masking) + - Default values: + - Blue: 0.875 + - Green: 1.000 + - Red: 1.000 + - Red Edge: 1.000 (when applicable) + - NIR: 1.000 (when applicable) + - Use the "Reset all" button to restore default values + +4. **Processing Options** + - Pixel Buffer Radius: Adjusts the expansion of masked regions (default: 0) + - Max Workers: Controls the number of parallel processing threads (default: 4) + +5. **Processing** + - Click "Run" to start generating masks + +### CLI For information about the parameters expected by the CLI, run glint-mask --help in a bash terminal or command line interface. All the functionality of the CLI is documented there. @@ -53,23 +126,45 @@ interface. All the functionality of the CLI is documented there. ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ``` -### Examples +#### CLI Examples ```bash -# Process rgb imagery directory with default parameters -glint-mask rgb_threshold /path/to/dir/with/images/ /path/to/out_masks/dir/ - -# Process PhaseONE camera imagery with image bands split over multiple files -glint-mask aco_threshold /path/to/dir/with/images/ /path/to/out_masks/dir/ - -# Process DJI P4MS imagery -glint-mask p4ms_threshold /path/to/dir/with/images/ /path/to/out_masks/dir/ - -# Process Micasense RedEdge imagery -glint-mask micasense_threshold /path/to/dir/with/images/ /path/to/out_masks/dir/ +# Process RGB imagery directory with default parameters +# - Uses default thresholds (Blue: 0.875, Green: 1.0, Red: 1.0) +# - No pixel buffer +# - 4 worker threads +glint-mask rgb-threshold /path/to/dir/with/images/ /path/to/out_masks/dir/ + +# Process PhaseONE CIR imagery with custom settings +# - Specify custom thresholds with --thresholds +# - Add 2-pixel buffer with --pixel-buffer +# - Use 8 worker threads with --max-workers +glint-mask cir-threshold \ + --thresholds 0.8,0.9,0.9,0.9 \ + --pixel-buffer 2 \ + --max-workers 8 \ + /path/to/dir/with/images/ \ + /path/to/out_masks/dir/ + +# Process DJI P4MS imagery with minimal masking +# - Higher thresholds mean less aggressive masking +# - Useful for scenes with minimal glint +glint-mask p4ms-threshold \ + --thresholds 0.95,1.0,1.0,1.0,1.0 \ + /path/to/dir/with/images/ \ + /path/to/out_masks/dir/ + +# Process Micasense RedEdge imagery with aggressive masking +# - Lower thresholds mean more aggressive masking +# - Larger pixel buffer for broader masked areas +glint-mask micasense-threshold \ + --thresholds 0.8,0.9,0.9,0.9,0.9 \ + --pixel-buffer 5 \ + /path/to/dir/with/images/ \ + /path/to/out_masks/dir/ ``` -## Python Package +### Python Library Installing the PyPi package allows integrating the mask generation workflow into existing python scripts with ease. @@ -79,28 +174,10 @@ from glint_mask_generator import MicasenseRedEdgeThresholdMasker # Also available: P4MSThresholdMasker, RGBIntensityRatioMasker, RGBThresholdMasker masker = MicasenseRedEdgeThresholdMasker( - img_dir="path/to/micasense/images/", + img_dir="path/to/micasense/images/", mask_dir="path/to/output/dir/", - thresholds=(0.875, 1, 1, 1, 1), + thresholds=(0.875, 1, 1, 1, 1), pixel_buffer=5 ) masker.process(max_workers=5, callback=print, err_callback=print) ``` - -## Notes - -### Directory of images processing - -- All files with "jpg", "jpeg", "tif", "tiff" and "png" extensions will be processed. This can be extended as needed. - File extension matching is case-insensitive. -- Output mask files with be in the specified directory, and have the same name as the input file with "_mask" appended - to the end of the file name stem. The file type will match the input type. - -### Multi-band image processing - -- For imagery types where each band is spread over multiple files, a mask will be generated for all the sibling band - images. - - For example, if a mask is generated using a threshold on the blue band image, identical masks are saved for - sibling red, green, blue, nir, and red_edge bands as well. - - If thresholds are passed for multiple bands, these mask outputs combined with a union operator before being saved - for all the sibling bands associated with that capture event. diff --git a/mkdocs.yml b/mkdocs.yml index 1c3d8fa..657d981 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -5,8 +5,10 @@ repo_name: HakaiInstitue/GlintMaskGenerator nav: - Home: index.md + - How it works: how_it_works.md - Installation: installation.md - Usage: usage.md + - FAQs: faq.md - Issue Tracker: 'https://github.com/HakaiInstitute/GlintMaskGenerator/issues' theme: @@ -51,3 +53,7 @@ markdown_extensions: - pymdownx.inlinehilite - pymdownx.snippets - pymdownx.superfences + +plugins: + - search: + lang: en From 5c1949732299aa9683d6e2c9a6974808710fdcf2 Mon Sep 17 00:00:00 2001 From: Taylor Denouden Date: Tue, 3 Dec 2024 16:02:39 -0800 Subject: [PATCH 11/11] Add docs config files --- .readthedocs.yaml | 19 +++++++++++++++++++ docs/requirements.txt | 2 ++ 2 files changed, 21 insertions(+) create mode 100644 .readthedocs.yaml create mode 100644 docs/requirements.txt diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..65f478b --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,19 @@ +version: 2 + +build: + os: "ubuntu-20.04" + tools: + python: "3.9" + +mkdocs: + configuration: mkdocs.yml + fail_on_warning: false + +python: + # Install our python package before building the docs + install: + - requirements: docs/requirements.txt + - method: pip + path: . + extra_requirements: + - docs diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..fc62ac1 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +mkdocs-material==9.5.47 +mkdocstrings-python