diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..9b322366 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,7 @@ +README.Rmd +README.md +docs/ +input/ +renv/library/ +renv/sandbox/ +renv/staging/ diff --git a/.gitignore b/.gitignore index fd3ee050..869ac903 100644 --- a/.gitignore +++ b/.gitignore @@ -6,8 +6,8 @@ .Rproj.user/ # knitr and R markdown default cache directories -/*_cache/ -/cache/ +*_cache/ +cache/ # Temporary files created by R markdown *.utf8.md @@ -21,11 +21,3 @@ *.xlsx *.xlsm *.html - -# Ignore python environment -pipenv/ -pipenv - -# Reporting files -*.html - diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 75483c8c..7ef5ebca 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,7 +2,7 @@ # R specific hooks: https://github.com/lorenzwalthert/precommit repos: - repo: https://github.com/lorenzwalthert/precommit - rev: v0.3.2.9013 + rev: v0.3.2.9027 hooks: - id: style-files args: [--style_pkg=styler, --style_fun=tidyverse_style] @@ -12,7 +12,7 @@ repos: - id: no-browser-statement - id: no-debug-statement - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v4.5.0 hooks: - id: check-added-large-files args: ['--maxkb=200'] diff --git a/.renvignore b/.renvignore index 43ae3942..742bbcf8 100644 --- a/.renvignore +++ b/.renvignore @@ -1,5 +1,6 @@ README.Rmd pipeline/00-ingest.R -pipeline/06-export.R -pipeline/07-api.R -reports/ \ No newline at end of file +pipeline/07-export.R +pipeline/08-api.R +reports/* +cache/* diff --git a/Dockerfile b/Dockerfile index 549c5736..7e9f87f8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,53 +1,50 @@ -FROM rocker/r-ver:4.3.1 +FROM rocker/r-ver:4.3.2 + +# Set the working directory to setup. Uses a dedicated directory instead of +# root since otherwise renv will try to scan every subdirectory +WORKDIR /setup # Use PPM for binary installs ENV RENV_CONFIG_REPOS_OVERRIDE "https://packagemanager.posit.co/cran/__linux__/jammy/latest" +ENV RENV_CONFIG_SANDBOX_ENABLED FALSE ENV RENV_PATHS_LIBRARY renv/library +ENV RENV_PATHS_CACHE /setup/cache # Install system dependencies -RUN apt-get update && apt-get install --no-install-recommends -y \ - libcurl4-openssl-dev libssl-dev libxml2-dev libgit2-dev git \ - libudunits2-dev python3-dev python3-pip libgdal-dev libgeos-dev \ - libproj-dev libfontconfig1-dev libharfbuzz-dev libfribidi-dev pandoc \ - curl gdebi-core +RUN apt-get update && \ + apt-get install --no-install-recommends -y \ + libcurl4-openssl-dev libssl-dev libxml2-dev libgit2-dev git \ + libudunits2-dev python3-dev python3-pip libgdal-dev libgeos-dev \ + libproj-dev libfontconfig1-dev libharfbuzz-dev libfribidi-dev pandoc \ + curl gdebi-core && \ + rm -rf /var/lib/apt/lists/* # Install Quarto RUN curl -o quarto-linux-amd64.deb -L \ https://github.com/quarto-dev/quarto-cli/releases/download/v1.3.450/quarto-1.3.450-linux-amd64.deb RUN gdebi -n quarto-linux-amd64.deb -# Install pipenv for Python dependencies -RUN pip install pipenv - -# Copy pipenv files into the image. The reason this is a separate step from -# the later step that adds files from the working directory is because we want -# to avoid having to reinstall dependencies every time a file in the directory -# changes, as Docker will bust the cache of every layer following a layer that -# needs to change -COPY Pipfile . -COPY Pipfile.lock . - -# Install Python dependencies -RUN pipenv install --system --deploy +# Install pipeline Python dependencies globally +RUN pip install --no-cache-dir dvc[s3] # Copy R bootstrap files into the image -COPY renv.lock . +COPY renv.lock .Rprofile ./ COPY renv/profiles/reporting/renv.lock reporting-renv.lock -COPY .Rprofile . COPY renv/ renv/ -# Install R dependencies -RUN Rscript -e 'renv::restore()' +# Install R dependencies. Restoring renv first ensures that it's +# using the same version as recorded in the lockfile +RUN Rscript -e 'renv::restore(packages = "renv"); renv::restore()' RUN Rscript -e 'renv::restore(lockfile = "reporting-renv.lock")' +# Set the working directory to the app dir +WORKDIR /model-res-avm/ + # Copy the directory into the container -ADD ./ model-res-avm/ +COPY ./ . # Copy R dependencies into the app directory -RUN rm -Rf model-res-avm/renv -RUN mv renv model-res-avm/ - -# Set the working directory to the app dir -WORKDIR model-res-avm/ +RUN rm -Rf /model-res-avm/renv && \ + mv /setup/renv /model-res-avm/renv CMD dvc pull && dvc repro diff --git a/Pipfile b/Pipfile deleted file mode 100644 index adab27a6..00000000 --- a/Pipfile +++ /dev/null @@ -1,12 +0,0 @@ -[[source]] -url = "https://pypi.org/simple" -verify_ssl = true -name = "pypi" - -[packages] -"dvc[s3]" = "*" - -[dev-packages] - -[requires] -python_version = "3.10" diff --git a/Pipfile.lock b/Pipfile.lock deleted file mode 100644 index 62be65af..00000000 --- a/Pipfile.lock +++ /dev/null @@ -1,1705 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "7e938cdc53ed747f58be3fc36f603ee425a0de2c17342406daafbca67db03cb0" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.10" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "aiobotocore": { - "extras": [ - "boto3" - ], - "hashes": [ - "sha256:506591374cc0aee1bdf0ebe290560424a24af176dfe2ea7057fe1df97c4f0467", - "sha256:aec605df77ce4635a0479b50fd849aa6b640900f7b295021ecca192e1140e551" - ], - "markers": "python_version >= '3.8'", - "version": "==2.7.0" - }, - "aiohttp": { - "hashes": [ - "sha256:002f23e6ea8d3dd8d149e569fd580c999232b5fbc601c48d55398fbc2e582e8c", - "sha256:01770d8c04bd8db568abb636c1fdd4f7140b284b8b3e0b4584f070180c1e5c62", - "sha256:0912ed87fee967940aacc5306d3aa8ba3a459fcd12add0b407081fbefc931e53", - "sha256:0cccd1de239afa866e4ce5c789b3032442f19c261c7d8a01183fd956b1935349", - "sha256:0fa375b3d34e71ccccf172cab401cd94a72de7a8cc01847a7b3386204093bb47", - "sha256:13da35c9ceb847732bf5c6c5781dcf4780e14392e5d3b3c689f6d22f8e15ae31", - "sha256:14cd52ccf40006c7a6cd34a0f8663734e5363fd981807173faf3a017e202fec9", - "sha256:16d330b3b9db87c3883e565340d292638a878236418b23cc8b9b11a054aaa887", - "sha256:1bed815f3dc3d915c5c1e556c397c8667826fbc1b935d95b0ad680787896a358", - "sha256:1d84166673694841d8953f0a8d0c90e1087739d24632fe86b1a08819168b4566", - "sha256:1f13f60d78224f0dace220d8ab4ef1dbc37115eeeab8c06804fec11bec2bbd07", - "sha256:229852e147f44da0241954fc6cb910ba074e597f06789c867cb7fb0621e0ba7a", - "sha256:253bf92b744b3170eb4c4ca2fa58f9c4b87aeb1df42f71d4e78815e6e8b73c9e", - "sha256:255ba9d6d5ff1a382bb9a578cd563605aa69bec845680e21c44afc2670607a95", - "sha256:2817b2f66ca82ee699acd90e05c95e79bbf1dc986abb62b61ec8aaf851e81c93", - "sha256:2b8d4e166e600dcfbff51919c7a3789ff6ca8b3ecce16e1d9c96d95dd569eb4c", - "sha256:2d5b785c792802e7b275c420d84f3397668e9d49ab1cb52bd916b3b3ffcf09ad", - "sha256:3161ce82ab85acd267c8f4b14aa226047a6bee1e4e6adb74b798bd42c6ae1f80", - "sha256:33164093be11fcef3ce2571a0dccd9041c9a93fa3bde86569d7b03120d276c6f", - "sha256:39a312d0e991690ccc1a61f1e9e42daa519dcc34ad03eb6f826d94c1190190dd", - "sha256:3b2ab182fc28e7a81f6c70bfbd829045d9480063f5ab06f6e601a3eddbbd49a0", - "sha256:3c68330a59506254b556b99a91857428cab98b2f84061260a67865f7f52899f5", - "sha256:3f0e27e5b733803333bb2371249f41cf42bae8884863e8e8965ec69bebe53132", - "sha256:3f5c7ce535a1d2429a634310e308fb7d718905487257060e5d4598e29dc17f0b", - "sha256:3fd194939b1f764d6bb05490987bfe104287bbf51b8d862261ccf66f48fb4096", - "sha256:41bdc2ba359032e36c0e9de5a3bd00d6fb7ea558a6ce6b70acedf0da86458321", - "sha256:41d55fc043954cddbbd82503d9cc3f4814a40bcef30b3569bc7b5e34130718c1", - "sha256:42c89579f82e49db436b69c938ab3e1559e5a4409eb8639eb4143989bc390f2f", - "sha256:45ad816b2c8e3b60b510f30dbd37fe74fd4a772248a52bb021f6fd65dff809b6", - "sha256:4ac39027011414dbd3d87f7edb31680e1f430834c8cef029f11c66dad0670aa5", - "sha256:4d4cbe4ffa9d05f46a28252efc5941e0462792930caa370a6efaf491f412bc66", - "sha256:4fcf3eabd3fd1a5e6092d1242295fa37d0354b2eb2077e6eb670accad78e40e1", - "sha256:5d791245a894be071d5ab04bbb4850534261a7d4fd363b094a7b9963e8cdbd31", - "sha256:6c43ecfef7deaf0617cee936836518e7424ee12cb709883f2c9a1adda63cc460", - "sha256:6c5f938d199a6fdbdc10bbb9447496561c3a9a565b43be564648d81e1102ac22", - "sha256:6e2f9cc8e5328f829f6e1fb74a0a3a939b14e67e80832975e01929e320386b34", - "sha256:713103a8bdde61d13490adf47171a1039fd880113981e55401a0f7b42c37d071", - "sha256:71783b0b6455ac8f34b5ec99d83e686892c50498d5d00b8e56d47f41b38fbe04", - "sha256:76b36b3124f0223903609944a3c8bf28a599b2cc0ce0be60b45211c8e9be97f8", - "sha256:7bc88fc494b1f0311d67f29fee6fd636606f4697e8cc793a2d912ac5b19aa38d", - "sha256:7ee912f7e78287516df155f69da575a0ba33b02dd7c1d6614dbc9463f43066e3", - "sha256:86f20cee0f0a317c76573b627b954c412ea766d6ada1a9fcf1b805763ae7feeb", - "sha256:89341b2c19fb5eac30c341133ae2cc3544d40d9b1892749cdd25892bbc6ac951", - "sha256:8a9b5a0606faca4f6cc0d338359d6fa137104c337f489cd135bb7fbdbccb1e39", - "sha256:8d399dade330c53b4106160f75f55407e9ae7505263ea86f2ccca6bfcbdb4921", - "sha256:8e31e9db1bee8b4f407b77fd2507337a0a80665ad7b6c749d08df595d88f1cf5", - "sha256:90c72ebb7cb3a08a7f40061079817133f502a160561d0675b0a6adf231382c92", - "sha256:918810ef188f84152af6b938254911055a72e0f935b5fbc4c1a4ed0b0584aed1", - "sha256:93c15c8e48e5e7b89d5cb4613479d144fda8344e2d886cf694fd36db4cc86865", - "sha256:96603a562b546632441926cd1293cfcb5b69f0b4159e6077f7c7dbdfb686af4d", - "sha256:99c5ac4ad492b4a19fc132306cd57075c28446ec2ed970973bbf036bcda1bcc6", - "sha256:9c19b26acdd08dd239e0d3669a3dddafd600902e37881f13fbd8a53943079dbc", - "sha256:9de50a199b7710fa2904be5a4a9b51af587ab24c8e540a7243ab737b45844543", - "sha256:9e2ee0ac5a1f5c7dd3197de309adfb99ac4617ff02b0603fd1e65b07dc772e4b", - "sha256:a2ece4af1f3c967a4390c284797ab595a9f1bc1130ef8b01828915a05a6ae684", - "sha256:a3628b6c7b880b181a3ae0a0683698513874df63783fd89de99b7b7539e3e8a8", - "sha256:ad1407db8f2f49329729564f71685557157bfa42b48f4b93e53721a16eb813ed", - "sha256:b04691bc6601ef47c88f0255043df6f570ada1a9ebef99c34bd0b72866c217ae", - "sha256:b0cf2a4501bff9330a8a5248b4ce951851e415bdcce9dc158e76cfd55e15085c", - "sha256:b2fe42e523be344124c6c8ef32a011444e869dc5f883c591ed87f84339de5976", - "sha256:b30e963f9e0d52c28f284d554a9469af073030030cef8693106d918b2ca92f54", - "sha256:bb54c54510e47a8c7c8e63454a6acc817519337b2b78606c4e840871a3e15349", - "sha256:bd111d7fc5591ddf377a408ed9067045259ff2770f37e2d94e6478d0f3fc0c17", - "sha256:bdf70bfe5a1414ba9afb9d49f0c912dc524cf60141102f3a11143ba3d291870f", - "sha256:ca80e1b90a05a4f476547f904992ae81eda5c2c85c66ee4195bb8f9c5fb47f28", - "sha256:caf486ac1e689dda3502567eb89ffe02876546599bbf915ec94b1fa424eeffd4", - "sha256:ccc360e87341ad47c777f5723f68adbb52b37ab450c8bc3ca9ca1f3e849e5fe2", - "sha256:d25036d161c4fe2225d1abff2bd52c34ed0b1099f02c208cd34d8c05729882f0", - "sha256:d52d5dc7c6682b720280f9d9db41d36ebe4791622c842e258c9206232251ab2b", - "sha256:d67f8baed00870aa390ea2590798766256f31dc5ed3ecc737debb6e97e2ede78", - "sha256:d76e8b13161a202d14c9584590c4df4d068c9567c99506497bdd67eaedf36403", - "sha256:d95fc1bf33a9a81469aa760617b5971331cdd74370d1214f0b3109272c0e1e3c", - "sha256:de6a1c9f6803b90e20869e6b99c2c18cef5cc691363954c93cb9adeb26d9f3ae", - "sha256:e1d8cb0b56b3587c5c01de3bf2f600f186da7e7b5f7353d1bf26a8ddca57f965", - "sha256:e2a988a0c673c2e12084f5e6ba3392d76c75ddb8ebc6c7e9ead68248101cd446", - "sha256:e3f1e3f1a1751bb62b4a1b7f4e435afcdade6c17a4fd9b9d43607cebd242924a", - "sha256:e6a00ffcc173e765e200ceefb06399ba09c06db97f401f920513a10c803604ca", - "sha256:e827d48cf802de06d9c935088c2924e3c7e7533377d66b6f31ed175c1620e05e", - "sha256:ebf3fd9f141700b510d4b190094db0ce37ac6361a6806c153c161dc6c041ccda", - "sha256:ec00c3305788e04bf6d29d42e504560e159ccaf0be30c09203b468a6c1ccd3b2", - "sha256:ec4fd86658c6a8964d75426517dc01cbf840bbf32d055ce64a9e63a40fd7b771", - "sha256:efd2fcf7e7b9d7ab16e6b7d54205beded0a9c8566cb30f09c1abe42b4e22bdcb", - "sha256:f0f03211fd14a6a0aed2997d4b1c013d49fb7b50eeb9ffdf5e51f23cfe2c77fa", - "sha256:f628dbf3c91e12f4d6c8b3f092069567d8eb17814aebba3d7d60c149391aee3a", - "sha256:f8ef51e459eb2ad8e7a66c1d6440c808485840ad55ecc3cafefadea47d1b1ba2", - "sha256:fc37e9aef10a696a5a4474802930079ccfc14d9f9c10b4662169671ff034b7df", - "sha256:fdee8405931b0615220e5ddf8cd7edd8592c606a8e4ca2a00704883c396e4479" - ], - "markers": "python_version >= '3.6'", - "version": "==3.8.6" - }, - "aiohttp-retry": { - "hashes": [ - "sha256:3aeeead8f6afe48272db93ced9440cf4eda8b6fd7ee2abb25357b7eb28525b45", - "sha256:9a8e637e31682ad36e1ff9f8bcba912fcfc7d7041722bc901a4b948da4d71ea9" - ], - "markers": "python_version >= '3.7'", - "version": "==2.8.3" - }, - "aioitertools": { - "hashes": [ - "sha256:04b95e3dab25b449def24d7df809411c10e62aab0cbe31a50ca4e68748c43394", - "sha256:42c68b8dd3a69c2bf7f2233bf7df4bb58b557bca5252ac02ed5187bbc67d6831" - ], - "markers": "python_version >= '3.6'", - "version": "==0.11.0" - }, - "aiosignal": { - "hashes": [ - "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc", - "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17" - ], - "markers": "python_version >= '3.7'", - "version": "==1.3.1" - }, - "amqp": { - "hashes": [ - "sha256:2c1b13fecc0893e946c65cbd5f36427861cffa4ea2201d8f6fca22e2a373b5e2", - "sha256:6f0956d2c23d8fa6e7691934d8c3930eadb44972cbbd1a7ae3a520f735d43359" - ], - "markers": "python_version >= '3.6'", - "version": "==5.1.1" - }, - "annotated-types": { - "hashes": [ - "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43", - "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d" - ], - "markers": "python_version >= '3.8'", - "version": "==0.6.0" - }, - "antlr4-python3-runtime": { - "hashes": [ - "sha256:f224469b4168294902bb1efa80a8bf7855f24c99aef99cbefc1bcd3cce77881b" - ], - "version": "==4.9.3" - }, - "appdirs": { - "hashes": [ - "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41", - "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128" - ], - "version": "==1.4.4" - }, - "async-timeout": { - "hashes": [ - "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", - "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028" - ], - "markers": "python_version >= '3.7'", - "version": "==4.0.3" - }, - "asyncssh": { - "hashes": [ - "sha256:1d112a93f926069932fecd9842f206fdd023eb860aea4efc95f92b5e031d7fe0", - "sha256:e03ef2d131fbb4371b4018718452ce8c735a48edfe0139d2abdce4c187a459c3" - ], - "markers": "python_version >= '3.6'", - "version": "==2.14.0" - }, - "atpublic": { - "hashes": [ - "sha256:0f40433219e124edf115c6c363808ca6f0e1cfa7d160d86b2fb94793086d1294", - "sha256:80057c55641253b86dcb68b524f82328172371b6547d4c7462a9127fbfbbabfc" - ], - "markers": "python_version >= '3.8'", - "version": "==4.0" - }, - "attrs": { - "hashes": [ - "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04", - "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015" - ], - "markers": "python_version >= '3.7'", - "version": "==23.1.0" - }, - "billiard": { - "hashes": [ - "sha256:0f50d6be051c6b2b75bfbc8bfd85af195c5739c281d3f5b86a5640c65563614a", - "sha256:1ad2eeae8e28053d729ba3373d34d9d6e210f6e4d8bf0a9c64f92bd053f1edf5" - ], - "markers": "python_version >= '3.7'", - "version": "==4.1.0" - }, - "boto3": { - "hashes": [ - "sha256:a5cf93b202568e9d378afdc84be55a6dedf11d30156289fe829e23e6d7dccabb", - "sha256:a99150a30c038c73e89662836820a8cce914afab5ea377942a37c484b85f4438" - ], - "version": "==1.28.64" - }, - "botocore": { - "hashes": [ - "sha256:7b709310343a5b430ec9025b2e17c0bac6b16c05f1ac1d9521dece3f10c71bac", - "sha256:d8eb4b724ac437343359b318d73de0cfae0fecb24095827e56135b0ad6b44caf" - ], - "markers": "python_version >= '3.7'", - "version": "==1.31.64" - }, - "celery": { - "hashes": [ - "sha256:1e6ed40af72695464ce98ca2c201ad0ef8fd192246f6c9eac8bba343b980ad34", - "sha256:9023df6a8962da79eb30c0c84d5f4863d9793a466354cc931d7f72423996de28" - ], - "markers": "python_version >= '3.8'", - "version": "==5.3.4" - }, - "certifi": { - "hashes": [ - "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082", - "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9" - ], - "markers": "python_version >= '3.6'", - "version": "==2023.7.22" - }, - "cffi": { - "hashes": [ - "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc", - "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a", - "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417", - "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab", - "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520", - "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36", - "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743", - "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8", - "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed", - "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684", - "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56", - "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324", - "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d", - "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235", - "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e", - "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088", - "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000", - "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7", - "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e", - "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673", - "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c", - "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe", - "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2", - "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098", - "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8", - "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a", - "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0", - "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b", - "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896", - "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e", - "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9", - "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2", - "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b", - "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6", - "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404", - "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f", - "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0", - "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4", - "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc", - "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936", - "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba", - "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872", - "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb", - "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614", - "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1", - "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d", - "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969", - "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b", - "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4", - "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627", - "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956", - "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357" - ], - "markers": "python_version >= '3.8'", - "version": "==1.16.0" - }, - "charset-normalizer": { - "hashes": [ - "sha256:06cf46bdff72f58645434d467bf5228080801298fbba19fe268a01b4534467f5", - "sha256:0c8c61fb505c7dad1d251c284e712d4e0372cef3b067f7ddf82a7fa82e1e9a93", - "sha256:10b8dd31e10f32410751b3430996f9807fc4d1587ca69772e2aa940a82ab571a", - "sha256:1171ef1fc5ab4693c5d151ae0fdad7f7349920eabbaca6271f95969fa0756c2d", - "sha256:17a866d61259c7de1bdadef418a37755050ddb4b922df8b356503234fff7932c", - "sha256:1d6bfc32a68bc0933819cfdfe45f9abc3cae3877e1d90aac7259d57e6e0f85b1", - "sha256:1ec937546cad86d0dce5396748bf392bb7b62a9eeb8c66efac60e947697f0e58", - "sha256:223b4d54561c01048f657fa6ce41461d5ad8ff128b9678cfe8b2ecd951e3f8a2", - "sha256:2465aa50c9299d615d757c1c888bc6fef384b7c4aec81c05a0172b4400f98557", - "sha256:28f512b9a33235545fbbdac6a330a510b63be278a50071a336afc1b78781b147", - "sha256:2c092be3885a1b7899cd85ce24acedc1034199d6fca1483fa2c3a35c86e43041", - "sha256:2c4c99f98fc3a1835af8179dcc9013f93594d0670e2fa80c83aa36346ee763d2", - "sha256:31445f38053476a0c4e6d12b047b08ced81e2c7c712e5a1ad97bc913256f91b2", - "sha256:31bbaba7218904d2eabecf4feec0d07469284e952a27400f23b6628439439fa7", - "sha256:34d95638ff3613849f473afc33f65c401a89f3b9528d0d213c7037c398a51296", - "sha256:352a88c3df0d1fa886562384b86f9a9e27563d4704ee0e9d56ec6fcd270ea690", - "sha256:39b70a6f88eebe239fa775190796d55a33cfb6d36b9ffdd37843f7c4c1b5dc67", - "sha256:3c66df3f41abee950d6638adc7eac4730a306b022570f71dd0bd6ba53503ab57", - "sha256:3f70fd716855cd3b855316b226a1ac8bdb3caf4f7ea96edcccc6f484217c9597", - "sha256:3f9bc2ce123637a60ebe819f9fccc614da1bcc05798bbbaf2dd4ec91f3e08846", - "sha256:3fb765362688821404ad6cf86772fc54993ec11577cd5a92ac44b4c2ba52155b", - "sha256:45f053a0ece92c734d874861ffe6e3cc92150e32136dd59ab1fb070575189c97", - "sha256:46fb9970aa5eeca547d7aa0de5d4b124a288b42eaefac677bde805013c95725c", - "sha256:4cb50a0335382aac15c31b61d8531bc9bb657cfd848b1d7158009472189f3d62", - "sha256:4e12f8ee80aa35e746230a2af83e81bd6b52daa92a8afaef4fea4a2ce9b9f4fa", - "sha256:4f3100d86dcd03c03f7e9c3fdb23d92e32abbca07e7c13ebd7ddfbcb06f5991f", - "sha256:4f6e2a839f83a6a76854d12dbebde50e4b1afa63e27761549d006fa53e9aa80e", - "sha256:4f861d94c2a450b974b86093c6c027888627b8082f1299dfd5a4bae8e2292821", - "sha256:501adc5eb6cd5f40a6f77fbd90e5ab915c8fd6e8c614af2db5561e16c600d6f3", - "sha256:520b7a142d2524f999447b3a0cf95115df81c4f33003c51a6ab637cbda9d0bf4", - "sha256:548eefad783ed787b38cb6f9a574bd8664468cc76d1538215d510a3cd41406cb", - "sha256:555fe186da0068d3354cdf4bbcbc609b0ecae4d04c921cc13e209eece7720727", - "sha256:55602981b2dbf8184c098bc10287e8c245e351cd4fdcad050bd7199d5a8bf514", - "sha256:58e875eb7016fd014c0eea46c6fa92b87b62c0cb31b9feae25cbbe62c919f54d", - "sha256:5a3580a4fdc4ac05f9e53c57f965e3594b2f99796231380adb2baaab96e22761", - "sha256:5b70bab78accbc672f50e878a5b73ca692f45f5b5e25c8066d748c09405e6a55", - "sha256:5ceca5876032362ae73b83347be8b5dbd2d1faf3358deb38c9c88776779b2e2f", - "sha256:61f1e3fb621f5420523abb71f5771a204b33c21d31e7d9d86881b2cffe92c47c", - "sha256:633968254f8d421e70f91c6ebe71ed0ab140220469cf87a9857e21c16687c034", - "sha256:63a6f59e2d01310f754c270e4a257426fe5a591dc487f1983b3bbe793cf6bac6", - "sha256:63accd11149c0f9a99e3bc095bbdb5a464862d77a7e309ad5938fbc8721235ae", - "sha256:6db3cfb9b4fcecb4390db154e75b49578c87a3b9979b40cdf90d7e4b945656e1", - "sha256:71ef3b9be10070360f289aea4838c784f8b851be3ba58cf796262b57775c2f14", - "sha256:7ae8e5142dcc7a49168f4055255dbcced01dc1714a90a21f87448dc8d90617d1", - "sha256:7b6cefa579e1237ce198619b76eaa148b71894fb0d6bcf9024460f9bf30fd228", - "sha256:800561453acdecedaac137bf09cd719c7a440b6800ec182f077bb8e7025fb708", - "sha256:82ca51ff0fc5b641a2d4e1cc8c5ff108699b7a56d7f3ad6f6da9dbb6f0145b48", - "sha256:851cf693fb3aaef71031237cd68699dded198657ec1e76a76eb8be58c03a5d1f", - "sha256:854cc74367180beb327ab9d00f964f6d91da06450b0855cbbb09187bcdb02de5", - "sha256:87071618d3d8ec8b186d53cb6e66955ef2a0e4fa63ccd3709c0c90ac5a43520f", - "sha256:871d045d6ccc181fd863a3cd66ee8e395523ebfbc57f85f91f035f50cee8e3d4", - "sha256:8aee051c89e13565c6bd366813c386939f8e928af93c29fda4af86d25b73d8f8", - "sha256:8af5a8917b8af42295e86b64903156b4f110a30dca5f3b5aedea123fbd638bff", - "sha256:8ec8ef42c6cd5856a7613dcd1eaf21e5573b2185263d87d27c8edcae33b62a61", - "sha256:91e43805ccafa0a91831f9cd5443aa34528c0c3f2cc48c4cb3d9a7721053874b", - "sha256:9505dc359edb6a330efcd2be825fdb73ee3e628d9010597aa1aee5aa63442e97", - "sha256:985c7965f62f6f32bf432e2681173db41336a9c2611693247069288bcb0c7f8b", - "sha256:9a74041ba0bfa9bc9b9bb2cd3238a6ab3b7618e759b41bd15b5f6ad958d17605", - "sha256:9edbe6a5bf8b56a4a84533ba2b2f489d0046e755c29616ef8830f9e7d9cf5728", - "sha256:a15c1fe6d26e83fd2e5972425a772cca158eae58b05d4a25a4e474c221053e2d", - "sha256:a66bcdf19c1a523e41b8e9d53d0cedbfbac2e93c649a2e9502cb26c014d0980c", - "sha256:ae4070f741f8d809075ef697877fd350ecf0b7c5837ed68738607ee0a2c572cf", - "sha256:ae55d592b02c4349525b6ed8f74c692509e5adffa842e582c0f861751701a673", - "sha256:b578cbe580e3b41ad17b1c428f382c814b32a6ce90f2d8e39e2e635d49e498d1", - "sha256:b891a2f68e09c5ef989007fac11476ed33c5c9994449a4e2c3386529d703dc8b", - "sha256:baec8148d6b8bd5cee1ae138ba658c71f5b03e0d69d5907703e3e1df96db5e41", - "sha256:bb06098d019766ca16fc915ecaa455c1f1cd594204e7f840cd6258237b5079a8", - "sha256:bc791ec3fd0c4309a753f95bb6c749ef0d8ea3aea91f07ee1cf06b7b02118f2f", - "sha256:bd28b31730f0e982ace8663d108e01199098432a30a4c410d06fe08fdb9e93f4", - "sha256:be4d9c2770044a59715eb57c1144dedea7c5d5ae80c68fb9959515037cde2008", - "sha256:c0c72d34e7de5604df0fde3644cc079feee5e55464967d10b24b1de268deceb9", - "sha256:c0e842112fe3f1a4ffcf64b06dc4c61a88441c2f02f373367f7b4c1aa9be2ad5", - "sha256:c15070ebf11b8b7fd1bfff7217e9324963c82dbdf6182ff7050519e350e7ad9f", - "sha256:c2000c54c395d9e5e44c99dc7c20a64dc371f777faf8bae4919ad3e99ce5253e", - "sha256:c30187840d36d0ba2893bc3271a36a517a717f9fd383a98e2697ee890a37c273", - "sha256:cb7cd68814308aade9d0c93c5bd2ade9f9441666f8ba5aa9c2d4b389cb5e2a45", - "sha256:cd805513198304026bd379d1d516afbf6c3c13f4382134a2c526b8b854da1c2e", - "sha256:d0bf89afcbcf4d1bb2652f6580e5e55a840fdf87384f6063c4a4f0c95e378656", - "sha256:d9137a876020661972ca6eec0766d81aef8a5627df628b664b234b73396e727e", - "sha256:dbd95e300367aa0827496fe75a1766d198d34385a58f97683fe6e07f89ca3e3c", - "sha256:dced27917823df984fe0c80a5c4ad75cf58df0fbfae890bc08004cd3888922a2", - "sha256:de0b4caa1c8a21394e8ce971997614a17648f94e1cd0640fbd6b4d14cab13a72", - "sha256:debb633f3f7856f95ad957d9b9c781f8e2c6303ef21724ec94bea2ce2fcbd056", - "sha256:e372d7dfd154009142631de2d316adad3cc1c36c32a38b16a4751ba78da2a397", - "sha256:ecd26be9f112c4f96718290c10f4caea6cc798459a3a76636b817a0ed7874e42", - "sha256:edc0202099ea1d82844316604e17d2b175044f9bcb6b398aab781eba957224bd", - "sha256:f194cce575e59ffe442c10a360182a986535fd90b57f7debfaa5c845c409ecc3", - "sha256:f5fb672c396d826ca16a022ac04c9dce74e00a1c344f6ad1a0fdc1ba1f332213", - "sha256:f6a02a3c7950cafaadcd46a226ad9e12fc9744652cc69f9e5534f98b47f3bbcf", - "sha256:fe81b35c33772e56f4b6cf62cf4aedc1762ef7162a31e6ac7fe5e40d0149eb67" - ], - "markers": "python_full_version >= '3.7.0'", - "version": "==3.3.1" - }, - "click": { - "hashes": [ - "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", - "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" - ], - "markers": "python_version >= '3.7'", - "version": "==8.1.7" - }, - "click-didyoumean": { - "hashes": [ - "sha256:a0713dc7a1de3f06bc0df5a9567ad19ead2d3d5689b434768a6145bff77c0667", - "sha256:f184f0d851d96b6d29297354ed981b7dd71df7ff500d82fa6d11f0856bee8035" - ], - "markers": "python_full_version >= '3.6.2' and python_full_version < '4.0.0'", - "version": "==0.3.0" - }, - "click-plugins": { - "hashes": [ - "sha256:46ab999744a9d831159c3411bb0c79346d94a444df9a3a3742e9ed63645f264b", - "sha256:5d262006d3222f5057fd81e1623d4443e41dcda5dc815c06b442aa3c02889fc8" - ], - "version": "==1.1.1" - }, - "click-repl": { - "hashes": [ - "sha256:17849c23dba3d667247dc4defe1757fff98694e90fe37474f3feebb69ced26a9", - "sha256:fb7e06deb8da8de86180a33a9da97ac316751c094c6899382da7feeeeb51b812" - ], - "markers": "python_version >= '3.6'", - "version": "==0.3.0" - }, - "colorama": { - "hashes": [ - "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", - "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", - "version": "==0.4.6" - }, - "configobj": { - "hashes": [ - "sha256:6f704434a07dc4f4dc7c9a745172c1cad449feb548febd9f7fe362629c627a97", - "sha256:a7a8c6ab7daade85c3f329931a807c8aee750a2494363934f8ea84d8a54c87ea", - "sha256:d808d7e04e6f81fbb23d5ac2cd50e69ccbee58eaf9360eb89ede22d93216a314" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==5.0.8" - }, - "cryptography": { - "hashes": [ - "sha256:0c327cac00f082013c7c9fb6c46b7cc9fa3c288ca702c74773968173bda421bf", - "sha256:0d2a6a598847c46e3e321a7aef8af1436f11c27f1254933746304ff014664d84", - "sha256:227ec057cd32a41c6651701abc0328135e472ed450f47c2766f23267b792a88e", - "sha256:22892cc830d8b2c89ea60148227631bb96a7da0c1b722f2aac8824b1b7c0b6b8", - "sha256:392cb88b597247177172e02da6b7a63deeff1937fa6fec3bbf902ebd75d97ec7", - "sha256:3be3ca726e1572517d2bef99a818378bbcf7d7799d5372a46c79c29eb8d166c1", - "sha256:573eb7128cbca75f9157dcde974781209463ce56b5804983e11a1c462f0f4e88", - "sha256:580afc7b7216deeb87a098ef0674d6ee34ab55993140838b14c9b83312b37b86", - "sha256:5a70187954ba7292c7876734183e810b728b4f3965fbe571421cb2434d279179", - "sha256:73801ac9736741f220e20435f84ecec75ed70eda90f781a148f1bad546963d81", - "sha256:7d208c21e47940369accfc9e85f0de7693d9a5d843c2509b3846b2db170dfd20", - "sha256:8254962e6ba1f4d2090c44daf50a547cd5f0bf446dc658a8e5f8156cae0d8548", - "sha256:88417bff20162f635f24f849ab182b092697922088b477a7abd6664ddd82291d", - "sha256:a48e74dad1fb349f3dc1d449ed88e0017d792997a7ad2ec9587ed17405667e6d", - "sha256:b948e09fe5fb18517d99994184854ebd50b57248736fd4c720ad540560174ec5", - "sha256:c707f7afd813478e2019ae32a7c49cd932dd60ab2d2a93e796f68236b7e1fbf1", - "sha256:d38e6031e113b7421db1de0c1b1f7739564a88f1684c6b89234fbf6c11b75147", - "sha256:d3977f0e276f6f5bf245c403156673db103283266601405376f075c849a0b936", - "sha256:da6a0ff8f1016ccc7477e6339e1d50ce5f59b88905585f77193ebd5068f1e797", - "sha256:e270c04f4d9b5671ebcc792b3ba5d4488bf7c42c3c241a3748e2599776f29696", - "sha256:e886098619d3815e0ad5790c973afeee2c0e6e04b4da90b88e6bd06e2a0b1b72", - "sha256:ec3b055ff8f1dce8e6ef28f626e0972981475173d7973d63f271b29c8a2897da", - "sha256:fba1e91467c65fe64a82c689dc6cf58151158993b13eb7a7f3f4b7f395636723" - ], - "markers": "python_version >= '3.7'", - "version": "==41.0.5" - }, - "dictdiffer": { - "hashes": [ - "sha256:17bacf5fbfe613ccf1b6d512bd766e6b21fb798822a133aa86098b8ac9997578", - "sha256:442bfc693cfcadaf46674575d2eba1c53b42f5e404218ca2c2ff549f2df56595" - ], - "version": "==0.9.0" - }, - "diskcache": { - "hashes": [ - "sha256:2c3a3fa2743d8535d832ec61c2054a1641f41775aa7c556758a109941e33e4fc", - "sha256:5e31b2d5fbad117cc363ebaf6b689474db18a1f6438bc82358b024abd4c2ca19" - ], - "markers": "python_version >= '3'", - "version": "==5.6.3" - }, - "distro": { - "hashes": [ - "sha256:02e111d1dc6a50abb8eed6bf31c3e48ed8b0830d1ea2a1b78c61765c2513fdd8", - "sha256:99522ca3e365cac527b44bde033f64c6945d90eb9f769703caaec52b09bbd3ff" - ], - "markers": "python_version >= '3.6'", - "version": "==1.8.0" - }, - "dpath": { - "hashes": [ - "sha256:31407395b177ab63ef72e2f6ae268c15e938f2990a8ecf6510f5686c02b6db73", - "sha256:f1e07c72e8605c6a9e80b64bc8f42714de08a789c7de417e49c3f87a19692e47" - ], - "markers": "python_version >= '3.7'", - "version": "==2.1.6" - }, - "dulwich": { - "hashes": [ - "sha256:008ff08629ab16d3638a9f36cfc6f5bd74b4d594657f2dc1583d8d3201794571", - "sha256:18697b58e0fc5972de68b529b08ac9ddda3f39af27bcf3f6999635ed3da7ef68", - "sha256:1fedd924763a5d640348db43a267a394aa80d551228ad45708e0b0cc2130bb62", - "sha256:22798e9ba59e32b8faff5d9067e2b5a308f6b0fba9b1e1e928571ad278e7b36c", - "sha256:24ad45928a65f39ea0f451f9989b7aaedba9893d48c3189b544a70c6a1043f71", - "sha256:28acbd08d6b38720d99cc01da9dd307a2e0585e00436c95bcac6357b9a9a6f76", - "sha256:28c9724a167c84a83fc6238e0781f4702b5fe8c53ede31604525fb1a9d1833f4", - "sha256:2a3fc071e5b14f164191286f7ffc02f60fe8b439d01fad0832697cc08c2237dd", - "sha256:30fbe87e8b51f3813c131e2841c86d007434d160bd16db586b40d47f31dd05b0", - "sha256:32d3a35caad6879d04711b358b861142440a543f5f4e02df67b13cbcd57f84a6", - "sha256:32d7acfe3fe2ce4502446d8f7a5ab34cfd24c9ff8961e60337638410906a8fbb", - "sha256:3b1682e8e826471ea3c22b8521435e93799e3db8ad05dd3c8f9b1aaacfa78147", - "sha256:40623cc39a3f1634663d22d87f86e2e406cc8ff17ae7a3edc7fcf963c288992f", - "sha256:4e09d0b4e985b371aa6728773781b19298d361a00772e20f98522868cf7edc6f", - "sha256:4fdc2f081bc3e9e120079c2cea4be213e3f127335aca7c0ab0c19fe791270caa", - "sha256:513d045e74307eeb31592255c38f37042c9aa68ce845a167943018ab5138b0e3", - "sha256:54342cf96fe8a44648505c65f23d18889595762003a168d67d7263df66143bd2", - "sha256:5d2ccf3d355850674f75655154a6519bf1f1664176c670109fa7041019b286f9", - "sha256:5e58171a5d70f7910f73d25ff82a058edff09a4c1c3bd1de0dc6b1fbc9a42c3e", - "sha256:6592ef2d16ac61a27022647cf64a048f5be6e0a6ab2ebc7322bfbe24fb2b971b", - "sha256:6c91e1ed20d3d9a6aaaed9e75adae37272b3fcbcc72bab1eb09574806da88563", - "sha256:6fe957564108f74325d0d042d85e0c67ef470921ca92b6e7d330c7c49a3b9c1d", - "sha256:7f89bee4c97372e8aaf8ffaf5899f1bcd5184b5306d7eaf68738c1101ceba10e", - "sha256:81d10aa50c0a9a6dd495990c639358e3a3bbff39e17ff302179be6e93b573da7", - "sha256:81e237a6b1b20c79ef62ca19a8fb231f5519bab874b9a1c2acf9c05edcabd600", - "sha256:847bb52562a211b596453a602e75739350c86d7edb846b5b1c46896a5c86b9bb", - "sha256:8b84450766a3b151c3676fec3e3ed76304e52a84d5d69ade0f34fff2782c1b41", - "sha256:8dfb50b3915e223a97f50fbac0dbc298d5fffeaac004eeeb3d552c57fe38416f", - "sha256:99577b2b37f64bc87280079245fb2963494c345d7db355173ecec7ab3d64b949", - "sha256:a1ac20dfcfd6057efb8499158d23f2c059f933aefa381e192100e6d8bc25d562", - "sha256:a2912c8a845c8ccbc79d068a89db7172e355adeb84eb31f062cd3a406d528b30", - "sha256:a3da632648ee27b64bb5b285a3a94fddf297a596891cca12ac0df43c4f59448f", - "sha256:a64eca1601e79c16df78afe08da9ac9497b934cbc5765990ca7d89a4b87453d9", - "sha256:a780e2a0ff208c4f218e72eff8d13f9aff485ff9a6f3066c22abe4ec8cec7dcd", - "sha256:a89b19f4960e759915dbc23a4dd0abc067b55d8d65e9df50961b73091b87b81a", - "sha256:a9b52a08d49731375662936d05a12c4a64a6fe0ce257111f62638e475fb5d26d", - "sha256:a9b6f8a16f32190aa88c37ef013858b3e01964774bc983900bd0d74ecb6576e6", - "sha256:b0545f0fa9444a0eb84977d08e302e3f55fd7c34a0466ec28bedc3c839b2fc1f", - "sha256:b1c9e55233f19cd19c484f607cd90ab578ac50ebfef607f77e3b35c2b6049470", - "sha256:bf469cd5076623c2aad69d01ce9d5392fcb38a5faef91abe1501be733453e37d", - "sha256:bf90f2f9328a82778cf85ab696e4a7926918c3f315c75fc432ba31346bfa89b7", - "sha256:c04df87098053b7767b46fc04b7943d75443f91c73560ca50157cdc22e27a5d3", - "sha256:c2f2683e0598f7c7071ef08a0822f062d8744549a0d45f2c156741033b7e3d7d", - "sha256:c816be529680659b6a19798287b4ec6de49040f58160d40b1b2934fd6c28e93f", - "sha256:ceabe8f96edfb9183034a860f5dc77586700b517457032867b64a03c44e5cf96", - "sha256:cef50c0a19f322b7150248b8fa0862ce1652dec657e340c4020573721e85f215", - "sha256:d7cd9fb896c65e4c28cb9332f2be192817805978dd8dc299681c4fe83c631158", - "sha256:d9002094198e57e88fe77412d3aa64dd05978046ae725a16123ba621a7704628", - "sha256:daa3584beabfcf0da76df57535a23c80ff6d8ccde6ddbd23bdc79d317a0e20a7", - "sha256:e07f145c7b0d82a9f77d157f493a61900e913d1c1f8b1f40d07d919ffb0929a4", - "sha256:e0dee3840c3c72e1d60c8f87a7a715d8eac023b9e1b80199d97790f7a1c60d9c", - "sha256:e1ac882afa890ef993b8502647e6c6d2b3977ce56e3fe80058ce64607cbc7107", - "sha256:e8ed878553f0b76facbb620b455fafa0943162fe8e386920717781e490444efa", - "sha256:ed2f1f638b9adfba862719693b371ffe5d58e94d552ace9a23dea0fb0db6f468", - "sha256:edc21c3784dd9d9b85abd9fe53f81a884e2cdcc4e5e09ada17287420d64cfd46", - "sha256:eee8aba4dec4d0a52737a8a141f3456229c87dcfd7961f8115786a27b6ebefed" - ], - "markers": "python_version >= '3.7'", - "version": "==0.21.6" - }, - "dvc": { - "extras": [ - "s3" - ], - "hashes": [ - "sha256:c04f40b4471b695cbe5452a6cbffac47d078863f7e462da2208238e6fb813ab5", - "sha256:d712ae9810a846d94437829dff1fc767ae5be7b33ffb63088a63a484f2ccccb9" - ], - "markers": "python_version >= '3.8'", - "version": "==3.27.0" - }, - "dvc-data": { - "hashes": [ - "sha256:389b172bdefeb89c63bac043cc699f1320e4bc6a6722a05a4c811551c41f5da6", - "sha256:f98df814b10861b8f44b0a8e3591309ae512ac980091159fd6b726369b15435f" - ], - "markers": "python_version >= '3.8'", - "version": "==2.18.2" - }, - "dvc-http": { - "hashes": [ - "sha256:d7cf66e8f8359cc9f5ca137de24d259beebdec444516fc7d085ad26fa7d3b34b", - "sha256:e5e8c915af84e6e464a67053e22b75fef77c2eabb3b7f4355c2b968ca7dcf52b" - ], - "markers": "python_version >= '3.8'", - "version": "==2.30.2" - }, - "dvc-objects": { - "hashes": [ - "sha256:0ac6b99e16557e094e02792d8c85face191ce41f98a44d381e87e408e2a623cb", - "sha256:a9fdf55552b95d3dfa1d4572b3938e893c4b4365bb551e168e164fcf5eab93dd" - ], - "markers": "python_version >= '3.8'", - "version": "==1.0.1" - }, - "dvc-render": { - "hashes": [ - "sha256:2dc6c73d02538e9396475e146048e20242233d418967f82e0627e5caa3360303", - "sha256:69b7dfdadf890beb6d7fa5b3d4bd33323d78fc4c3ce33ed1bf777026192f9b4d" - ], - "markers": "python_version >= '3.8'", - "version": "==0.6.0" - }, - "dvc-s3": { - "hashes": [ - "sha256:1f28598f5b0def4a350933428aba062a368c93bb411aa3c6d8f46cae79b5b957", - "sha256:796ffad62405e9c3a001dcfdfb609d972426d504e80b24a877f517e841c07d50" - ], - "version": "==2.23.0" - }, - "dvc-studio-client": { - "hashes": [ - "sha256:46dd508a0fb2c1c9986efd4111aa16ad3e40718c5e86a2be9f6e5ee509ff44a1", - "sha256:f51f36f9a86ea2bfcaed95b2ad6f532ed59a4d527c1febe079a938d79ff86796" - ], - "markers": "python_version >= '3.8'", - "version": "==0.15.0" - }, - "dvc-task": { - "hashes": [ - "sha256:637908e3a54670cb09924dd96161e025399c426fc3cb2e3b9b8a030d7cfcfbcd", - "sha256:6ab288bfbbc4a2df8ef145c543bb979d6cb8fb49037fec821a59ad6e1dfdddce" - ], - "markers": "python_version >= '3.8'", - "version": "==0.3.0" - }, - "entrypoints": { - "hashes": [ - "sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4", - "sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f" - ], - "markers": "python_version >= '3.6'", - "version": "==0.4" - }, - "filelock": { - "hashes": [ - "sha256:08c21d87ded6e2b9da6728c3dff51baf1dcecf973b768ef35bcbc3447edb9ad4", - "sha256:2e6f249f1f3654291606e046b09f1fd5eac39b360664c27f5aad072012f8bcbd" - ], - "markers": "python_version >= '3.8'", - "version": "==3.12.4" - }, - "flatten-dict": { - "hashes": [ - "sha256:506a96b6e6f805b81ae46a0f9f31290beb5fa79ded9d80dbe1b7fa236ab43076", - "sha256:7e245b20c4c718981212210eec4284a330c9f713e632e98765560e05421e48ad" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==0.4.2" - }, - "flufl.lock": { - "hashes": [ - "sha256:96d2c0448ba9fd8fc65d5d681ed7217c8e1625149c1c880bba50559bb680a615", - "sha256:af14172b35bbc58687bd06b70d1693fd8d48cbf0ffde7e51a618c148ae24042d" - ], - "markers": "python_version >= '3.7'", - "version": "==7.1.1" - }, - "frozenlist": { - "hashes": [ - "sha256:007df07a6e3eb3e33e9a1fe6a9db7af152bbd8a185f9aaa6ece10a3529e3e1c6", - "sha256:008eb8b31b3ea6896da16c38c1b136cb9fec9e249e77f6211d479db79a4eaf01", - "sha256:09163bdf0b2907454042edb19f887c6d33806adc71fbd54afc14908bfdc22251", - "sha256:0c7c1b47859ee2cac3846fde1c1dc0f15da6cec5a0e5c72d101e0f83dcb67ff9", - "sha256:0e5c8764c7829343d919cc2dfc587a8db01c4f70a4ebbc49abde5d4b158b007b", - "sha256:10ff5faaa22786315ef57097a279b833ecab1a0bfb07d604c9cbb1c4cdc2ed87", - "sha256:17ae5cd0f333f94f2e03aaf140bb762c64783935cc764ff9c82dff626089bebf", - "sha256:19488c57c12d4e8095a922f328df3f179c820c212940a498623ed39160bc3c2f", - "sha256:1a0848b52815006ea6596c395f87449f693dc419061cc21e970f139d466dc0a0", - "sha256:1e78fb68cf9c1a6aa4a9a12e960a5c9dfbdb89b3695197aa7064705662515de2", - "sha256:261b9f5d17cac914531331ff1b1d452125bf5daa05faf73b71d935485b0c510b", - "sha256:2b8bcf994563466db019fab287ff390fffbfdb4f905fc77bc1c1d604b1c689cc", - "sha256:38461d02d66de17455072c9ba981d35f1d2a73024bee7790ac2f9e361ef1cd0c", - "sha256:490132667476f6781b4c9458298b0c1cddf237488abd228b0b3650e5ecba7467", - "sha256:491e014f5c43656da08958808588cc6c016847b4360e327a62cb308c791bd2d9", - "sha256:515e1abc578dd3b275d6a5114030b1330ba044ffba03f94091842852f806f1c1", - "sha256:556de4430ce324c836789fa4560ca62d1591d2538b8ceb0b4f68fb7b2384a27a", - "sha256:5833593c25ac59ede40ed4de6d67eb42928cca97f26feea219f21d0ed0959b79", - "sha256:6221d84d463fb110bdd7619b69cb43878a11d51cbb9394ae3105d082d5199167", - "sha256:6918d49b1f90821e93069682c06ffde41829c346c66b721e65a5c62b4bab0300", - "sha256:6c38721585f285203e4b4132a352eb3daa19121a035f3182e08e437cface44bf", - "sha256:71932b597f9895f011f47f17d6428252fc728ba2ae6024e13c3398a087c2cdea", - "sha256:7211ef110a9194b6042449431e08c4d80c0481e5891e58d429df5899690511c2", - "sha256:764226ceef3125e53ea2cb275000e309c0aa5464d43bd72abd661e27fffc26ab", - "sha256:7645a8e814a3ee34a89c4a372011dcd817964ce8cb273c8ed6119d706e9613e3", - "sha256:76d4711f6f6d08551a7e9ef28c722f4a50dd0fc204c56b4bcd95c6cc05ce6fbb", - "sha256:7f4f399d28478d1f604c2ff9119907af9726aed73680e5ed1ca634d377abb087", - "sha256:88f7bc0fcca81f985f78dd0fa68d2c75abf8272b1f5c323ea4a01a4d7a614efc", - "sha256:8d0edd6b1c7fb94922bf569c9b092ee187a83f03fb1a63076e7774b60f9481a8", - "sha256:901289d524fdd571be1c7be054f48b1f88ce8dddcbdf1ec698b27d4b8b9e5d62", - "sha256:93ea75c050c5bb3d98016b4ba2497851eadf0ac154d88a67d7a6816206f6fa7f", - "sha256:981b9ab5a0a3178ff413bca62526bb784249421c24ad7381e39d67981be2c326", - "sha256:9ac08e601308e41eb533f232dbf6b7e4cea762f9f84f6357136eed926c15d12c", - "sha256:a02eb8ab2b8f200179b5f62b59757685ae9987996ae549ccf30f983f40602431", - "sha256:a0c6da9aee33ff0b1a451e867da0c1f47408112b3391dd43133838339e410963", - "sha256:a6c8097e01886188e5be3e6b14e94ab365f384736aa1fca6a0b9e35bd4a30bc7", - "sha256:aa384489fefeb62321b238e64c07ef48398fe80f9e1e6afeff22e140e0850eef", - "sha256:ad2a9eb6d9839ae241701d0918f54c51365a51407fd80f6b8289e2dfca977cc3", - "sha256:b206646d176a007466358aa21d85cd8600a415c67c9bd15403336c331a10d956", - "sha256:b826d97e4276750beca7c8f0f1a4938892697a6bcd8ec8217b3312dad6982781", - "sha256:b89ac9768b82205936771f8d2eb3ce88503b1556324c9f903e7156669f521472", - "sha256:bd7bd3b3830247580de99c99ea2a01416dfc3c34471ca1298bccabf86d0ff4dc", - "sha256:bdf1847068c362f16b353163391210269e4f0569a3c166bc6a9f74ccbfc7e839", - "sha256:c11b0746f5d946fecf750428a95f3e9ebe792c1ee3b1e96eeba145dc631a9672", - "sha256:c5374b80521d3d3f2ec5572e05adc94601985cc526fb276d0c8574a6d749f1b3", - "sha256:ca265542ca427bf97aed183c1676e2a9c66942e822b14dc6e5f42e038f92a503", - "sha256:ce31ae3e19f3c902de379cf1323d90c649425b86de7bbdf82871b8a2a0615f3d", - "sha256:ceb6ec0a10c65540421e20ebd29083c50e6d1143278746a4ef6bcf6153171eb8", - "sha256:d081f13b095d74b67d550de04df1c756831f3b83dc9881c38985834387487f1b", - "sha256:d5655a942f5f5d2c9ed93d72148226d75369b4f6952680211972a33e59b1dfdc", - "sha256:d5a32087d720c608f42caed0ef36d2b3ea61a9d09ee59a5142d6070da9041b8f", - "sha256:d6484756b12f40003c6128bfcc3fa9f0d49a687e171186c2d85ec82e3758c559", - "sha256:dd65632acaf0d47608190a71bfe46b209719bf2beb59507db08ccdbe712f969b", - "sha256:de343e75f40e972bae1ef6090267f8260c1446a1695e77096db6cfa25e759a95", - "sha256:e29cda763f752553fa14c68fb2195150bfab22b352572cb36c43c47bedba70eb", - "sha256:e41f3de4df3e80de75845d3e743b3f1c4c8613c3997a912dbf0229fc61a8b963", - "sha256:e66d2a64d44d50d2543405fb183a21f76b3b5fd16f130f5c99187c3fb4e64919", - "sha256:e74b0506fa5aa5598ac6a975a12aa8928cbb58e1f5ac8360792ef15de1aa848f", - "sha256:f0ed05f5079c708fe74bf9027e95125334b6978bf07fd5ab923e9e55e5fbb9d3", - "sha256:f61e2dc5ad442c52b4887f1fdc112f97caeff4d9e6ebe78879364ac59f1663e1", - "sha256:fec520865f42e5c7f050c2a79038897b1c7d1595e907a9e08e3353293ffc948e" - ], - "markers": "python_version >= '3.8'", - "version": "==1.4.0" - }, - "fsspec": { - "extras": [ - "http" - ], - "hashes": [ - "sha256:330c66757591df346ad3091a53bd907e15348c2ba17d63fd54f5c39c4457d2a5", - "sha256:346a8f024efeb749d2a5fca7ba8854474b1ff9af7c3faaf636a4548781136529" - ], - "markers": "python_version >= '3.8'", - "version": "==2023.10.0" - }, - "funcy": { - "hashes": [ - "sha256:3963315d59d41c6f30c04bc910e10ab50a3ac4a225868bfa96feed133df075cb", - "sha256:53df23c8bb1651b12f095df764bfb057935d49537a56de211b098f4c79614bb0" - ], - "version": "==2.0" - }, - "gitdb": { - "hashes": [ - "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4", - "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b" - ], - "markers": "python_version >= '3.7'", - "version": "==4.0.11" - }, - "gitpython": { - "hashes": [ - "sha256:22b126e9ffb671fdd0c129796343a02bf67bf2994b35449ffc9321aa755e18a4", - "sha256:cf14627d5a8049ffbf49915732e5eddbe8134c3bdb9d476e6182b676fc573f8a" - ], - "markers": "python_version >= '3.7'", - "version": "==3.1.40" - }, - "grandalf": { - "hashes": [ - "sha256:2813f7aab87f0d20f334a3162ccfbcbf085977134a17a5b516940a93a77ea974", - "sha256:793ca254442f4a79252ea9ff1ab998e852c1e071b863593e5383afee906b4185", - "sha256:e62f76c6abadf74e9489bf6a5db0afce544a5e3e543708cf52e4707fd0a1a4f3" - ], - "version": "==0.8" - }, - "gto": { - "hashes": [ - "sha256:2bd2f67d172133584a47b2f3db906efb13a24258e094a930c4a1d800310d89d9", - "sha256:b021956c7892992caa341f06f977de613c6379eca823eb51020c2e5cc064d76b" - ], - "markers": "python_version >= '3.8'", - "version": "==1.4.0" - }, - "hydra-core": { - "hashes": [ - "sha256:8a878ed67216997c3e9d88a8e72e7b4767e81af37afb4ea3334b269a4390a824", - "sha256:fa0238a9e31df3373b35b0bfb672c34cc92718d21f81311d8996a16de1141d8b" - ], - "version": "==1.3.2" - }, - "idna": { - "hashes": [ - "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4", - "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2" - ], - "markers": "python_version >= '3.5'", - "version": "==3.4" - }, - "iterative-telemetry": { - "hashes": [ - "sha256:5bed9d19109c892cff2a4712a2fb18ad727079a7ab260a28b1e2f6934eec652d", - "sha256:af0a37ec727c1fd728df6e8103e4c89557b99869218e668dce5ca99e6e51231f" - ], - "markers": "python_version >= '3.8'", - "version": "==0.0.8" - }, - "jmespath": { - "hashes": [ - "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", - "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe" - ], - "markers": "python_version >= '3.7'", - "version": "==1.0.1" - }, - "kombu": { - "hashes": [ - "sha256:0ba213f630a2cb2772728aef56ac6883dc3a2f13435e10048f6e97d48506dbbd", - "sha256:b753c9cfc9b1e976e637a7cbc1a65d446a22e45546cd996ea28f932082b7dc9e" - ], - "markers": "python_version >= '3.8'", - "version": "==5.3.2" - }, - "markdown-it-py": { - "hashes": [ - "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", - "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb" - ], - "markers": "python_version >= '3.8'", - "version": "==3.0.0" - }, - "mdurl": { - "hashes": [ - "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", - "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba" - ], - "markers": "python_version >= '3.7'", - "version": "==0.1.2" - }, - "multidict": { - "hashes": [ - "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9", - "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8", - "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03", - "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710", - "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161", - "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664", - "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569", - "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067", - "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313", - "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706", - "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2", - "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636", - "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49", - "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93", - "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603", - "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0", - "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60", - "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4", - "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e", - "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1", - "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60", - "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951", - "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc", - "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe", - "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95", - "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d", - "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8", - "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed", - "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2", - "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775", - "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87", - "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c", - "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2", - "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98", - "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3", - "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe", - "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78", - "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660", - "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176", - "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e", - "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988", - "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c", - "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c", - "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0", - "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449", - "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f", - "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde", - "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5", - "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d", - "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac", - "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a", - "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9", - "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca", - "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11", - "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35", - "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063", - "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b", - "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982", - "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258", - "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1", - "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52", - "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480", - "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7", - "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461", - "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d", - "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc", - "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779", - "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a", - "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547", - "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0", - "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171", - "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf", - "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d", - "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba" - ], - "markers": "python_version >= '3.7'", - "version": "==6.0.4" - }, - "networkx": { - "hashes": [ - "sha256:8b25f564bd28f94ac821c58b04ae1a3109e73b001a7d476e4bb0d00d63706bf8", - "sha256:bda29edf392d9bfa5602034c767d28549214ec45f620081f0b74dc036a1fbbc1" - ], - "markers": "python_version >= '3.9'", - "version": "==3.2" - }, - "omegaconf": { - "hashes": [ - "sha256:7b4df175cdb08ba400f45cae3bdcae7ba8365db4d165fc65fd04b050ab63b46b", - "sha256:d5d4b6d29955cc50ad50c46dc269bcd92c6e00f5f90d23ab5fee7bfca4ba4cc7" - ], - "markers": "python_version >= '3.6'", - "version": "==2.3.0" - }, - "orjson": { - "hashes": [ - "sha256:02e693843c2959befdd82d1ebae8b05ed12d1cb821605d5f9fe9f98ca5c9fd2b", - "sha256:06f0c024a75e8ba5d9101facb4fb5a028cdabe3cdfe081534f2a9de0d5062af2", - "sha256:0a1a4d9e64597e550428ba091e51a4bcddc7a335c8f9297effbfa67078972b5c", - "sha256:0d2cd6ef4726ef1b8c63e30d8287225a383dbd1de3424d287b37c1906d8d2855", - "sha256:0f89dc338a12f4357f5bf1b098d3dea6072fb0b643fd35fec556f4941b31ae27", - "sha256:12b83e0d8ba4ca88b894c3e00efc59fe6d53d9ffb5dbbb79d437a466fc1a513d", - "sha256:1ef06431f021453a47a9abb7f7853f04f031d31fbdfe1cc83e3c6aadde502cce", - "sha256:1f352117eccac268a59fedac884b0518347f5e2b55b9f650c2463dd1e732eb61", - "sha256:24301f2d99d670ded4fb5e2f87643bc7428a54ba49176e38deb2887e42fe82fb", - "sha256:31d676bc236f6e919d100fb85d0a99812cff1ebffaa58106eaaec9399693e227", - "sha256:335406231f9247f985df045f0c0c8f6b6d5d6b3ff17b41a57c1e8ef1a31b4d04", - "sha256:397a185e5dd7f8ebe88a063fe13e34d61d394ebb8c70a443cee7661b9c89bda7", - "sha256:4a308aeac326c2bafbca9abbae1e1fcf682b06e78a54dad0347b760525838d85", - "sha256:50232572dd300c49f134838c8e7e0917f29a91f97dbd608d23f2895248464b7f", - "sha256:512e5a41af008e76451f5a344941d61f48dddcf7d7ddd3073deb555de64596a6", - "sha256:5424ecbafe57b2de30d3b5736c5d5835064d522185516a372eea069b92786ba6", - "sha256:543b36df56db195739c70d645ecd43e49b44d5ead5f8f645d2782af118249b37", - "sha256:678ffb5c0a6b1518b149cc328c610615d70d9297e351e12c01d0beed5d65360f", - "sha256:6fcf06c69ccc78e32d9f28aa382ab2ab08bf54b696dbe00ee566808fdf05da7d", - "sha256:75b805549cbbcb963e9c9068f1a05abd0ea4c34edc81f8d8ef2edb7e139e5b0f", - "sha256:8038ba245d0c0a6337cfb6747ea0c51fe18b0cf1a4bc943d530fd66799fae33d", - "sha256:879d2d1f6085c9c0831cec6716c63aaa89e41d8e036cabb19a315498c173fcc6", - "sha256:8cba20c9815c2a003b8ca4429b0ad4aa87cb6649af41365821249f0fd397148e", - "sha256:8e7877256b5092f1e4e48fc0f1004728dc6901e7a4ffaa4acb0a9578610aa4ce", - "sha256:906cac73b7818c20cf0f6a7dde5a6f009c52aecc318416c7af5ea37f15ca7e66", - "sha256:920814e02e3dd7af12f0262bbc18b9fe353f75a0d0c237f6a67d270da1a1bb44", - "sha256:957a45fb201c61b78bcf655a16afbe8a36c2c27f18a998bd6b5d8a35e358d4ad", - "sha256:9a4402e7df1b5c9a4c71c7892e1c8f43f642371d13c73242bda5964be6231f95", - "sha256:9d9b5440a5d215d9e1cfd4aee35fd4101a8b8ceb8329f549c16e3894ed9f18b5", - "sha256:a3bf6ca6bce22eb89dd0650ef49c77341440def966abcb7a2d01de8453df083a", - "sha256:a71b0cc21f2c324747bc77c35161e0438e3b5e72db6d3b515310457aba743f7f", - "sha256:ab7bae2b8bf17620ed381e4101aeeb64b3ba2a45fc74c7617c633a923cb0f169", - "sha256:ae72621f216d1d990468291b1ec153e1b46e0ed188a86d54e0941f3dabd09ee8", - "sha256:b20becf50d4aec7114dc902b58d85c6431b3a59b04caa977e6ce67b6fee0e159", - "sha256:b28c1a65cd13fff5958ab8b350f0921121691464a7a1752936b06ed25c0c7b6e", - "sha256:b97a67c47840467ccf116136450c50b6ed4e16a8919c81a4b4faef71e0a2b3f4", - "sha256:bd55ea5cce3addc03f8fb0705be0cfed63b048acc4f20914ce5e1375b15a293b", - "sha256:c4eb31a8e8a5e1d9af5aa9e247c2a52ad5cf7e968aaa9aaefdff98cfcc7f2e37", - "sha256:c63eca397127ebf46b59c9c1fb77b30dd7a8fc808ac385e7a58a7e64bae6e106", - "sha256:c959550e0705dc9f59de8fca1a316da0d9b115991806b217c82931ac81d75f74", - "sha256:cffb77cf0cd3cbf20eb603f932e0dde51b45134bdd2d439c9f57924581bb395b", - "sha256:d1c01cf4b8e00c7e98a0a7cf606a30a26c32adf2560be2d7d5d6766d6f474b31", - "sha256:d3f56e41bc79d30fdf077073072f2377d2ebf0b946b01f2009ab58b08907bc28", - "sha256:e159b97f5676dcdac0d0f75ec856ef5851707f61d262851eb41a30e8fadad7c9", - "sha256:e98ca450cb4fb176dd572ce28c6623de6923752c70556be4ef79764505320acb", - "sha256:eb50d869b3c97c7c5187eda3759e8eb15deb1271d694bc5d6ba7040db9e29036", - "sha256:ece2d8ed4c34903e7f1b64fb1e448a00e919a4cdb104fc713ad34b055b665fca", - "sha256:f28090060a31f4d11221f9ba48b2273b0d04b702f4dcaa197c38c64ce639cc51", - "sha256:f692e7aabad92fa0fff5b13a846fb586b02109475652207ec96733a085019d80", - "sha256:f708ca623287186e5876256cb30599308bce9b2757f90d917b7186de54ce6547" - ], - "markers": "implementation_name == 'cpython'", - "version": "==3.9.9" - }, - "packaging": { - "hashes": [ - "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", - "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" - ], - "markers": "python_version >= '3.7'", - "version": "==23.2" - }, - "pathspec": { - "hashes": [ - "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20", - "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3" - ], - "markers": "python_version >= '3.7'", - "version": "==0.11.2" - }, - "platformdirs": { - "hashes": [ - "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3", - "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e" - ], - "markers": "python_version >= '3.7'", - "version": "==3.11.0" - }, - "prompt-toolkit": { - "hashes": [ - "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac", - "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88" - ], - "markers": "python_full_version >= '3.7.0'", - "version": "==3.0.39" - }, - "psutil": { - "hashes": [ - "sha256:10e8c17b4f898d64b121149afb136c53ea8b68c7531155147867b7b1ac9e7e28", - "sha256:18cd22c5db486f33998f37e2bb054cc62fd06646995285e02a51b1e08da97017", - "sha256:3ebf2158c16cc69db777e3c7decb3c0f43a7af94a60d72e87b2823aebac3d602", - "sha256:51dc3d54607c73148f63732c727856f5febec1c7c336f8f41fcbd6315cce76ac", - "sha256:6e5fb8dc711a514da83098bc5234264e551ad980cec5f85dabf4d38ed6f15e9a", - "sha256:70cb3beb98bc3fd5ac9ac617a327af7e7f826373ee64c80efd4eb2856e5051e9", - "sha256:748c9dd2583ed86347ed65d0035f45fa8c851e8d90354c122ab72319b5f366f4", - "sha256:91ecd2d9c00db9817a4b4192107cf6954addb5d9d67a969a4f436dbc9200f88c", - "sha256:92e0cc43c524834af53e9d3369245e6cc3b130e78e26100d1f63cdb0abeb3d3c", - "sha256:a6f01f03bf1843280f4ad16f4bde26b817847b4c1a0db59bf6419807bc5ce05c", - "sha256:c69596f9fc2f8acd574a12d5f8b7b1ba3765a641ea5d60fb4736bf3c08a8214a", - "sha256:ca2780f5e038379e520281e4c032dddd086906ddff9ef0d1b9dcf00710e5071c", - "sha256:daecbcbd29b289aac14ece28eca6a3e60aa361754cf6da3dfb20d4d32b6c7f57", - "sha256:e4b92ddcd7dd4cdd3f900180ea1e104932c7bce234fb88976e2a3b296441225a", - "sha256:fb8a697f11b0f5994550555fcfe3e69799e5b060c8ecf9e2f75c69302cc35c0d", - "sha256:ff18b8d1a784b810df0b0fff3bcb50ab941c3b8e2c8de5726f9c71c601c611aa" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", - "version": "==5.9.6" - }, - "pycparser": { - "hashes": [ - "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9", - "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206" - ], - "version": "==2.21" - }, - "pydantic": { - "hashes": [ - "sha256:94f336138093a5d7f426aac732dcfe7ab4eb4da243c88f891d65deb4a2556ee7", - "sha256:bc3ddf669d234f4220e6e1c4d96b061abe0998185a8d7855c0126782b7abc8c1" - ], - "markers": "python_version >= '3.7'", - "version": "==2.4.2" - }, - "pydantic-core": { - "hashes": [ - "sha256:042462d8d6ba707fd3ce9649e7bf268633a41018d6a998fb5fbacb7e928a183e", - "sha256:0523aeb76e03f753b58be33b26540880bac5aa54422e4462404c432230543f33", - "sha256:05560ab976012bf40f25d5225a58bfa649bb897b87192a36c6fef1ab132540d7", - "sha256:0675ba5d22de54d07bccde38997e780044dcfa9a71aac9fd7d4d7a1d2e3e65f7", - "sha256:073d4a470b195d2b2245d0343569aac7e979d3a0dcce6c7d2af6d8a920ad0bea", - "sha256:07ec6d7d929ae9c68f716195ce15e745b3e8fa122fc67698ac6498d802ed0fa4", - "sha256:0880e239827b4b5b3e2ce05e6b766a7414e5f5aedc4523be6b68cfbc7f61c5d0", - "sha256:0c27f38dc4fbf07b358b2bc90edf35e82d1703e22ff2efa4af4ad5de1b3833e7", - "sha256:0d8a8adef23d86d8eceed3e32e9cca8879c7481c183f84ed1a8edc7df073af94", - "sha256:0e2a35baa428181cb2270a15864ec6286822d3576f2ed0f4cd7f0c1708472aff", - "sha256:0f8682dbdd2f67f8e1edddcbffcc29f60a6182b4901c367fc8c1c40d30bb0a82", - "sha256:0fa467fd300a6f046bdb248d40cd015b21b7576c168a6bb20aa22e595c8ffcdd", - "sha256:128552af70a64660f21cb0eb4876cbdadf1a1f9d5de820fed6421fa8de07c893", - "sha256:1396e81b83516b9d5c9e26a924fa69164156c148c717131f54f586485ac3c15e", - "sha256:149b8a07712f45b332faee1a2258d8ef1fb4a36f88c0c17cb687f205c5dc6e7d", - "sha256:14ac492c686defc8e6133e3a2d9eaf5261b3df26b8ae97450c1647286750b901", - "sha256:14cfbb00959259e15d684505263d5a21732b31248a5dd4941f73a3be233865b9", - "sha256:14e09ff0b8fe6e46b93d36a878f6e4a3a98ba5303c76bb8e716f4878a3bee92c", - "sha256:154ea7c52e32dce13065dbb20a4a6f0cc012b4f667ac90d648d36b12007fa9f7", - "sha256:15d6bca84ffc966cc9976b09a18cf9543ed4d4ecbd97e7086f9ce9327ea48891", - "sha256:1d40f55222b233e98e3921df7811c27567f0e1a4411b93d4c5c0f4ce131bc42f", - "sha256:25bd966103890ccfa028841a8f30cebcf5875eeac8c4bde4fe221364c92f0c9a", - "sha256:2cf5bb4dd67f20f3bbc1209ef572a259027c49e5ff694fa56bed62959b41e1f9", - "sha256:2e0e2959ef5d5b8dc9ef21e1a305a21a36e254e6a34432d00c72a92fdc5ecda5", - "sha256:320f14bd4542a04ab23747ff2c8a778bde727158b606e2661349557f0770711e", - "sha256:3625578b6010c65964d177626fde80cf60d7f2e297d56b925cb5cdeda6e9925a", - "sha256:39215d809470f4c8d1881758575b2abfb80174a9e8daf8f33b1d4379357e417c", - "sha256:3f0ac9fb8608dbc6eaf17956bf623c9119b4db7dbb511650910a82e261e6600f", - "sha256:417243bf599ba1f1fef2bb8c543ceb918676954734e2dcb82bf162ae9d7bd514", - "sha256:420a692b547736a8d8703c39ea935ab5d8f0d2573f8f123b0a294e49a73f214b", - "sha256:443fed67d33aa85357464f297e3d26e570267d1af6fef1c21ca50921d2976302", - "sha256:48525933fea744a3e7464c19bfede85df4aba79ce90c60b94d8b6e1eddd67096", - "sha256:485a91abe3a07c3a8d1e082ba29254eea3e2bb13cbbd4351ea4e5a21912cc9b0", - "sha256:4a5be350f922430997f240d25f8219f93b0c81e15f7b30b868b2fddfc2d05f27", - "sha256:4d966c47f9dd73c2d32a809d2be529112d509321c5310ebf54076812e6ecd884", - "sha256:524ff0ca3baea164d6d93a32c58ac79eca9f6cf713586fdc0adb66a8cdeab96a", - "sha256:53df009d1e1ba40f696f8995683e067e3967101d4bb4ea6f667931b7d4a01357", - "sha256:5994985da903d0b8a08e4935c46ed8daf5be1cf217489e673910951dc533d430", - "sha256:5cabb9710f09d5d2e9e2748c3e3e20d991a4c5f96ed8f1132518f54ab2967221", - "sha256:5fdb39f67c779b183b0c853cd6b45f7db84b84e0571b3ef1c89cdb1dfc367325", - "sha256:600d04a7b342363058b9190d4e929a8e2e715c5682a70cc37d5ded1e0dd370b4", - "sha256:631cb7415225954fdcc2a024119101946793e5923f6c4d73a5914d27eb3d3a05", - "sha256:63974d168b6233b4ed6a0046296803cb13c56637a7b8106564ab575926572a55", - "sha256:64322bfa13e44c6c30c518729ef08fda6026b96d5c0be724b3c4ae4da939f875", - "sha256:655f8f4c8d6a5963c9a0687793da37b9b681d9ad06f29438a3b2326d4e6b7970", - "sha256:6835451b57c1b467b95ffb03a38bb75b52fb4dc2762bb1d9dbed8de31ea7d0fc", - "sha256:6db2eb9654a85ada248afa5a6db5ff1cf0f7b16043a6b070adc4a5be68c716d6", - "sha256:7c4d1894fe112b0864c1fa75dffa045720a194b227bed12f4be7f6045b25209f", - "sha256:7eb037106f5c6b3b0b864ad226b0b7ab58157124161d48e4b30c4a43fef8bc4b", - "sha256:8282bab177a9a3081fd3d0a0175a07a1e2bfb7fcbbd949519ea0980f8a07144d", - "sha256:82f55187a5bebae7d81d35b1e9aaea5e169d44819789837cdd4720d768c55d15", - "sha256:8572cadbf4cfa95fb4187775b5ade2eaa93511f07947b38f4cd67cf10783b118", - "sha256:8cdbbd92154db2fec4ec973d45c565e767ddc20aa6dbaf50142676484cbff8ee", - "sha256:8f6e6aed5818c264412ac0598b581a002a9f050cb2637a84979859e70197aa9e", - "sha256:92f675fefa977625105708492850bcbc1182bfc3e997f8eecb866d1927c98ae6", - "sha256:962ed72424bf1f72334e2f1e61b68f16c0e596f024ca7ac5daf229f7c26e4208", - "sha256:9badf8d45171d92387410b04639d73811b785b5161ecadabf056ea14d62d4ede", - "sha256:9c120c9ce3b163b985a3b966bb701114beb1da4b0468b9b236fc754783d85aa3", - "sha256:9f6f3e2598604956480f6c8aa24a3384dbf6509fe995d97f6ca6103bb8c2534e", - "sha256:a1254357f7e4c82e77c348dabf2d55f1d14d19d91ff025004775e70a6ef40ada", - "sha256:a1392e0638af203cee360495fd2cfdd6054711f2db5175b6e9c3c461b76f5175", - "sha256:a1c311fd06ab3b10805abb72109f01a134019739bd3286b8ae1bc2fc4e50c07a", - "sha256:a5cb87bdc2e5f620693148b5f8f842d293cae46c5f15a1b1bf7ceeed324a740c", - "sha256:a7a7902bf75779bc12ccfc508bfb7a4c47063f748ea3de87135d433a4cca7a2f", - "sha256:aad7bd686363d1ce4ee930ad39f14e1673248373f4a9d74d2b9554f06199fb58", - "sha256:aafdb89fdeb5fe165043896817eccd6434aee124d5ee9b354f92cd574ba5e78f", - "sha256:ae8a8843b11dc0b03b57b52793e391f0122e740de3df1474814c700d2622950a", - "sha256:b00bc4619f60c853556b35f83731bd817f989cba3e97dc792bb8c97941b8053a", - "sha256:b1f22a9ab44de5f082216270552aa54259db20189e68fc12484873d926426921", - "sha256:b3c01c2fb081fced3bbb3da78510693dc7121bb893a1f0f5f4b48013201f362e", - "sha256:b3dcd587b69bbf54fc04ca157c2323b8911033e827fffaecf0cafa5a892a0904", - "sha256:b4a6db486ac8e99ae696e09efc8b2b9fea67b63c8f88ba7a1a16c24a057a0776", - "sha256:bec7dd208a4182e99c5b6c501ce0b1f49de2802448d4056091f8e630b28e9a52", - "sha256:c0877239307b7e69d025b73774e88e86ce82f6ba6adf98f41069d5b0b78bd1bf", - "sha256:caa48fc31fc7243e50188197b5f0c4228956f97b954f76da157aae7f67269ae8", - "sha256:cfe1090245c078720d250d19cb05d67e21a9cd7c257698ef139bc41cf6c27b4f", - "sha256:d43002441932f9a9ea5d6f9efaa2e21458221a3a4b417a14027a1d530201ef1b", - "sha256:d64728ee14e667ba27c66314b7d880b8eeb050e58ffc5fec3b7a109f8cddbd63", - "sha256:d6495008733c7521a89422d7a68efa0a0122c99a5861f06020ef5b1f51f9ba7c", - "sha256:d8f1ebca515a03e5654f88411420fea6380fc841d1bea08effb28184e3d4899f", - "sha256:d99277877daf2efe074eae6338453a4ed54a2d93fb4678ddfe1209a0c93a2468", - "sha256:da01bec0a26befab4898ed83b362993c844b9a607a86add78604186297eb047e", - "sha256:db9a28c063c7c00844ae42a80203eb6d2d6bbb97070cfa00194dff40e6f545ab", - "sha256:dda81e5ec82485155a19d9624cfcca9be88a405e2857354e5b089c2a982144b2", - "sha256:e357571bb0efd65fd55f18db0a2fb0ed89d0bb1d41d906b138f088933ae618bb", - "sha256:e544246b859f17373bed915182ab841b80849ed9cf23f1f07b73b7c58baee5fb", - "sha256:e562617a45b5a9da5be4abe72b971d4f00bf8555eb29bb91ec2ef2be348cd132", - "sha256:e570ffeb2170e116a5b17e83f19911020ac79d19c96f320cbfa1fa96b470185b", - "sha256:e6f31a17acede6a8cd1ae2d123ce04d8cca74056c9d456075f4f6f85de055607", - "sha256:e9121b4009339b0f751955baf4543a0bfd6bc3f8188f8056b1a25a2d45099934", - "sha256:ebedb45b9feb7258fac0a268a3f6bec0a2ea4d9558f3d6f813f02ff3a6dc6698", - "sha256:ecaac27da855b8d73f92123e5f03612b04c5632fd0a476e469dfc47cd37d6b2e", - "sha256:ecdbde46235f3d560b18be0cb706c8e8ad1b965e5c13bbba7450c86064e96561", - "sha256:ed550ed05540c03f0e69e6d74ad58d026de61b9eaebebbaaf8873e585cbb18de", - "sha256:eeb3d3d6b399ffe55f9a04e09e635554012f1980696d6b0aca3e6cf42a17a03b", - "sha256:ef337945bbd76cce390d1b2496ccf9f90b1c1242a3a7bc242ca4a9fc5993427a", - "sha256:f1365e032a477c1430cfe0cf2856679529a2331426f8081172c4a74186f1d595", - "sha256:f23b55eb5464468f9e0e9a9935ce3ed2a870608d5f534025cd5536bca25b1402", - "sha256:f2e9072d71c1f6cfc79a36d4484c82823c560e6f5599c43c1ca6b5cdbd54f881", - "sha256:f323306d0556351735b54acbf82904fe30a27b6a7147153cbe6e19aaaa2aa429", - "sha256:f36a3489d9e28fe4b67be9992a23029c3cec0babc3bd9afb39f49844a8c721c5", - "sha256:f64f82cc3443149292b32387086d02a6c7fb39b8781563e0ca7b8d7d9cf72bd7", - "sha256:f6defd966ca3b187ec6c366604e9296f585021d922e666b99c47e78738b5666c", - "sha256:f7c2b8eb9fc872e68b46eeaf835e86bccc3a58ba57d0eedc109cbb14177be531", - "sha256:fa7db7558607afeccb33c0e4bf1c9a9a835e26599e76af6fe2fcea45904083a6", - "sha256:fcb83175cc4936a5425dde3356f079ae03c0802bbdf8ff82c035f8a54b333521" - ], - "markers": "python_version >= '3.7'", - "version": "==2.10.1" - }, - "pydot": { - "hashes": [ - "sha256:248081a39bcb56784deb018977e428605c1c758f10897a339fce1dd728ff007d", - "sha256:66c98190c65b8d2e2382a441b4c0edfdb4f4c025ef9cb9874de478fb0793a451" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.4.2" - }, - "pygit2": { - "hashes": [ - "sha256:30db67f73ef28b07864f2509978b7396d1ed3b72f6f252d301db12a4c9f90f5b", - "sha256:33bbe4d7501a600be320147c63a8d1a966fb7424595e6eb53fdc30259b8921dc", - "sha256:357c11b30d6c63ff58401a897df39b27903beffebb24842c8ce9ce77b90fe0b1", - "sha256:5bd649b9ef17564b642f59e1a2751e30fdd07d3707b0642d8012062615651039", - "sha256:697044df77c8b3849fec8d7dd454acd347b180212c6bc5526eeb9309eff63a65", - "sha256:6ede9700fdbf78a5a1513549f37884233f29d3343412272c0800cda40c4c2c56", - "sha256:74af678b98f6a08ef4315f5b64889011e05ad702e340cc6cde59926906650039", - "sha256:787ea717bb9fadb3ee2836ed32a9ed2110ef861862bfe6b693becda75a2eaa5c", - "sha256:8004244da8183fcefcf7c3d4d119806e9c705543bcf24045b97e3eddaa869aef", - "sha256:825f22a1bbf73c7a11c69e53a29485d10b4df6a635ccd120cf2966e6535a5b52", - "sha256:8d2d97cfe2bf2abbb0ef5984771578d1b05053942bfe1b46d4ac48d19c5eda56", - "sha256:949ad31e0fab408449721cc5b582350f6c5c56ab068bfa10cd6d10c2830deaa9", - "sha256:9c84eff2223e5fd442b746785b9cd21f98c1f53a0f3fe8d4ed06aee60a09ea35", - "sha256:b7356d4e41f122a066fa1cce3f5dbedf73c03781692f5eab3687bc355a083575", - "sha256:ce8618e5876b4c54942587d72a0d84f6e6a5b0e69db5f8d06dc5f567abd07ed1", - "sha256:cf47de2e21cdeb5d8c35f0d1a381b56fdb365dac3dcd8ea7fa057b390ce83d40", - "sha256:d2dbf3d6976b0626fafd7d1c7363ae92dcacaa63789e8c432bc8caea86132235", - "sha256:d6a162db1afdc5bae608d739395a248a373165176f83c7fe57a1073e9168b459", - "sha256:d8e6d540aad9ded1cf2c6bda31ba48b1e20c18525807dbd837317bef4dccb994", - "sha256:ea2b870675ef1a2bef3300dda725aae9f8c68265e633ed683fce85588cfb4d37", - "sha256:ed7fc70bc8f6db227c9919958d064cb49eaa68cc97f51c1f9de920a4500c6766" - ], - "markers": "python_version >= '3.8'", - "version": "==1.13.1" - }, - "pygments": { - "hashes": [ - "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692", - "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29" - ], - "markers": "python_version >= '3.7'", - "version": "==2.16.1" - }, - "pygtrie": { - "hashes": [ - "sha256:203514ad826eb403dab1d2e2ddd034e0d1534bbe4dbe0213bb0593f66beba4e2", - "sha256:8795cda8105493d5ae159a5bef313ff13156c5d4d72feddefacaad59f8c8ce16" - ], - "version": "==2.5.0" - }, - "pyparsing": { - "hashes": [ - "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb", - "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db" - ], - "markers": "python_full_version >= '3.6.8'", - "version": "==3.1.1" - }, - "python-dateutil": { - "hashes": [ - "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", - "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==2.8.2" - }, - "pyyaml": { - "hashes": [ - "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5", - "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc", - "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df", - "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741", - "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206", - "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27", - "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595", - "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62", - "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98", - "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696", - "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290", - "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9", - "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d", - "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6", - "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867", - "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47", - "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486", - "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6", - "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3", - "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007", - "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938", - "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0", - "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c", - "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735", - "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d", - "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28", - "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", - "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", - "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", - "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", - "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", - "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", - "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0", - "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515", - "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c", - "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c", - "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924", - "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34", - "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43", - "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859", - "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673", - "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54", - "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a", - "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b", - "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab", - "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa", - "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c", - "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585", - "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d", - "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f" - ], - "markers": "python_version >= '3.6'", - "version": "==6.0.1" - }, - "requests": { - "hashes": [ - "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f", - "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1" - ], - "markers": "python_version >= '3.7'", - "version": "==2.31.0" - }, - "rich": { - "hashes": [ - "sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245", - "sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef" - ], - "markers": "python_full_version >= '3.7.0'", - "version": "==13.6.0" - }, - "ruamel.yaml": { - "hashes": [ - "sha256:92076ac8a83dbf44ca661dbed3c935229c8cbc2f10b05959dd3bd5292d8353d3", - "sha256:9bce33f7a814cea4c29a9c62fe872d2363d6220b767891d956eacea8fa5e6fe8" - ], - "markers": "python_version >= '3'", - "version": "==0.18.2" - }, - "ruamel.yaml.clib": { - "hashes": [ - "sha256:024cfe1fc7c7f4e1aff4a81e718109e13409767e4f871443cbff3dba3578203d", - "sha256:03d1162b6d1df1caa3a4bd27aa51ce17c9afc2046c31b0ad60a0a96ec22f8001", - "sha256:07238db9cbdf8fc1e9de2489a4f68474e70dffcb32232db7c08fa61ca0c7c462", - "sha256:09b055c05697b38ecacb7ac50bdab2240bfca1a0c4872b0fd309bb07dc9aa3a9", - "sha256:1758ce7d8e1a29d23de54a16ae867abd370f01b5a69e1a3ba75223eaa3ca1a1b", - "sha256:184565012b60405d93838167f425713180b949e9d8dd0bbc7b49f074407c5a8b", - "sha256:1b617618914cb00bf5c34d4357c37aa15183fa229b24767259657746c9077615", - "sha256:25ac8c08322002b06fa1d49d1646181f0b2c72f5cbc15a85e80b4c30a544bb15", - "sha256:25c515e350e5b739842fc3228d662413ef28f295791af5e5110b543cf0b57d9b", - "sha256:3213ece08ea033eb159ac52ae052a4899b56ecc124bb80020d9bbceeb50258e9", - "sha256:3f215c5daf6a9d7bbed4a0a4f760f3113b10e82ff4c5c44bec20a68c8014f675", - "sha256:3fcc54cb0c8b811ff66082de1680b4b14cf8a81dce0d4fbf665c2265a81e07a1", - "sha256:46d378daaac94f454b3a0e3d8d78cafd78a026b1d71443f4966c696b48a6d899", - "sha256:4ecbf9c3e19f9562c7fdd462e8d18dd902a47ca046a2e64dba80699f0b6c09b7", - "sha256:53a300ed9cea38cf5a2a9b069058137c2ca1ce658a874b79baceb8f892f915a7", - "sha256:56f4252222c067b4ce51ae12cbac231bce32aee1d33fbfc9d17e5b8d6966c312", - "sha256:5c365d91c88390c8d0a8545df0b5857172824b1c604e867161e6b3d59a827eaa", - "sha256:665f58bfd29b167039f714c6998178d27ccd83984084c286110ef26b230f259f", - "sha256:700e4ebb569e59e16a976857c8798aee258dceac7c7d6b50cab63e080058df91", - "sha256:7048c338b6c86627afb27faecf418768acb6331fc24cfa56c93e8c9780f815fa", - "sha256:75e1ed13e1f9de23c5607fe6bd1aeaae21e523b32d83bb33918245361e9cc51b", - "sha256:7f67a1ee819dc4562d444bbafb135832b0b909f81cc90f7aa00260968c9ca1b3", - "sha256:840f0c7f194986a63d2c2465ca63af8ccbbc90ab1c6001b1978f05119b5e7334", - "sha256:84b554931e932c46f94ab306913ad7e11bba988104c5cff26d90d03f68258cd5", - "sha256:87ea5ff66d8064301a154b3933ae406b0863402a799b16e4a1d24d9fbbcbe0d3", - "sha256:955eae71ac26c1ab35924203fda6220f84dce57d6d7884f189743e2abe3a9fbe", - "sha256:9eb5dee2772b0f704ca2e45b1713e4e5198c18f515b52743576d196348f374d3", - "sha256:a5aa27bad2bb83670b71683aae140a1f52b0857a2deff56ad3f6c13a017a26ed", - "sha256:a6a9ffd280b71ad062eae53ac1659ad86a17f59a0fdc7699fd9be40525153337", - "sha256:a75879bacf2c987c003368cf14bed0ffe99e8e85acfa6c0bfffc21a090f16880", - "sha256:aab7fd643f71d7946f2ee58cc88c9b7bfc97debd71dcc93e03e2d174628e7e2d", - "sha256:b16420e621d26fdfa949a8b4b47ade8810c56002f5389970db4ddda51dbff248", - "sha256:b42169467c42b692c19cf539c38d4602069d8c1505e97b86387fcf7afb766e1d", - "sha256:b5edda50e5e9e15e54a6a8a0070302b00c518a9d32accc2346ad6c984aacd279", - "sha256:bba64af9fa9cebe325a62fa398760f5c7206b215201b0ec825005f1b18b9bccf", - "sha256:beb2e0404003de9a4cab9753a8805a8fe9320ee6673136ed7f04255fe60bb512", - "sha256:bef08cd86169d9eafb3ccb0a39edb11d8e25f3dae2b28f5c52fd997521133069", - "sha256:c2a72e9109ea74e511e29032f3b670835f8a59bbdc9ce692c5b4ed91ccf1eedb", - "sha256:c58ecd827313af6864893e7af0a3bb85fd529f862b6adbefe14643947cfe2942", - "sha256:c69212f63169ec1cfc9bb44723bf2917cbbd8f6191a00ef3410f5a7fe300722d", - "sha256:cabddb8d8ead485e255fe80429f833172b4cadf99274db39abc080e068cbcc31", - "sha256:d176b57452ab5b7028ac47e7b3cf644bcfdc8cacfecf7e71759f7f51a59e5c92", - "sha256:d92f81886165cb14d7b067ef37e142256f1c6a90a65cd156b063a43da1708cfd", - "sha256:da09ad1c359a728e112d60116f626cc9f29730ff3e0e7db72b9a2dbc2e4beed5", - "sha256:e2b4c44b60eadec492926a7270abb100ef9f72798e18743939bdbf037aab8c28", - "sha256:e79e5db08739731b0ce4850bed599235d601701d5694c36570a99a0c5ca41a9d", - "sha256:ebc06178e8821efc9692ea7544aa5644217358490145629914d8020042c24aa1", - "sha256:edaef1c1200c4b4cb914583150dcaa3bc30e592e907c01117c08b13a07255ec2", - "sha256:f481f16baec5290e45aebdc2a5168ebc6d35189ae6fea7a58787613a25f6e875", - "sha256:fff3573c2db359f091e1589c3d7c5fc2f86f5bdb6f24252c2d8e539d4e45f412" - ], - "markers": "python_version < '3.13' and platform_python_implementation == 'CPython'", - "version": "==0.2.8" - }, - "s3fs": { - "hashes": [ - "sha256:3df68ff4f5f70c3338219a66df92e91fd15c6b78d0f559e57f617dfdd49feb41", - "sha256:c40f238ccc9fefff3f6d09d4b5762abd6c913ba42e1a328976b54d038901b835" - ], - "markers": "python_version >= '3.8'", - "version": "==2023.10.0" - }, - "s3transfer": { - "hashes": [ - "sha256:10d6923c6359175f264811ef4bf6161a3156ce8e350e705396a7557d6293c33a", - "sha256:fd3889a66f5fe17299fe75b82eae6cf722554edca744ca5d5fe308b104883d2e" - ], - "markers": "python_version >= '3.7'", - "version": "==0.7.0" - }, - "scmrepo": { - "hashes": [ - "sha256:4c474005593c078dc27dbc51aa03ffcb6d6530fb2090a93862ef8ae83d50eac9", - "sha256:9548b3fe5de7240bb52d2c9b81da24dd31fa9f612776cfd20e72c8c9e9ddef13" - ], - "markers": "python_version >= '3.8'", - "version": "==1.4.0" - }, - "semver": { - "hashes": [ - "sha256:6253adb39c70f6e51afed2fa7152bcd414c411286088fb4b9effb133885ab4cc", - "sha256:b1ea4686fe70b981f85359eda33199d60c53964284e0cfb4977d243e37cf4bf4" - ], - "markers": "python_version >= '3.7'", - "version": "==3.0.2" - }, - "setuptools": { - "hashes": [ - "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87", - "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a" - ], - "markers": "python_version >= '3.8'", - "version": "==68.2.2" - }, - "shortuuid": { - "hashes": [ - "sha256:27ea8f28b1bd0bf8f15057a3ece57275d2059d2b0bb02854f02189962c13b6aa", - "sha256:fc75f2615914815a8e4cb1501b3a513745cb66ef0fd5fc6fb9f8c3fa3481f789" - ], - "markers": "python_version >= '3.5'", - "version": "==1.0.11" - }, - "shtab": { - "hashes": [ - "sha256:4be38887a912091a1640e06f5ccbcbd24e176cf2fcb9ef0c2e011ee22d63834f", - "sha256:aba9e049bed54ffdb650cb2e02657282d8c0148024b0f500277052df124d47de" - ], - "markers": "python_version >= '3.7'", - "version": "==1.6.4" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" - }, - "smmap": { - "hashes": [ - "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62", - "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da" - ], - "markers": "python_version >= '3.7'", - "version": "==5.0.1" - }, - "sqltrie": { - "hashes": [ - "sha256:80a708960fd9468b645f527b39ea6beae30e57d5d5dd284f54a49ac267d240eb", - "sha256:a773e41f00ae9215a79d3e0537526eaf5e37100037a2ef042d09edcc209abc9e" - ], - "markers": "python_version >= '3.8'", - "version": "==0.8.0" - }, - "tabulate": { - "hashes": [ - "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c", - "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f" - ], - "markers": "python_version >= '3.7'", - "version": "==0.9.0" - }, - "tomlkit": { - "hashes": [ - "sha256:38e1ff8edb991273ec9f6181244a6a391ac30e9f5098e7535640ea6be97a7c86", - "sha256:712cbd236609acc6a3e2e97253dfc52d4c2082982a88f61b640ecf0817eab899" - ], - "markers": "python_version >= '3.7'", - "version": "==0.12.1" - }, - "tqdm": { - "hashes": [ - "sha256:d302b3c5b53d47bce91fea46679d9c3c6508cf6332229aa1e7d8653723793386", - "sha256:d88e651f9db8d8551a62556d3cff9e3034274ca5d66e93197cf2490e2dcb69c7" - ], - "markers": "python_version >= '3.7'", - "version": "==4.66.1" - }, - "typer": { - "hashes": [ - "sha256:50922fd79aea2f4751a8e0408ff10d2662bd0c8bbfa84755a699f3bada2978b2", - "sha256:5d96d986a21493606a358cae4461bd8cdf83cbf33a5aa950ae629ca3b51467ee" - ], - "markers": "python_version >= '3.6'", - "version": "==0.9.0" - }, - "typing-extensions": { - "hashes": [ - "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0", - "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef" - ], - "markers": "python_version >= '3.8'", - "version": "==4.8.0" - }, - "tzdata": { - "hashes": [ - "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a", - "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda" - ], - "markers": "python_version >= '2'", - "version": "==2023.3" - }, - "urllib3": { - "hashes": [ - "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84", - "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e" - ], - "markers": "python_version >= '3.7'", - "version": "==2.0.7" - }, - "vine": { - "hashes": [ - "sha256:4c9dceab6f76ed92105027c49c823800dd33cacce13bdedc5b914e3514b7fb30", - "sha256:7d3b1624a953da82ef63462013bbd271d3eb75751489f9807598e8f340bd637e" - ], - "markers": "python_version >= '3.6'", - "version": "==5.0.0" - }, - "voluptuous": { - "hashes": [ - "sha256:4b838b185f5951f2d6e8752b68fcf18bd7a9c26ded8f143f92d6d28f3921a3e6", - "sha256:e8d31c20601d6773cb14d4c0f42aee29c6821bbd1018039aac7ac5605b489723" - ], - "version": "==0.13.1" - }, - "wcwidth": { - "hashes": [ - "sha256:77f719e01648ed600dfa5402c347481c0992263b81a027344f3e1ba25493a704", - "sha256:8705c569999ffbb4f6a87c6d1b80f324bd6db952f5eb0b95bc07517f4c1813d4" - ], - "version": "==0.2.8" - }, - "wrapt": { - "hashes": [ - "sha256:02fce1852f755f44f95af51f69d22e45080102e9d00258053b79367d07af39c0", - "sha256:077ff0d1f9d9e4ce6476c1a924a3332452c1406e59d90a2cf24aeb29eeac9420", - "sha256:078e2a1a86544e644a68422f881c48b84fef6d18f8c7a957ffd3f2e0a74a0d4a", - "sha256:0970ddb69bba00670e58955f8019bec4a42d1785db3faa043c33d81de2bf843c", - "sha256:1286eb30261894e4c70d124d44b7fd07825340869945c79d05bda53a40caa079", - "sha256:21f6d9a0d5b3a207cdf7acf8e58d7d13d463e639f0c7e01d82cdb671e6cb7923", - "sha256:230ae493696a371f1dbffaad3dafbb742a4d27a0afd2b1aecebe52b740167e7f", - "sha256:26458da5653aa5b3d8dc8b24192f574a58984c749401f98fff994d41d3f08da1", - "sha256:2cf56d0e237280baed46f0b5316661da892565ff58309d4d2ed7dba763d984b8", - "sha256:2e51de54d4fb8fb50d6ee8327f9828306a959ae394d3e01a1ba8b2f937747d86", - "sha256:2fbfbca668dd15b744418265a9607baa970c347eefd0db6a518aaf0cfbd153c0", - "sha256:38adf7198f8f154502883242f9fe7333ab05a5b02de7d83aa2d88ea621f13364", - "sha256:3a8564f283394634a7a7054b7983e47dbf39c07712d7b177b37e03f2467a024e", - "sha256:3abbe948c3cbde2689370a262a8d04e32ec2dd4f27103669a45c6929bcdbfe7c", - "sha256:3bbe623731d03b186b3d6b0d6f51865bf598587c38d6f7b0be2e27414f7f214e", - "sha256:40737a081d7497efea35ab9304b829b857f21558acfc7b3272f908d33b0d9d4c", - "sha256:41d07d029dd4157ae27beab04d22b8e261eddfc6ecd64ff7000b10dc8b3a5727", - "sha256:46ed616d5fb42f98630ed70c3529541408166c22cdfd4540b88d5f21006b0eff", - "sha256:493d389a2b63c88ad56cdc35d0fa5752daac56ca755805b1b0c530f785767d5e", - "sha256:4ff0d20f2e670800d3ed2b220d40984162089a6e2c9646fdb09b85e6f9a8fc29", - "sha256:54accd4b8bc202966bafafd16e69da9d5640ff92389d33d28555c5fd4f25ccb7", - "sha256:56374914b132c702aa9aa9959c550004b8847148f95e1b824772d453ac204a72", - "sha256:578383d740457fa790fdf85e6d346fda1416a40549fe8db08e5e9bd281c6a475", - "sha256:58d7a75d731e8c63614222bcb21dd992b4ab01a399f1f09dd82af17bbfc2368a", - "sha256:5c5aa28df055697d7c37d2099a7bc09f559d5053c3349b1ad0c39000e611d317", - "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2", - "sha256:63424c681923b9f3bfbc5e3205aafe790904053d42ddcc08542181a30a7a51bd", - "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640", - "sha256:74934ebd71950e3db69960a7da29204f89624dde411afbfb3b4858c1409b1e98", - "sha256:75669d77bb2c071333417617a235324a1618dba66f82a750362eccbe5b61d248", - "sha256:75760a47c06b5974aa5e01949bf7e66d2af4d08cb8c1d6516af5e39595397f5e", - "sha256:76407ab327158c510f44ded207e2f76b657303e17cb7a572ffe2f5a8a48aa04d", - "sha256:76e9c727a874b4856d11a32fb0b389afc61ce8aaf281ada613713ddeadd1cfec", - "sha256:77d4c1b881076c3ba173484dfa53d3582c1c8ff1f914c6461ab70c8428b796c1", - "sha256:780c82a41dc493b62fc5884fb1d3a3b81106642c5c5c78d6a0d4cbe96d62ba7e", - "sha256:7dc0713bf81287a00516ef43137273b23ee414fe41a3c14be10dd95ed98a2df9", - "sha256:7eebcdbe3677e58dd4c0e03b4f2cfa346ed4049687d839adad68cc38bb559c92", - "sha256:896689fddba4f23ef7c718279e42f8834041a21342d95e56922e1c10c0cc7afb", - "sha256:96177eb5645b1c6985f5c11d03fc2dbda9ad24ec0f3a46dcce91445747e15094", - "sha256:96e25c8603a155559231c19c0349245eeb4ac0096fe3c1d0be5c47e075bd4f46", - "sha256:9d37ac69edc5614b90516807de32d08cb8e7b12260a285ee330955604ed9dd29", - "sha256:9ed6aa0726b9b60911f4aed8ec5b8dd7bf3491476015819f56473ffaef8959bd", - "sha256:a487f72a25904e2b4bbc0817ce7a8de94363bd7e79890510174da9d901c38705", - "sha256:a4cbb9ff5795cd66f0066bdf5947f170f5d63a9274f99bdbca02fd973adcf2a8", - "sha256:a74d56552ddbde46c246b5b89199cb3fd182f9c346c784e1a93e4dc3f5ec9975", - "sha256:a89ce3fd220ff144bd9d54da333ec0de0399b52c9ac3d2ce34b569cf1a5748fb", - "sha256:abd52a09d03adf9c763d706df707c343293d5d106aea53483e0ec8d9e310ad5e", - "sha256:abd8f36c99512755b8456047b7be10372fca271bf1467a1caa88db991e7c421b", - "sha256:af5bd9ccb188f6a5fdda9f1f09d9f4c86cc8a539bd48a0bfdc97723970348418", - "sha256:b02f21c1e2074943312d03d243ac4388319f2456576b2c6023041c4d57cd7019", - "sha256:b06fa97478a5f478fb05e1980980a7cdf2712015493b44d0c87606c1513ed5b1", - "sha256:b0724f05c396b0a4c36a3226c31648385deb6a65d8992644c12a4963c70326ba", - "sha256:b130fe77361d6771ecf5a219d8e0817d61b236b7d8b37cc045172e574ed219e6", - "sha256:b56d5519e470d3f2fe4aa7585f0632b060d532d0696c5bdfb5e8319e1d0f69a2", - "sha256:b67b819628e3b748fd3c2192c15fb951f549d0f47c0449af0764d7647302fda3", - "sha256:ba1711cda2d30634a7e452fc79eabcadaffedf241ff206db2ee93dd2c89a60e7", - "sha256:bbeccb1aa40ab88cd29e6c7d8585582c99548f55f9b2581dfc5ba68c59a85752", - "sha256:bd84395aab8e4d36263cd1b9308cd504f6cf713b7d6d3ce25ea55670baec5416", - "sha256:c99f4309f5145b93eca6e35ac1a988f0dc0a7ccf9ccdcd78d3c0adf57224e62f", - "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1", - "sha256:cd525e0e52a5ff16653a3fc9e3dd827981917d34996600bbc34c05d048ca35cc", - "sha256:cdb4f085756c96a3af04e6eca7f08b1345e94b53af8921b25c72f096e704e145", - "sha256:ce42618f67741d4697684e501ef02f29e758a123aa2d669e2d964ff734ee00ee", - "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a", - "sha256:d5fe3e099cf07d0fb5a1e23d399e5d4d1ca3e6dfcbe5c8570ccff3e9208274f7", - "sha256:d6bcbfc99f55655c3d93feb7ef3800bd5bbe963a755687cbf1f490a71fb7794b", - "sha256:d787272ed958a05b2c86311d3a4135d3c2aeea4fc655705f074130aa57d71653", - "sha256:e169e957c33576f47e21864cf3fc9ff47c223a4ebca8960079b8bd36cb014fd0", - "sha256:e20076a211cd6f9b44a6be58f7eeafa7ab5720eb796975d0c03f05b47d89eb90", - "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29", - "sha256:eef4d64c650f33347c1f9266fa5ae001440b232ad9b98f1f43dfe7a79435c0a6", - "sha256:f2e69b3ed24544b0d3dbe2c5c0ba5153ce50dcebb576fdc4696d52aa22db6034", - "sha256:f87ec75864c37c4c6cb908d282e1969e79763e0d9becdfe9fe5473b7bb1e5f09", - "sha256:fbec11614dba0424ca72f4e8ba3c420dba07b4a7c206c8c8e4e73f2e98f4c559", - "sha256:fd69666217b62fa5d7c6aa88e507493a34dec4fa20c5bd925e4bc12fce586639" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==1.15.0" - }, - "yarl": { - "hashes": [ - "sha256:04ab9d4b9f587c06d801c2abfe9317b77cdf996c65a90d5e84ecc45010823571", - "sha256:066c163aec9d3d073dc9ffe5dd3ad05069bcb03fcaab8d221290ba99f9f69ee3", - "sha256:13414591ff516e04fcdee8dc051c13fd3db13b673c7a4cb1350e6b2ad9639ad3", - "sha256:149ddea5abf329752ea5051b61bd6c1d979e13fbf122d3a1f9f0c8be6cb6f63c", - "sha256:159d81f22d7a43e6eabc36d7194cb53f2f15f498dbbfa8edc8a3239350f59fe7", - "sha256:1b1bba902cba32cdec51fca038fd53f8beee88b77efc373968d1ed021024cc04", - "sha256:22a94666751778629f1ec4280b08eb11815783c63f52092a5953faf73be24191", - "sha256:2a96c19c52ff442a808c105901d0bdfd2e28575b3d5f82e2f5fd67e20dc5f4ea", - "sha256:2b0738fb871812722a0ac2154be1f049c6223b9f6f22eec352996b69775b36d4", - "sha256:2c315df3293cd521033533d242d15eab26583360b58f7ee5d9565f15fee1bef4", - "sha256:32f1d071b3f362c80f1a7d322bfd7b2d11e33d2adf395cc1dd4df36c9c243095", - "sha256:3458a24e4ea3fd8930e934c129b676c27452e4ebda80fbe47b56d8c6c7a63a9e", - "sha256:38a3928ae37558bc1b559f67410df446d1fbfa87318b124bf5032c31e3447b74", - "sha256:3da8a678ca8b96c8606bbb8bfacd99a12ad5dd288bc6f7979baddd62f71c63ef", - "sha256:494053246b119b041960ddcd20fd76224149cfea8ed8777b687358727911dd33", - "sha256:50f33040f3836e912ed16d212f6cc1efb3231a8a60526a407aeb66c1c1956dde", - "sha256:52a25809fcbecfc63ac9ba0c0fb586f90837f5425edfd1ec9f3372b119585e45", - "sha256:53338749febd28935d55b41bf0bcc79d634881195a39f6b2f767870b72514caf", - "sha256:5415d5a4b080dc9612b1b63cba008db84e908b95848369aa1da3686ae27b6d2b", - "sha256:5610f80cf43b6202e2c33ba3ec2ee0a2884f8f423c8f4f62906731d876ef4fac", - "sha256:566185e8ebc0898b11f8026447eacd02e46226716229cea8db37496c8cdd26e0", - "sha256:56ff08ab5df8429901ebdc5d15941b59f6253393cb5da07b4170beefcf1b2528", - "sha256:59723a029760079b7d991a401386390c4be5bfec1e7dd83e25a6a0881859e716", - "sha256:5fcd436ea16fee7d4207c045b1e340020e58a2597301cfbcfdbe5abd2356c2fb", - "sha256:61016e7d582bc46a5378ffdd02cd0314fb8ba52f40f9cf4d9a5e7dbef88dee18", - "sha256:63c48f6cef34e6319a74c727376e95626f84ea091f92c0250a98e53e62c77c72", - "sha256:646d663eb2232d7909e6601f1a9107e66f9791f290a1b3dc7057818fe44fc2b6", - "sha256:662e6016409828ee910f5d9602a2729a8a57d74b163c89a837de3fea050c7582", - "sha256:674ca19cbee4a82c9f54e0d1eee28116e63bc6fd1e96c43031d11cbab8b2afd5", - "sha256:6a5883464143ab3ae9ba68daae8e7c5c95b969462bbe42e2464d60e7e2698368", - "sha256:6e7221580dc1db478464cfeef9b03b95c5852cc22894e418562997df0d074ccc", - "sha256:75df5ef94c3fdc393c6b19d80e6ef1ecc9ae2f4263c09cacb178d871c02a5ba9", - "sha256:783185c75c12a017cc345015ea359cc801c3b29a2966c2655cd12b233bf5a2be", - "sha256:822b30a0f22e588b32d3120f6d41e4ed021806418b4c9f0bc3048b8c8cb3f92a", - "sha256:8288d7cd28f8119b07dd49b7230d6b4562f9b61ee9a4ab02221060d21136be80", - "sha256:82aa6264b36c50acfb2424ad5ca537a2060ab6de158a5bd2a72a032cc75b9eb8", - "sha256:832b7e711027c114d79dffb92576acd1bd2decc467dec60e1cac96912602d0e6", - "sha256:838162460b3a08987546e881a2bfa573960bb559dfa739e7800ceeec92e64417", - "sha256:83fcc480d7549ccebe9415d96d9263e2d4226798c37ebd18c930fce43dfb9574", - "sha256:84e0b1599334b1e1478db01b756e55937d4614f8654311eb26012091be109d59", - "sha256:891c0e3ec5ec881541f6c5113d8df0315ce5440e244a716b95f2525b7b9f3608", - "sha256:8c2ad583743d16ddbdf6bb14b5cd76bf43b0d0006e918809d5d4ddf7bde8dd82", - "sha256:8c56986609b057b4839968ba901944af91b8e92f1725d1a2d77cbac6972b9ed1", - "sha256:8ea48e0a2f931064469bdabca50c2f578b565fc446f302a79ba6cc0ee7f384d3", - "sha256:8ec53a0ea2a80c5cd1ab397925f94bff59222aa3cf9c6da938ce05c9ec20428d", - "sha256:95d2ecefbcf4e744ea952d073c6922e72ee650ffc79028eb1e320e732898d7e8", - "sha256:9b3152f2f5677b997ae6c804b73da05a39daa6a9e85a512e0e6823d81cdad7cc", - "sha256:9bf345c3a4f5ba7f766430f97f9cc1320786f19584acc7086491f45524a551ac", - "sha256:a60347f234c2212a9f0361955007fcf4033a75bf600a33c88a0a8e91af77c0e8", - "sha256:a74dcbfe780e62f4b5a062714576f16c2f3493a0394e555ab141bf0d746bb955", - "sha256:a83503934c6273806aed765035716216cc9ab4e0364f7f066227e1aaea90b8d0", - "sha256:ac9bb4c5ce3975aeac288cfcb5061ce60e0d14d92209e780c93954076c7c4367", - "sha256:aff634b15beff8902d1f918012fc2a42e0dbae6f469fce134c8a0dc51ca423bb", - "sha256:b03917871bf859a81ccb180c9a2e6c1e04d2f6a51d953e6a5cdd70c93d4e5a2a", - "sha256:b124e2a6d223b65ba8768d5706d103280914d61f5cae3afbc50fc3dfcc016623", - "sha256:b25322201585c69abc7b0e89e72790469f7dad90d26754717f3310bfe30331c2", - "sha256:b7232f8dfbd225d57340e441d8caf8652a6acd06b389ea2d3222b8bc89cbfca6", - "sha256:b8cc1863402472f16c600e3e93d542b7e7542a540f95c30afd472e8e549fc3f7", - "sha256:b9a4e67ad7b646cd6f0938c7ebfd60e481b7410f574c560e455e938d2da8e0f4", - "sha256:be6b3fdec5c62f2a67cb3f8c6dbf56bbf3f61c0f046f84645cd1ca73532ea051", - "sha256:bf74d08542c3a9ea97bb8f343d4fcbd4d8f91bba5ec9d5d7f792dbe727f88938", - "sha256:c027a6e96ef77d401d8d5a5c8d6bc478e8042f1e448272e8d9752cb0aff8b5c8", - "sha256:c0c77533b5ed4bcc38e943178ccae29b9bcf48ffd1063f5821192f23a1bd27b9", - "sha256:c1012fa63eb6c032f3ce5d2171c267992ae0c00b9e164efe4d73db818465fac3", - "sha256:c3a53ba34a636a256d767c086ceb111358876e1fb6b50dfc4d3f4951d40133d5", - "sha256:d4e2c6d555e77b37288eaf45b8f60f0737c9efa3452c6c44626a5455aeb250b9", - "sha256:de119f56f3c5f0e2fb4dee508531a32b069a5f2c6e827b272d1e0ff5ac040333", - "sha256:e65610c5792870d45d7b68c677681376fcf9cc1c289f23e8e8b39c1485384185", - "sha256:e9fdc7ac0d42bc3ea78818557fab03af6181e076a2944f43c38684b4b6bed8e3", - "sha256:ee4afac41415d52d53a9833ebae7e32b344be72835bbb589018c9e938045a560", - "sha256:f364d3480bffd3aa566e886587eaca7c8c04d74f6e8933f3f2c996b7f09bee1b", - "sha256:f3b078dbe227f79be488ffcfc7a9edb3409d018e0952cf13f15fd6512847f3f7", - "sha256:f4e2d08f07a3d7d3e12549052eb5ad3eab1c349c53ac51c209a0e5991bbada78", - "sha256:f7a3d8146575e08c29ed1cd287068e6d02f1c7bdff8970db96683b9591b86ee7" - ], - "markers": "python_version >= '3.7'", - "version": "==1.9.2" - }, - "zc.lockfile": { - "hashes": [ - "sha256:adb2ee6d9e6a2333c91178dcb2c9b96a5744c78edb7712dc784a7d75648e81ec", - "sha256:ddb2d71088c061dc8a5edbaa346b637d742ca1e1564be75cb98e7dcae715de19" - ], - "markers": "python_version >= '3.7'", - "version": "==3.0.post1" - } - }, - "develop": {} -} diff --git a/R/delete_current_year_model_runs.R b/R/delete_current_year_model_runs.R index a1a95019..45b0efdb 100644 --- a/R/delete_current_year_model_runs.R +++ b/R/delete_current_year_model_runs.R @@ -13,9 +13,11 @@ # # delete_current_year_model_runs.R 123,456,789 -library(glue) -library(here) -library(magrittr) +suppressPackageStartupMessages({ + library(glue) + library(here) + library(magrittr) +}) source(here("R", "helpers.R")) current_date <- as.POSIXct(Sys.Date()) diff --git a/README.Rmd b/README.Rmd index 71abcadf..0d65684e 100644 --- a/README.Rmd +++ b/README.Rmd @@ -1,6 +1,6 @@ --- title: "Table of Contents" -output: +output: github_document: toc: true toc_depth: 3 @@ -103,7 +103,7 @@ To counter this, we've listed the major choices we've made about our modeling pr ### Model Selection -We use [LightGBM](https://lightgbm.readthedocs.io/en/latest/) for our primary valuation model. LightGBM is a [GBDT (gradient-boosting decision tree)](https://arogozhnikov.github.io/2016/06/24/gradient_boosting_explained.html) framework created and maintained by Microsoft. It has [an excellent R API](https://cran.r-project.org/web/packages/lightgbm/index.html) and has been around since 2016. +We use [LightGBM](https://lightgbm.readthedocs.io/en/latest/) for our primary valuation model. LightGBM is a [GBDT (gradient-boosting decision tree)](https://arogozhnikov.github.io/2016/06/24/gradient_boosting_explained.html) framework created and maintained by Microsoft. It has [an excellent R API](https://cran.r-project.org/web/packages/lightgbm/index.html) and has been around since 2016. We tried a number of other model types and frameworks, including regularized linear models, [XGBoost](https://xgboost.readthedocs.io/en/latest/), [CatBoost](https://catboost.ai/), random forest, shallow neural networks, and support vector machines. We even tried ensemble methods such as [model stacking](https://github.com/ccao-data/model-res-avm/commit/77de50dce86986f8d442f05c161438933c097958). We chose LightGBM because it has the right mix of trade-offs for our needs. Specifically, LightGBM is: @@ -124,7 +124,7 @@ The downsides of LightGBM are that it is: ### Framework Selection -We use [Tidymodels](https://www.tidymodels.org/) as our primary machine-learning framework. Tidymodels is a set of R packages that work well together and with the [Tidyverse](https://www.tidyverse.org/). These packages abstract away complicated machine-learning logic and allow us to focus on improving our data and models. +We use [Tidymodels](https://www.tidymodels.org/) as our primary machine-learning framework. Tidymodels is a set of R packages that work well together and with the [Tidyverse](https://www.tidyverse.org/). These packages abstract away complicated machine-learning logic and allow us to focus on improving our data and models. Additionally, Tidymodels is: @@ -297,8 +297,8 @@ param_tbl <- as_tibble(params$model$predictor$all) # as a new column param_notes <- param_tbl$value %>% ccao::vars_rename(names_from = "model", names_to = "athena") %>% - map(\(x) get_column_description( - x, dbt_manifest$nodes, hardcoded_descriptions + map(~ get_column_description( + .x, dbt_manifest$nodes, hardcoded_descriptions )) %>% unlist() @@ -417,24 +417,18 @@ These sale prices are our initial prediction for what each property is worth. Th The pipeline also uses a few secondary data sets in the valuation process. These data sets are included in [`input/`](./input) but are not actually used by the model itself. They include: * [`complex_id_data`](#getting-data) - Complex identifiers for class 210 and 295 town/rowhomes. Intended to group like units together to ensure that nearly identical units in close proximity receive the same assessed value. This is accomplished with a "fuzzy grouping" strategy that allows slightly dissimilar characteristics. -* [`land_site_rate_data`](#getting-data) - Fixed, PIN-level land values for class 210 and 295 units. Provided by the Valuations department. -* [`land_nbhd_rate_data`](#getting-data) - Fixed $/sqft land rates by assessor neighborhood for residential property classes except 210 and 295. Provided by the Valuations department. +* [`land_site_rate_data`](#getting-data) - Fixed, PIN-level land values for class 210 and 295 units. Provided by the Valuations department. +* [`land_nbhd_rate_data`](#getting-data) - Fixed $/sqft land rates by assessor neighborhood for residential property classes except 210 and 295. Provided by the Valuations department. #### Representativeness -There's a common saying in the machine learning world: "garbage in, garbage out." This is a succinct way to say that training a predictive model with bad, unrepresentative, or biased data leads to bad results. +There's a common saying in the machine learning world: "garbage in, garbage out." This is a succinct way to say that training a predictive model with bad, unrepresentative, or biased data leads to bad results. To help mitigate the bad data problem and ensure accurate prediction, we do our best to ensure that the sales data used to train the model is representative of the actual market and universe of properties. We accomplish this in two ways. ##### 1. Sales Validation -We use a heuristics-based approach to drop non-arms-length sales, remove outliers, and manually flag certain suspect sales. The code for this approach can be found in [`flagging.py`](./py/flagging.py) and was developed in partnership with the [Mansueto Institute](https://miurban.uchicago.edu/). - -The heuristics classify the following types of outliers using information about each sale: - -![](./docs/figures/sales_validation.png) - -We also employ a few additional heuristics that combine statistical methods with flags derived from the [PTAX-203 form](https://clintonco.illinois.gov/wp-content/uploads/PTAX-203.pdf). Both the heuristic and PTAX-203 flags can be found in the `sv_outier_type` column of the [training data](#primary-data). +We use a heuristics-based approach to drop non-arms-length sales, remove outliers, and manually flag certain suspect sales. This approach was developed in partnership with the [Mansueto Institute](https://miurban.uchicago.edu/). As of 2023, the sales validation code can be found in a dedicated repository at [ccao-data/model-sales-val](https://github.com/ccao-data/model-sales-val). Please visit that repository for more information. ##### 2. Balance Tests @@ -498,8 +492,9 @@ This repository represents a significant departure from the old [residential mod * Dropped explicit spatial lag generation in the ingest stage. * Lots of other bugfixes and minor improvements. -### Upcoming +### `assessment-year-2024` (WIP) +* Moved sales validation to a dedicated repository located at [ccao-data/model-sales-val](https://github.com/ccao-data/model-sales-val). * Infrastructure improvements * Added [`build-and-run-model`](https://github.com/ccao-data/model-res-avm/actions/workflows/build-and-run-model.yaml) workflow to run the model using GitHub Actions and AWS Batch. * Added [`delete-model-run`](https://github.com/ccao-data/model-res-avm/actions/workflows/delete-model-runs.yaml) workflow to delete test run artifacts in S3 using GitHub Actions. @@ -544,7 +539,7 @@ It is difficult for our office to determine whether or not any given property sa ##### Incentives Not to Disclose Accurate Information -The Cook County property tax system is complex and can sometimes create perverse incentives. +The Cook County property tax system is complex and can sometimes create perverse incentives. For example, most property owners want their property taxes to be as low as possible, and are thus disincentivized from reporting characteristic errors which could raise their assessed value. Conversely, if a property owner plans to sell their home on a listing website, then they have a strong incentive (the highest possible sale price) to ensure the website accurately reflects their property's characteristics. Listing websites know this and offer easy ways to self-update property attributes. @@ -554,12 +549,12 @@ Falsely altering or not reporting property characteristics may change an assesse ### Heterogeneity and Extremes -In addition to the data challenges that are specific to our office, we also face the same modeling issues as most assessors and machine learning practitioners. +In addition to the data challenges that are specific to our office, we also face the same modeling issues as most assessors and machine learning practitioners. ##### Housing Heterogeneity -Cook County is an extremely large and diverse housing market. It spans millions of properties that vary widely in type, age, location, and quality. In some regions of the county, sales are common; in other -regions, sales are sparse. Accurately estimating the price of such different properties and regions is a complicated, challenging task. +Cook County is an extremely large and diverse housing market. It spans millions of properties that vary widely in type, age, location, and quality. In some regions of the county, sales are common; in other +regions, sales are sparse. Accurately estimating the price of such different properties and regions is a complicated, challenging task. This challenge is especially acute in areas with high housing characteristic and price heterogeneity. For example, the Hyde Park neighborhood in Chicago is home to the University of Chicago and has large, multi-million-dollar houses near campus. However, sale prices drop precipitously just a few blocks away, as one passes south of 63rd street or west of I-90. This sort of sharp price discontinuity makes it difficult to accurately assess properties, as models tend to "smooth" such hard breaks unless geographic boundaries are explicitly defined. @@ -599,7 +594,7 @@ The importance of individual features in the model varies from place to place. S **Q: How much will one additional bedroom add to my assessed value?** -Our model is non-linear, meaning it's difficult to say things like, "Each additional square foot will increase this property's value by $50," as the relationship between price and individual features varies from property to property. +Our model is non-linear, meaning it's difficult to say things like, "Each additional square foot will increase this property's value by $50," as the relationship between price and individual features varies from property to property. We do calculate the contribution of each feature to each property's final value. For example, we can say things like, "Your close proximity to Lake Michigan added $5,000 to your home's value." We're currently working on a way to share those feature-level results with property owners. @@ -647,7 +642,7 @@ To use this repository, simply open the [pipeline/](./pipeline) directory and ru * [`pipeline/00-ingest.R`](pipeline/00-ingest.R) - Requires access to CCAO internal AWS services to pull data. See [Getting Data](#getting-data) if you are a member of the public. * [`pipeline/06-upload.R`](pipeline/06-upload.R) - Requires access to CCAO internal AWS services to upload model results. -* [`pipeline/07-export.R`](pipeline/07-export.R) - Only required for CCAO internal processes. +* [`pipeline/07-export.R`](pipeline/07-export.R) - Only required for CCAO internal processes. #### Using DVC diff --git a/README.md b/README.md index 64522247..3069a7f9 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Table of Contents - [`assessment-year-2021`](#assessment-year-2021) - [`assessment-year-2022`](#assessment-year-2022) - [`assessment-year-2023`](#assessment-year-2023) - - [Upcoming](#upcoming) + - [`assessment-year-2024` (WIP)](#assessment-year-2024-wip) - [Ongoing Issues](#ongoing-issues) - [Data Quality and Integrity](#data-quality-and-integrity) - [Heterogeneity and Extremes](#heterogeneity-and-extremes) @@ -340,7 +340,7 @@ districts](https://gitlab.com/ccao-data-science---modeling/models/ccao_res_avm/- and many others. The features in the table below are the ones that made the cut. They’re the right combination of easy to understand and impute, powerfully predictive, and well-behaved. Most of them are in use in the -model as of 2023-12-01. +model as of 2023-12-02. | Feature Name | Category | Type | Possible Values | Notes | |:------------------------------------------------------------------------|:---------------|:------------|:-----------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------| @@ -595,21 +595,12 @@ accomplish this in two ways. ##### 1. Sales Validation We use a heuristics-based approach to drop non-arms-length sales, remove -outliers, and manually flag certain suspect sales. The code for this -approach can be found in [`flagging.py`](./py/flagging.py) and was +outliers, and manually flag certain suspect sales. This approach was developed in partnership with the [Mansueto -Institute](https://miurban.uchicago.edu/). - -The heuristics classify the following types of outliers using -information about each sale: - -![](./docs/figures/sales_validation.png) - -We also employ a few additional heuristics that combine statistical -methods with flags derived from the [PTAX-203 -form](https://clintonco.illinois.gov/wp-content/uploads/PTAX-203.pdf). -Both the heuristic and PTAX-203 flags can be found in the -`sv_outier_type` column of the [training data](#primary-data). +Institute](https://miurban.uchicago.edu/). As of 2023, the sales +validation code can be found in a dedicated repository at +[ccao-data/model-sales-val](https://github.com/ccao-data/model-sales-val). +Please visit that repository for more information. ##### 2. Balance Tests @@ -768,8 +759,10 @@ the following major changes to the residential modeling codebase: - Dropped explicit spatial lag generation in the ingest stage. - Lots of other bugfixes and minor improvements. -### Upcoming +### `assessment-year-2024` (WIP) +- Moved sales validation to a dedicated repository located at + [ccao-data/model-sales-val](https://github.com/ccao-data/model-sales-val). - Infrastructure improvements - Added [`build-and-run-model`](https://github.com/ccao-data/model-res-avm/actions/workflows/build-and-run-model.yaml) diff --git a/docs/figures/sales_validation.png b/docs/figures/sales_validation.png deleted file mode 100644 index b8f3ca74..00000000 Binary files a/docs/figures/sales_validation.png and /dev/null differ diff --git a/params.yaml b/params.yaml index 264d5d43..93718299 100644 --- a/params.yaml +++ b/params.yaml @@ -11,9 +11,9 @@ # Note included with each run. Use this to summarize what changed about the run # or add context -run_note: > - Rebuilt final 2023 run (relaxed-dan) using updated proration method. - Re-running with the same model for posterity of the original results +run_note: | + Test run for updated 2024 model pipeline. Uses 2022 data to assess 2023 + since full 2023 data isn't available yet # Determines what stages and outputs are produced. See misc/file_dict.csv for # details. Note, DVC does not support "conditional" stages, so changing this to @@ -41,14 +41,14 @@ toggle: assessment: # Year of assessment. Used to partition results and pull data year: "2023" - + # The statutorily set "sale date" for the purpose of prediction date: "2023-01-01" - + # Added context for model artifacts stored in s3. Does not change behavior triad: "south" group: "residential" - + # Year from which property characteristics are pulled. Usually lags the # assessment year by 1 data_year: "2022" @@ -58,34 +58,9 @@ input: # The min and max year of sales to use for the training data sample min_sale_year: "2014" max_sale_year: "2022" - + # Time window (in months) used for rolling origin cross-validation time_split: 15 - - # Parameters used to trim the training data (sales) of outliers - sale_validation: - - # Summary statistics grouping for detecting outlier sales i.e. an outlier - # might be 3 standard deviations from the mean of township and class - stat_groups: [ - "meta_year", - "meta_township_code", - "meta_class" - ] - - # Predictor variables to use in the isolation forest classifier - iso_forest: [ - "meta_sale_price", - "sv_price_per_sqft", - "sv_days_since_last_transaction", - "sv_cgdr", - "sv_sale_dup_counts" - ] - - # Left and right boundaries (in standard deviations) used to trim the - # training sample e.g. any sales more than 3 standard deviations from the - # mean will be dropped - dev_bounds: [2, 3] # Parameters used to generate townhome complex identifiers complex: @@ -101,7 +76,7 @@ input: "meta_pin_num_cards", "meta_tieback_proration_rate" ] - + # Townhomes should match fuzzily on these variables to be in the same # complex e.g. a PIN with 2000 and a PIN with 2020 square feet will match match_fuzzy: @@ -123,13 +98,13 @@ cv: # Number of initial iterations to create before tuning. Recommend this number # be greater than the number of hyperparameters being tuned initial_set: 25 - + # Max number of total search iterations max_iterations: 70 - + # Max number of search iterations without improvement before stopping search no_improve: 30 - + # Metric used to select the "best" set of parameters from CV iterations. Must # be manually included the metric_set() passed to tune_bayes() best_metric: "rmse" @@ -141,20 +116,20 @@ cv: # model itself model: engine: "lightgbm" - + # Objective/loss function minimized by LightGBM. See website for possible # options: https://lightgbm.readthedocs.io/en/latest/Parameters.html#objective objective: "rmse" - - # Parameters related to model determinism. Current settings should force + + # Parameters related to model determinism. Current settings should force # the same output every time if the same hyperparameters are used seed: 2023 deterministic: TRUE force_row_wise: TRUE - + # Model verbosity: < 0: Fatal, = 0: Error (Warning), = 1: Info, > 1: Debug verbose: -1 - + predictor: # Vector of predictors from the training data included in the model. Edit # this list to add or remove variables from the model @@ -252,7 +227,7 @@ model: "time_sale_day_of_week", "time_sale_post_covid" ] - + # List of predictors included in predictor.all which are categoricals. # It is CRITICAL that any categorical variables are included in this list, # else LightGBM will treat them as numeric @@ -282,7 +257,7 @@ model: "loc_school_secondary_district_geoid", "time_sale_quarter_of_year" ] - + # List of identifiers for each observation, can be ignored id: [ "meta_year", @@ -299,24 +274,24 @@ model: # number of iterations num_iterations: 2000 learning_rate: 0.025 - - # For CV only, proportion of the training data to hold out for use in + + # For CV only, proportion of the training data to hold out for use in # early stopping + the metric to evaluate. See R docs for details: # https://lightgbm.readthedocs.io/en/latest/R/reference/lgb.train.html#arguments # WARNING: See issue #82 for critical notes about early stopping / CV validation_prop: 0.1 validation_type: "recent" validation_metric: "rmse" - + # Custom parameters added by the CCAO's lightsnip wrapper package. Setting # to TRUE will set max_depth = floor(log2(num_leaves)) + add_to_linked_depth # This is to prevent tune_bayes from exploring useless parameter space link_max_depth: TRUE - + # Maximum number of bins for discretizing continuous features. Lower uses # less memory and speeds up training max_bin: 512 - + # During CV, the number of iterations to go without improvement before # stopping training stop_iter: 40 @@ -336,7 +311,7 @@ model: cat_l2: 1.00 lambda_l1: 0.124 lambda_l2: 1.655 - + # Range of possible hyperparameter values for tune_bayes to explore range: num_leaves: [50, 2000] @@ -359,12 +334,12 @@ pv: # For multi-card PINs (rare), implement a heuristic that caps the potential # change in value. See assess stage code for details multicard_yoy_cap: 2.2 - + # Cap the proportion of the PIN's total value dedicated to land. This is # necessary since sometimes the model provides low predictions relative to the # land rates created by Valuations land_pct_of_total_cap: 0.5 - + # Rounding settings to apply to initial predictions. Rounding is done to # indicate to property owners that model values are estimates, not exact round_break: [1000, 10000, 100000] @@ -385,7 +360,7 @@ ratio_study: near_year: "2022" near_stage: "certified" near_column: "meta_certified_tot" - + # Quantile breakouts to use in the evaluate stage. For example, 3 will split # each geography in evaluate into terciles num_quantile: [3, 5, 10] diff --git a/pipeline/00-ingest.R b/pipeline/00-ingest.R index 2505400d..63cf6c01 100644 --- a/pipeline/00-ingest.R +++ b/pipeline/00-ingest.R @@ -20,7 +20,6 @@ suppressPackageStartupMessages({ library(igraph) library(lubridate) library(purrr) - library(reticulate) library(RJDBC) library(tictoc) library(tidyr) @@ -28,10 +27,6 @@ suppressPackageStartupMessages({ }) source(here("R", "helpers.R")) -# Load Python packages and functions with reticulate -use_virtualenv("pipenv/") -source_python("py/flagging.py") - # Initialize a dictionary of file paths. See misc/file_dict.csv for details paths <- model_file_dict() @@ -74,16 +69,20 @@ training_data <- dbGetQuery( sale.deed_type AS meta_sale_deed_type, sale.seller_name AS meta_sale_seller_name, sale.buyer_name AS meta_sale_buyer_name, - sale.sale_filter_is_outlier AS sv_is_ptax203_outlier, + sale.sv_is_outlier, + sale.sv_outlier_type, res.* FROM model.vw_card_res_input res INNER JOIN default.vw_pin_sale sale ON sale.pin = res.meta_pin AND sale.year = res.meta_year - WHERE (res.meta_year + WHERE res.meta_year BETWEEN '{params$input$min_sale_year}' - AND '{params$input$max_sale_year}') + AND '{params$input$max_sale_year}' AND NOT sale.is_multisale + AND NOT sale.sale_filter_same_sale_within_365 + AND NOT sale.sale_filter_less_than_10k + AND NOT sale.sale_filter_deed_type AND Year(sale.sale_date) >= {params$input$min_sale_year} ") ) @@ -147,7 +146,8 @@ rm(AWS_ATHENA_CONN_JDBC, aws_athena_jdbc_driver) # Create a dictionary of column types, as specified in ccao::vars_dict col_type_dict <- ccao::vars_dict %>% - distinct(var_name = var_name_model, var_type = var_data_type) + distinct(var_name = var_name_model, var_type = var_data_type) %>% + drop_na(var_name) # Mini-function to ensure that columns are the correct type recode_column_type <- function(col, col_name, dict = col_type_dict) { @@ -267,71 +267,15 @@ assessment_data_w_hie <- assessment_data %>% #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 5. Validate Sales ------------------------------------------------------------ -#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -message("Validating training data sales") - -# Create an outlier sale flag using a variety of heuristics. See flagging.py for -# the full list. Also exclude any sales that have a flag on Q10 of the PTAX-203 -# form AND are large statistical outliers -training_data_w_sv <- training_data_w_hie %>% - mutate( - meta_sale_price = as.numeric(meta_sale_price), - sv_is_ptax203_outlier = as.logical(as.numeric(sv_is_ptax203_outlier)) - ) %>% - # Run Python-based automatic sales validation to identify outliers - create_stats(as.list(params$input$sale_validation$stat_groups)) %>% - string_processing() %>% - iso_forest( - as.list(params$input$sale_validation$stat_groups), - params$input$sale_validation$iso_forest - ) %>% - outlier_taxonomy( - as.list(params$input$sale_validation$dev_bounds), - as.list(params$input$sale_validation$stat_groups) - ) %>% - # Combine outliers identified via PTAX-203 with the heuristic-based outliers - rename(sv_is_autoval_outlier = sv_is_outlier) %>% - mutate( - sv_is_autoval_outlier = sv_is_autoval_outlier == "Outlier", - sv_is_autoval_outlier = replace_na(sv_is_autoval_outlier, FALSE), - sv_is_outlier = sv_is_autoval_outlier | sv_is_ptax203_outlier, - sv_outlier_type = ifelse( - sv_outlier_type == "Not outlier" & sv_is_ptax203_outlier, - "PTAX-203 flag", - sv_outlier_type - ), - sv_outlier_type = replace_na(sv_outlier_type, "Not outlier"), - sv_is_outlier = sv_outlier_type != "Not outlier" - ) %>% - select( - meta_pin, meta_card_num, meta_sale_date, meta_sale_document_num, - sv_is_ptax203_outlier, sv_is_autoval_outlier, sv_is_outlier, sv_outlier_type - ) %>% - # Rejoin validation output to the original training data. CAUTION: converting - # data to pandas and back WILL alter certain R data types. For example, - # missing character values are replaced with "NA" - right_join( - training_data_w_hie %>% select(-sv_is_ptax203_outlier), - by = c( - "meta_pin", "meta_card_num", - "meta_sale_date", "meta_sale_document_num" - ) - ) - - - - -#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# 6. Add Features and Clean ---------------------------------------------------- +# 5. Add Features and Clean ---------------------------------------------------- #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - message("Adding time features and cleaning") -## 6.1. Training Data ---------------------------------------------------------- +## 5.1. Training Data ---------------------------------------------------------- # Clean up the training data. Goal is to get it into a publishable format. # Final featurization, missingness, etc. is handled via Tidymodels recipes -training_data_clean <- training_data_w_sv %>% +training_data_clean <- training_data_w_hie %>% # Recode factor variables using the definitions stored in ccao::vars_dict # This will remove any categories not stored in the dictionary and convert # them to NA (useful since there are a lot of misrecorded variables) @@ -340,7 +284,7 @@ training_data_clean <- training_data_w_sv %>% # because the SQL drivers will often coerce types on pull (boolean becomes # character) mutate(across( - !starts_with("sv_"), + any_of(col_type_dict$var_name), ~ recode_column_type(.x, cur_column()) )) %>% # Create time/date features using lubridate @@ -378,14 +322,17 @@ training_data_clean <- training_data_w_sv %>% write_parquet(paths$input$training$local) -## 6.2. Assessment Data -------------------------------------------------------- +## 5.2. Assessment Data -------------------------------------------------------- # Clean the assessment data. This is the target data that the trained model is # used on. The cleaning steps are the same as above, with the exception of the # time variables and identifying complexes assessment_data_clean <- assessment_data_w_hie %>% ccao::vars_recode(cols = starts_with("char_"), type = "code") %>% - mutate(across(everything(), ~ recode_column_type(.x, cur_column()))) %>% + mutate(across( + any_of(col_type_dict$var_name), + ~ recode_column_type(.x, cur_column()) + )) %>% # Create sale date features BASED ON THE ASSESSMENT DATE. The model predicts # the sale price of properties on the date of assessment. Not the date of an # actual sale @@ -407,7 +354,7 @@ assessment_data_clean <- assessment_data_w_hie %>% write_parquet(paths$input$assessment$local) -## 6.3. Complex IDs ------------------------------------------------------------ +## 5.3. Complex IDs ------------------------------------------------------------ message("Creating townhome complex identifiers") # Townhomes and rowhomes within the same "complex" or building should @@ -432,7 +379,8 @@ complex_id_temp <- assessment_data_clean %>% full_join( eval(.), by = params$input$complex$match_exact, - multiple = "all" + multiple = "all", + relationship = "many-to-many" ) %>% # Filter with attributes that can be "fuzzy" matched filter( @@ -440,19 +388,18 @@ complex_id_temp <- assessment_data_clean %>% char_rooms.x <= char_rooms.y + params$input$complex$match_fuzzy$rooms, char_bldg_sf.x >= char_bldg_sf.y - params$input$complex$match_fuzzy$bldg_sf, char_bldg_sf.x <= char_bldg_sf.y + params$input$complex$match_fuzzy$bldg_sf, - ((char_yrblt.x >= char_yrblt.y - params$input$complex$match_fuzzy$yrblt & + # nolint start + (char_yrblt.x >= char_yrblt.y - params$input$complex$match_fuzzy$yrblt & char_yrblt.x <= char_yrblt.y + params$input$complex$match_fuzzy$yrblt) | - is.na(char_yrblt.x) - ), + is.na(char_yrblt.x), # Units must be within 250 feet of other units - ((loc_x_3435.x >= loc_x_3435.y - params$input$complex$match_fuzzy$dist_ft & + (loc_x_3435.x >= loc_x_3435.y - params$input$complex$match_fuzzy$dist_ft & loc_x_3435.x <= loc_x_3435.y + params$input$complex$match_fuzzy$dist_ft) | - is.na(loc_x_3435.x) - ), - ((loc_y_3435.x >= loc_y_3435.y - params$input$complex$match_fuzzy$dist_ft & + is.na(loc_x_3435.x), + (loc_y_3435.x >= loc_y_3435.y - params$input$complex$match_fuzzy$dist_ft & loc_y_3435.x <= loc_y_3435.y + params$input$complex$match_fuzzy$dist_ft) | is.na(loc_y_3435.x) - ) + # nolint end ) %>% # Combine PINs into a graph select(meta_pin.x, meta_pin.y) %>% @@ -500,7 +447,7 @@ complex_id_data <- assessment_data_clean %>% write_parquet(paths$input$complex_id$local) -## 6.4. Land Rates ------------------------------------------------------------- +## 5.4. Land Rates ------------------------------------------------------------- message("Saving land rates") # Write land data directly to file, since it's already mostly clean diff --git a/pipeline/02-assess.R b/pipeline/02-assess.R index bde44453..bf88bbdf 100644 --- a/pipeline/02-assess.R +++ b/pipeline/02-assess.R @@ -192,12 +192,14 @@ assessment_pin_data_w_land <- assessment_card_data_round %>% left_join(land_nbhd_rate, by = c("meta_nbhd_code" = "meta_nbhd")) %>% mutate( pred_pin_final_fmv_land = ceiling(case_when( + # nolint start # Use the fixed late value first (unless it exceeds the land % cap) !is.na(land_rate_per_pin) & (land_rate_per_pin > pred_pin_final_fmv_round_no_prorate * params$pv$land_pct_of_total_cap) ~ pred_pin_final_fmv_round_no_prorate * params$pv$land_pct_of_total_cap, !is.na(land_rate_per_pin) ~ land_rate_per_pin, + # nolint end # Otherwise, use the land $/sqft rate (again checking against the cap) char_land_sf * land_rate_per_sqft >= pred_pin_final_fmv_round_no_prorate * params$pv$land_pct_of_total_cap ~ @@ -240,8 +242,8 @@ assessment_pin_data_prorated <- assessment_pin_data_w_land %>% # the proportion of the building's value held by each PIN pred_pin_final_fmv_bldg = pred_pin_final_fmv_bldg_no_prorate * meta_tieback_proration_rate, - temp_bldg_frac_prop = pred_pin_final_fmv_bldg - - as.integer(pred_pin_final_fmv_bldg) + temp_bldg_frac_prop = + pred_pin_final_fmv_bldg - as.integer(pred_pin_final_fmv_bldg) ) %>% # 3. Assign the fractional portion of a building (cents) to whichever portion # is largest i.e. [1.59, 1.41] becomes [2, 1] @@ -310,8 +312,7 @@ assessment_card_data_merged <- assessment_pin_data_prorated %>% sum(pred_card_final_fmv, na.rm = TRUE) - sum(as.integer(pred_card_final_fmv), na.rm = TRUE) ), - pred_card_final_fmv = round(as.integer(pred_card_final_fmv) + - temp_add_diff) + pred_card_final_fmv = round(as.integer(pred_card_final_fmv) + temp_add_diff) ) %>% ungroup() %>% select(-starts_with("temp_")) @@ -514,7 +515,7 @@ assessment_pin_data_final <- assessment_pin_data_sale %>% mutate( flag_prior_near_to_pred_unchanged = prior_near_tot >= pred_pin_final_fmv_round - 100 & - prior_near_tot <= pred_pin_final_fmv_round + 100, + prior_near_tot <= pred_pin_final_fmv_round + 100, # nolint flag_pred_initial_to_final_changed = ccao::val_round_fmv( pred_pin_initial_fmv, breaks = params$pv$round_break, diff --git a/pipeline/05-finalize.R b/pipeline/05-finalize.R index b9bd5ddf..b87c66a2 100644 --- a/pipeline/05-finalize.R +++ b/pipeline/05-finalize.R @@ -11,6 +11,7 @@ suppressPackageStartupMessages({ library(arrow) library(ccao) library(dplyr) + library(git2r) library(here) library(lubridate) library(purrr) diff --git a/pipeline/06-upload.R b/pipeline/06-upload.R index c8db021e..13b3e8a9 100644 --- a/pipeline/06-upload.R +++ b/pipeline/06-upload.R @@ -10,6 +10,7 @@ suppressPackageStartupMessages({ library(arrow) library(aws.s3) library(aws.ec2metadata) + library(ccao) library(dplyr) library(glue) library(here) diff --git a/py/flagging.py b/py/flagging.py deleted file mode 100644 index 3833698b..00000000 --- a/py/flagging.py +++ /dev/null @@ -1,963 +0,0 @@ -""" -This file contains all necessary functions to create a DataFrame ready to use for -non-arms length transaction detection using statistical and heurstic methods. -""" - -import re -import numpy as np -import pandas as pd - -from scipy.stats import zscore -from sklearn.ensemble import IsolationForest -from sklearn.decomposition import PCA - -SHORT_TERM_OWNER_THRESHOLD = 365 # 365 = 365 days or 1 year - - -def create_group_string(groups: tuple, sep: str) -> str: - """ - Creates a string joined on a separator from the groups tuple. - For the purpose of making column names and descriptions. - Inputs: - groups (tuple): the columns being used in groupby() - sep (str): string to separate the groups with. - Outputs: - groups as a string joined by given separator - """ - return sep.join(groups) - - -def outlier_taxonomy(df: pd.DataFrame, permut: tuple, groups: tuple): - """ - Creates columns having to do with our chosen outlier taxonomy. - Ex: Family sale, Home flip sale, Non-person sale, High price (raw and or sqft), etc. - Inputs: - df (pd.DataFrame): dataframe to create taxonomy on. - permut (tuple): permutation of std deviations - groups (tuple): columns to do grouping on. - Probably 'township' and 'class'. - Ouputs: - df (pd.DataFrame): dataframe with outlier taxonomy - """ - - df = check_days(df, SHORT_TERM_OWNER_THRESHOLD) - - df = pricing_info(df, permut, groups) - - df = outlier_type(df) - df = outlier_flag(df) - df = special_flag(df) - - return df - - -def iso_forest(df: pd.DataFrame, - groups: tuple, - columns: list, - n_estimators: int = 1000, - max_samples: int or float = .2) -> pd.DataFrame: - """ - Runs an isolation forest model on our data for outlier detection. - First does PCA, then, attaches township/class info, and then runs the - IsoForest model with given parameters. - Inputs: - df (pd.DataFrame): dataframe with data for IsoForest - groups (tuple): grouping for the data to input into the IsoForest - columns (list): list with columns to run PCA/IsoForest on - n_estimators (int): number of estimators in IsoForest - max_samples(int or float): share of data to use as sample if float, - number to use if int - Outputs: - df (pd.DataFrame): with 'sv_anomaly' column from IsoForest. - """ - - df.set_index('meta_sale_document_num', inplace=True) - - feed = pca(df, columns) - - feed.index = df.index - for group in groups: - feed[group] = df[group] - - isof = IsolationForest(n_estimators=n_estimators, max_samples=max_samples, bootstrap=True, random_state=42) - df['sv_anomaly'] = isof.fit_predict(feed) - - df['sv_anomaly'] = np.select([(df['sv_anomaly'] == -1), (df['sv_anomaly'] == 1)], - ['Outlier', 'Not Outlier'], default= 'Not Outlier') - - df.reset_index(inplace=True) - - return df - - -def pca(df:pd.DataFrame, columns: list) -> pd.DataFrame: - """ - Runs PCA on data, selects compoents where explained variance > 1. - Inputs: - df (pd.DataFrame): dataframe to run PCA on. - columns (list): columns of dataframe to run PCA on. - Outputs: - df (pd.DataFrame): dataframe of principal components - """ - - feed_data = df[columns] - feed_data = feed_data.fillna(0) - feed_data = feed_data.replace([np.inf, -np.inf], 0) - - pca = PCA(n_components = len(feed_data.columns)) - pc = pca.fit_transform(feed_data) - - cols = ['PC' + str(num) for num in range(len(feed_data.columns))] - - pc_df = pd.DataFrame(data = pc, - columns = cols) - take = len(pca.explained_variance_[pca.explained_variance_ > 1]) - - df = pc_df[pc_df.columns[:take]] - - return df - -def pricing_info(df: pd.DataFrame, permut: tuple, groups: tuple) -> pd.DataFrame: - """ - Creates information about whether the price is an outlier, and its movement. - Also fetches the sandard deviation for the record. - pricing is whether it is a high/low outlier and whether it is a price swing. - which_price is whether it is the raw price, price/sqft or both that are outliers. - Inputs: - df (pd.DataFrame): dataframe of sales - permut (tuple): tuple of standard deviation boundaries. - Ex: (2,2) is 2 std away on both sides. - Outputs: - df (pd.DataFrame): dataframe with 3 extra columns of price info. - """ - group_string = create_group_string(groups, '_') - - df = z_normalize(df, ['meta_sale_price', 'sv_price_per_sqft']) - - prices = [f'sv_price_per_sqft_deviation_{group_string}', - f'sv_price_deviation_{group_string}', f'sv_cgdr_deviation_{group_string}'] - - df[f'sv_price_deviation_{group_string}'] = df.groupby(list(groups), group_keys=False)['meta_sale_price'].apply(z_normalize_groupby) - df[f'sv_price_per_sqft_deviation_{group_string}'] = df.groupby(list(groups), group_keys=False)['sv_price_per_sqft'].apply(z_normalize_groupby) - df[f'sv_cgdr_deviation_{group_string}'] = df.groupby(list(groups), group_keys=False)['sv_cgdr'].apply(z_normalize_groupby) - - holds = get_thresh(df, prices, permut, groups) - - df['sv_pricing'] = df.apply(price_column, args=(holds, groups), axis=1) - df['sv_which_price'] = df.apply(which_price, args=(holds, groups), axis=1) - - return df - - -def special_flag(df: pd.DataFrame) -> pd.DataFrame: - """ - Creates column that checks whether there is a special flag for this record. - Inputs: - df (pd.DataFrame): dataframe to add flags onto - Outputs: - df (pd.DataFrame): dataframe with 'special_flags' column - """ - cond = [(df['sv_name_match'] != 'No match'), (df['sv_short_owner'] == 'Short-term owner'), - (df['sv_transaction_type'] == 'legal_entity-legal_entity')] - labels = ['Family sale', 'Home flip sale', 'Non-person sale'] - - df['sv_special_flags'] = np.select(cond, labels, default = 'Not special') - - return df - - -def which_price(row: pd.Series, thresholds: dict, groups: tuple) -> str: - """ - Determines whether sale_price, price_per_sqft, or both are outliers, - and returns a string resembling it. - Inputs: - thresholds (dict): dict of thresholds from get_thresh - Outputs: - value (str): string saying which of these are outliers. - """ - value = 'Non-outlier' - group_string = create_group_string(groups, '_') - key = tuple(row[group] for group in groups) - - if thresholds.get(f'sv_price_deviation_{group_string}').get(key) and \ - thresholds.get(f'sv_price_per_sqft_deviation_{group_string}').get(key): - s_std, *s_std_range = thresholds.get(f'sv_price_deviation_{group_string}').get(key) - s_lower, s_upper = s_std_range - sq_std, *sq_std_range = thresholds.get(f'sv_price_per_sqft_deviation_{group_string}').get(key) - sq_lower, sq_upper = sq_std_range - if not between_two_numbers(row[f'sv_price_deviation_{group_string}'], s_lower, s_upper) and \ - between_two_numbers(row[f'sv_price_per_sqft_deviation_{group_string}'], sq_lower, sq_upper): - value = '(raw)' - elif between_two_numbers(row[f'sv_price_deviation_{group_string}'], s_lower, s_upper) and \ - not between_two_numbers(row[f'sv_price_per_sqft_deviation_{group_string}'], sq_lower, sq_upper): - value = '(sqft)' - elif not between_two_numbers(row[f'sv_price_deviation_{group_string}'], s_lower, s_upper) and \ - not between_two_numbers(row[f'sv_price_per_sqft_deviation_{group_string}'], sq_lower, sq_upper): - value = '(raw & sqft)' - - return value - - -def between_two_numbers(num: int or float, a: int or float, b: int or float) -> bool: - return a < num < b - - -def price_column(row: pd.Series, thresholds: dict, groups: tuple) -> str: - """ - Determines whether the record is a high price outlier or a low price outlier. - If the record is also a price change outlier, than add 'swing' to the string. - Inputs: - thresholds (dict): dict of standard deviation thresholds from get_thresh() - Outputs: - value (str): string showing what kind of price outlier the record is. - """ - value = 'Not price outlier' - price = False - - group_string = create_group_string(groups, '_') - key = tuple(row[group] for group in groups) - - if thresholds.get(f'sv_price_deviation_{group_string}').get(key) and \ - thresholds.get(f'sv_price_per_sqft_deviation_{group_string}').get(key): - - s_std, *s_std_range = thresholds.get(f'sv_price_deviation_{group_string}').get(key) - s_lower, s_upper = s_std_range - - sq_std, *sq_std_range = thresholds.get(f'sv_price_per_sqft_deviation_{group_string}').get(key) - sq_lower, sq_upper = sq_std_range - - if row[f'sv_price_deviation_{group_string}'] > s_upper or\ - row[f'sv_price_per_sqft_deviation_{group_string}'] > sq_upper: - value = 'High price' - price = True - elif row[f'sv_price_deviation_{group_string}'] < s_lower or\ - row[f'sv_price_per_sqft_deviation_{group_string}'] < sq_lower: - value = 'Low price' - price = True - - if price and pd.notnull(row[f'sv_cgdr_deviation_{group_string}']) and\ - thresholds.get(f'sv_cgdr_deviation_{group_string}').get(key): - # not every combo will have pct change info so we need this check - p_std, *p_std_range = thresholds.get(f'sv_cgdr_deviation_{group_string}').get(key) - - p_lower, p_upper = p_std_range - if row['sv_price_movement'] == 'Away from mean' and \ - not between_two_numbers(row[f'sv_cgdr_deviation_{group_string}'], p_lower, p_upper): - value += ' swing' - - return value - - -def create_stats(df: pd.DataFrame, groups: tuple) -> pd.DataFrame: - """ - Create all statistical outlier measures. - Inputs: - df (pd.DataFrame): Dataframe to create statistics from - groups (tuple): grouping for groupby. Usually 'township' and 'class' - Outputs: - df(pd.DataFrame): dataframe with statistical measures calculated. - """ - - df = price_sqft(df) - df = grouping_mean(df, groups) - df = deviation_dollars(df, groups) - df = dup_stats(df, groups) - df = transaction_days(df) - df = percent_change(df) - - return df - - -def percent_change(df: pd.DataFrame) -> pd.DataFrame: - """ - Generates CGR for all records. Requires that transaction_days() has already been run. - Creates 'previous_price' column as intermediary to help calculate CGR. - Calculate the compound growth rate where the previous transaction is the - beginning value, the current price is the end value, and the number of periods - is the number of days since the last transaction. - This enables us to better compare percent change accross different time periods - as opposed to pandas pct_change() function which does not account for time period. - Helper for create_stats(). - Inputs: - df (pd.DataFrame): datarame to create CGR on. - Outputs: - df (pd.DataFrame): dataframe with CGR statistic and previous_price column - """ - - df['sv_previous_price'] = df.sort_values('meta_sale_date').groupby(['meta_pin'])['meta_sale_price'].shift(axis=0) - df['sv_cgdr'] = ((df['meta_sale_price'] / df['sv_previous_price']) ** (1 / df['sv_days_since_last_transaction'])) - 1 - - return df - - -def dup_stats(df: pd.DataFrame, groups: tuple) -> pd.DataFrame: - """ - Stats that can only be calculated for PINs occuring more than once, such as sale volatiltiy, - and growth rates. - Helper for create_stats(). - Inputs: - df (pd.DataFrame): dataframe with sales data - groups (tuple): for get_movement groups - Outputs:mean - df(pd.DataFrame): dataframe with sale counts and town_class movement columns. - """ - dups = df[df.meta_pin.duplicated(keep=False)] - dups = get_sale_counts(dups) - dups = get_movement(dups, groups) - - df = pd.merge(df, dups, how='outer') - - return df - - -def price_sqft(df: pd.DataFrame) -> pd.DataFrame: - """ - Creates price/sqft columns in DataFrame. Must contain 'sale_price', - 'sale_price_log10' and 'sqft' in the columns, where the first two names are - self explanatory and 'sqft' is the properties square footage. - Helper for create_stats(). - Inputs: - df (pd.DataFrame): pandas dataframe with required columns. - Outputs: - df (pd.DataFrame): pandas dataframe with _per_sqft columns. - """ - df['sv_price_per_sqft'] = df['meta_sale_price'] / df['char_bldg_sf'] - df['sv_price_per_sqft'].replace([np.inf, -np.inf], np.nan, inplace=True) - - return df - - -def deviation_dollars(df: pd.DataFrame, groups: tuple) -> pd.DataFrame: - """ - Creates the deviation in dollars of this record from the mean - sale_price and price_per_sqft for the groupby groups. - Inputs: - df (pd.DataFrame): dataframe to create deviations on - groups (tuple): tuple of groups being grouped by - Outputs: - df (pd.DataFrame): dataframe with deviation columns - """ - group_string = create_group_string(groups, '_') - - df[f'sv_deviation_{group_string}_mean_price'] = df['meta_sale_price'] - df[f'sv_mean_price_{group_string}'] - df[f'sv_deviation_{group_string}_mean_price_per_sqft'] = df['sv_price_per_sqft'] - df[f'sv_mean_price_per_sqft_{group_string}'] - - return df - - -def grouping_mean(df: pd.DataFrame, groups: tuple) -> pd.DataFrame: - """ - Gets sale_price mean by two groupings. Usually town + class. - Helper for create_stats(). - Inputs: - df (pd.DataFrame): dataframe with the grouping columns - groups (tuple): tuple (len == 2) where each element is a column name to be grouped by. - Outputs: - df (pd.DataFrame): dataframe with grouped by mean column - """ - group_string = create_group_string(groups, '_') - - group_mean = df.groupby(list(groups))['meta_sale_price'].mean() - group_mean_sqft = df.groupby(list(groups))['sv_price_per_sqft'].mean() - df.set_index(list(groups), inplace=True) - df[f'sv_mean_price_{group_string}'] = group_mean - df[f'sv_mean_price_per_sqft_{group_string}'] = group_mean_sqft - - df.reset_index(inplace=True) - - return df - - -def get_sale_counts(dups: pd.DataFrame) -> pd.DataFrame: - """ - Calculates how many times transactions occured for a gieven property. - Helper for dup_stats() - Inputs: - df (pd.DataFrame): pandsa dataframe - """ - v_counts = dups.meta_pin.value_counts().reset_index().rename(columns={'index':'meta_pin', 'meta_pin':'sv_sale_dup_counts'}) - dups = pd.merge(dups, v_counts, how='outer') - - return dups - - -def get_movement(dups: pd.DataFrame, groups:tuple) -> pd.DataFrame: - """ - Creates a coloumn that determines whether the price movement of the records is - towards or away from the mean. - Helper for dup_stats(). - Inputs: - df (pd.DataFrame): duplicate records - groups (tuple): groupby groups - Outputs: - df (pd.DataFrame): duplicate records with new column - """ - group_string = create_group_string(groups, '_') - - dups[f'sv_deviation_{group_string}_mean_price_abs'] = abs(dups[f'sv_mean_price_{group_string}'] - dups['meta_sale_price']) - - temp = dups.sort_values('meta_sale_date').groupby(['meta_pin'])[f'sv_deviation_{group_string}_mean_price_abs'].shift() - dups['sv_price_movement'] = dups[f'sv_deviation_{group_string}_mean_price_abs'].lt(temp).astype(float) - dups['sv_price_movement'] = np.select([(dups['sv_price_movement'] == 0), (dups['sv_price_movement'] == 1)], - ['Away from mean', 'Towards mean'], default='First sale') - - return dups - - -def transaction_days(df: pd.DataFrame) -> pd.DataFrame: - """ - For each record, gets number of days since the last transaction. - Inputs: - df (pd.DataFrame): DataFrame with a sale_date column in datetime - Outputs: - df (pd.DataFrame): DataFrame with new column - """ - - df['sv_days_since_last_transaction'] = \ - df.sort_values('meta_sale_date').groupby('meta_pin')['meta_sale_date'].diff().apply(lambda x: x.days) - - return df - - -def check_days(df: pd.DataFrame, threshold: int) -> pd.DataFrame: - """ - Creates a label of whether or not the transaction - was only owned for a short term. - If owned for less than the threshold, is a short term owner. - Inputs: - df (pd.DataFrame): dataframe to have short term owners checked - threshold (int): the threshold fo being a short term owner - Oututs: - df (pd.DataFrame): datafrme with 'short_owner' column - """ - df['sv_short_owner'] = np.select([(df['sv_days_since_last_transaction'] < threshold)], - ['Short-term owner'], default = f'Over {threshold} days') - - return df - - -def get_thresh(df: pd.DataFrame, cols: list, permut: tuple, groups: tuple) -> dict: - """ - Creates a nested dictionary where the top level key is a column - and the 2nd-level key is a (township, class) combo. - Ex: stds['sale_price'][76, 203] - Needed in order to keep track of specific thresholds for each township/class combo. - Theoretically each std should be 1(because of z_normalization), but in practical terms - it is in a very very small range around 1, so using a uniform cutoff of 2 and -2 - loses us some precision. - - We also want to allow for some flexibility in how the thresholds are calculated; - and this function allows for more flexbility in the event of future changes. - Inputs: - df (pd.DataFrame): Dataframe to create dictionary from. - cols (list): list of columns to get standard deviations for. - permut (tuple): standard deviation range for lower_limit and upper_limit - First term is how many stndard deviations away on the left - Second term is how many standard deviations away on the right. - Outputs: - stds (dict): nested dictionary of std deviations for all columns - from DataFrame. - """ - stds = {} - - for col in cols: - df[col] = df[col].astype(float) - grouped = df.dropna(subset=list(groups) + [col]).groupby(list(groups))[col] - lower_limit = grouped.mean() - (grouped.std(ddof=0) * permut[0]) - upper_limit = grouped.mean() + (grouped.std(ddof=0) * permut[1]) - std = grouped.std(ddof=0) - lower_limit = lower_limit.to_dict() - upper_limit = upper_limit.to_dict() - std = std.to_dict() - - limits = {x: (std.get(x, 0), lower_limit.get(x, 0), upper_limit.get(x, 0)) - for x in set(std).union(upper_limit, lower_limit)} - stds[col] = limits - - return stds - - -def z_normalize(df: pd.DataFrame, columns: list) -> pd.DataFrame: - """ - Do zscore normalization on given column set so that - we can compare them apples to apples. - Inputs: - df (pd.DataFrame): - columns (list): columsn to be normalized - Outputs: - df (pd.DataFrame): dataframe with given columns normalized - as 'column_name_zscore' - """ - for col in columns: - df['sv_' + col + '_deviation_county'] = zscore(df[col], nan_policy='omit') - - return df - - -def z_normalize_groupby(s: pd.Series): - """ - Function used to z_normailize groups of records. - Pandas stiches it back together into a complete column. - Meant for groupby.apply(). - Inputs: - s(pd.Series): grouped series from groupby.apply - Ouputs: - z_normalized series grouped by class and township - that is then stiched into complete column by pandas - """ - return zscore(s, nan_policy='omit') - - -def outlier_type(df: pd.DataFrame) -> pd.DataFrame: - """ - Runs np.select that creates an outlier taxonomy. - Inputs: - df (pd.DataFrame): dataframe with necessary columns created from previous functions. - Outputs: - df (pd.DataFrame): dataframe with 'sv_outlier_type' column. - """ - conditions = [ - (df['sv_short_owner'] == 'Short-term owner') & (df['sv_pricing'].str.contains('High')), - (df['sv_name_match'] != 'No match') & (df['sv_pricing'].str.contains('High')), - (df['sv_transaction_type'] == 'legal_entity-legal_entity') & (df['sv_pricing'].str.contains('High')), - (df['sv_anomaly'] == 'Outlier') & (df['sv_pricing'].str.contains('High')), - (df['sv_pricing'].str.contains('High price swing')), - (df['sv_pricing'].str.contains('High')) & (df['sv_which_price'] == '(raw & sqft)'), - (df['sv_pricing'].str.contains('High')) & (df['sv_which_price'] == '(raw)'), - (df['sv_pricing'].str.contains('High')) & (df['sv_which_price'] == '(sqft)'), - (df['sv_short_owner'] == 'Short-term owner') & (df['sv_pricing'].str.contains('Low')), - (df['sv_name_match'] != 'No match') & (df['sv_pricing'].str.contains('Low')), - (df['sv_transaction_type'] == 'legal_entity-legal_entity') & (df['sv_pricing'].str.contains('Low')), - (df['sv_anomaly'] == 'Outlier') & (df['sv_pricing'].str.contains('Low')), - (df['sv_pricing'].str.contains('Low price swing')), - (df['sv_pricing'].str.contains('Low')) & (df['sv_which_price'] == '(raw & sqft)'), - (df['sv_pricing'].str.contains('Low')) & (df['sv_which_price'] == '(raw)'), - (df['sv_pricing'].str.contains('Low')) & (df['sv_which_price'] == '(sqft)')] - - labels = ['Home flip sale (high)', 'Family sale (high)', - 'Non-person sale (high)', 'Anomaly (high)', - 'High price swing', - 'High price (raw & sqft)', 'High price (raw)', - 'High price (sqft)', - 'Home flip sale (low)', 'Family sale (low)', - 'Non-person sale (low)', 'Anomaly (low)', - 'Low price swing', - 'Low price (raw & sqft)', 'Low price (raw)', - 'Low price (sqft)'] - - df["sv_outlier_type"] = np.select(conditions, labels, default='Not outlier') - - return df - - -def outlier_flag(df: pd.DataFrame) -> pd.DataFrame: - """ - Creates a flag that shows whether the record is an - outlier (a special flag) according to our outlier taxonomy. - Inputs: - df (pd.DataFrame): dataframe to create outlier flag - Outputs: - df (pd.DataFrame): dataframe with 'is_outlier' column - """ - - df['sv_is_outlier'] = np.select([(df['sv_outlier_type'] == 'Not outlier')], - ['Not outlier'], default='Outlier') - - return df - - -# STRING CLEANUP - -""" - An outline of our overall approach: - - Tries to create an identifier from the buyer/seller name. - Our appraoch is to try to identify if it is a legal identify of some sort, - such as a bank, construction company, trust, LLC, or other and - return the string as-is with some formatting applied if so. We also combine some - spellings/mispellings of big entities. - - If we can't identify the string as a legal entity we assume the string contains a person's name. - We then process these strings to determine if the person is a trustee, successor, - or a successor trustee from the fragements of the strings. - Once we do this, we determine the best place tosplit the string in split_logic(), - looking out for certain tokens. After we've determnined where to split - the string we send the tokens to name_selector, where we attempt to select - the last name of the string. - - We then create a column that tells us whether it's person, or a legal entity, - as per our identification method that we used in get_id(). - - Then we use the trustee, successor, or as successor trustee parts of - the string we constructed earlier to determine the role of the buyer - or seller in the transaction(trustee, successor, successor trustee). - - We then remove the trustee, successor, as successor trustee parts of the string - from buyer/seller id. - - Finally we create a transaction_type column that is just what kind of entity it is - with a dash between them. - - TODO: Process more string types: - - If a name contains 'and', we split the string on it and take - the token directly to the left. We could take a more sophisticated - approach to determine if the last name in this case. - - 'co-trustee' handling. - - Handle different name formats. Assume people use - but sometimes its or other such formats. - - Find trends in string cutoffs(some are cut off at 25, characters, others 25, etc) - that could help use better process strings that are cutoff. - - Cleanup/debug regex. This is a lot of dirty regex, and it is picking up - some names that we don't want, or not correctly identifying every case that we do want. - So it could use some work in some cases. - """ - - -entity_keywords = r"llc| ll$| l$|l l c|estate|training|construction|building|masonry|"\ - r"apartments|plumbing|service|professional|roofing|advanced|office|"\ - r"\blaw\b|loan|legal|production|woodwork|concepts|corp| company|"\ - r" united|\binc\b|county|entertainment|community|heating|cooling"\ - r"|partners|equity|indsutries|series|revitalization|collection|"\ - r"agency|renovation|consulting|flippers|estates|\bthe \b|dept|"\ - r"funding|opportunity|improvements|servicing|equities|sale|"\ - r"judicial| in$|bank|\btrust\b|holding|investment|housing"\ - r"|properties|limited|realty|development|capital|management"\ - r"|developers|construction|rentals|group|investments|invest|"\ - r"residences|enterprise|enterprises|ventures|remodeling|"\ - r"specialists|homes|business|venture|restoration|renovations"\ - r"|maintenance|ltd|real estate|builders|buyers|property|financial"\ - r"|associates|consultants|international|acquisitions|credit|design"\ - r"|homeownership|solutions|home|diversified|assets|family|land|"\ - r"revocable|services|rehabbing|living|county of cook|fannie mae|"\ - r"land|veteran|mortgage|savings|lp$" - - -def get_id(row: pd.Series, col: str) -> str: - """ - Creates an ID from the buyer/seller name. - - Returns string as-is if identified as legal entity. - Combined with other entities if its a common mispelling/cutoff. - - Attempts to identify last name if not a legal entity. - - Inputs: - row: from apply() - col (str): 'buyer' or 'seller' - Outputs: - id (str): string as-is if legal entity - identified last name if otherwise. - """ - - column = col + '_name' - words = str(row[column]).lower() - - words = re.sub(r' amp ','', words) - words = re.sub(' +', ' ', words) - - if words.isspace() or re.search(r'^[.]*$', words): - id = 'Empty Name' - return id - - if any(x in words for x in ['vt investment corpor', 'v t investment corp']): - return 'vt investment corporation' - - if any(x in words for x in ['first integrity group inc', 'first integrity group in']): - return 'first integrity group inc' - - if words in ['deutsche bank national tr']: - return 'deutsche bank national trust company' - - if any(x in words for x in ['cirrus investment group l', 'cirrus investment group']): - return 'cirrus investment group' - - if any(x in words for x in ['fannie mae aka federal na', - 'fannie mae a k a federal', 'federal national mortgage']): - return 'fannie mae' - - if any(x in words for x in ['the judicial sales corpor', 'judicial sales corp', - 'judicial sales corporatio', 'judicial sale corp', 'the judicial sales corp']): - return 'the judicial sales corporation' - - if any(x in words for x in ['jpmorgan chase bank n a', 'jpmorgan chase bank nati']): - return 'jp morgan chase bank' - - if any(x in words for x in ['wells fargo bank na', 'wells fargo bank n a', - 'wells fargo bank nationa', 'wells fargo bank n a a']): - return 'wells fargo bank national' - - if any(x in words for x in ['bayview loan servicing l', 'bayview loan servicing ll']): - return 'bayview loan servicing llc' - - if any(x in words for x in ['thr property illinois l', 'thr property illinois lp']): - return 'thr property illinois lp' - - if any(x in words for x in ['ih3 property illinois lp', 'ih3 property illinois l']): - return 'ih3 property illinois lp' - - if any(x in words for x in ['ih2 property illinois lp', 'ih2 property illinois l']): - return 'ih2 property illinois lp' - - if any(x in words for x in ['secretary of housing and', - 'the secretary of housing', 'secretary of housing ']): - return 'secretary of housing and urban development' - - if any(x in words for x in ['secretary of veterans aff', 'the secretary of veterans']): - return 'secretary of veterans affairs' - - if any(x in words for x in ['bank of america n a', - 'bank of america na', 'bank of america national',]): - return 'bank of america national' - - if any(x in words for x in ['us bank national association', 'u s bank national assoc', - 'u s bank national associ', 'u s bank trust n a as', 'u s bank n a', - 'us bank national associat', 'u s bank trust national']): - return 'us bank national association' - - words = re.sub('suc t$|as succ t$|successor tr$|successor tru$|'\ - 'successor trus$|successor trust$|successor truste$|'\ - 'successor trustee$|successor t$|as successor t$', - 'as successor trustee', words) - words = re.sub('as t$|as s t$|as sole t$|as tr$|as tru$|as trus$|as trust$|'\ - 'as truste$|as trustee$|as trustee o$|as trustee of$|trustee of$|'\ - 'trustee of$|tr$|tru$|trus$|truste$|trustee$|, t|, tr|, tru|, trus|'\ - ', trust|, truste', - 'as trustee', words) - words = re.sub('su$|suc$|succ$|succe$|succes$|success$|successo$|successor$|as s$|as su$|'\ - 'as suc$|as succ$|as succe$|as sucess$|as successo$|, s$|, su$|, suc$|, succ$|'\ - ', succe$|, succes$|, success$|, successo$', - 'as successor', words) - - if re.search(entity_keywords, words) or re.search(r'\d{4}|\d{3}', words) or \ - re.search('as trustee$|as successor$|as successor trustee$', words): - id = words - return id - - words = re.sub(' in$|indi$|indiv$|indivi$|indivi$|individ$|individu$|individua$|individual$'\ - '|not i$|not ind$| ind$| inde$|indep$|indepe$|indepen$|independ$|independe$'\ - '|independen$|independent$', - '', words) - - tokens = split_logic(words) - - id = name_selector(tokens) - - return id - - -def split_logic(words: str): - """ - Given a cleaned string, determines where to split the string. - Splits on 'and', variations of FKA/NKA/KNA if present, on spaces if not. - Helper to get_id(). - Inputs: - words (str): cleaned str from get_id - Outputs: - 'Empty Name' if string is empty - tokens (list): lsit of tokens in string from split - """ - - words = re.sub(' +', ' ', words) - - if words.isspace() or re.search(r'^[.]*$', words) or words == 'Empty Name': - return 'Empty Name' - - words = re.sub(' as$| as $|as $','', words) - - _and = re.search(r'\b and\b|\b an$\b|\b a$\b|f k a|\bfka\b| n k a|\bnka\b|'\ - r'\b aka\b|a k a|\b kna\b|k n a| f k$|n k$|a k$|\b not\b| married', words) - - if _and: - tokens = words.split(_and.group()) - tokens = tokens[0].strip().split() - else: - tokens = words.split() - - return tokens - - -def name_selector(tokens) -> str: - """ - Attempts to select the last name of a persons name based on number of tokens. - Inputs: - tokens: name to be identified - Outputs: - 'Empty Name' if name is empty. - id (str): identified last name - """ - if tokens == 'Empty Name': - return tokens - # Ex: John Smith Jr - if tokens[-1] in ['jr', 'sr', 'ii', 'iii', 'iv', 'v']: - tokens = tokens[:-1] - #Ex: John Smith - if len(tokens) == 2: - id = tokens[1] - # John George Smith - if len(tokens) == 3: - id = tokens[2] - # John George Theodore Smith - else: - id = tokens[-1] - - return id - - -def get_category(row: pd.Series, col: str) -> str: - """ - Gets category buyer/seller id. legal_entity if in entity keywords, - person if otherwise. - Inputs: - row: from pandas dataframe - col (str): column to process. 'buyer' or 'seller' - Outputs: - category (str): category of buyer/seller id - """ - - column = col + '_id' - words = row[column] - - if re.search(entity_keywords, words): - category = 'legal_entity' - elif words == 'Empty Name': - category = 'none' - else: - category = 'person' - - return category - - -def get_role(row: pd.Series, col: str) -> str: - """ - Picks the role th person is playing in the transaction off of the - buyer/seller_id. Meant for apply() - Ex: 'as trustee', or 'as successor' - Inputs: - row: from pandas dataframe - col (str): column to process. 'buyer' or 'seller' - Outputs: - roles(str): the role of the person n the transaction - - """ - role = None - column = col + '_id' - words = row[column] - - suc_trust = re.search(' as successor trustee' , words) - suc = re.search(' as successor' , words) - trust = re.search(' as trustee' , words) - - if suc_trust: - role = suc_trust.group() - - if suc: - role = suc.group() - - if trust: - role = trust.group() - - return role - - -def clean_id(row: pd.Series, col: str) -> str: - """ - Cleans id field after get_role() by removing role. - Inputs: - row: from padnas dataframe - col (str): column to process. 'seller' or 'buyer' - Outputs: - words (str): seller/buyer id without role. - """ - - column = col + '_id' - words = row[column] - - words = re.sub(r' as successor trustee|\b as successor\b| as trustee', '', words) - words = re.sub(' as$| as $|as $','', words) - - if not (re.search(entity_keywords, words) or \ - re.search(r'\d{4}|\d{3}', words) or \ - len(words.split()) == 1): - words = name_selector(split_logic(words)) - - return words - - -def create_judicial_flag(df: pd.DataFrame) -> pd.DataFrame: - """ - Creates a column that contains 1 if sold from a judicial corp - and 0 otherwise. Mean for use with apply(). - Inputs: - df (pd.DataFrame): dataframe to create flag on - Outputs: - df (pd.DataFrame): dataframe with 'sv_is_judicial_sale' column - """ - - df['sv_is_judicial_sale'] = np.select([(df['sv_seller_id'] == 'the judicial sale corporation') | (df['sv_seller_id'] == 'intercounty judicial sale')], - ['1'], default = '0' ) - - return df - - -def create_match_flag(row: pd.Series) -> str: - """ - Creates a column that says whether the buyer/seller id match. - Meant for apply(). - Inputs: - row: from dataframe - Outputs: - value (str): whether the buyer and seller ID match - """ - if row['buyer_id'] == row['seller_id'] and row['buyer_id'] != 'Empty Name': - value = 'Buyer ID and Seller ID match' - else: - value = 'No match' - - return value - - -def create_name_match(row: pd.Series) -> str: - """ - Creates a column that contains the actual string that was matched. - Meant for apply(). - Inputs: - row: from pandas dataframe - Outputs: - value (str or None): string match if applicable, None otherwise - """ - if row['sv_buyer_id'] == row['sv_seller_id'] and row['sv_buyer_id'] != 'Empty Name': - value = row['sv_seller_id'] - else: - value = 'No match' - - return value - - -def string_processing(df: pd.DataFrame) -> pd.DataFrame: - """ - Brings together all of the apply functions for string processing. - Results in 7 additional columns. - ID, category, and role for buyer and seller. As well as transaction category type - for each record. - Inputs: - df (pd.dataFrame): dataframe with buyer/seller id columns. - Ouputs: - df(pd.DataFrame): dataframe with 7 new columns from apply functions - """ - df.meta_sale_buyer_name = df.meta_sale_buyer_name.str.encode('ascii', 'ignore').str.decode('ascii') - df.meta_sale_seller_name = df.meta_sale_seller_name.str.encode('ascii', 'ignore').str.decode('ascii') - df.meta_sale_buyer_name = df.meta_sale_buyer_name.str.replace(r'[^a-zA-Z0-9\-]', ' ', regex=True).str.strip() - df.meta_sale_seller_name = df.meta_sale_seller_name.str.replace(r'[^a-zA-Z0-9\-]', ' ', regex=True).str.strip() - - df['sv_buyer_id'] = df.apply(get_id, args=('meta_sale_buyer',), axis=1) - df['sv_seller_id'] = df.apply(get_id, args=('meta_sale_seller',), axis=1) - df['sv_buyer_category'] = df.apply(get_category, args=('sv_buyer',), axis=1) - df['sv_seller_category'] = df.apply(get_category, args=('sv_seller',), axis=1) - df['sv_buyer_id'] = df.apply(clean_id, args=('sv_buyer',), axis=1) - df['sv_seller_id'] = df.apply(clean_id, args=('sv_seller',), axis=1) - df['sv_transaction_type'] = df['sv_buyer_category'] + '-' + df['sv_seller_category'] - - df = create_judicial_flag(df) - df['sv_name_match'] = df.apply(create_name_match, axis=1) - - return df diff --git a/renv.lock b/renv.lock index 089b0da2..421ff83d 100644 --- a/renv.lock +++ b/renv.lock @@ -58,7 +58,7 @@ }, "Matrix": { "Package": "Matrix", - "Version": "1.6-0", + "Version": "1.6-4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -71,7 +71,7 @@ "stats", "utils" ], - "Hash": "31262fd18481fab05c5e7258dac163ca" + "Hash": "d9c655b30a2edc6bb2244c1d1e8d549d" }, "R6": { "Package": "R6", @@ -116,7 +116,7 @@ }, "arrow": { "Package": "arrow", - "Version": "12.0.1", + "Version": "14.0.0.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -134,17 +134,17 @@ "utils", "vctrs" ], - "Hash": "6f47141e9d2f266b3cd87ac0cb013031" + "Hash": "75782a533f9cddf70709455abcc52d5d" }, "askpass": { "Package": "askpass", - "Version": "1.1", + "Version": "1.2.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "sys" ], - "Hash": "e8a22846fff485f0be3770c2da758713" + "Hash": "cad6cf7f1d5f6e906700b9d3e718c796" }, "assertthat": { "Package": "assertthat", @@ -158,19 +158,19 @@ }, "assessr": { "Package": "assessr", - "Version": "0.5.2", + "Version": "0.6.0", "Source": "GitHub", "RemoteType": "github", + "RemoteHost": "api.github.com", "RemoteUsername": "ccao-data", "RemoteRepo": "assessr", "RemoteRef": "master", - "RemoteSha": "dcfc0f0585462cc87cab42b965d16ec4c5546256", - "RemoteHost": "api.github.com", + "RemoteSha": "de392fb4cfa22f531a913c22d76fee8e717a028e", "Requirements": [ "R", "stats" ], - "Hash": "2bb19b867910fb7334778ec519fac8d2" + "Hash": "530136430459d930e44278cda4a57bd6" }, "aws.ec2metadata": { "Package": "aws.ec2metadata", @@ -278,9 +278,9 @@ }, "butcher": { "Package": "butcher", - "Version": "0.3.2", + "Version": "0.3.3", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -292,7 +292,7 @@ "utils", "vctrs" ], - "Hash": "0804e023949503fee9fab811788deb2f" + "Hash": "0d2c66e9ab0e4f3adfbde1cbb2ed244c" }, "cachem": { "Package": "cachem", @@ -307,14 +307,14 @@ }, "ccao": { "Package": "ccao", - "Version": "1.2.2", + "Version": "1.3.0", "Source": "GitHub", "RemoteType": "github", "RemoteHost": "api.github.com", "RemoteUsername": "ccao-data", "RemoteRepo": "ccao", "RemoteRef": "master", - "RemoteSha": "74737102c48ce07b769a10f42693d9c2c958e9ef", + "RemoteSha": "250586c57b0edf4fe20674953844a4c4797c42b4", "Remotes": "ccao-data/assessr", "Requirements": [ "R", @@ -324,7 +324,7 @@ "rlang", "tidyr" ], - "Hash": "2aaaeceb70766ef2dc175999eb4aa0ad" + "Hash": "dedeeee03ad59adb1892134419d1c793" }, "class": { "Package": "class", @@ -415,10 +415,13 @@ }, "cpp11": { "Package": "cpp11", - "Version": "0.4.4", + "Version": "0.4.6", "Source": "Repository", - "Repository": "CRAN", - "Hash": "3f7d8664d7324406cd10cd650ad85e5f" + "Repository": "RSPM", + "Requirements": [ + "R" + ], + "Hash": "707fae4bbf73697ec8d85f9d7076c061" }, "crayon": { "Package": "crayon", @@ -434,13 +437,13 @@ }, "curl": { "Package": "curl", - "Version": "5.0.1", + "Version": "5.1.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "2118af9cb164c8d2dddc7b89eaf732d9" + "Hash": "9123f3ef96a2c1a93927d828b2fe7d4c" }, "data.table": { "Package": "data.table", @@ -503,9 +506,9 @@ }, "dplyr": { "Package": "dplyr", - "Version": "1.1.2", + "Version": "1.1.4", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -522,7 +525,7 @@ "utils", "vctrs" ], - "Hash": "dea6970ff715ca541c387de363ff405e" + "Hash": "fedd9d00c2944ff00a0e2696ccf048ec" }, "ellipsis": { "Package": "ellipsis", @@ -537,26 +540,26 @@ }, "evaluate": { "Package": "evaluate", - "Version": "0.21", + "Version": "0.23", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "methods" ], - "Hash": "d59f3b464e8da1aef82dc04b588b8dfb" + "Hash": "daf4a1246be12c1fa8c7705a0935c1a0" }, "fansi": { "Package": "fansi", - "Version": "1.0.4", + "Version": "1.0.5", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "grDevices", "utils" ], - "Hash": "1d9e7ad3c8312a192dea7d3db0274fde" + "Hash": "3e8583a60163b4bc1a80016e63b9959e" }, "farver": { "Package": "farver", @@ -643,9 +646,9 @@ }, "ggplot2": { "Package": "ggplot2", - "Version": "3.4.2", + "Version": "3.4.4", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "MASS", "R", @@ -664,11 +667,11 @@ "vctrs", "withr" ], - "Hash": "3a147ee02e85a8941aad9909f1b43b7b" + "Hash": "313d31eff2274ecf4c1d3581db7241f9" }, "git2r": { "Package": "git2r", - "Version": "0.32.0", + "Version": "0.33.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -676,7 +679,7 @@ "graphics", "utils" ], - "Hash": "1882d7a76fd8c14b2322865f74c9a348" + "Hash": "cdec9964efeda730d1b2cd3d5dd27747" }, "globals": { "Package": "globals", @@ -709,7 +712,7 @@ }, "gtable": { "Package": "gtable", - "Version": "0.3.3", + "Version": "0.3.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -720,7 +723,7 @@ "lifecycle", "rlang" ], - "Hash": "b44addadb528a0d227794121c00572a0" + "Hash": "b29cf3031f49b04ab9c852c912547eef" }, "hardhat": { "Package": "hardhat", @@ -774,7 +777,7 @@ }, "httr": { "Package": "httr", - "Version": "1.4.6", + "Version": "1.4.7", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -785,13 +788,13 @@ "mime", "openssl" ], - "Hash": "7e5e3cbd2a7bc07880c94e22348fb661" + "Hash": "ac107251d9d9fd72f0ca8049988f1d7f" }, "infer": { "Package": "infer", - "Version": "1.0.4", + "Version": "1.0.5", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "broom", @@ -806,9 +809,10 @@ "purrr", "rlang", "tibble", - "tidyr" + "tidyr", + "vctrs" ], - "Hash": "b1aa2741a03a90aa9d8187997cfc55c9" + "Hash": "d4e1d781a855d40ebb9ae3aa92daa68d" }, "ipred": { "Package": "ipred", @@ -860,7 +864,7 @@ }, "knitr": { "Package": "knitr", - "Version": "1.43", + "Version": "1.45", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -872,22 +876,22 @@ "xfun", "yaml" ], - "Hash": "9775eb076713f627c07ce41d8199d8f6" + "Hash": "1ec462871063897135c1bcbe0fc8f07d" }, "labeling": { "Package": "labeling", - "Version": "0.4.2", + "Version": "0.4.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "graphics", "stats" ], - "Hash": "3d5108641f47470611a32d0bdf357a72" + "Hash": "b64ec208ac5bc1852b285f665d6368b3" }, "lattice": { "Package": "lattice", - "Version": "0.21-8", + "Version": "0.22-5", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -898,11 +902,11 @@ "stats", "utils" ], - "Hash": "0b8a6d63c8770f02a8b5635f3c431e6b" + "Hash": "7c5e89f04e72d6611c77451f6331a091" }, "lava": { "Package": "lava", - "Version": "1.7.2.1", + "Version": "1.7.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -918,7 +922,7 @@ "survival", "utils" ], - "Hash": "bbc70840ea0f91f34dd9703efe4c96c3" + "Hash": "975f46623ba2e2c059fc959e8bee92b8" }, "lhs": { "Package": "lhs", @@ -933,7 +937,7 @@ }, "lifecycle": { "Package": "lifecycle", - "Version": "1.0.3", + "Version": "1.0.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -942,7 +946,7 @@ "glue", "rlang" ], - "Hash": "001cecbeac1cff9301bdc3775ee46a86" + "Hash": "b8552d117e1b808b09a832f589b79035" }, "lightgbm": { "Package": "lightgbm", @@ -966,11 +970,11 @@ "Version": "0.0.6", "Source": "GitHub", "RemoteType": "github", - "RemoteHost": "api.github.com", "RemoteUsername": "ccao-data", "RemoteRepo": "lightsnip", "RemoteRef": "master", - "RemoteSha": "f877e887a51f8d423d5ca80719e345e31c4c311c", + "RemoteSha": "c2319dbbbf09cbb4655b134b27085293ef01589c", + "RemoteHost": "api.github.com", "Requirements": [ "butcher", "dials", @@ -983,7 +987,7 @@ "tibble", "zip" ], - "Hash": "0d4041d95f45d2d5eaa5aaa1114f2213" + "Hash": "44eadebf16dd7fee876510232e0073b8" }, "listenv": { "Package": "listenv", @@ -1012,16 +1016,16 @@ }, "lubridate": { "Package": "lubridate", - "Version": "1.9.2", + "Version": "1.9.3", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "generics", "methods", "timechange" ], - "Hash": "e25f18436e3efd42c7c590a1c4c15390" + "Hash": "680ad542fbcf801442c83a6ac5a2126c" }, "magrittr": { "Package": "magrittr", @@ -1073,9 +1077,9 @@ }, "modeldata": { "Package": "modeldata", - "Version": "1.1.0", + "Version": "1.2.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "MASS", "R", @@ -1084,7 +1088,7 @@ "rlang", "tibble" ], - "Hash": "df65cdee10e24635c6491ed5a98a31ef" + "Hash": "0b63eecd920994f133739d2e6a17e75e" }, "modelenv": { "Package": "modelenv", @@ -1112,7 +1116,7 @@ }, "nlme": { "Package": "nlme", - "Version": "3.1-162", + "Version": "3.1-164", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1122,7 +1126,7 @@ "stats", "utils" ], - "Hash": "0984ce8da8da9ead8643c5cbbb60f83e" + "Hash": "a623a2239e642806158bc4dc3f51565d" }, "nnet": { "Package": "nnet", @@ -1148,13 +1152,13 @@ }, "openssl": { "Package": "openssl", - "Version": "2.0.6", + "Version": "2.1.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "askpass" ], - "Hash": "0f7cd2962e3044bb940cca4f4b5cecbe" + "Hash": "2a0dc8c6adfb6f032e4d4af82d258ab5" }, "parallelly": { "Package": "parallelly", @@ -1170,9 +1174,9 @@ }, "parsnip": { "Package": "parsnip", - "Version": "1.1.0", + "Version": "1.1.1", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1195,47 +1199,49 @@ "vctrs", "withr" ], - "Hash": "009152502d5125513c353612052e9d4e" + "Hash": "cbb49c720a5e4bf1fe36a870b07d1a0c" }, "patchwork": { "Package": "patchwork", - "Version": "1.1.2", + "Version": "1.1.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ + "cli", "ggplot2", "grDevices", "graphics", "grid", "gtable", + "rlang", "stats", "utils" ], - "Hash": "63b611e9d909a9ed057639d9c3b77152" + "Hash": "c5754106c02e8e019941100c81149431" }, "paws.analytics": { "Package": "paws.analytics", - "Version": "0.3.0", + "Version": "0.4.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "paws.common" ], - "Hash": "f3a27b0314926120e8c333db7645351a" + "Hash": "0690ad4abdce9d81f1df66a4dcc98d6e" }, "paws.application.integration": { "Package": "paws.application.integration", - "Version": "0.3.1", + "Version": "0.4.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "paws.common" ], - "Hash": "bd24295846d31fbfba786d9560b34c6d" + "Hash": "31228082fcbb37d21007efa46f890d63" }, "paws.common": { "Package": "paws.common", - "Version": "0.5.8", + "Version": "0.6.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1246,10 +1252,11 @@ "httr", "jsonlite", "methods", + "stats", "utils", "xml2" ], - "Hash": "35039630a878ed95aa7780ebe8f7e0bf" + "Hash": "fcc0e7509d0c9da0874b5d3a7d8ea904" }, "pillar": { "Package": "pillar", @@ -1280,16 +1287,19 @@ }, "prettyunits": { "Package": "prettyunits", - "Version": "1.1.1", + "Version": "1.2.0", "Source": "Repository", "Repository": "CRAN", - "Hash": "95ef9167b75dde9d2ccc3c7528393e7e" + "Requirements": [ + "R" + ], + "Hash": "6b01fc98b1e86c4f705ce9dcfd2f57c7" }, "prodlim": { "Package": "prodlim", - "Version": "2023.03.31", + "Version": "2023.08.28", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "KernSmooth", "R", @@ -1302,7 +1312,7 @@ "stats", "survival" ], - "Hash": "3f60fadb28cfebdd20b0dd4198a38c60" + "Hash": "c73e09a2039a0f75ac0a1e5454b39993" }, "progress": { "Package": "progress", @@ -1319,21 +1329,21 @@ }, "progressr": { "Package": "progressr", - "Version": "0.13.0", + "Version": "0.14.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "digest", "utils" ], - "Hash": "376a8ebcc878f9c1395e212548fc297a" + "Hash": "ac50c4ffa8f6a46580dd4d7813add3c4" }, "purrr": { "Package": "purrr", - "Version": "1.0.1", + "Version": "1.0.2", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1342,7 +1352,7 @@ "rlang", "vctrs" ], - "Hash": "d71c815267c640f17ddbf7f16144b4bb" + "Hash": "1cba04a4e9414bdefc9dcaa99649a8dc" }, "readr": { "Package": "readr", @@ -1369,9 +1379,9 @@ }, "recipes": { "Package": "recipes", - "Version": "1.0.6", + "Version": "1.0.8", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "Matrix", "R", @@ -1398,32 +1408,30 @@ "vctrs", "withr" ], - "Hash": "eb53ffc9674dc9a52c3a7e22d96d3f56" + "Hash": "d146b858006ebd52e1fe215ee774e3d5" }, "renv": { "Package": "renv", - "Version": "1.0.0", - "Source": "Repository", + "Version": "1.0.3", + "OS_type": null, + "NeedsCompilation": "no", "Repository": "CRAN", - "Requirements": [ - "utils" - ], - "Hash": "c321cd99d56443dbffd1c9e673c0c1a2" + "Source": "Repository" }, "rlang": { "Package": "rlang", - "Version": "1.1.1", + "Version": "1.1.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "utils" ], - "Hash": "a85c767b55f0bf9b7ad16c6d7baee5bb" + "Hash": "50a6dbdc522936ca35afc5e2082ea91b" }, "rpart": { "Package": "rpart", - "Version": "4.1.19", + "Version": "4.1.21", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1432,29 +1440,31 @@ "graphics", "stats" ], - "Hash": "b3c892a81783376cc2204af0f5805a80" + "Hash": "d5bc1a16e01e50e08581f0c362d3955d" }, "rprojroot": { "Package": "rprojroot", - "Version": "2.0.3", + "Version": "2.0.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "1de7ab598047a87bba48434ba35d497d" + "Hash": "4c8415e0ec1e29f3f4f6fc108bef0144" }, "rsample": { "Package": "rsample", - "Version": "1.1.1", + "Version": "1.2.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", + "cli", "dplyr", "furrr", "generics", "glue", + "lifecycle", "methods", "pillar", "purrr", @@ -1465,7 +1475,7 @@ "tidyselect", "vctrs" ], - "Hash": "cb0c54ebc268ec382be8e4d4a8c34557" + "Hash": "b20bb09ceef690842b44585ef49db74e" }, "rstudioapi": { "Package": "rstudioapi", @@ -1476,21 +1486,23 @@ }, "scales": { "Package": "scales", - "Version": "1.2.1", + "Version": "1.3.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "R6", "RColorBrewer", + "cli", "farver", + "glue", "labeling", "lifecycle", "munsell", "rlang", "viridisLite" ], - "Hash": "906cb23d2f1c5680b8ce439b44c6fa63" + "Hash": "c19df082ba346b0ffa6f833e92de34d1" }, "shape": { "Package": "shape", @@ -1507,7 +1519,7 @@ }, "slider": { "Package": "slider", - "Version": "0.3.0", + "Version": "0.3.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1517,11 +1529,11 @@ "vctrs", "warp" ], - "Hash": "c1c73df260af9e1e3692eb3b8e1ecb88" + "Hash": "a584625e2b9e4fad4be135c8ea5c99aa" }, "stringi": { "Package": "stringi", - "Version": "1.7.12", + "Version": "1.8.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1530,11 +1542,11 @@ "tools", "utils" ], - "Hash": "ca8bd84263c77310739d2cf64d84d7c9" + "Hash": "e68c45f81639001af5f1b15cd3599bbd" }, "stringr": { "Package": "stringr", - "Version": "1.5.0", + "Version": "1.5.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1547,11 +1559,11 @@ "stringi", "vctrs" ], - "Hash": "671a4d384ae9d32fc47a14e98bfa3dc8" + "Hash": "960e2ae9e09656611e0b8214ad543207" }, "survival": { "Package": "survival", - "Version": "3.5-5", + "Version": "3.5-7", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1563,7 +1575,7 @@ "stats", "utils" ], - "Hash": "d683341b1fa2e8d817efde27d6e6d35b" + "Hash": "b8e943d262c3da0b0febd3e04517c197" }, "sys": { "Package": "sys", @@ -1604,9 +1616,9 @@ }, "tidymodels": { "Package": "tidymodels", - "Version": "1.1.0", + "Version": "1.1.1", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "broom", @@ -1631,7 +1643,7 @@ "workflowsets", "yardstick" ], - "Hash": "65f6942e7cb9396aa31daeaf0d79f70c" + "Hash": "d48f93a7b5a68070a7a7796e68d281b1" }, "tidyr": { "Package": "tidyr", @@ -1699,9 +1711,9 @@ }, "tune": { "Package": "tune", - "Version": "1.1.1", + "Version": "1.1.2", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "GPfit", "R", @@ -1727,7 +1739,7 @@ "workflows", "yardstick" ], - "Hash": "abf2edf028c09305eaf0159fbb27d851" + "Hash": "d684ce908eb093910df3493510eebbc7" }, "tzdb": { "Package": "tzdb", @@ -1742,17 +1754,17 @@ }, "utf8": { "Package": "utf8", - "Version": "1.2.3", + "Version": "1.2.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "1fe17157424bb09c48a8b3b550c753bc" + "Hash": "62b65c52671e6665f803ff02954446e9" }, "vctrs": { "Package": "vctrs", - "Version": "0.6.3", + "Version": "0.6.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1762,7 +1774,7 @@ "lifecycle", "rlang" ], - "Hash": "d0ef2856b83dc33ea6e255caf6229ee2" + "Hash": "266c1ca411266ba8f365fcc726444b87" }, "viridisLite": { "Package": "viridisLite", @@ -1776,7 +1788,7 @@ }, "vroom": { "Package": "vroom", - "Version": "1.6.3", + "Version": "1.6.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1798,21 +1810,21 @@ "vctrs", "withr" ], - "Hash": "8318e64ffb3a70e652494017ec455561" + "Hash": "9db52c1656cf19c124f93124ea57f0fd" }, "warp": { "Package": "warp", - "Version": "0.2.0", + "Version": "0.2.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "2982481615756e24e79fee95bdc95daa" + "Hash": "fea474d578b1cbcb696ae6ac8bdcc439" }, "withr": { "Package": "withr", - "Version": "2.5.0", + "Version": "2.5.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1821,7 +1833,7 @@ "graphics", "stats" ], - "Hash": "c0e49a9760983e81e55cdd9be92e7182" + "Hash": "4b25e70111b7d644322e9513f403a272" }, "workflows": { "Package": "workflows", @@ -1875,14 +1887,14 @@ }, "xfun": { "Package": "xfun", - "Version": "0.39", + "Version": "0.41", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "stats", "tools" ], - "Hash": "8f56e9acb54fb525e66464d57ab58bcb" + "Hash": "460a5e0fe46a80ef87424ad216028014" }, "xml2": { "Package": "xml2", diff --git a/renv/.gitignore b/renv/.gitignore index 63b9ec4c..f8efdc81 100644 --- a/renv/.gitignore +++ b/renv/.gitignore @@ -5,3 +5,4 @@ local/ lock/ python/ staging/ +profile diff --git a/renv/activate.R b/renv/activate.R index cc742fc9..cb5401f9 100644 --- a/renv/activate.R +++ b/renv/activate.R @@ -2,12 +2,27 @@ local({ # the requested version of renv - version <- "1.0.0" + version <- "1.0.3" attr(version, "sha") <- NULL # the project directory project <- getwd() + # use start-up diagnostics if enabled + diagnostics <- Sys.getenv("RENV_STARTUP_DIAGNOSTICS", unset = "FALSE") + if (diagnostics) { + start <- Sys.time() + profile <- tempfile("renv-startup-", fileext = ".Rprof") + utils::Rprof(profile) + on.exit({ + utils::Rprof(NULL) + elapsed <- signif(difftime(Sys.time(), start, units = "auto"), digits = 2L) + writeLines(sprintf("- renv took %s to run the autoloader.", format(elapsed))) + writeLines(sprintf("- Profile: %s", profile)) + print(utils::summaryRprof(profile)) + }, add = TRUE) + } + # figure out whether the autoloader is enabled enabled <- local({ @@ -504,7 +519,7 @@ local({ # open the bundle for reading # We use gzcon for everything because (from ?gzcon) - # > Reading from a connection which does not supply a ‘gzip’ magic + # > Reading from a connection which does not supply a 'gzip' magic # > header is equivalent to reading from the original connection conn <- gzcon(file(bundle, open = "rb", raw = TRUE)) on.exit(close(conn)) @@ -767,10 +782,12 @@ local({ renv_bootstrap_validate_version <- function(version, description = NULL) { # resolve description file - description <- description %||% { - path <- getNamespaceInfo("renv", "path") - packageDescription("renv", lib.loc = dirname(path)) - } + # + # avoid passing lib.loc to `packageDescription()` below, since R will + # use the loaded version of the package by default anyhow. note that + # this function should only be called after 'renv' is loaded + # https://github.com/rstudio/renv/issues/1625 + description <- description %||% packageDescription("renv") # check whether requested version 'version' matches loaded version of renv sha <- attr(version, "sha", exact = TRUE) @@ -841,7 +858,7 @@ local({ hooks <- getHook("renv::autoload") for (hook in hooks) if (is.function(hook)) - tryCatch(hook(), error = warning) + tryCatch(hook(), error = warnify) # load the project renv::load(project) @@ -982,10 +999,15 @@ local({ } - renv_bootstrap_version_friendly <- function(version, sha = NULL) { + renv_bootstrap_version_friendly <- function(version, shafmt = NULL, sha = NULL) { sha <- sha %||% attr(version, "sha", exact = TRUE) - parts <- c(version, sprintf("[sha: %s]", substring(sha, 1L, 7L))) - paste(parts, collapse = " ") + parts <- c(version, sprintf(shafmt %||% " [sha: %s]", substring(sha, 1L, 7L))) + paste(parts, collapse = "") + } + + renv_bootstrap_exec <- function(project, libpath, version) { + if (!renv_bootstrap_load(project, libpath, version)) + renv_bootstrap_run(version, libpath) } renv_bootstrap_run <- function(version, libpath) { @@ -1012,11 +1034,6 @@ local({ } - - renv_bootstrap_in_rstudio <- function() { - commandArgs()[[1]] == "RStudio" - } - renv_json_read <- function(file = NULL, text = NULL) { jlerr <- NULL @@ -1155,26 +1172,8 @@ local({ # construct full libpath libpath <- file.path(root, prefix) - # attempt to load - if (renv_bootstrap_load(project, libpath, version)) - return(TRUE) - - if (renv_bootstrap_in_rstudio()) { - setHook("rstudio.sessionInit", function(...) { - renv_bootstrap_run(version, libpath) - - # Work around buglet in RStudio if hook uses readline - tryCatch( - { - tools <- as.environment("tools:rstudio") - tools$.rs.api.sendToConsole("", echo = FALSE, focus = FALSE) - }, - error = function(cnd) {} - ) - }) - } else { - renv_bootstrap_run(version, libpath) - } + # run bootstrap code + renv_bootstrap_exec(project, libpath, version) invisible() diff --git a/renv/profiles/reporting/renv.lock b/renv/profiles/reporting/renv.lock index 2b58417f..ca612662 100644 --- a/renv/profiles/reporting/renv.lock +++ b/renv/profiles/reporting/renv.lock @@ -1,6 +1,6 @@ { "R": { - "Version": "4.2.2", + "Version": "4.3.2", "Repositories": [ { "Name": "CRAN", @@ -48,9 +48,9 @@ }, "Matrix": { "Package": "Matrix", - "Version": "1.6-0", + "Version": "1.6-4", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "grDevices", @@ -61,7 +61,7 @@ "stats", "utils" ], - "Hash": "31262fd18481fab05c5e7258dac163ca" + "Hash": "d9c655b30a2edc6bb2244c1d1e8d549d" }, "R6": { "Package": "R6", @@ -96,13 +96,13 @@ }, "askpass": { "Package": "askpass", - "Version": "1.1", + "Version": "1.2.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "sys" ], - "Hash": "e8a22846fff485f0be3770c2da758713" + "Hash": "cad6cf7f1d5f6e906700b9d3e718c796" }, "base64enc": { "Package": "base64enc", @@ -116,9 +116,9 @@ }, "bslib": { "Package": "bslib", - "Version": "0.5.1", + "Version": "0.6.1", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "base64enc", @@ -127,12 +127,13 @@ "htmltools", "jquerylib", "jsonlite", + "lifecycle", "memoise", "mime", "rlang", "sass" ], - "Hash": "283015ddfbb9d7bf15ea9f0b5698f0d9" + "Hash": "c0d8599494bc7fb408cd206bbdd9cab0" }, "cachem": { "Package": "cachem", @@ -201,33 +202,36 @@ }, "cpp11": { "Package": "cpp11", - "Version": "0.4.4", + "Version": "0.4.6", "Source": "Repository", "Repository": "RSPM", - "Hash": "3f7d8664d7324406cd10cd650ad85e5f" + "Requirements": [ + "R" + ], + "Hash": "707fae4bbf73697ec8d85f9d7076c061" }, "crosstalk": { "Package": "crosstalk", - "Version": "1.2.0", + "Version": "1.2.1", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R6", "htmltools", "jsonlite", "lazyeval" ], - "Hash": "6aa54f69598c32177e920eb3402e8293" + "Hash": "ab12c7b080a57475248a30f4db6298c0" }, "curl": { "Package": "curl", - "Version": "5.0.1", + "Version": "5.1.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "R" ], - "Hash": "2118af9cb164c8d2dddc7b89eaf732d9" + "Hash": "9123f3ef96a2c1a93927d828b2fe7d4c" }, "data.table": { "Package": "data.table", @@ -253,9 +257,9 @@ }, "dplyr": { "Package": "dplyr", - "Version": "1.1.2", + "Version": "1.1.4", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -272,7 +276,7 @@ "utils", "vctrs" ], - "Hash": "dea6970ff715ca541c387de363ff405e" + "Hash": "fedd9d00c2944ff00a0e2696ccf048ec" }, "e1071": { "Package": "e1071", @@ -303,26 +307,26 @@ }, "evaluate": { "Package": "evaluate", - "Version": "0.21", + "Version": "0.23", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "R", "methods" ], - "Hash": "d59f3b464e8da1aef82dc04b588b8dfb" + "Hash": "daf4a1246be12c1fa8c7705a0935c1a0" }, "fansi": { "Package": "fansi", - "Version": "1.0.4", + "Version": "1.0.5", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "grDevices", "utils" ], - "Hash": "1d9e7ad3c8312a192dea7d3db0274fde" + "Hash": "3e8583a60163b4bc1a80016e63b9959e" }, "farver": { "Package": "farver", @@ -374,7 +378,7 @@ }, "ggplot2": { "Package": "ggplot2", - "Version": "3.4.2", + "Version": "3.4.4", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -395,7 +399,7 @@ "vctrs", "withr" ], - "Hash": "3a147ee02e85a8941aad9909f1b43b7b" + "Hash": "313d31eff2274ecf4c1d3581db7241f9" }, "glue": { "Package": "glue", @@ -424,7 +428,7 @@ }, "gtable": { "Package": "gtable", - "Version": "0.3.3", + "Version": "0.3.4", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -435,7 +439,17 @@ "lifecycle", "rlang" ], - "Hash": "b44addadb528a0d227794121c00572a0" + "Hash": "b29cf3031f49b04ab9c852c912547eef" + }, + "here": { + "Package": "here", + "Version": "1.0.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "rprojroot" + ], + "Hash": "24b224366f9c2e7534d2344d10d59211" }, "highr": { "Package": "highr", @@ -450,9 +464,9 @@ }, "htmltools": { "Package": "htmltools", - "Version": "0.5.6", + "Version": "0.5.7", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "base64enc", @@ -463,11 +477,11 @@ "rlang", "utils" ], - "Hash": "a2326a66919a3311f7fbb1e3bf568283" + "Hash": "2d7b3857980e0e0d0a1fd6f11928ab0f" }, "htmlwidgets": { "Package": "htmlwidgets", - "Version": "1.6.2", + "Version": "1.6.3", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -478,11 +492,11 @@ "rmarkdown", "yaml" ], - "Hash": "a865aa85bcb2697f47505bfd70422471" + "Hash": "a4040b08269c9af64554e55f514d002c" }, "httr": { "Package": "httr", - "Version": "1.4.6", + "Version": "1.4.7", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -493,7 +507,7 @@ "mime", "openssl" ], - "Hash": "7e5e3cbd2a7bc07880c94e22348fb661" + "Hash": "ac107251d9d9fd72f0ca8049988f1d7f" }, "isoband": { "Package": "isoband", @@ -528,7 +542,7 @@ }, "knitr": { "Package": "knitr", - "Version": "1.43", + "Version": "1.45", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -540,18 +554,18 @@ "xfun", "yaml" ], - "Hash": "9775eb076713f627c07ce41d8199d8f6" + "Hash": "1ec462871063897135c1bcbe0fc8f07d" }, "labeling": { "Package": "labeling", - "Version": "0.4.2", + "Version": "0.4.3", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "graphics", "stats" ], - "Hash": "3d5108641f47470611a32d0bdf357a72" + "Hash": "b64ec208ac5bc1852b285f665d6368b3" }, "later": { "Package": "later", @@ -566,7 +580,7 @@ }, "lattice": { "Package": "lattice", - "Version": "0.21-8", + "Version": "0.22-5", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -577,7 +591,7 @@ "stats", "utils" ], - "Hash": "0b8a6d63c8770f02a8b5635f3c431e6b" + "Hash": "7c5e89f04e72d6611c77451f6331a091" }, "lazyeval": { "Package": "lazyeval", @@ -627,16 +641,16 @@ }, "lifecycle": { "Package": "lifecycle", - "Version": "1.0.3", + "Version": "1.0.4", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "cli", "glue", "rlang" ], - "Hash": "001cecbeac1cff9301bdc3775ee46a86" + "Hash": "b8552d117e1b808b09a832f589b79035" }, "magrittr": { "Package": "magrittr", @@ -699,9 +713,9 @@ }, "nlme": { "Package": "nlme", - "Version": "3.1-162", + "Version": "3.1-164", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "graphics", @@ -709,17 +723,17 @@ "stats", "utils" ], - "Hash": "0984ce8da8da9ead8643c5cbbb60f83e" + "Hash": "a623a2239e642806158bc4dc3f51565d" }, "openssl": { "Package": "openssl", - "Version": "2.0.6", + "Version": "2.1.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "askpass" ], - "Hash": "0f7cd2962e3044bb940cca4f4b5cecbe" + "Hash": "2a0dc8c6adfb6f032e4d4af82d258ab5" }, "packrat": { "Package": "packrat", @@ -856,9 +870,9 @@ }, "purrr": { "Package": "purrr", - "Version": "1.0.1", + "Version": "1.0.2", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -867,7 +881,7 @@ "rlang", "vctrs" ], - "Hash": "d71c815267c640f17ddbf7f16144b4bb" + "Hash": "1cba04a4e9414bdefc9dcaa99649a8dc" }, "quarto": { "Package": "quarto", @@ -912,24 +926,24 @@ }, "renv": { "Package": "renv", - "Version": "1.0.0", + "Version": "1.0.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "utils" ], - "Hash": "c321cd99d56443dbffd1c9e673c0c1a2" + "Hash": "41b847654f567341725473431dd0d5ab" }, "rlang": { "Package": "rlang", - "Version": "1.1.1", + "Version": "1.1.2", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "utils" ], - "Hash": "a85c767b55f0bf9b7ad16c6d7baee5bb" + "Hash": "50a6dbdc522936ca35afc5e2082ea91b" }, "rmarkdown": { "Package": "rmarkdown", @@ -955,6 +969,16 @@ ], "Hash": "d65e35823c817f09f4de424fcdfa812a" }, + "rprojroot": { + "Package": "rprojroot", + "Version": "2.0.4", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R" + ], + "Hash": "4c8415e0ec1e29f3f4f6fc108bef0144" + }, "rsconnect": { "Package": "rsconnect", "Version": "1.1.1", @@ -1012,21 +1036,23 @@ }, "scales": { "Package": "scales", - "Version": "1.2.1", + "Version": "1.3.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R6", "RColorBrewer", + "cli", "farver", + "glue", "labeling", "lifecycle", "munsell", "rlang", "viridisLite" ], - "Hash": "906cb23d2f1c5680b8ce439b44c6fa63" + "Hash": "c19df082ba346b0ffa6f833e92de34d1" }, "sf": { "Package": "sf", @@ -1053,7 +1079,7 @@ }, "sp": { "Package": "sp", - "Version": "2.1-1", + "Version": "2.1-2", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1066,26 +1092,26 @@ "stats", "utils" ], - "Hash": "e9090fe4ff468d366aa6a76a9b3ec078" + "Hash": "40a9887191d33b2521a1d741f8c8aea2" }, "stringi": { "Package": "stringi", - "Version": "1.7.12", + "Version": "1.8.2", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "stats", "tools", "utils" ], - "Hash": "ca8bd84263c77310739d2cf64d84d7c9" + "Hash": "e68c45f81639001af5f1b15cd3599bbd" }, "stringr": { "Package": "stringr", - "Version": "1.5.0", + "Version": "1.5.1", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1096,7 +1122,7 @@ "stringi", "vctrs" ], - "Hash": "671a4d384ae9d32fc47a14e98bfa3dc8" + "Hash": "960e2ae9e09656611e0b8214ad543207" }, "sys": { "Package": "sys", @@ -1177,40 +1203,40 @@ }, "tinytex": { "Package": "tinytex", - "Version": "0.47", + "Version": "0.49", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "xfun" ], - "Hash": "8d4ccb733843e513c1c1cdd66a759f0d" + "Hash": "5ac22900ae0f386e54f1c307eca7d843" }, "units": { "Package": "units", - "Version": "0.8-4", + "Version": "0.8-5", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "Rcpp" ], - "Hash": "e0fbcea25008a7540c83c2c294135de0" + "Hash": "119d19da480e873f72241ff6962ffd83" }, "utf8": { "Package": "utf8", - "Version": "1.2.3", + "Version": "1.2.4", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R" ], - "Hash": "1fe17157424bb09c48a8b3b550c753bc" + "Hash": "62b65c52671e6665f803ff02954446e9" }, "vctrs": { "Package": "vctrs", - "Version": "0.6.3", + "Version": "0.6.4", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1218,7 +1244,7 @@ "lifecycle", "rlang" ], - "Hash": "d0ef2856b83dc33ea6e255caf6229ee2" + "Hash": "266c1ca411266ba8f365fcc726444b87" }, "viridis": { "Package": "viridis", @@ -1245,37 +1271,37 @@ }, "withr": { "Package": "withr", - "Version": "2.5.0", + "Version": "2.5.2", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "grDevices", "graphics", "stats" ], - "Hash": "c0e49a9760983e81e55cdd9be92e7182" + "Hash": "4b25e70111b7d644322e9513f403a272" }, "wk": { "Package": "wk", - "Version": "0.9.0", + "Version": "0.9.1", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R" ], - "Hash": "f58cfa8d9c3a78a309d455a647dee853" + "Hash": "5d4545e140e36476f35f20d0ca87963e" }, "xfun": { "Package": "xfun", - "Version": "0.39", + "Version": "0.41", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "stats", "tools" ], - "Hash": "8f56e9acb54fb525e66464d57ab58bcb" + "Hash": "460a5e0fe46a80ef87424ad216028014" }, "yaml": { "Package": "yaml", diff --git a/renv/settings.json b/renv/settings.json index f836f3f1..af034ffd 100644 --- a/renv/settings.json +++ b/renv/settings.json @@ -1,7 +1,9 @@ { "bioconductor.version": null, "external.libraries": [], - "ignored.packages": [], + "ignored.packages": [ + "quarto" + ], "package.dependency.fields": [ "Imports", "Depends",