diff --git a/.github/workflows/pytest_workflow.yml b/.github/workflows/pytest_workflow.yml index d19329b..b5ddd1c 100644 --- a/.github/workflows/pytest_workflow.yml +++ b/.github/workflows/pytest_workflow.yml @@ -23,7 +23,7 @@ jobs: poetry config virtualenvs.in-project true - name: Install dependencies with Poetry run: | - poetry install + poetry install --with api - name: Run tests with coverage using Poetry run: > poetry run pytest tests --cov=./ --cov-report=term diff --git a/Makefile b/Makefile index 7d1e4eb..865f030 100644 --- a/Makefile +++ b/Makefile @@ -7,14 +7,14 @@ export LANG # Initializes submodules and copies environment file sample to env file. .PHONY:init -init: - make envfile; \ - git submodule update --init; \ +init:.env + poetry install --with api + git submodule update --init; # Environment file copy -envfile: +.env: ifeq ($(wildcard envfile),) - cp api.env.sample api.env; \ + cp env.sample .env; \ echo -e "\nDon't forget to update 'envfile' with all your secrets!"; endif diff --git a/README.md b/README.md index fa14a0a..3f0ecb3 100644 --- a/README.md +++ b/README.md @@ -15,8 +15,8 @@ The TA1 Middleware Service is designed to provide an intermediate job queue for ## Quickstart -1. Run `make init` which will create a stub `api.env` file. -2. Ensure that `api.env` contains the correct endpoint and other information +1. Run `make init` which will create a stub `.env` file. +2. Ensure that `.env` contains the correct endpoint and other information 3. Run `make up` diff --git a/api/Dockerfile b/api/Dockerfile index 6991061..3873964 100644 --- a/api/Dockerfile +++ b/api/Dockerfile @@ -13,7 +13,7 @@ COPY --from=tmp / / WORKDIR / RUN pip install --no-cache-dir poetry==1.5.1 RUN poetry config virtualenvs.create false && \ - poetry install --no-root --no-cache --extras api + poetry install --no-root --no-cache --with api COPY api ta1-service/api WORKDIR /ta1-service diff --git a/api/server.py b/api/server.py index 52fc6c0..622398e 100644 --- a/api/server.py +++ b/api/server.py @@ -4,13 +4,14 @@ from enum import Enum from typing import Annotated, List, Optional -from fastapi import FastAPI, HTTPException, Path, status +from fastapi import FastAPI, HTTPException, Path, Depends, status from fastapi.middleware.cors import CORSMiddleware from api.models import EquationType, ExtractionJob -from api.utils import create_job, fetch_job_status +from api.utils import create_job, fetch_job_status, get_redis +from lib.settings import settings -LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO").upper() # default to INFO if not set +LOG_LEVEL = settings.LOG_LEVEL numeric_level = getattr(logging, LOG_LEVEL, None) if not isinstance(numeric_level, int): raise ValueError(f"Invalid log level: {LOG_LEVEL}") @@ -43,12 +44,12 @@ def build_api(*args) -> FastAPI: @app.get("/status/{extraction_job_id}") -def get_status(extraction_job_id: str) -> ExtractionJob: +def get_status(extraction_job_id: str, redis=Depends(get_redis)) -> ExtractionJob: """ Retrieve the status of a extraction """ - extraction_job_status = fetch_job_status(extraction_job_id) + extraction_job_status = fetch_job_status(extraction_job_id, redis) if ( isinstance(extraction_job_status, int) and extraction_job_status == status.HTTP_404_NOT_FOUND @@ -67,6 +68,7 @@ def equations_to_amr( model: str = "petrinet", name: Optional[str] = None, description: Optional[str] = None, + redis = Depends(get_redis) ) -> ExtractionJob: """Post equations and store an AMR to TDS @@ -89,14 +91,14 @@ def equations_to_amr( "description": description, } - resp = create_job(operation_name=operation_name, options=options) + resp = create_job(operation_name=operation_name, options=options, redis=redis) return resp @app.post("/code_to_amr") def code_to_amr( - artifact_id: str, name: Optional[str] = None, description: Optional[str] = None + artifact_id: str, name: Optional[str] = None, description: Optional[str] = None, redis=Depends(get_redis) ) -> ExtractionJob: """ Converts a code artifact to an AMR. Assumes that the code file is the first @@ -112,13 +114,13 @@ def code_to_amr( operation_name = "operations.code_to_amr" options = {"artifact_id": artifact_id, "name": name, "description": description} - resp = create_job(operation_name=operation_name, options=options) + resp = create_job(operation_name=operation_name, options=options, redis=redis) return resp @app.post("/pdf_to_text") -def pdf_to_text(artifact_id: str) -> ExtractionJob: +def pdf_to_text(artifact_id: str, redis=Depends(get_redis)) -> ExtractionJob: """Run text extractions over pdfs and stores the text as metadata on the artifact Args: @@ -128,7 +130,7 @@ def pdf_to_text(artifact_id: str) -> ExtractionJob: options = {"artifact_id": artifact_id} - resp = create_job(operation_name=operation_name, options=options) + resp = create_job(operation_name=operation_name, options=options, redis=redis) return resp @@ -140,6 +142,7 @@ async def pdf_extractions( annotate_mit: bool = True, name: str = None, description: str = None, + redis = Depends(get_redis) ) -> ExtractionJob: """Run text extractions over pdfs @@ -157,14 +160,14 @@ async def pdf_extractions( "description": description, } - resp = create_job(operation_name=operation_name, options=options) + resp = create_job(operation_name=operation_name, options=options, redis=redis) return resp @app.post("/profile_dataset/{dataset_id}") def profile_dataset( - dataset_id: str, artifact_id: Optional[str] = None + dataset_id: str, artifact_id: Optional[str] = None, redis=Depends(get_redis) ) -> ExtractionJob: """Profile dataset with MIT's profiling service. This optionally accepts an `artifact_id` which is expected to be some user uploaded document which has had its text extracted and stored to @@ -183,13 +186,13 @@ def profile_dataset( "artifact_id": artifact_id, } - resp = create_job(operation_name=operation_name, options=options) + resp = create_job(operation_name=operation_name, options=options, redis=redis) return resp @app.post("/profile_model/{model_id}") -def profile_model(model_id: str, paper_artifact_id: str) -> ExtractionJob: +def profile_model(model_id: str, paper_artifact_id: str, redis=Depends(get_redis)) -> ExtractionJob: """Profile model with MIT's profiling service. This takes in a paper and code artifact and updates a model (AMR) with the profiled metadata card. It requires that the paper has been extracted with `/pdf_to_text` and the code has been converted to an AMR @@ -205,13 +208,13 @@ def profile_model(model_id: str, paper_artifact_id: str) -> ExtractionJob: options = {"model_id": model_id, "paper_artifact_id": paper_artifact_id} - resp = create_job(operation_name=operation_name, options=options) + resp = create_job(operation_name=operation_name, options=options, redis=redis) return resp @app.post("/link_amr") -def link_amr(artifact_id: str, model_id: str) -> ExtractionJob: +def link_amr(artifact_id: str, model_id: str, redis=Depends(get_redis)) -> ExtractionJob: raise HTTPException(status_code=501, detail="Endpoint is under development") operation_name = "operations.link_amr" @@ -221,6 +224,6 @@ def link_amr(artifact_id: str, model_id: str) -> ExtractionJob: "model_id": model_id, } - resp = create_job(operation_name=operation_name, options=options) + resp = create_job(operation_name=operation_name, options=options, redis=redis) return resp diff --git a/api/utils.py b/api/utils.py index 1e2b460..522360a 100644 --- a/api/utils.py +++ b/api/utils.py @@ -17,8 +17,9 @@ from rq.job import Job from api.models import ExtractionJob +from lib.settings import settings -LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO").upper() # default to INFO if not set +LOG_LEVEL = settings.LOG_LEVEL.upper() numeric_level = getattr(logging, LOG_LEVEL, None) if not isinstance(numeric_level, int): raise ValueError(f"Invalid log level: {LOG_LEVEL}") @@ -26,20 +27,15 @@ logging.getLogger().setLevel(numeric_level) # REDIS CONNECTION AND QUEUE OBJECTS -redis = Redis( - os.environ.get("REDIS_HOST", "redis.ta1-service"), - os.environ.get("REDIS_PORT", "6379"), -) - -q = Queue(connection=redis, default_timeout=-1) - - -def get_queue(): - return q +def get_redis(): + redis = Redis( + settings.REDIS_HOST, + settings.REDIS_PORT, + ) -def create_job(operation_name: str, options: Optional[Dict[Any, Any]] = None): - q = get_queue() +def create_job(operation_name: str, options: Optional[Dict[Any, Any]] = None, *, redis): + q = Queue(connection=redis, default_timeout=-1) if options is None: options = {} @@ -61,7 +57,7 @@ def create_job(operation_name: str, options: Optional[Dict[Any, Any]] = None): if not job or force_restart: flattened_options = deepcopy(options) job = q.enqueue_call( - func=operation_name, args=[], kwargs=flattened_options, job_id=job_id + func=f"worker.{operation_name}", args=[], kwargs=flattened_options, job_id=job_id ) if synchronous: timer = 0.0 @@ -91,7 +87,7 @@ def create_job(operation_name: str, options: Optional[Dict[Any, Any]] = None): return ExtractionJob(id=job_id, status=status, result=result) -def fetch_job_status(job_id): +def fetch_job_status(job_id, redis): """Fetch a job's results from RQ. Args: diff --git a/docker-compose.prod.yaml b/docker-compose.prod.yaml index cb30303..e4ef7eb 100644 --- a/docker-compose.prod.yaml +++ b/docker-compose.prod.yaml @@ -13,7 +13,7 @@ services: ports: - "8010:8000" env_file: - - api.env + - .env networks: - ta1-service depends_on: @@ -35,7 +35,7 @@ services: context: ./ dockerfile: workers/Dockerfile env_file: - - api.env + - .env depends_on: - redis networks: diff --git a/docker-compose.yaml b/docker-compose.yaml index 8c6aa6b..711fa4e 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -15,7 +15,7 @@ services: ports: - "8010:8000" env_file: - - api.env + - .env networks: - ta1-service - data-api @@ -38,7 +38,7 @@ services: context: ./ dockerfile: workers/Dockerfile env_file: - - api.env + - .env depends_on: - redis networks: diff --git a/api.env.sample b/env.sample similarity index 100% rename from api.env.sample rename to env.sample diff --git a/workers/__init__.py b/lib/__init__.py similarity index 100% rename from workers/__init__.py rename to lib/__init__.py diff --git a/lib/settings.py b/lib/settings.py new file mode 100644 index 0000000..3eddc98 --- /dev/null +++ b/lib/settings.py @@ -0,0 +1,15 @@ +from pydantic_settings import BaseSettings + +class Settings(BaseSettings): + LIVE: bool = False + REDIS_HOST: str = "redis.ta1-service" + REDIS_PORT: int = 6379 + TA1_UNIFIED_URL: str = "http://ta1:5" + SKEMA_RS_URL: str = "http://skema-rs.staging.terarium.ai" + MIT_TR_URL: str = "http://mit:10" + TDS_URL: str = "http://tds:15" + OPENAI_API_KEY: str = "foo" + LOG_LEVEL: str = "INFO" + + +settings = Settings() \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index f107877..06f031f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,18 +1,26 @@ +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. + [[package]] name = "annotated-types" version = "0.5.0" description = "Reusable constraint types to use with typing.Annotated" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "annotated_types-0.5.0-py3-none-any.whl", hash = "sha256:58da39888f92c276ad970249761ebea80ba544b77acddaa1a4d6cf78287d45fd"}, + {file = "annotated_types-0.5.0.tar.gz", hash = "sha256:47cdc3490d9ac1506ce92c7aaa76c579dc3509ff11e098fc867e5130ab7be802"}, +] [[package]] name = "anyio" version = "3.7.1" description = "High level compatibility layer for multiple asynchronous event loop implementations" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"}, + {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"}, +] [package.dependencies] exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} @@ -26,19 +34,25 @@ trio = ["trio (<0.22)"] [[package]] name = "async-timeout" -version = "4.0.2" +version = "4.0.3" description = "Timeout context manager for asyncio programs" -category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" +files = [ + {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, + {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, +] [[package]] name = "attrs" version = "23.1.0" description = "Classes Without Boilerplate" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, + {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, +] [package.extras] cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] @@ -51,25 +65,107 @@ tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pyte name = "certifi" version = "2023.7.22" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, + {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, +] [[package]] name = "charset-normalizer" version = "3.2.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, + {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, + {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, + {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, + {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, + {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, + {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, +] [[package]] name = "click" -version = "8.1.4" +version = "8.1.7" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} @@ -78,17 +174,73 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] [[package]] name = "coverage" -version = "7.2.7" +version = "7.3.0" description = "Code coverage measurement for Python" -category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" +files = [ + {file = "coverage-7.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db76a1bcb51f02b2007adacbed4c88b6dee75342c37b05d1822815eed19edee5"}, + {file = "coverage-7.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c02cfa6c36144ab334d556989406837336c1d05215a9bdf44c0bc1d1ac1cb637"}, + {file = "coverage-7.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:477c9430ad5d1b80b07f3c12f7120eef40bfbf849e9e7859e53b9c93b922d2af"}, + {file = "coverage-7.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce2ee86ca75f9f96072295c5ebb4ef2a43cecf2870b0ca5e7a1cbdd929cf67e1"}, + {file = "coverage-7.3.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68d8a0426b49c053013e631c0cdc09b952d857efa8f68121746b339912d27a12"}, + {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b3eb0c93e2ea6445b2173da48cb548364f8f65bf68f3d090404080d338e3a689"}, + {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:90b6e2f0f66750c5a1178ffa9370dec6c508a8ca5265c42fbad3ccac210a7977"}, + {file = "coverage-7.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:96d7d761aea65b291a98c84e1250cd57b5b51726821a6f2f8df65db89363be51"}, + {file = "coverage-7.3.0-cp310-cp310-win32.whl", hash = "sha256:63c5b8ecbc3b3d5eb3a9d873dec60afc0cd5ff9d9f1c75981d8c31cfe4df8527"}, + {file = "coverage-7.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:97c44f4ee13bce914272589b6b41165bbb650e48fdb7bd5493a38bde8de730a1"}, + {file = "coverage-7.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:74c160285f2dfe0acf0f72d425f3e970b21b6de04157fc65adc9fd07ee44177f"}, + {file = "coverage-7.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b543302a3707245d454fc49b8ecd2c2d5982b50eb63f3535244fd79a4be0c99d"}, + {file = "coverage-7.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad0f87826c4ebd3ef484502e79b39614e9c03a5d1510cfb623f4a4a051edc6fd"}, + {file = "coverage-7.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:13c6cbbd5f31211d8fdb477f0f7b03438591bdd077054076eec362cf2207b4a7"}, + {file = "coverage-7.3.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fac440c43e9b479d1241fe9d768645e7ccec3fb65dc3a5f6e90675e75c3f3e3a"}, + {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3c9834d5e3df9d2aba0275c9f67989c590e05732439b3318fa37a725dff51e74"}, + {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4c8e31cf29b60859876474034a83f59a14381af50cbe8a9dbaadbf70adc4b214"}, + {file = "coverage-7.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7a9baf8e230f9621f8e1d00c580394a0aa328fdac0df2b3f8384387c44083c0f"}, + {file = "coverage-7.3.0-cp311-cp311-win32.whl", hash = "sha256:ccc51713b5581e12f93ccb9c5e39e8b5d4b16776d584c0f5e9e4e63381356482"}, + {file = "coverage-7.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:887665f00ea4e488501ba755a0e3c2cfd6278e846ada3185f42d391ef95e7e70"}, + {file = "coverage-7.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d000a739f9feed900381605a12a61f7aaced6beae832719ae0d15058a1e81c1b"}, + {file = "coverage-7.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:59777652e245bb1e300e620ce2bef0d341945842e4eb888c23a7f1d9e143c446"}, + {file = "coverage-7.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9737bc49a9255d78da085fa04f628a310c2332b187cd49b958b0e494c125071"}, + {file = "coverage-7.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5247bab12f84a1d608213b96b8af0cbb30d090d705b6663ad794c2f2a5e5b9fe"}, + {file = "coverage-7.3.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2ac9a1de294773b9fa77447ab7e529cf4fe3910f6a0832816e5f3d538cfea9a"}, + {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:85b7335c22455ec12444cec0d600533a238d6439d8d709d545158c1208483873"}, + {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:36ce5d43a072a036f287029a55b5c6a0e9bd73db58961a273b6dc11a2c6eb9c2"}, + {file = "coverage-7.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:211a4576e984f96d9fce61766ffaed0115d5dab1419e4f63d6992b480c2bd60b"}, + {file = "coverage-7.3.0-cp312-cp312-win32.whl", hash = "sha256:56afbf41fa4a7b27f6635bc4289050ac3ab7951b8a821bca46f5b024500e6321"}, + {file = "coverage-7.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:7f297e0c1ae55300ff688568b04ff26b01c13dfbf4c9d2b7d0cb688ac60df479"}, + {file = "coverage-7.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ac0dec90e7de0087d3d95fa0533e1d2d722dcc008bc7b60e1143402a04c117c1"}, + {file = "coverage-7.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:438856d3f8f1e27f8e79b5410ae56650732a0dcfa94e756df88c7e2d24851fcd"}, + {file = "coverage-7.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1084393c6bda8875c05e04fce5cfe1301a425f758eb012f010eab586f1f3905e"}, + {file = "coverage-7.3.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49ab200acf891e3dde19e5aa4b0f35d12d8b4bd805dc0be8792270c71bd56c54"}, + {file = "coverage-7.3.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a67e6bbe756ed458646e1ef2b0778591ed4d1fcd4b146fc3ba2feb1a7afd4254"}, + {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8f39c49faf5344af36042b293ce05c0d9004270d811c7080610b3e713251c9b0"}, + {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7df91fb24c2edaabec4e0eee512ff3bc6ec20eb8dccac2e77001c1fe516c0c84"}, + {file = "coverage-7.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:34f9f0763d5fa3035a315b69b428fe9c34d4fc2f615262d6be3d3bf3882fb985"}, + {file = "coverage-7.3.0-cp38-cp38-win32.whl", hash = "sha256:bac329371d4c0d456e8d5f38a9b0816b446581b5f278474e416ea0c68c47dcd9"}, + {file = "coverage-7.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:b859128a093f135b556b4765658d5d2e758e1fae3e7cc2f8c10f26fe7005e543"}, + {file = "coverage-7.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed8d310afe013db1eedd37176d0839dc66c96bcfcce8f6607a73ffea2d6ba"}, + {file = "coverage-7.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61260ec93f99f2c2d93d264b564ba912bec502f679793c56f678ba5251f0393"}, + {file = "coverage-7.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97af9554a799bd7c58c0179cc8dbf14aa7ab50e1fd5fa73f90b9b7215874ba28"}, + {file = "coverage-7.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3558e5b574d62f9c46b76120a5c7c16c4612dc2644c3d48a9f4064a705eaee95"}, + {file = "coverage-7.3.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37d5576d35fcb765fca05654f66aa71e2808d4237d026e64ac8b397ffa66a56a"}, + {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:07ea61bcb179f8f05ffd804d2732b09d23a1238642bf7e51dad62082b5019b34"}, + {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:80501d1b2270d7e8daf1b64b895745c3e234289e00d5f0e30923e706f110334e"}, + {file = "coverage-7.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4eddd3153d02204f22aef0825409091a91bf2a20bce06fe0f638f5c19a85de54"}, + {file = "coverage-7.3.0-cp39-cp39-win32.whl", hash = "sha256:2d22172f938455c156e9af2612650f26cceea47dc86ca048fa4e0b2d21646ad3"}, + {file = "coverage-7.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:60f64e2007c9144375dd0f480a54d6070f00bb1a28f65c408370544091c9bc9e"}, + {file = "coverage-7.3.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:5492a6ce3bdb15c6ad66cb68a0244854d9917478877a25671d70378bdc8562d0"}, + {file = "coverage-7.3.0.tar.gz", hash = "sha256:49dbb19cdcafc130f597d9e04a29d0a032ceedf729e41b181f51cd170e6ee865"}, +] [package.dependencies] tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} @@ -98,22 +250,28 @@ toml = ["tomli"] [[package]] name = "exceptiongroup" -version = "1.1.2" +version = "1.1.3" description = "Backport of PEP 654 (exception groups)" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.1.3-py3-none-any.whl", hash = "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"}, + {file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"}, +] [package.extras] test = ["pytest (>=6)"] [[package]] name = "fakeredis" -version = "2.17.0" +version = "2.18.0" description = "Python implementation of redis API, can be used for testing purposes." -category = "main" optional = false python-versions = ">=3.7,<4.0" +files = [ + {file = "fakeredis-2.18.0-py3-none-any.whl", hash = "sha256:bc7a82e9caec80096659fd9a810b72d21f833574be26ff7b97955db626d60bac"}, + {file = "fakeredis-2.18.0.tar.gz", hash = "sha256:f9c18d3dba81a470953cc042868b411e334109e065cde53a7a82beef6702a1de"}, +] [package.dependencies] redis = ">=4" @@ -121,15 +279,18 @@ sortedcontainers = ">=2,<3" [package.extras] json = ["jsonpath-ng (>=1.5,<2.0)"] -lua = ["lupa (>=1.14,<2.0)"] +lua = ["lupa (>=1.14,<3.0)"] [[package]] name = "fastapi" -version = "0.100.0" +version = "0.100.1" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "fastapi-0.100.1-py3-none-any.whl", hash = "sha256:ec6dd52bfc4eff3063cfcd0713b43c87640fefb2687bbbe3d8a08d94049cdf32"}, + {file = "fastapi-0.100.1.tar.gz", hash = "sha256:522700d7a469e4a973d92321ab93312448fbe20fca9c8da97effc7e7bc56df23"}, +] [package.dependencies] pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<3.0.0" @@ -143,71 +304,89 @@ all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)" name = "h11" version = "0.14.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] [[package]] name = "httpcore" -version = "0.16.3" +version = "0.17.3" description = "A minimal low-level HTTP client." -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "httpcore-0.17.3-py3-none-any.whl", hash = "sha256:c2789b767ddddfa2a5782e3199b2b7f6894540b17b16ec26b2c4d8e103510b87"}, + {file = "httpcore-0.17.3.tar.gz", hash = "sha256:a6f30213335e34c1ade7be6ec7c47f19f50c56db36abef1a9dfa3815b1cb3888"}, +] [package.dependencies] anyio = ">=3.0,<5.0" certifi = "*" h11 = ">=0.13,<0.15" -sniffio = ">=1.0.0,<2.0.0" +sniffio = "==1.*" [package.extras] http2 = ["h2 (>=3,<5)"] -socks = ["socksio (>=1.0.0,<2.0.0)"] +socks = ["socksio (==1.*)"] [[package]] name = "httpx" -version = "0.23.3" +version = "0.24.1" description = "The next generation HTTP client." -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "httpx-0.24.1-py3-none-any.whl", hash = "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd"}, + {file = "httpx-0.24.1.tar.gz", hash = "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd"}, +] [package.dependencies] certifi = "*" -httpcore = ">=0.15.0,<0.17.0" -rfc3986 = {version = ">=1.3,<2", extras = ["idna2008"]} +httpcore = ">=0.15.0,<0.18.0" +idna = "*" sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] -cli = ["click (>=8.0.0,<9.0.0)", "pygments (>=2.0.0,<3.0.0)", "rich (>=10,<13)"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] -socks = ["socksio (>=1.0.0,<2.0.0)"] +socks = ["socksio (==1.*)"] [[package]] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" +files = [ + {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, + {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, +] [[package]] name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] [[package]] name = "jsonschema" version = "4.19.0" description = "An implementation of JSON Schema validation for Python" -category = "main" optional = false python-versions = ">=3.8" +files = [ + {file = "jsonschema-4.19.0-py3-none-any.whl", hash = "sha256:043dc26a3845ff09d20e4420d6012a9c91c9aa8999fa184e7efcfeccb41e32cb"}, + {file = "jsonschema-4.19.0.tar.gz", hash = "sha256:6e1e7569ac13be8139b2dd2c21a55d350066ee3f80df06c608b398cdc6f30e8f"}, +] [package.dependencies] attrs = ">=22.2.0" @@ -223,54 +402,94 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- name = "jsonschema-specifications" version = "2023.7.1" description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" -category = "main" optional = false python-versions = ">=3.8" +files = [ + {file = "jsonschema_specifications-2023.7.1-py3-none-any.whl", hash = "sha256:05adf340b659828a004220a9613be00fa3f223f2b82002e273dee62fd50524b1"}, + {file = "jsonschema_specifications-2023.7.1.tar.gz", hash = "sha256:c91a50404e88a1f6ba40636778e2ee08f6e24c5613fe4c53ac24578a5a7f72bb"}, +] [package.dependencies] referencing = ">=0.28.0" [[package]] name = "numpy" -version = "1.25.1" +version = "1.25.2" description = "Fundamental package for array computing in Python" -category = "main" optional = false python-versions = ">=3.9" +files = [ + {file = "numpy-1.25.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:db3ccc4e37a6873045580d413fe79b68e47a681af8db2e046f1dacfa11f86eb3"}, + {file = "numpy-1.25.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:90319e4f002795ccfc9050110bbbaa16c944b1c37c0baeea43c5fb881693ae1f"}, + {file = "numpy-1.25.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfe4a913e29b418d096e696ddd422d8a5d13ffba4ea91f9f60440a3b759b0187"}, + {file = "numpy-1.25.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f08f2e037bba04e707eebf4bc934f1972a315c883a9e0ebfa8a7756eabf9e357"}, + {file = "numpy-1.25.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bec1e7213c7cb00d67093247f8c4db156fd03075f49876957dca4711306d39c9"}, + {file = "numpy-1.25.2-cp310-cp310-win32.whl", hash = "sha256:7dc869c0c75988e1c693d0e2d5b26034644399dd929bc049db55395b1379e044"}, + {file = "numpy-1.25.2-cp310-cp310-win_amd64.whl", hash = "sha256:834b386f2b8210dca38c71a6e0f4fd6922f7d3fcff935dbe3a570945acb1b545"}, + {file = "numpy-1.25.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c5462d19336db4560041517dbb7759c21d181a67cb01b36ca109b2ae37d32418"}, + {file = "numpy-1.25.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5652ea24d33585ea39eb6a6a15dac87a1206a692719ff45d53c5282e66d4a8f"}, + {file = "numpy-1.25.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d60fbae8e0019865fc4784745814cff1c421df5afee233db6d88ab4f14655a2"}, + {file = "numpy-1.25.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60e7f0f7f6d0eee8364b9a6304c2845b9c491ac706048c7e8cf47b83123b8dbf"}, + {file = "numpy-1.25.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bb33d5a1cf360304754913a350edda36d5b8c5331a8237268c48f91253c3a364"}, + {file = "numpy-1.25.2-cp311-cp311-win32.whl", hash = "sha256:5883c06bb92f2e6c8181df7b39971a5fb436288db58b5a1c3967702d4278691d"}, + {file = "numpy-1.25.2-cp311-cp311-win_amd64.whl", hash = "sha256:5c97325a0ba6f9d041feb9390924614b60b99209a71a69c876f71052521d42a4"}, + {file = "numpy-1.25.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b79e513d7aac42ae918db3ad1341a015488530d0bb2a6abcbdd10a3a829ccfd3"}, + {file = "numpy-1.25.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:eb942bfb6f84df5ce05dbf4b46673ffed0d3da59f13635ea9b926af3deb76926"}, + {file = "numpy-1.25.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e0746410e73384e70d286f93abf2520035250aad8c5714240b0492a7302fdca"}, + {file = "numpy-1.25.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7806500e4f5bdd04095e849265e55de20d8cc4b661b038957354327f6d9b295"}, + {file = "numpy-1.25.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8b77775f4b7df768967a7c8b3567e309f617dd5e99aeb886fa14dc1a0791141f"}, + {file = "numpy-1.25.2-cp39-cp39-win32.whl", hash = "sha256:2792d23d62ec51e50ce4d4b7d73de8f67a2fd3ea710dcbc8563a51a03fb07b01"}, + {file = "numpy-1.25.2-cp39-cp39-win_amd64.whl", hash = "sha256:76b4115d42a7dfc5d485d358728cdd8719be33cc5ec6ec08632a5d6fca2ed380"}, + {file = "numpy-1.25.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1a1329e26f46230bf77b02cc19e900db9b52f398d6722ca853349a782d4cff55"}, + {file = "numpy-1.25.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c3abc71e8b6edba80a01a52e66d83c5d14433cbcd26a40c329ec7ed09f37901"}, + {file = "numpy-1.25.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:1b9735c27cea5d995496f46a8b1cd7b408b3f34b6d50459d9ac8fe3a20cc17bf"}, + {file = "numpy-1.25.2.tar.gz", hash = "sha256:fd608e19c8d7c55021dffd43bfe5492fab8cc105cc8986f813f8c3c048b38760"}, +] [[package]] name = "packaging" version = "23.1" description = "Core utilities for Python packages" -category = "main" optional = false python-versions = ">=3.7" - -[[package]] -name = "pact-python" -version = "2.0.1" -description = "Tools for creating and verifying consumer driven contracts using the Pact framework." -category = "main" -optional = false -python-versions = ">=3.6,<4" - -[package.dependencies] -click = ">=8.1.3" -fastapi = ">=0.67.0" -httpx = "0.23.3" -psutil = ">=5.9.4" -requests = ">=2.28.0" -six = ">=1.16.0" -urllib3 = ">=1.26.12" -uvicorn = ">=0.19.0" +files = [ + {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, + {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, +] [[package]] name = "pandas" version = "2.0.3" description = "Powerful data structures for data analysis, time series, and statistics" -category = "main" optional = false python-versions = ">=3.8" +files = [ + {file = "pandas-2.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e4c7c9f27a4185304c7caf96dc7d91bc60bc162221152de697c98eb0b2648dd8"}, + {file = "pandas-2.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f167beed68918d62bffb6ec64f2e1d8a7d297a038f86d4aed056b9493fca407f"}, + {file = "pandas-2.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce0c6f76a0f1ba361551f3e6dceaff06bde7514a374aa43e33b588ec10420183"}, + {file = "pandas-2.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba619e410a21d8c387a1ea6e8a0e49bb42216474436245718d7f2e88a2f8d7c0"}, + {file = "pandas-2.0.3-cp310-cp310-win32.whl", hash = "sha256:3ef285093b4fe5058eefd756100a367f27029913760773c8bf1d2d8bebe5d210"}, + {file = "pandas-2.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:9ee1a69328d5c36c98d8e74db06f4ad518a1840e8ccb94a4ba86920986bb617e"}, + {file = "pandas-2.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b084b91d8d66ab19f5bb3256cbd5ea661848338301940e17f4492b2ce0801fe8"}, + {file = "pandas-2.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37673e3bdf1551b95bf5d4ce372b37770f9529743d2498032439371fc7b7eb26"}, + {file = "pandas-2.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9cb1e14fdb546396b7e1b923ffaeeac24e4cedd14266c3497216dd4448e4f2d"}, + {file = "pandas-2.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9cd88488cceb7635aebb84809d087468eb33551097d600c6dad13602029c2df"}, + {file = "pandas-2.0.3-cp311-cp311-win32.whl", hash = "sha256:694888a81198786f0e164ee3a581df7d505024fbb1f15202fc7db88a71d84ebd"}, + {file = "pandas-2.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:6a21ab5c89dcbd57f78d0ae16630b090eec626360085a4148693def5452d8a6b"}, + {file = "pandas-2.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9e4da0d45e7f34c069fe4d522359df7d23badf83abc1d1cef398895822d11061"}, + {file = "pandas-2.0.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:32fca2ee1b0d93dd71d979726b12b61faa06aeb93cf77468776287f41ff8fdc5"}, + {file = "pandas-2.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:258d3624b3ae734490e4d63c430256e716f488c4fcb7c8e9bde2d3aa46c29089"}, + {file = "pandas-2.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eae3dc34fa1aa7772dd3fc60270d13ced7346fcbcfee017d3132ec625e23bb0"}, + {file = "pandas-2.0.3-cp38-cp38-win32.whl", hash = "sha256:f3421a7afb1a43f7e38e82e844e2bca9a6d793d66c1a7f9f0ff39a795bbc5e02"}, + {file = "pandas-2.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:69d7f3884c95da3a31ef82b7618af5710dba95bb885ffab339aad925c3e8ce78"}, + {file = "pandas-2.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5247fb1ba347c1261cbbf0fcfba4a3121fbb4029d95d9ef4dc45406620b25c8b"}, + {file = "pandas-2.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:81af086f4543c9d8bb128328b5d32e9986e0c84d3ee673a2ac6fb57fd14f755e"}, + {file = "pandas-2.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1994c789bf12a7c5098277fb43836ce090f1073858c10f9220998ac74f37c69b"}, + {file = "pandas-2.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ec591c48e29226bcbb316e0c1e9423622bc7a4eaf1ef7c3c9fa1a3981f89641"}, + {file = "pandas-2.0.3-cp39-cp39-win32.whl", hash = "sha256:04dbdbaf2e4d46ca8da896e1805bc04eb85caa9a82e259e8eed00254d5e0c682"}, + {file = "pandas-2.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:1168574b036cd8b93abc746171c9b4f1b83467438a5e45909fed645cf8692dbc"}, + {file = "pandas-2.0.3.tar.gz", hash = "sha256:c02f372a88e0d17f36d3093a644c73cfc1788e876a7c4bcb4020a77512e2043c"}, +] [package.dependencies] numpy = [ @@ -305,48 +524,75 @@ sql-other = ["SQLAlchemy (>=1.4.16)"] test = ["hypothesis (>=6.34.2)", "pytest (>=7.3.2)", "pytest-asyncio (>=0.17.0)", "pytest-xdist (>=2.2.0)"] xml = ["lxml (>=4.6.3)"] +[[package]] +name = "pastel" +version = "0.2.1" +description = "Bring colors to your terminal." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pastel-0.2.1-py2.py3-none-any.whl", hash = "sha256:4349225fcdf6c2bb34d483e523475de5bb04a5c10ef711263452cb37d7dd4364"}, + {file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"}, +] + [[package]] name = "pathspec" version = "0.11.2" description = "Utility library for gitignore style pattern matching of file paths." -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, + {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, +] [[package]] name = "pluggy" version = "1.2.0" description = "plugin and hook calling mechanisms for python" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, + {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, +] [package.extras] dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] [[package]] -name = "psutil" -version = "5.9.5" -description = "Cross-platform lib for process and system monitoring in Python." -category = "main" +name = "poethepoet" +version = "0.22.0" +description = "A task runner that works well with poetry." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.8" +files = [ + {file = "poethepoet-0.22.0-py3-none-any.whl", hash = "sha256:f654e52c19b7c689d5293ab6a065787b21f125884c0b367650292df4f3cb508c"}, + {file = "poethepoet-0.22.0.tar.gz", hash = "sha256:659d7678fd8b349bd40941e3de7d6d386171dab3e7c8babcdcd8ead288c9ea47"}, +] + +[package.dependencies] +pastel = ">=0.2.1,<0.3.0" +tomli = ">=1.2.2" [package.extras] -test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] +poetry-plugin = ["poetry (>=1.0,<2.0)"] [[package]] name = "pydantic" -version = "2.0.2" +version = "2.2.1" description = "Data validation using Python type hints" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "pydantic-2.2.1-py3-none-any.whl", hash = "sha256:0c88bd2b63ed7a5109c75ab180d55f58f80a4b559682406812d0684d3f4b9192"}, + {file = "pydantic-2.2.1.tar.gz", hash = "sha256:31b5cada74b2320999fb2577e6df80332a200ff92e7775a52448b6b036fce24a"}, +] [package.dependencies] annotated-types = ">=0.4.0" -pydantic-core = "2.1.2" +pydantic-core = "2.6.1" typing-extensions = ">=4.6.1" [package.extras] @@ -354,40 +600,168 @@ email = ["email-validator (>=2.0.0)"] [[package]] name = "pydantic-core" -version = "2.1.2" +version = "2.6.1" description = "" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "pydantic_core-2.6.1-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:f55001a689111a297c0006c46c0589cfd559261baaa9a37bc35eff05b8cae1a6"}, + {file = "pydantic_core-2.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bb6273068e9450c5c91f58dd277fbd406b896ffa30f0ef312edc5519d07f16ae"}, + {file = "pydantic_core-2.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:043212f21c75cb6ee3a92fffbc747410e32b08e1a419ce16a9da98a16d660a7c"}, + {file = "pydantic_core-2.6.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:db0c12f1e9d3bf658634621f3423486803d749fef77a64cfb4252f9d619e1817"}, + {file = "pydantic_core-2.6.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:81424dc05c4342a19fb64323bb9d4468e7407b745c00377ccc4d3dd96d5e02fe"}, + {file = "pydantic_core-2.6.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3c8f3aebaf92f088b1dafd7101d1ccca0459ae0f5b26017411b9969667d289a9"}, + {file = "pydantic_core-2.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd9f14454b4bc89c705ce17951f9c783db82efd2b44a424487c593e2269eef61"}, + {file = "pydantic_core-2.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2effc71653247e76c5b95d15c58d4ca3f591f42f714eb3b32df9d6ec613794a5"}, + {file = "pydantic_core-2.6.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:56672429f8a89d2a0f4402d912f0dad68c2d05f7c278d3152c6fb4a76c2a429a"}, + {file = "pydantic_core-2.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d0bf1c2545ab253732229c7fe8294d98eb08f99aa25a388267e1bc4d2d7e0a34"}, + {file = "pydantic_core-2.6.1-cp310-none-win32.whl", hash = "sha256:c5be947ad41a7602f941dc834d03e64dd1c7fae65fa85cb4f1004a95c5d50df1"}, + {file = "pydantic_core-2.6.1-cp310-none-win_amd64.whl", hash = "sha256:3d14ae98a8d251402ef8ed017039d2fc3e29fb155f909cd3816ba259fd30fb48"}, + {file = "pydantic_core-2.6.1-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:4a3c20808d3ced90e29439f72a563eadf21d29560935cc818b2dab80b92c114a"}, + {file = "pydantic_core-2.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:da240bbd8191edc6009e7793d5d4d67c55f56225c4788f068d6286c20e5a2038"}, + {file = "pydantic_core-2.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de1a3e56e34264d5216c67d2a48185216ada8f5f35a7f4c96a3971847c0de897"}, + {file = "pydantic_core-2.6.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9b623e09239ed333d14c02c9fcd1a7bb350b95eca8383f6e9b0d8e373d5a14b5"}, + {file = "pydantic_core-2.6.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a12520a6d502a25f6e47319874e47056b290f1b3c2ed9391444ce81c8cc5b83"}, + {file = "pydantic_core-2.6.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1141f18414aee8865c7917ae1432e419c1983272f53625152493692ff3d6783"}, + {file = "pydantic_core-2.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7888b3ee7566865cff3e9edab5d6cdf2e7cf793df17fe53d5e7be3e57eae45ec"}, + {file = "pydantic_core-2.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3bdf293b6304bc451678b7016c2505b7d97aa85ff13dac4420027b1b69e15d3d"}, + {file = "pydantic_core-2.6.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7ef56a05bb60336d5e795bf166d6712b2362e6478522c77e8336cb0da8909913"}, + {file = "pydantic_core-2.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3210eb73707e3487c16ef25cfd1663660f4e7d647a181d6c2fb18bc6167985fb"}, + {file = "pydantic_core-2.6.1-cp311-none-win32.whl", hash = "sha256:707e3005e8c129bdac117285b71717c13b9ed81a81eae0b1642f4ddc60028e63"}, + {file = "pydantic_core-2.6.1-cp311-none-win_amd64.whl", hash = "sha256:2b8ccec2189d8a8b83929f79e5bc00c0656f6c2ba4345125c0c82d1b77e15a26"}, + {file = "pydantic_core-2.6.1-cp311-none-win_arm64.whl", hash = "sha256:c1e44b77442fb5b1b6fccea30e3359b14d0a2e5896801243defe54482a591500"}, + {file = "pydantic_core-2.6.1-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:c82fb25f965f6777032fc2f2856c86149f7709c8f7fd0c020a8631b8211f2bab"}, + {file = "pydantic_core-2.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:494b211b12b8fedd184dbba609f6ed582e23561db57c1996fd6773989dbaef9b"}, + {file = "pydantic_core-2.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1281c940f47e5c89b594ef7580045647df1f9ad687edd503bcc0485be94576f4"}, + {file = "pydantic_core-2.6.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2d41701c88d8b678c16c10562949f2d28aceacd767cbe51dac9c8c41e6e609fb"}, + {file = "pydantic_core-2.6.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6a839c95d5cc91eed053d8dafde4e200c4bc82f56fb1cf7bbfaeb03e2d907929"}, + {file = "pydantic_core-2.6.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c22e4fbfb5823d0fcb2c20ed164b39c3588554f9635f70765e8c9cff0fef67ad"}, + {file = "pydantic_core-2.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2fed4ad60ccf2698bd04e95dfc3bd84149ced9605a29fd27d624701e1da300c"}, + {file = "pydantic_core-2.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33b9343aa464d60c31937b361abde08d3af9943f3eb09d3216211b6236bd40c4"}, + {file = "pydantic_core-2.6.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:56e4953cd911293d6d755e2a97c651826aca76201db8f1ee298939e703721390"}, + {file = "pydantic_core-2.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cd163109047ab41ef1ea34258b35beb3ccac90af2012927ee8ab6ff122fef671"}, + {file = "pydantic_core-2.6.1-cp312-none-win32.whl", hash = "sha256:f5b51ec04743c94288c46e3759769611ab7c5ce0f941113363da96d20d345fb6"}, + {file = "pydantic_core-2.6.1-cp312-none-win_amd64.whl", hash = "sha256:ca5606bd82e255b1d704a4334e5ebf05ae966b69686fae02dcd31c057bdcb113"}, + {file = "pydantic_core-2.6.1-cp312-none-win_arm64.whl", hash = "sha256:dfc8f534a21b60b00f87e5a4fc36b8b8945160a6cc9e7b6e67db541c766c9597"}, + {file = "pydantic_core-2.6.1-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:b1aed20778092f8334c8eaf91550fa2805221d5e9b40ebdd1f46ee7efc159a48"}, + {file = "pydantic_core-2.6.1-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:64ff7a4b7ee2a56735af28da76c5dacbba6995801080f739d14610f4aa3de35d"}, + {file = "pydantic_core-2.6.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2d8faedb138c704957642fdf154c94f1b3d2a15cbd2472e45665f80463e85ee"}, + {file = "pydantic_core-2.6.1-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:55aac69d7339a63e37164f0a629c3034becc6746d68d126118a3ee4493514bed"}, + {file = "pydantic_core-2.6.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dfdb1617af455a551be4cc0471f0bf3bfb1e882db71afad0e587c821326bb749"}, + {file = "pydantic_core-2.6.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aadc84f5bd7b1421b5a6b389ceff46062dd4a58c44cfb75990e9ca2d9d8270df"}, + {file = "pydantic_core-2.6.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1a01dce87507b9a8f1b71933ade85c573a22c9bd4649590e28d8a497afb68bd"}, + {file = "pydantic_core-2.6.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cd6f05f3e237ed6b3949464e7679e55843645fe0fe8d3b33277c321386836f6a"}, + {file = "pydantic_core-2.6.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:760f8a0aeb43ceeff1e536859e071a72e91075d4d37d51470812c4f49e682702"}, + {file = "pydantic_core-2.6.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a1ad48e77935d7dbbc2d75aeb638abbfbd0df0cfacf774dbe98d52271468f00c"}, + {file = "pydantic_core-2.6.1-cp37-none-win32.whl", hash = "sha256:153a5dd24c09ab7544beda967366afbaae8350b327a4ebd5807ed45ec791baa0"}, + {file = "pydantic_core-2.6.1-cp37-none-win_amd64.whl", hash = "sha256:cc7fc3e81b4ea6bce7e0e1d9797f496e957c5e66adf483f89afdce2d81d19986"}, + {file = "pydantic_core-2.6.1-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:5482d692ae37857695feccb179022728b275b7bfcc1c85bcdf7b556e76bffcd8"}, + {file = "pydantic_core-2.6.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:45d248c3c5c5c23a8d048cfdebc8151ae7b32a6dc6d68fbca995521e54692207"}, + {file = "pydantic_core-2.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6dd6c9f47e26779bf1f7da4d6ccd60f66973e63b0a143438f1e20bae296c3fde"}, + {file = "pydantic_core-2.6.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:55701608e60418a423db2486b5c64d790f86eb78a11b9077efb6302c50e62564"}, + {file = "pydantic_core-2.6.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:420a76a62dd20a6ef08445abf7cf04dcd8a845a5bb15932c2e88a8e518c70d43"}, + {file = "pydantic_core-2.6.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5f253d20314e53ba0fb2b95541b6ed23f44fbcd927fe7674de341545c3327c3d"}, + {file = "pydantic_core-2.6.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5127b811c6a26deb85f5b17a06c26c28ce204e51e0a963b75bdf8612b22546d"}, + {file = "pydantic_core-2.6.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:51ffa985b874ca7d0dc199bb75c67b77907379291c91532a9e2d981f7b681527"}, + {file = "pydantic_core-2.6.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4902300e763a2fcc49ae14366493ef1fdbd3c7128b9acf37aef505f671aa681f"}, + {file = "pydantic_core-2.6.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e1c69334bb843c9bff98f52a1fa6c06420081a561fcecb03c6b9376960bd7de2"}, + {file = "pydantic_core-2.6.1-cp38-none-win32.whl", hash = "sha256:e84812b1ca989b2e9f4913d7b75ae0eece2a90154de35b4c5411ad640bfd387c"}, + {file = "pydantic_core-2.6.1-cp38-none-win_amd64.whl", hash = "sha256:775098e3629a959dfec8444667a53e0916839e9fbf6b55e07d6e2aadde006400"}, + {file = "pydantic_core-2.6.1-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:a32ed5a794918a61bf77b967c197eb78f31ad4e3145860193dc381bde040717e"}, + {file = "pydantic_core-2.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:66eda8ac48ac33e9e5c6541c8e30c702924b70a6f2e9732b74230d9b2dd35fb6"}, + {file = "pydantic_core-2.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb5131d75d69b0547ef9a8f46f7b94857411c9badcdd5092de61a3b4943f08c7"}, + {file = "pydantic_core-2.6.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:20e850f3242d7836a5e15453f798d8569b9754350c8e184ba32d102c515dd507"}, + {file = "pydantic_core-2.6.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f4327fa6a1ac3da62b27d43bb0f27657ed4e601b141ecbfcf8523814b6c33b6"}, + {file = "pydantic_core-2.6.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c7b89b2875b967ad5c3c980bf72773851554f80c2529796e815a10c99295d872"}, + {file = "pydantic_core-2.6.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78eadd8d7d5cd8c3616e363c394d721437c339feaa4c28404e2eda79add69781"}, + {file = "pydantic_core-2.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:17ab25bb24e98b61d120b7248c2b49ea56ce754a050d6b348be42015fcb7aa25"}, + {file = "pydantic_core-2.6.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6ea8dd2854fe6cee5ea0d60304ee7877dffe487cf118f221e85029269dd1235d"}, + {file = "pydantic_core-2.6.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9bf3ba6b4878ee692f6e24230801f682807fd97356bc2064f630fc0a2ad2ead6"}, + {file = "pydantic_core-2.6.1-cp39-none-win32.whl", hash = "sha256:b974d65692333931b4c7f730e7a3135ff854a1e5384bc260de3327ea364c835a"}, + {file = "pydantic_core-2.6.1-cp39-none-win_amd64.whl", hash = "sha256:f34f26d8a5f1a45366189ec30a57f43b21e2172d0d3b62822638dd885cc8eaab"}, + {file = "pydantic_core-2.6.1-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:f7ec4c6edafa3f0eb1aa461e31ea263736cc541b2459dddfbda7085b30844801"}, + {file = "pydantic_core-2.6.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:3679b9a1f41eb1b699e9556f91281d78c416cdc59ae90d5733fbe2017f1effe9"}, + {file = "pydantic_core-2.6.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3ff36f945342086ee917d4219dd0e59660a2dfcdb86a07696c2791f5d59c07d"}, + {file = "pydantic_core-2.6.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:734864605d722a6f8db3b9c96371710f7cb591fbfca40cfeaedf5b67df282438"}, + {file = "pydantic_core-2.6.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7188359b95a2b1aef5744a2ee6af2d9cfc733dd823f8840f4c896129477a172b"}, + {file = "pydantic_core-2.6.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:382d40843ae759d43ef65b67dec713390f9417135c1dd730afbf03cf2f450f45"}, + {file = "pydantic_core-2.6.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:4525b8498d362e4e324e3e175239b364768f52bd3563ac4ef9750160f5789de8"}, + {file = "pydantic_core-2.6.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e55514a022c768cccf07a675d20d07b847980dcd9250f6b516a86bab5612fc01"}, + {file = "pydantic_core-2.6.1-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:34734d486d059f0f6f5bfa9ba4a41449f666e2abbde002e9fa8b050bc50e3347"}, + {file = "pydantic_core-2.6.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a809498dceb0cd1cd1e57a2bfdc70ea82f424776e0196f4d63c4b6fcdaeb5aab"}, + {file = "pydantic_core-2.6.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:588a5ffd8bbf1b2230611ed1b45221adcf05b981037b2f853b5f20465849b5c1"}, + {file = "pydantic_core-2.6.1-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:26b81017aeae0d96f776fbce34a3a763d26ac575d8ad3f1202bdfdd2b935954b"}, + {file = "pydantic_core-2.6.1-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:7ddaa2c3c66682f0ff4ebc8c85ef2d8305f32deba79416464c47c93d94ca3740"}, + {file = "pydantic_core-2.6.1-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d6971131de66d1a37293f2e032206b6984b0dec44f568b453dfe89a84a2de0cc"}, + {file = "pydantic_core-2.6.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:200704f6824f8014bdccb1ce57cbd328666e6de4ecd77f0b8ab472cdea9c49ce"}, + {file = "pydantic_core-2.6.1-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:6916b27072c957947919fb32551f08486562bb8616f2e3db9e4e9c1d83d36886"}, + {file = "pydantic_core-2.6.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:136de286abf53f326b90389aaaca8a8050c2570adfc74afe06ab1c35d5d242bf"}, + {file = "pydantic_core-2.6.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60a238bb4ab09a81a6b25c9a0bb12756cfab2d9f3a7a471f857a179f83da0df6"}, + {file = "pydantic_core-2.6.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2034d9b83a59b3b74b9dbf97ddb99de86c08863c1c33aabf80bc95791c7d50c3"}, + {file = "pydantic_core-2.6.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7c3a2b4d1636446dc71da1e949d2cf9ac1ee691ca63a640b77fce0360b4b75be"}, + {file = "pydantic_core-2.6.1-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:09e4ebd11a0b333b1fca75c1004c76dc9719f3aaf83ae38c42358754d8a76148"}, + {file = "pydantic_core-2.6.1-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:a4536d132a8bbd05bf368fb802a264cb9828f6c85e4029a6a3670bc98ba97323"}, + {file = "pydantic_core-2.6.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:6221c97d6d58f2370650cfe3d81408901a1951c99960e1df9f6f9f8482d73d08"}, + {file = "pydantic_core-2.6.1-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:4223e8bdad41d846a84cda400cd538e1cdc63d98eb4d41951396bfdb88fd8ce9"}, + {file = "pydantic_core-2.6.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c07cdb2e02733e5f26b9b004a1a8b99814d175f8953fa9f59e4293de2b8e9787"}, + {file = "pydantic_core-2.6.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8714e958d01342d08e520ffec6c1acf66cdec83ce51302f9a1a6efb2f784d0b6"}, + {file = "pydantic_core-2.6.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f03541c25a77fb5445055e070b69d292c9818a9195ffbfd3962c0ad0da983e8"}, + {file = "pydantic_core-2.6.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:364c13ef48c9e2f8c2ea8ee0da5ea23db5e218f99e796cbf360a2a7cab511439"}, + {file = "pydantic_core-2.6.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:27ba58bbfd1b2b9da45bfe524e680e2bc747a1ca9738ee5aa18d8cbdcc08e5e6"}, + {file = "pydantic_core-2.6.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:92321582e59da185b76b2eca4488ea95e41800672e57107509d32ebf8ad550f8"}, + {file = "pydantic_core-2.6.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2da1d21a4f2675d5b8a749674993a65c0537e2066e7ab7b1a4a54ef0b3ac8efd"}, + {file = "pydantic_core-2.6.1.tar.gz", hash = "sha256:5b4efa68bcfa6f2b93624c6660b6cf4b7b4336d4225afb314254a0ed9c9f4153"}, +] [package.dependencies] typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" +[[package]] +name = "pydantic-settings" +version = "2.0.3" +description = "Settings management using Pydantic" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydantic_settings-2.0.3-py3-none-any.whl", hash = "sha256:ddd907b066622bd67603b75e2ff791875540dc485b7307c4fffc015719da8625"}, + {file = "pydantic_settings-2.0.3.tar.gz", hash = "sha256:962dc3672495aad6ae96a4390fac7e593591e144625e5112d359f8f67fb75945"}, +] + +[package.dependencies] +pydantic = ">=2.0.1" +python-dotenv = ">=0.21.0" + [[package]] name = "pypdf" -version = "3.12.1" +version = "3.15.2" description = "A pure-python PDF library capable of splitting, merging, cropping, and transforming PDF files" -category = "main" -optional = true +optional = false python-versions = ">=3.6" +files = [ + {file = "pypdf-3.15.2-py3-none-any.whl", hash = "sha256:f6e598292be34187287a609c72815c1502b3dc2c997b374ba0870ce79d2e975a"}, + {file = "pypdf-3.15.2.tar.gz", hash = "sha256:cdf7d75ebb8901f3352cf9488c5f662c6de9c52e432c429d15cada67ba372fce"}, +] [package.dependencies] typing_extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} [package.extras] -crypto = ["PyCryptodome"] -dev = ["black", "flit", "pip-tools", "pre-commit (<2.18.0)", "pytest-cov", "pytest-socket", "wheel"] +crypto = ["PyCryptodome", "cryptography"] +dev = ["black", "flit", "pip-tools", "pre-commit (<2.18.0)", "pytest-cov", "pytest-socket", "pytest-timeout", "wheel"] docs = ["myst_parser", "sphinx", "sphinx_rtd_theme"] -full = ["Pillow", "PyCryptodome"] -image = ["Pillow"] +full = ["Pillow (>=8.0.0)", "PyCryptodome", "cryptography"] +image = ["Pillow (>=8.0.0)"] [[package]] name = "pytest" version = "7.4.0" description = "pytest: simple powerful testing with Python" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "pytest-7.4.0-py3-none-any.whl", hash = "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32"}, + {file = "pytest-7.4.0.tar.gz", hash = "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a"}, +] [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} @@ -404,9 +778,12 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "pytest-cov" version = "4.1.0" description = "Pytest plugin for measuring coverage." -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, + {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, +] [package.dependencies] coverage = {version = ">=5.2.1", extras = ["toml"]} @@ -419,20 +796,40 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] [package.dependencies] six = ">=1.5" +[[package]] +name = "python-dotenv" +version = "1.0.0" +description = "Read key-value pairs from a .env file and set them as environment variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba"}, + {file = "python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a"}, +] + +[package.extras] +cli = ["click (>=5.0)"] + [[package]] name = "python-multipart" version = "0.0.6" description = "A streaming multipart parser for Python" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "python_multipart-0.0.6-py3-none-any.whl", hash = "sha256:ee698bab5ef148b0a760751c261902cd096e57e10558e11aca17646b74ee1c18"}, + {file = "python_multipart-0.0.6.tar.gz", hash = "sha256:e9925a80bb668529f1b67c7fdb0a5dacdd7cbfc6fb0bff3ea443fe22bdd62132"}, +] [package.extras] dev = ["atomicwrites (==1.2.1)", "attrs (==19.2.0)", "coverage (==6.5.0)", "hatch", "invoke (==1.7.3)", "more-itertools (==4.3.0)", "pbr (==4.3.0)", "pluggy (==1.0.0)", "py (==1.11.0)", "pytest (==7.2.0)", "pytest-cov (==4.0.0)", "pytest-timeout (==2.1.0)", "pyyaml (==5.1)"] @@ -441,25 +838,72 @@ dev = ["atomicwrites (==1.2.1)", "attrs (==19.2.0)", "coverage (==6.5.0)", "hatc name = "pytz" version = "2023.3" description = "World timezone definitions, modern and historical" -category = "main" optional = false python-versions = "*" +files = [ + {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, + {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, +] [[package]] name = "pyyaml" version = "6.0.1" description = "YAML parser and emitter for Python" -category = "main" optional = false python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] [[package]] name = "redis" version = "4.6.0" description = "Python client for Redis database and key-value store" -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "redis-4.6.0-py3-none-any.whl", hash = "sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c"}, + {file = "redis-4.6.0.tar.gz", hash = "sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d"}, +] [package.dependencies] async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2\""} @@ -472,9 +916,12 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)" name = "referencing" version = "0.30.2" description = "JSON Referencing + Python" -category = "main" optional = false python-versions = ">=3.8" +files = [ + {file = "referencing-0.30.2-py3-none-any.whl", hash = "sha256:449b6669b6121a9e96a7f9e410b245d471e8d48964c67113ce9afe50c8dd7bdf"}, + {file = "referencing-0.30.2.tar.gz", hash = "sha256:794ad8003c65938edcdbc027f1933215e0d0ccc0291e3ce20a4d87432b59efc0"}, +] [package.dependencies] attrs = ">=22.2.0" @@ -484,9 +931,12 @@ rpds-py = ">=0.7.0" name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] [package.dependencies] certifi = ">=2017.4.17" @@ -499,637 +949,31 @@ socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] -name = "rfc3986" -version = "1.5.0" -description = "Validating URI References per RFC 3986" -category = "main" +name = "requests-mock" +version = "1.11.0" +description = "Mock out responses from the requests package" optional = false python-versions = "*" +files = [ + {file = "requests-mock-1.11.0.tar.gz", hash = "sha256:ef10b572b489a5f28e09b708697208c4a3b2b89ef80a9f01584340ea357ec3c4"}, + {file = "requests_mock-1.11.0-py2.py3-none-any.whl", hash = "sha256:f7fae383f228633f6bececebdab236c478ace2284d6292c6e7e2867b9ab74d15"}, +] [package.dependencies] -idna = {version = "*", optional = true, markers = "extra == \"idna2008\""} +requests = ">=2.3,<3" +six = "*" [package.extras] -idna2008 = ["idna"] +fixture = ["fixtures"] +test = ["fixtures", "mock", "purl", "pytest", "requests-futures", "sphinx", "testtools"] [[package]] name = "rpds-py" version = "0.9.2" description = "Python bindings to Rust's persistent data structures (rpds)" -category = "main" optional = false python-versions = ">=3.8" - -[[package]] -name = "rq" -version = "1.15.1" -description = "RQ is a simple, lightweight, library for creating background jobs, and processing them." -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -click = ">=5.0.0" -redis = ">=4.0.0" - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" - -[[package]] -name = "sniffio" -version = "1.3.0" -description = "Sniff out which async library your code is running under" -category = "main" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "sortedcontainers" -version = "2.4.0" -description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" -category = "main" -optional = false -python-versions = "*" - -[[package]] -name = "starlette" -version = "0.27.0" -description = "The little ASGI library that shines." -category = "main" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -anyio = ">=3.4.0,<5" -typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} - -[package.extras] -full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyaml"] - -[[package]] -name = "tomli" -version = "2.0.1" -description = "A lil' TOML parser" -category = "main" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "typing-extensions" -version = "4.7.1" -description = "Backported and Experimental Type Hints for Python 3.7+" -category = "main" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "tzdata" -version = "2023.3" -description = "Provider of IANA time zone data" -category = "main" -optional = false -python-versions = ">=2" - -[[package]] -name = "urllib3" -version = "2.0.4" -description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" -optional = false -python-versions = ">=3.7" - -[package.extras] -brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] -secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] -socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] -zstd = ["zstandard (>=0.18.0)"] - -[[package]] -name = "uvicorn" -version = "0.22.0" -description = "The lightning-fast ASGI server." -category = "main" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -click = ">=7.0" -h11 = ">=0.8" - -[package.extras] -standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] - -[[package]] -name = "yamllint" -version = "1.32.0" -description = "A linter for YAML files." -category = "main" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -pathspec = ">=0.5.3" -pyyaml = "*" - -[package.extras] -dev = ["doc8", "flake8", "flake8-import-order", "rstcheck[sphinx]", "sphinx"] - -[extras] -api = ["uvicorn", "fastapi", "pypdf", "pandas"] - -[metadata] -lock-version = "1.1" -python-versions = "^3.9" -content-hash = "5f155173ab7706b5196291ebc6367f1c03fe4bc09f61d97656dd75fe59455e3a" - -[metadata.files] -annotated-types = [ - {file = "annotated_types-0.5.0-py3-none-any.whl", hash = "sha256:58da39888f92c276ad970249761ebea80ba544b77acddaa1a4d6cf78287d45fd"}, - {file = "annotated_types-0.5.0.tar.gz", hash = "sha256:47cdc3490d9ac1506ce92c7aaa76c579dc3509ff11e098fc867e5130ab7be802"}, -] -anyio = [ - {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"}, - {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"}, -] -async-timeout = [ - {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, - {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, -] -attrs = [ - {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, - {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, -] -certifi = [ - {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, - {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, -] -charset-normalizer = [ - {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, - {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, - {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, - {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, - {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, - {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, - {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, -] -click = [ - {file = "click-8.1.4-py3-none-any.whl", hash = "sha256:2739815aaa5d2c986a88f1e9230c55e17f0caad3d958a5e13ad0797c166db9e3"}, - {file = "click-8.1.4.tar.gz", hash = "sha256:b97d0c74955da062a7d4ef92fadb583806a585b2ea81958a81bd72726cbb8e37"}, -] -colorama = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] -coverage = [ - {file = "coverage-7.2.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8"}, - {file = "coverage-7.2.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495"}, - {file = "coverage-7.2.7-cp310-cp310-win32.whl", hash = "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818"}, - {file = "coverage-7.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850"}, - {file = "coverage-7.2.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f"}, - {file = "coverage-7.2.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a"}, - {file = "coverage-7.2.7-cp311-cp311-win32.whl", hash = "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a"}, - {file = "coverage-7.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562"}, - {file = "coverage-7.2.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d"}, - {file = "coverage-7.2.7-cp312-cp312-win32.whl", hash = "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511"}, - {file = "coverage-7.2.7-cp312-cp312-win_amd64.whl", hash = "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3"}, - {file = "coverage-7.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02"}, - {file = "coverage-7.2.7-cp37-cp37m-win32.whl", hash = "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f"}, - {file = "coverage-7.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0"}, - {file = "coverage-7.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5"}, - {file = "coverage-7.2.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f"}, - {file = "coverage-7.2.7-cp38-cp38-win32.whl", hash = "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e"}, - {file = "coverage-7.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c"}, - {file = "coverage-7.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9"}, - {file = "coverage-7.2.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2"}, - {file = "coverage-7.2.7-cp39-cp39-win32.whl", hash = "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb"}, - {file = "coverage-7.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27"}, - {file = "coverage-7.2.7-pp37.pp38.pp39-none-any.whl", hash = "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d"}, - {file = "coverage-7.2.7.tar.gz", hash = "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59"}, -] -exceptiongroup = [ - {file = "exceptiongroup-1.1.2-py3-none-any.whl", hash = "sha256:e346e69d186172ca7cf029c8c1d16235aa0e04035e5750b4b95039e65204328f"}, - {file = "exceptiongroup-1.1.2.tar.gz", hash = "sha256:12c3e887d6485d16943a309616de20ae5582633e0a2eda17f4e10fd61c1e8af5"}, -] -fakeredis = [ - {file = "fakeredis-2.17.0-py3-none-any.whl", hash = "sha256:a99ef6e5642c31e91d36be78809fec3743e2bf7aaa682685b0d65a849fecd148"}, - {file = "fakeredis-2.17.0.tar.gz", hash = "sha256:e304bc7addb2f862c3550cb7db58548418a0fadd4cd78a4de66464c84fbc2195"}, -] -fastapi = [ - {file = "fastapi-0.100.0-py3-none-any.whl", hash = "sha256:271662daf986da8fa98dc2b7c7f61c4abdfdccfb4786d79ed8b2878f172c6d5f"}, - {file = "fastapi-0.100.0.tar.gz", hash = "sha256:acb5f941ea8215663283c10018323ba7ea737c571b67fc7e88e9469c7eb1d12e"}, -] -h11 = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, -] -httpcore = [ - {file = "httpcore-0.16.3-py3-none-any.whl", hash = "sha256:da1fb708784a938aa084bde4feb8317056c55037247c787bd7e19eb2c2949dc0"}, - {file = "httpcore-0.16.3.tar.gz", hash = "sha256:c5d6f04e2fc530f39e0c077e6a30caa53f1451096120f1f38b954afd0b17c0cb"}, -] -httpx = [ - {file = "httpx-0.23.3-py3-none-any.whl", hash = "sha256:a211fcce9b1254ea24f0cd6af9869b3d29aba40154e947d2a07bb499b3e310d6"}, - {file = "httpx-0.23.3.tar.gz", hash = "sha256:9818458eb565bb54898ccb9b8b251a28785dd4a55afbc23d0eb410754fe7d0f9"}, -] -idna = [ - {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, - {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, -] -iniconfig = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] -jsonschema = [ - {file = "jsonschema-4.19.0-py3-none-any.whl", hash = "sha256:043dc26a3845ff09d20e4420d6012a9c91c9aa8999fa184e7efcfeccb41e32cb"}, - {file = "jsonschema-4.19.0.tar.gz", hash = "sha256:6e1e7569ac13be8139b2dd2c21a55d350066ee3f80df06c608b398cdc6f30e8f"}, -] -jsonschema-specifications = [ - {file = "jsonschema_specifications-2023.7.1-py3-none-any.whl", hash = "sha256:05adf340b659828a004220a9613be00fa3f223f2b82002e273dee62fd50524b1"}, - {file = "jsonschema_specifications-2023.7.1.tar.gz", hash = "sha256:c91a50404e88a1f6ba40636778e2ee08f6e24c5613fe4c53ac24578a5a7f72bb"}, -] -numpy = [ - {file = "numpy-1.25.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:77d339465dff3eb33c701430bcb9c325b60354698340229e1dff97745e6b3efa"}, - {file = "numpy-1.25.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d736b75c3f2cb96843a5c7f8d8ccc414768d34b0a75f466c05f3a739b406f10b"}, - {file = "numpy-1.25.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a90725800caeaa160732d6b31f3f843ebd45d6b5f3eec9e8cc287e30f2805bf"}, - {file = "numpy-1.25.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c6c9261d21e617c6dc5eacba35cb68ec36bb72adcff0dee63f8fbc899362588"}, - {file = "numpy-1.25.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0def91f8af6ec4bb94c370e38c575855bf1d0be8a8fbfba42ef9c073faf2cf19"}, - {file = "numpy-1.25.1-cp310-cp310-win32.whl", hash = "sha256:fd67b306320dcadea700a8f79b9e671e607f8696e98ec255915c0c6d6b818503"}, - {file = "numpy-1.25.1-cp310-cp310-win_amd64.whl", hash = "sha256:c1516db588987450b85595586605742879e50dcce923e8973f79529651545b57"}, - {file = "numpy-1.25.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6b82655dd8efeea69dbf85d00fca40013d7f503212bc5259056244961268b66e"}, - {file = "numpy-1.25.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e8f6049c4878cb16960fbbfb22105e49d13d752d4d8371b55110941fb3b17800"}, - {file = "numpy-1.25.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41a56b70e8139884eccb2f733c2f7378af06c82304959e174f8e7370af112e09"}, - {file = "numpy-1.25.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5154b1a25ec796b1aee12ac1b22f414f94752c5f94832f14d8d6c9ac40bcca6"}, - {file = "numpy-1.25.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:38eb6548bb91c421261b4805dc44def9ca1a6eef6444ce35ad1669c0f1a3fc5d"}, - {file = "numpy-1.25.1-cp311-cp311-win32.whl", hash = "sha256:791f409064d0a69dd20579345d852c59822c6aa087f23b07b1b4e28ff5880fcb"}, - {file = "numpy-1.25.1-cp311-cp311-win_amd64.whl", hash = "sha256:c40571fe966393b212689aa17e32ed905924120737194b5d5c1b20b9ed0fb171"}, - {file = "numpy-1.25.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3d7abcdd85aea3e6cdddb59af2350c7ab1ed764397f8eec97a038ad244d2d105"}, - {file = "numpy-1.25.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1a180429394f81c7933634ae49b37b472d343cccb5bb0c4a575ac8bbc433722f"}, - {file = "numpy-1.25.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d412c1697c3853c6fc3cb9751b4915859c7afe6a277c2bf00acf287d56c4e625"}, - {file = "numpy-1.25.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20e1266411120a4f16fad8efa8e0454d21d00b8c7cee5b5ccad7565d95eb42dd"}, - {file = "numpy-1.25.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f76aebc3358ade9eacf9bc2bb8ae589863a4f911611694103af05346637df1b7"}, - {file = "numpy-1.25.1-cp39-cp39-win32.whl", hash = "sha256:247d3ffdd7775bdf191f848be8d49100495114c82c2bd134e8d5d075fb386a1c"}, - {file = "numpy-1.25.1-cp39-cp39-win_amd64.whl", hash = "sha256:1d5d3c68e443c90b38fdf8ef40e60e2538a27548b39b12b73132456847f4b631"}, - {file = "numpy-1.25.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:35a9527c977b924042170a0887de727cd84ff179e478481404c5dc66b4170009"}, - {file = "numpy-1.25.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d3fe3dd0506a28493d82dc3cf254be8cd0d26f4008a417385cbf1ae95b54004"}, - {file = "numpy-1.25.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:012097b5b0d00a11070e8f2e261128c44157a8689f7dedcf35576e525893f4fe"}, - {file = "numpy-1.25.1.tar.gz", hash = "sha256:9a3a9f3a61480cc086117b426a8bd86869c213fc4072e606f01c4e4b66eb92bf"}, -] -packaging = [ - {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, - {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, -] -pact-python = [ - {file = "pact-python-2.0.1.tar.gz", hash = "sha256:151d18c22cd997d8f25a3b584189fb9ae17cae9b99d76eca585636a45355ee59"}, -] -pandas = [ - {file = "pandas-2.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e4c7c9f27a4185304c7caf96dc7d91bc60bc162221152de697c98eb0b2648dd8"}, - {file = "pandas-2.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f167beed68918d62bffb6ec64f2e1d8a7d297a038f86d4aed056b9493fca407f"}, - {file = "pandas-2.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce0c6f76a0f1ba361551f3e6dceaff06bde7514a374aa43e33b588ec10420183"}, - {file = "pandas-2.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba619e410a21d8c387a1ea6e8a0e49bb42216474436245718d7f2e88a2f8d7c0"}, - {file = "pandas-2.0.3-cp310-cp310-win32.whl", hash = "sha256:3ef285093b4fe5058eefd756100a367f27029913760773c8bf1d2d8bebe5d210"}, - {file = "pandas-2.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:9ee1a69328d5c36c98d8e74db06f4ad518a1840e8ccb94a4ba86920986bb617e"}, - {file = "pandas-2.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b084b91d8d66ab19f5bb3256cbd5ea661848338301940e17f4492b2ce0801fe8"}, - {file = "pandas-2.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:37673e3bdf1551b95bf5d4ce372b37770f9529743d2498032439371fc7b7eb26"}, - {file = "pandas-2.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9cb1e14fdb546396b7e1b923ffaeeac24e4cedd14266c3497216dd4448e4f2d"}, - {file = "pandas-2.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9cd88488cceb7635aebb84809d087468eb33551097d600c6dad13602029c2df"}, - {file = "pandas-2.0.3-cp311-cp311-win32.whl", hash = "sha256:694888a81198786f0e164ee3a581df7d505024fbb1f15202fc7db88a71d84ebd"}, - {file = "pandas-2.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:6a21ab5c89dcbd57f78d0ae16630b090eec626360085a4148693def5452d8a6b"}, - {file = "pandas-2.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9e4da0d45e7f34c069fe4d522359df7d23badf83abc1d1cef398895822d11061"}, - {file = "pandas-2.0.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:32fca2ee1b0d93dd71d979726b12b61faa06aeb93cf77468776287f41ff8fdc5"}, - {file = "pandas-2.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:258d3624b3ae734490e4d63c430256e716f488c4fcb7c8e9bde2d3aa46c29089"}, - {file = "pandas-2.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eae3dc34fa1aa7772dd3fc60270d13ced7346fcbcfee017d3132ec625e23bb0"}, - {file = "pandas-2.0.3-cp38-cp38-win32.whl", hash = "sha256:f3421a7afb1a43f7e38e82e844e2bca9a6d793d66c1a7f9f0ff39a795bbc5e02"}, - {file = "pandas-2.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:69d7f3884c95da3a31ef82b7618af5710dba95bb885ffab339aad925c3e8ce78"}, - {file = "pandas-2.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5247fb1ba347c1261cbbf0fcfba4a3121fbb4029d95d9ef4dc45406620b25c8b"}, - {file = "pandas-2.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:81af086f4543c9d8bb128328b5d32e9986e0c84d3ee673a2ac6fb57fd14f755e"}, - {file = "pandas-2.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1994c789bf12a7c5098277fb43836ce090f1073858c10f9220998ac74f37c69b"}, - {file = "pandas-2.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ec591c48e29226bcbb316e0c1e9423622bc7a4eaf1ef7c3c9fa1a3981f89641"}, - {file = "pandas-2.0.3-cp39-cp39-win32.whl", hash = "sha256:04dbdbaf2e4d46ca8da896e1805bc04eb85caa9a82e259e8eed00254d5e0c682"}, - {file = "pandas-2.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:1168574b036cd8b93abc746171c9b4f1b83467438a5e45909fed645cf8692dbc"}, - {file = "pandas-2.0.3.tar.gz", hash = "sha256:c02f372a88e0d17f36d3093a644c73cfc1788e876a7c4bcb4020a77512e2043c"}, -] -pathspec = [ - {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, - {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, -] -pluggy = [ - {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, - {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, -] -psutil = [ - {file = "psutil-5.9.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:be8929ce4313f9f8146caad4272f6abb8bf99fc6cf59344a3167ecd74f4f203f"}, - {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ab8ed1a1d77c95453db1ae00a3f9c50227ebd955437bcf2a574ba8adbf6a74d5"}, - {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:4aef137f3345082a3d3232187aeb4ac4ef959ba3d7c10c33dd73763fbc063da4"}, - {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ea8518d152174e1249c4f2a1c89e3e6065941df2fa13a1ab45327716a23c2b48"}, - {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:acf2aef9391710afded549ff602b5887d7a2349831ae4c26be7c807c0a39fac4"}, - {file = "psutil-5.9.5-cp27-none-win32.whl", hash = "sha256:5b9b8cb93f507e8dbaf22af6a2fd0ccbe8244bf30b1baad6b3954e935157ae3f"}, - {file = "psutil-5.9.5-cp27-none-win_amd64.whl", hash = "sha256:8c5f7c5a052d1d567db4ddd231a9d27a74e8e4a9c3f44b1032762bd7b9fdcd42"}, - {file = "psutil-5.9.5-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:3c6f686f4225553615612f6d9bc21f1c0e305f75d7d8454f9b46e901778e7217"}, - {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a7dd9997128a0d928ed4fb2c2d57e5102bb6089027939f3b722f3a210f9a8da"}, - {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89518112647f1276b03ca97b65cc7f64ca587b1eb0278383017c2a0dcc26cbe4"}, - {file = "psutil-5.9.5-cp36-abi3-win32.whl", hash = "sha256:104a5cc0e31baa2bcf67900be36acde157756b9c44017b86b2c049f11957887d"}, - {file = "psutil-5.9.5-cp36-abi3-win_amd64.whl", hash = "sha256:b258c0c1c9d145a1d5ceffab1134441c4c5113b2417fafff7315a917a026c3c9"}, - {file = "psutil-5.9.5-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:c607bb3b57dc779d55e1554846352b4e358c10fff3abf3514a7a6601beebdb30"}, - {file = "psutil-5.9.5.tar.gz", hash = "sha256:5410638e4df39c54d957fc51ce03048acd8e6d60abc0f5107af51e5fb566eb3c"}, -] -pydantic = [ - {file = "pydantic-2.0.2-py3-none-any.whl", hash = "sha256:f5581e0c79b2ec2fa25a9d30d766629811cdda022107fa73d022ab5578873ae3"}, - {file = "pydantic-2.0.2.tar.gz", hash = "sha256:b802f5245b8576315fe619e5989fd083448fa1258638ef9dac301ca60878396d"}, -] -pydantic-core = [ - {file = "pydantic_core-2.1.2-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:b4815720c266e832b20e27a7a5f3772bb09fdedb31a9a34bab7b49d98967ef5a"}, - {file = "pydantic_core-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8884a1dbfc5cb8c54b48446ca916d4577c1f4d901126091e4ab25d00194e065f"}, - {file = "pydantic_core-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74a33aa69d476773230396396afb8e11908f8dafdcfd422e746770599a3f889d"}, - {file = "pydantic_core-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af832edd384755826e494ffdcf1fdda86e4babc42a0b18d342943fb18181040e"}, - {file = "pydantic_core-2.1.2-cp310-cp310-manylinux_2_24_armv7l.whl", hash = "sha256:017700236ea2e7afbef5d3803559c80bd8720306778ebd49268de7ce9972e83e"}, - {file = "pydantic_core-2.1.2-cp310-cp310-manylinux_2_24_ppc64le.whl", hash = "sha256:c2d00a96fdf26295c6f25eaf9e4a233f353146a73713cd97a5f5dc6090c3aef2"}, - {file = "pydantic_core-2.1.2-cp310-cp310-manylinux_2_24_s390x.whl", hash = "sha256:2575664f0a559a7b951a518f6f34c23cab7190f34f8220b8c8218c4f403147ee"}, - {file = "pydantic_core-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:24c3c9180a2d19d640bacc2d00f497a9a1f2abadb2a9ee201b56bb03bc5343bd"}, - {file = "pydantic_core-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:88a56f0f6d020b4d17641f4b4d1f9540a536d4146768d059c430e97bdb485fc1"}, - {file = "pydantic_core-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fa38a76e832743866aed6b715869757074b06357d1a260163ec26d84974245fe"}, - {file = "pydantic_core-2.1.2-cp310-none-win32.whl", hash = "sha256:a772c652603855d7180015849d483a1f539351a263bb9b81bfe85193a33ce124"}, - {file = "pydantic_core-2.1.2-cp310-none-win_amd64.whl", hash = "sha256:b4673d1f29487608d613ebcc5caa99ba15eb58450a7449fb6d800f29d90bebc1"}, - {file = "pydantic_core-2.1.2-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:76c9c55462740d728b344e3a087775846516c3fee31ec56e2075faa7cfcafcbf"}, - {file = "pydantic_core-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cb854ec52e6e2e05b83d647695f4d913452fdd45a3dfa8233d7dab5967b3908f"}, - {file = "pydantic_core-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ac140d54da366672f6b91f9a1e8e2d4e7e72720143353501ae886d3fca03272"}, - {file = "pydantic_core-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:818f5cb1b209ab1295087c45717178f4bbbd2bd7eda421f7a119e7b9b736a3cb"}, - {file = "pydantic_core-2.1.2-cp311-cp311-manylinux_2_24_armv7l.whl", hash = "sha256:db4564aea8b3cb6cf1e5f3fd80f1ced73a255d492396d1bd8abd688795b34d63"}, - {file = "pydantic_core-2.1.2-cp311-cp311-manylinux_2_24_ppc64le.whl", hash = "sha256:2ca2d2d5ab65fb40dd05259965006edcc62a9d9b30102737c0a6f45bcbd254e8"}, - {file = "pydantic_core-2.1.2-cp311-cp311-manylinux_2_24_s390x.whl", hash = "sha256:7c7ad8958aadfbcd664078002246796ecd5566b64b22f6af4fd1bbcec6bf8f60"}, - {file = "pydantic_core-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:080a7af828388284a68ad7d3d3eac3bcfff6a580292849aff087e7d556ec42d4"}, - {file = "pydantic_core-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bad7029fb2251c1ac7d3acdd607e540d40d137a7d43a5e5acdcfdbd38db3fc0a"}, - {file = "pydantic_core-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1635a37137fafbc6ee0a8c879857e05b30b1aabaa927e653872b71f1501b1502"}, - {file = "pydantic_core-2.1.2-cp311-none-win32.whl", hash = "sha256:eb4301f009a44bb5db5edfe4e51a8175a4112b566baec07f4af8b1f8cb4649a2"}, - {file = "pydantic_core-2.1.2-cp311-none-win_amd64.whl", hash = "sha256:ebf583f4d9b52abd15cc59e5f6eeca7e3e9741c6ea62d8711c00ac3acb067875"}, - {file = "pydantic_core-2.1.2-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:90b06bb47e60173d24c7cb79670aa8dd6081797290353b9d3c66d3a23e88eb34"}, - {file = "pydantic_core-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0e5761ce986ec709897b1b965fad9743f301500434bea3cbab2b6e662571580f"}, - {file = "pydantic_core-2.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b9f8bf1d7008a58fbb6eb334dc6e2f2905400cced8dadb46c4ca28f005a8562"}, - {file = "pydantic_core-2.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a014ee88980013d192a718cbb88e8cea20acd3afad69bc6d15672d05a49cdb6"}, - {file = "pydantic_core-2.1.2-cp312-cp312-manylinux_2_24_armv7l.whl", hash = "sha256:8125152b03dd91deca5afe5b933a1994b39405adf6be2fe8dce3632319283f85"}, - {file = "pydantic_core-2.1.2-cp312-cp312-manylinux_2_24_ppc64le.whl", hash = "sha256:dc737506b4a0ba2922a2626fc6d620ce50a46aebd0fe2fbcad1b93bbdd8c7e78"}, - {file = "pydantic_core-2.1.2-cp312-cp312-manylinux_2_24_s390x.whl", hash = "sha256:bb471ea8650796060afc99909d9b75da583d317e52f660faf64c45f70b3bf1e2"}, - {file = "pydantic_core-2.1.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b1fad38db1744d27061df516e59c5025b09b0a50a337c04e6eebdbddc18951bc"}, - {file = "pydantic_core-2.1.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:94d368af9e6563de6e7170a74710a2cbace7a1e9c8e507d9e3ac34c7065d7ae3"}, - {file = "pydantic_core-2.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:bd95d223de5162811a7b36c73d48eac4fee03b075132f3a1b73c132ce157a60c"}, - {file = "pydantic_core-2.1.2-cp312-none-win32.whl", hash = "sha256:cd62f73830d4715bc643ae39de0bd4fb9c81d6d743530074da91e77a2cccfe67"}, - {file = "pydantic_core-2.1.2-cp312-none-win_amd64.whl", hash = "sha256:51968887d6bd1eaa7fc7759701ea8ccb470c04654beaa8ede6835b0533f206a9"}, - {file = "pydantic_core-2.1.2-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:7ff6bfe63f447a509ed4d368a7f4ba6a7abc03bc4744fc3fb30f2ffab73f3821"}, - {file = "pydantic_core-2.1.2-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:4e67f9b9dfda2e42b39459cbf99d319ccb90da151e35cead3521975b2afbf673"}, - {file = "pydantic_core-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b815a769b019dd96be6571096f246b74f63330547e9b30244c51b4a2eb0277fc"}, - {file = "pydantic_core-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4aff436c23c68449601b3fba7075b4f37ef8fbb893c8c1ed3ef898f090332b1e"}, - {file = "pydantic_core-2.1.2-cp37-cp37m-manylinux_2_24_armv7l.whl", hash = "sha256:2ee3ae58f271851362f6c9b33e4c9f9e866557ec7d8c03dc091e9b5aa5566cec"}, - {file = "pydantic_core-2.1.2-cp37-cp37m-manylinux_2_24_ppc64le.whl", hash = "sha256:cf92dccca8f66e987f6c4378700447f82b79e86407912ab1ee06b16b82f05120"}, - {file = "pydantic_core-2.1.2-cp37-cp37m-manylinux_2_24_s390x.whl", hash = "sha256:4663293a36a851a860b1299c50837914269fca127434911297dd39fea9667a01"}, - {file = "pydantic_core-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1c917f7a41d9d09b8b024a5d65cf37e5588ccdb6e610d2df565fb7186b1f3b1c"}, - {file = "pydantic_core-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:06ae67547251135a1b3f8dd465797b13146295a3866bc12ddd73f7512787bb7c"}, - {file = "pydantic_core-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:4938b32c09dbcecbeb652327cb4a449b1ef1a1bf6c8fc2c8241aa6b8f6d63b54"}, - {file = "pydantic_core-2.1.2-cp37-none-win32.whl", hash = "sha256:682ff9228c838018c47dfa89b3d84cca45f88cacde28807ab8296ec221862af4"}, - {file = "pydantic_core-2.1.2-cp37-none-win_amd64.whl", hash = "sha256:6e3bcb4a9bc209a61ea2aceb7433ce2ece32c7e670b0c06848bf870c9b3e7d87"}, - {file = "pydantic_core-2.1.2-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:2278ca0b0dfbcfb1e12fa58570916dc260dc72bee5e6e342debf5329d8204688"}, - {file = "pydantic_core-2.1.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:87cff210af3258ca0c829e3ebc849d7981bfde23a99d6cb7a3c17a163b3dbad2"}, - {file = "pydantic_core-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7684b5fb906b37e940c5df3f57118f32e033af5e4770e5ae2ae56fbd2fe1a30a"}, - {file = "pydantic_core-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3747a4178139ebf3f19541285b2eb7c886890ca4eb7eec851578c02a13cc1385"}, - {file = "pydantic_core-2.1.2-cp38-cp38-manylinux_2_24_armv7l.whl", hash = "sha256:e17056390068afd4583d88dcf4d4495764e4e2c7d756464468e0d21abcb8931e"}, - {file = "pydantic_core-2.1.2-cp38-cp38-manylinux_2_24_ppc64le.whl", hash = "sha256:c720e55cef609d50418bdfdfb5c44a76efc020ae7455505788d0113c54c7df55"}, - {file = "pydantic_core-2.1.2-cp38-cp38-manylinux_2_24_s390x.whl", hash = "sha256:b59a64c367f350873c40a126ffe9184d903d2126c701380b4b55753484df5948"}, - {file = "pydantic_core-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68a2a767953c707d9575dcf14d8edee7930527ee0141a8bb612c22d1f1059f9a"}, - {file = "pydantic_core-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a4ae46769d9a7138d58cd190441cac14ce954010a0081f28462ed916c8e55a4f"}, - {file = "pydantic_core-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fc909f62325a631e1401dd07dfc386986dbcac15f98c9ff2145d930678a9d25a"}, - {file = "pydantic_core-2.1.2-cp38-none-win32.whl", hash = "sha256:b4038869ba1d8fa33863b4b1286ab07e6075a641ae269b865f94d7e10b3e800e"}, - {file = "pydantic_core-2.1.2-cp38-none-win_amd64.whl", hash = "sha256:5948af62f323252d56acaec8ebfca5f15933f6b72f8dbe3bf21ee97b2d10e3f0"}, - {file = "pydantic_core-2.1.2-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:8e6ce261ccb9a986953c4dce070327e4954f9dd4cd214746dfc70efbc713b6a1"}, - {file = "pydantic_core-2.1.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d35d634d9d1ed280c87bc2a7a6217b8787eedc86f368fc2fa1c0c8c78f7d3c93"}, - {file = "pydantic_core-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0be2e2812a43205728a06c9d0fd090432cd76a9bb5bff2bfcfdf8b0e27d51851"}, - {file = "pydantic_core-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0eb54b11cd4fe0c6404611eef77086ade03eb1457e92910bbb4f3479efa3f79"}, - {file = "pydantic_core-2.1.2-cp39-cp39-manylinux_2_24_armv7l.whl", hash = "sha256:087ddbb754575618a8832ee4ab52fe7eb332f502e2a56088b53dbeb5c4efdf9f"}, - {file = "pydantic_core-2.1.2-cp39-cp39-manylinux_2_24_ppc64le.whl", hash = "sha256:b74906e01c7fc938ac889588ef438de812989817095c3c4904721f647d64a4d1"}, - {file = "pydantic_core-2.1.2-cp39-cp39-manylinux_2_24_s390x.whl", hash = "sha256:60b7239206a2f61ad89c7518adfacb3ccd6662eaa07c5e437317aea2615a1f18"}, - {file = "pydantic_core-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:be3419204952bbe9b72b90008977379c52f99ae1c6e640488de4be783c345d71"}, - {file = "pydantic_core-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:804cf8f6a859620f8eb754c02f7770f61c3e9c519f8338c331d555b3d6976e3c"}, - {file = "pydantic_core-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cbba32fb14e199d0493c6b9c44870dab0a9c37af9f0f729068459d1849279ffd"}, - {file = "pydantic_core-2.1.2-cp39-none-win32.whl", hash = "sha256:6bf00f56a4468f5b03dadb672a5f1d24aea303d4ccffe8a0f548c9e36017edd3"}, - {file = "pydantic_core-2.1.2-cp39-none-win_amd64.whl", hash = "sha256:ac462a28218ea7d592c7ad51b517558f4ac6565a4e53db7a4811eeaf9c9660b0"}, - {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:047e782b9918f35ef534ced36f1fd2064f5581229b7a15e4d3177387a6b53134"}, - {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c0213891898fa5b404cf3edf4797e3ac7819a0708ea5473fc6432a2aa27c189"}, - {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0f481aaf0119f77b200e5a5e2799b3e14c015a317eaa948f42263908735cc9f"}, - {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:15eb4cb543ed36f6a4f16e3bee7aa7ed1c3757be95a3f3bbb2b82b9887131e0f"}, - {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:ef71e73a81a4cd7e87c93e8ff0170140fd93ba33b0f61e83da3f55f6e0a84fb4"}, - {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:840238c845b0f80777151fef0003088ab91c6f7b3467edaff4932b425c4e3c3f"}, - {file = "pydantic_core-2.1.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7648e48ba263ca0a8a2dc55a60a219c9133fb101ba52c89a14a29fb3d4322ca3"}, - {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:8eb4e2b71562375609c66a79f89acd4fe95c5cba23473d04952c8b14b6f908f5"}, - {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5056afea59651c4e47ec6dadbb77ccae4742c059a3d12bc1c0e393d189d2970d"}, - {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46cd323371aa7e4053010ccdb94063a4273aa9e5dbe97f8a1147faa769de8d8d"}, - {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aa39499625239da4ec960cf4fc66b023929b24cc77fb8520289cfdb3c1986428"}, - {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f5de2d4167fd4bc5ad205fb7297e25867b8e335ca08d64ed7a561d2955a2c32d"}, - {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:9a5fba9168fc27805553760fa8198db46eef83bf52b4e87ebbe1333b823d0e70"}, - {file = "pydantic_core-2.1.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:e68a404fad8493989d6f07b7b9e066f1d2524d7cb64db2d4e9a84c920032c67f"}, - {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:1a5c4475510d1a9cc1458a26cfc21442223e52ce9adb640775c38739315d03c7"}, - {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0681472245ef182554208a25d16884c84f1c5a69f14e6169b88932e5da739a1c"}, - {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7fd334b40c5e13a97becfcaba314de0dcc6f7fe21ec8f992139bcc64700e9dc"}, - {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7345b1741bf66a9d8ed0ec291c3eabd534444e139e1ea6db5742ac9fd3be2530"}, - {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:0855cf8b760fb40f97f0226cb527c8a94a2ab9d8179628beae20d6939aaeacb0"}, - {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d281a10837d98db997c0247f45d138522c91ce30cf3ae7a6afdb5e709707d360"}, - {file = "pydantic_core-2.1.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:82e09f27edab289187dd924d4d93f2a35f21aa969699b2504aa643da7fbfeff9"}, - {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:aa54902fa51f7d921ba80923cf1c7ff3dce796a7903300bd8824deb90e357744"}, - {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b9a5fc4058d64c9c826684dcdb43891c1b474a4a88dcf8dfc3e1fb5889496f8"}, - {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:817681d111cb65f07d46496eafec815f48e1aff37713b73135a0a9eb4d3610ab"}, - {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0b5d37aedea5963f2097bddbcdb255483191646a52d40d8bb66d61c190fcac91"}, - {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:f2de65752fff248319bcd3b29da24e205fa505607539fcd4acc4037355175b63"}, - {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:a8b9c2cc4c5f8169b943d24be4bd1548fe81c016d704126e3a3124a2fc164885"}, - {file = "pydantic_core-2.1.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f7bcdf70c8b6e70be11c78d3c00b80a24cccfb408128f23e91ec3019bed1ecc1"}, - {file = "pydantic_core-2.1.2.tar.gz", hash = "sha256:d2c790f0d928b672484eac4f5696dd0b78f3d6d148a641ea196eb49c0875e30a"}, -] -pypdf = [ - {file = "pypdf-3.12.1-py3-none-any.whl", hash = "sha256:74aa287c83e9aad2ce4a3627458dad729e39b5deae52175fe9f97bfffdde41bc"}, - {file = "pypdf-3.12.1.tar.gz", hash = "sha256:68bf9e089caaab356518410168df9ed90f0a6109e29adac168449d4054fa0094"}, -] -pytest = [ - {file = "pytest-7.4.0-py3-none-any.whl", hash = "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32"}, - {file = "pytest-7.4.0.tar.gz", hash = "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a"}, -] -pytest-cov = [ - {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, - {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, -] -python-dateutil = [ - {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, - {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, -] -python-multipart = [ - {file = "python_multipart-0.0.6-py3-none-any.whl", hash = "sha256:ee698bab5ef148b0a760751c261902cd096e57e10558e11aca17646b74ee1c18"}, - {file = "python_multipart-0.0.6.tar.gz", hash = "sha256:e9925a80bb668529f1b67c7fdb0a5dacdd7cbfc6fb0bff3ea443fe22bdd62132"}, -] -pytz = [ - {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, - {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, -] -pyyaml = [ - {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, - {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, - {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, - {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, - {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, - {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, - {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, - {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, - {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, - {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, - {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, - {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, - {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, - {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, - {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, - {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, - {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, - {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, - {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, -] -redis = [ - {file = "redis-4.6.0-py3-none-any.whl", hash = "sha256:e2b03db868160ee4591de3cb90d40ebb50a90dd302138775937f6a42b7ed183c"}, - {file = "redis-4.6.0.tar.gz", hash = "sha256:585dc516b9eb042a619ef0a39c3d7d55fe81bdb4df09a52c9cdde0d07bf1aa7d"}, -] -referencing = [ - {file = "referencing-0.30.2-py3-none-any.whl", hash = "sha256:449b6669b6121a9e96a7f9e410b245d471e8d48964c67113ce9afe50c8dd7bdf"}, - {file = "referencing-0.30.2.tar.gz", hash = "sha256:794ad8003c65938edcdbc027f1933215e0d0ccc0291e3ce20a4d87432b59efc0"}, -] -requests = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, -] -rfc3986 = [ - {file = "rfc3986-1.5.0-py2.py3-none-any.whl", hash = "sha256:a86d6e1f5b1dc238b218b012df0aa79409667bb209e58da56d0b94704e712a97"}, - {file = "rfc3986-1.5.0.tar.gz", hash = "sha256:270aaf10d87d0d4e095063c65bf3ddbc6ee3d0b226328ce21e036f946e421835"}, -] -rpds-py = [ +files = [ {file = "rpds_py-0.9.2-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:ab6919a09c055c9b092798ce18c6c4adf49d24d4d9e43a92b257e3f2548231e7"}, {file = "rpds_py-0.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d55777a80f78dd09410bd84ff8c95ee05519f41113b2df90a69622f5540c4f8b"}, {file = "rpds_py-0.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a216b26e5af0a8e265d4efd65d3bcec5fba6b26909014effe20cd302fd1138fa"}, @@ -1228,47 +1072,160 @@ rpds-py = [ {file = "rpds_py-0.9.2-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:c27ee01a6c3223025f4badd533bea5e87c988cb0ba2811b690395dfe16088cfe"}, {file = "rpds_py-0.9.2.tar.gz", hash = "sha256:8d70e8f14900f2657c249ea4def963bed86a29b81f81f5b76b5a9215680de945"}, ] -rq = [ + +[[package]] +name = "rq" +version = "1.15.1" +description = "RQ is a simple, lightweight, library for creating background jobs, and processing them." +optional = false +python-versions = ">=3.6" +files = [ {file = "rq-1.15.1-py2.py3-none-any.whl", hash = "sha256:6e243d8d9c4af4686ded4b01b25ea1ff4bac4fc260b02638fbe9c8c17b004bd1"}, {file = "rq-1.15.1.tar.gz", hash = "sha256:1f49f4ac1a084044bb8e95b3f305c0bf17e55618b08c18e0b60c080f12d6f008"}, ] -six = [ + +[package.dependencies] +click = ">=5.0.0" +redis = ">=4.0.0" + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] -sniffio = [ + +[[package]] +name = "sniffio" +version = "1.3.0" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" +files = [ {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, ] -sortedcontainers = [ + +[[package]] +name = "sortedcontainers" +version = "2.4.0" +description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" +optional = false +python-versions = "*" +files = [ {file = "sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"}, {file = "sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88"}, ] -starlette = [ + +[[package]] +name = "starlette" +version = "0.27.0" +description = "The little ASGI library that shines." +optional = false +python-versions = ">=3.7" +files = [ {file = "starlette-0.27.0-py3-none-any.whl", hash = "sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91"}, {file = "starlette-0.27.0.tar.gz", hash = "sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75"}, ] -tomli = [ + +[package.dependencies] +anyio = ">=3.4.0,<5" +typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} + +[package.extras] +full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyaml"] + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] -typing-extensions = [ + +[[package]] +name = "typing-extensions" +version = "4.7.1" +description = "Backported and Experimental Type Hints for Python 3.7+" +optional = false +python-versions = ">=3.7" +files = [ {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, ] -tzdata = [ + +[[package]] +name = "tzdata" +version = "2023.3" +description = "Provider of IANA time zone data" +optional = false +python-versions = ">=2" +files = [ {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, ] -urllib3 = [ + +[[package]] +name = "urllib3" +version = "2.0.4" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.7" +files = [ {file = "urllib3-2.0.4-py3-none-any.whl", hash = "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4"}, {file = "urllib3-2.0.4.tar.gz", hash = "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11"}, ] -uvicorn = [ + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "uvicorn" +version = "0.22.0" +description = "The lightning-fast ASGI server." +optional = false +python-versions = ">=3.7" +files = [ {file = "uvicorn-0.22.0-py3-none-any.whl", hash = "sha256:e9434d3bbf05f310e762147f769c9f21235ee118ba2d2bf1155a7196448bd996"}, {file = "uvicorn-0.22.0.tar.gz", hash = "sha256:79277ae03db57ce7d9aa0567830bbb51d7a612f54d6e1e3e92da3ef24c2c8ed8"}, ] -yamllint = [ + +[package.dependencies] +click = ">=7.0" +h11 = ">=0.8" + +[package.extras] +standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] + +[[package]] +name = "yamllint" +version = "1.32.0" +description = "A linter for YAML files." +optional = false +python-versions = ">=3.7" +files = [ {file = "yamllint-1.32.0-py3-none-any.whl", hash = "sha256:d97a66e48da820829d96077d76b8dfbe6c6140f106e558dae87e81ac4e6b30b7"}, {file = "yamllint-1.32.0.tar.gz", hash = "sha256:d01dde008c65de5b235188ab3110bebc59d18e5c65fc8a58267cd211cd9df34a"}, ] + +[package.dependencies] +pathspec = ">=0.5.3" +pyyaml = "*" + +[package.extras] +dev = ["doc8", "flake8", "flake8-import-order", "rstcheck[sphinx]", "sphinx"] + +[metadata] +lock-version = "2.0" +python-versions = "^3.9" +content-hash = "57a6d3f697de24d30dd4364958e1176e9638c7de5740ff606328523f460570b1" diff --git a/pyproject.toml b/pyproject.toml index fffaf48..de2d728 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,6 +4,7 @@ version = "0.1.0" description = "" authors = ["Powell Fendley"] readme = "README.md" +packages = [{include = "lib"}, {include = "worker"}, {include = "api"}, {include = "tests"}] [tool.poetry.dependencies] python = "^3.9" @@ -13,22 +14,30 @@ pydantic = "^2.0.2" idna = "^3.4" python-multipart = "^0.0.6" pandas = "^2.0.3" +requests = "^2.31.0" +pydantic-settings = "^2.0.3" + + +[tool.poetry.group.api] +optional = true -uvicorn = { version = "^0.22.0", optional = true } -fastapi = { version = "^0.100.0", optional = true } -pypdf = { version = "^3.12.0", optional = true } +[tool.poetry.group.api.dependencies] +uvicorn = "^0.22.0" +fastapi = "^0.100.0" +pypdf = "^3.12.0" + +[tool.poetry.group.dev.dependencies] pytest = "^7.4.0" -httpx = "0.23.3" -requests = "^2.31.0" -fakeredis = "^2.17.0" +httpx = "^0.24.1" +fakeredis = "^2.18.0" pytest-cov = "^4.1.0" -pact-python = "^2.0.1" jsonschema = "^4.19.0" yamllint = "^1.32.0" +poethepoet = "^0.22.0" +requests-mock = "^1.11.0" - -[tool.poetry.extras] -api = ["uvicorn", "fastapi", "pypdf", "pandas"] +[tool.pytest.ini_options] +markers = ["resource"] [build-system] requires = ["poetry-core"] diff --git a/tests/conftest.py b/tests/conftest.py index c39f495..e7a7e46 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,34 +1,131 @@ import os +import pytest +from pydantic_settings import BaseSettings +import logging +import sys +import re +from urllib.parse import urlparse, parse_qs, quote_plus +import json +from collections import namedtuple +from io import BytesIO +from itertools import count -############################## -###### Setup Environment ##### -############################## +import requests +import requests +import requests_mock +from rq import SimpleWorker, Queue +from fastapi.testclient import TestClient +from fakeredis import FakeStrictRedis +from api.server import app, get_redis +from lib.settings import settings -os.environ["LIVE"] = "FALSE" -os.environ["TA1_UNIFIED_URL"] = "https://ta1:5" -os.environ["MIT_TR_URL"] = "http://mit:10" -os.environ["TDS_URL"] = "http://tds:15" -os.environ["OPENAI_API_KEY"] = "foo" -os.environ["LOG_LEVEL"] = "INFO" +@pytest.fixture(autouse=True) +def loghandler(): + LOG_LEVEL = settings.LOG_LEVEL.upper() + numeric_level = getattr(logging, LOG_LEVEL, None) + if not isinstance(numeric_level, int): + raise ValueError(f"Invalid log level: {LOG_LEVEL}") + + logger = logging.getLogger(__name__) + logger.setLevel(numeric_level) + handler = logging.StreamHandler() + formatter = logging.Formatter( + "%(asctime)s - %(name)s - %(levelname)s - [%(lineno)d] - %(message)s" + ) + handler.setFormatter(formatter) + logger.addHandler(handler) + + +@pytest.fixture +def redis(): + return FakeStrictRedis() + + +@pytest.fixture +def worker(redis): + queue = Queue(connection=redis, default_timeout=-1) + return SimpleWorker([queue], connection=redis) + + +@pytest.fixture +def client(redis): + app.dependency_overrides[get_redis] = lambda: redis + yield TestClient(app) + app.dependency_overrides[get_redis] = get_redis + + +@pytest.fixture +def context_dir(request): + chosen = request.node.get_closest_marker("resource").args[0] + yield f"./tests/resources/{chosen}" + + +@pytest.fixture +def http_mock(): + # adapter = requests_mock.Adapter() + # session = requests.Session() + # session.mount('mock://', adapter) + with requests_mock.Mocker(real_http=True) as mocker:#, session=session) as mocker: + yield mocker + + +@pytest.fixture +def file_storage(http_mock): + storage = {} + + def get_filename(url): + return parse_qs(urlparse(url).query)["filename"][0] + + def get_loc(request, _): + filename = get_filename(request.url) + return {"url": f"mock://filesave?filename={filename}"} + + def save(request, context): + filename = get_filename(request.url) + storage[filename] = request.body.read().decode("utf-8") + return {"status": "success"} + + def retrieve(filename): + return storage[filename] + + def retrieve_from_url(request, _): + return retrieve(get_filename(request.url)).encode() + + def upload(filename, content): + if isinstance(content, dict): + content = json.dumps(content) + if isinstance(content, str): + content = BytesIO(content.encode()) + requests.put(f"mock://filesave?filename={quote_plus(filename)}", content) + + get_file_url = re.compile(f"(?:(?:upload)|(?:download))-url") + http_mock.get(get_file_url, json=get_loc) + file_url = re.compile("filesave") + http_mock.put(file_url, json=save) + http_mock.get(file_url, content=retrieve_from_url) + Storage = namedtuple("Storage", ["retrieve", "upload"]) + + yield Storage(retrieve=retrieve, upload=upload) -############################## -######## Setup Logging ####### -############################## -import logging -LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO").upper() -numeric_level = getattr(logging, LOG_LEVEL, None) -if not isinstance(numeric_level, int): - raise ValueError(f"Invalid log level: {LOG_LEVEL}") - -logger = logging.getLogger(__name__) -logger.setLevel(numeric_level) -handler = logging.StreamHandler() -formatter = logging.Formatter( - "%(asctime)s - %(name)s - %(levelname)s - [%(lineno)d] - %(message)s" -) -handler.setFormatter(formatter) -logger.addHandler(handler) +@pytest.fixture +def gen_tds_artifact(context_dir, http_mock, file_storage): + # Mock the TDS artifact + counter = count() + def generate(): + artifact = { + "id": f"artifact-{next(counter)}", + "name": "artifact", + "description": "test artifact", + "timestamp": "2023-07-17T19:11:43", + "file_names": [], + "metadata": {}, + } + artifact_url = f"{settings.TDS_URL}/artifacts/{artifact['id']}" + http_mock.get(artifact_url, json=artifact) + http_mock.put(artifact_url) + return artifact + return generate diff --git a/tests/test_code_to_amr/amr.json b/tests/resources/basic_code_to_amr/amr.json similarity index 100% rename from tests/test_code_to_amr/amr.json rename to tests/resources/basic_code_to_amr/amr.json diff --git a/tests/test_code_to_amr/code.py b/tests/resources/basic_code_to_amr/code.py similarity index 100% rename from tests/test_code_to_amr/code.py rename to tests/resources/basic_code_to_amr/code.py diff --git a/tests/test_equations_to_amr/amr.json b/tests/resources/basic_equations_to_amr/amr.json similarity index 100% rename from tests/test_equations_to_amr/amr.json rename to tests/resources/basic_equations_to_amr/amr.json diff --git a/tests/test_equations_to_amr/equations.txt b/tests/resources/basic_equations_to_amr/equations.txt similarity index 100% rename from tests/test_equations_to_amr/equations.txt rename to tests/resources/basic_equations_to_amr/equations.txt diff --git a/tests/test_pdf_extractions/extractions.json b/tests/resources/basic_pdf_extraction/extractions.json similarity index 100% rename from tests/test_pdf_extractions/extractions.json rename to tests/resources/basic_pdf_extraction/extractions.json diff --git a/tests/test_pdf_extractions/text.json b/tests/resources/basic_pdf_extraction/text.json similarity index 100% rename from tests/test_pdf_extractions/text.json rename to tests/resources/basic_pdf_extraction/text.json diff --git a/tests/test_pdf_to_text/paper.pdf b/tests/resources/basic_pdf_to_text/paper.pdf similarity index 100% rename from tests/test_pdf_to_text/paper.pdf rename to tests/resources/basic_pdf_to_text/paper.pdf diff --git a/tests/test_pdf_to_text/text.json b/tests/resources/basic_pdf_to_text/text.json similarity index 100% rename from tests/test_pdf_to_text/text.json rename to tests/resources/basic_pdf_to_text/text.json diff --git a/tests/test_profile_dataset/data.csv b/tests/resources/basic_profile_dataset/data.csv similarity index 100% rename from tests/test_profile_dataset/data.csv rename to tests/resources/basic_profile_dataset/data.csv diff --git a/tests/test_profile_dataset/data_card.json b/tests/resources/basic_profile_dataset/data_card.json similarity index 100% rename from tests/test_profile_dataset/data_card.json rename to tests/resources/basic_profile_dataset/data_card.json diff --git a/tests/resources/basic_profile_dataset/text.json b/tests/resources/basic_profile_dataset/text.json new file mode 100644 index 0000000..5eaa7d7 --- /dev/null +++ b/tests/resources/basic_profile_dataset/text.json @@ -0,0 +1,5172 @@ +[ + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 107.0, + 1275.0, + 195.0 + ], + "classes":[ + "Equation label", + "Section Header", + "Page Header", + "Body Text", + "Figure", + "Other", + "Equation", + "Reference text", + "Figure Caption", + "Table", + "Page Footer", + "Table Note", + "Table Caption", + "Abstract" + ], + "scores":[ + -5.158577919, + -8.3714532852, + -10.0183992386, + -10.2071590424, + -11.1120090485, + -11.1143541336, + -11.2161874771, + -13.0983781815, + -15.0558624268, + -15.1471719742, + -15.9366912842, + -18.405462265, + -18.7139511108, + -18.9916629791 + ], + "content":"", + "postprocess_cls":"Page Header", + "postprocess_score":0.9985458851, + "detect_cls":"Equation label", + "detect_score":-5.158577919 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 80.0, + 234.0, + 1197.0, + 305.0 + ], + "classes":[ + "Body Text", + "Other", + "Equation label", + "Section Header", + "Reference text", + "Table Note", + "Page Footer", + "Figure", + "Abstract", + "Equation", + "Page Header", + "Table", + "Figure Caption", + "Table Caption" + ], + "scores":[ + -1.9848747253, + -7.259475708, + -11.0177192688, + -12.7866334915, + -13.10891819, + -14.0849218369, + -14.3103981018, + -14.6399879456, + -14.7027568817, + -15.8481864929, + -16.2041015625, + -17.3444747925, + -17.9344902039, + -20.9808273315 + ], + "content":"Article Dynamical Analysis of Universal Masking on the Pandemic", + "postprocess_cls":"Body Text", + "postprocess_score":0.9914546013, + "detect_cls":"Body Text", + "detect_score":-1.9848747253 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 83.0, + 343.0, + 1044.0, + 370.0 + ], + "classes":[ + "Section Header", + "Other", + "Equation label", + "Equation", + "Body Text", + "Page Footer", + "Figure", + "Reference text", + "Abstract", + "Table Note", + "Table Caption", + "Table", + "Figure Caption", + "Page Header" + ], + "scores":[ + -2.0326740742, + -2.7304286957, + -4.5183801651, + -5.2259273529, + -6.2282066345, + -6.3734707832, + -6.7899360657, + -7.0165834427, + -7.4191837311, + -7.4662895203, + -7.9870581627, + -8.0286159515, + -8.2380943298, + -8.6224336624 + ], + "content":"Brandon Kaiheng Tay † , Carvalho Andrea Roby †, Jodi Wenjiang Wu † and Da Yang Tan *", + "postprocess_cls":"Section Header", + "postprocess_score":0.9072340131, + "detect_cls":"Section Header", + "detect_score":-2.0326740742 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 418.0, + 1226.0, + 535.0 + ], + "classes":[ + "Page Footer", + "Other", + "Table Note", + "Table", + "Page Header", + "Figure", + "Body Text", + "Table Caption", + "Figure Caption", + "Reference text", + "Abstract", + "Section Header", + "Equation label", + "Equation" + ], + "scores":[ + -2.5388700962, + -3.7671117783, + -5.0030655861, + -5.7867355347, + -6.5778765678, + -6.8421964645, + -6.8604774475, + -7.6586065292, + -7.836004734, + -7.9547429085, + -8.0516815186, + -9.3464565277, + -9.8778991699, + -10.1746559143 + ], + "content":"Science, Mathematics and Technology, Singapore University of Technology and Design, 8 Somapah Road, Singapore 487372, Singapore; brandontay6@gmail.com (B.K.T.); andwea3@gmail.com (C.A.R.); jodiwwj@gmail.com (J.W.W.) * Correspondence: dayang_tan@sutd.edu.sg † These authors contributed equally to this work.", + "postprocess_cls":"Other", + "postprocess_score":0.6949161887, + "detect_cls":"Page Footer", + "detect_score":-2.5388700962 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 381.0, + 573.0, + 1278.0, + 890.0 + ], + "classes":[ + "Abstract", + "Other", + "Section Header", + "Body Text", + "Equation label", + "Reference text", + "Table Note", + "Table", + "Figure Caption", + "Figure", + "Page Footer", + "Table Caption", + "Page Header", + "Equation" + ], + "scores":[ + -6.553381443, + -7.0592031479, + -7.5321784019, + -8.1746530533, + -9.3305721283, + -9.5875043869, + -10.8356370926, + -10.9991464615, + -11.3415498734, + -11.5023822784, + -11.6590452194, + -11.7893009186, + -12.5354270935, + -14.5688781738 + ], + "content":"Abstract: We investigate the impact of the delay in compulsory mask wearing on the spread of COVID-19 in the community, set in the Singapore context. By using modified SEIR-based compart- mental models, we focus on macroscopic population-level analysis of the relationships between the delay in compulsory mask wearing and the maximum infection, through a series of scenario-based analysis. Our analysis suggests that collective masking can meaningfully reduce the transmission of COVID-19 in the community, but only if implemented within a critical time window of approximately before 80–100 days delay after the first infection is detected, coupled with strict enforcement to ensure compliance throughout the duration. We also identify a delay threshold of about 100 days that results in masking enforcement having little significant impact on the Maximum Infected Values. The results therefore highlight the necessity for rapid implementation of compulsory mask wearing to curb the spread of the pandemic.", + "postprocess_cls":"Abstract", + "postprocess_score":0.9484135509, + "detect_cls":"Abstract", + "detect_score":-6.553381443 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 926.0, + 1275.0, + 984.0 + ], + "classes":[ + "Body Text", + "Page Header", + "Other", + "Equation label", + "Figure", + "Section Header", + "Equation", + "Table", + "Figure Caption", + "Page Footer", + "Reference text", + "Abstract", + "Table Caption", + "Table Note" + ], + "scores":[ + -5.5984277725, + -6.6887278557, + -7.2796764374, + -7.5727577209, + -8.1192560196, + -8.3920602798, + -9.5373849869, + -9.6610832214, + -10.6693582535, + -11.2980852127, + -12.0429611206, + -12.0956077576, + -12.9813222885, + -13.2261285782 + ], + "content":"Keywords: SEIR model; SEIS model; mask wearing; compartmental model; epidemic modelling", + "postprocess_cls":"Body Text", + "postprocess_score":0.7085515261, + "detect_cls":"Body Text", + "detect_score":-5.5984277725 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 81.0, + 1002.0, + 345.0, + 1154.0 + ], + "classes":[ + "Body Text", + "Section Header", + "Figure", + "Other", + "Page Header", + "Figure Caption", + "Reference text", + "Equation label", + "Abstract", + "Table Note", + "Page Footer", + "Table", + "Table Caption", + "Equation" + ], + "scores":[ + -0.4976767898, + -7.6454410553, + -9.3069028854, + -9.428153038, + -9.6553201675, + -10.0410013199, + -10.3448381424, + -10.689655304, + -11.2578315735, + -11.2712049484, + -11.7054204941, + -15.0347061157, + -15.1838083267, + -15.3739404678 + ], + "content":"Citation: Tay, B.K.; Roby, C.A.; Wu, J.W.; Tan, D.Y. Dynamical Analysis of Universal Masking on the Pandemic. Int. J. Environ. Res. Public Health 2021, 18, 9027. https:// doi.org/10.3390/ijerph18179027", + "postprocess_cls":"Body Text", + "postprocess_score":0.8970527649, + "detect_cls":"Body Text", + "detect_score":-0.4976767898 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 1038.0, + 536.0, + 1055.0 + ], + "classes":[ + "Body Text", + "Section Header", + "Page Header", + "Figure", + "Reference text", + "Other", + "Page Footer", + "Equation label", + "Figure Caption", + "Equation", + "Table Note", + "Abstract", + "Table", + "Table Caption" + ], + "scores":[ + -1.8938975334, + -4.3468050957, + -5.930565834, + -7.1995210648, + -7.2024521828, + -7.6047611237, + -8.6509456635, + -9.3752946854, + -9.4793462753, + -11.2701282501, + -11.3327894211, + -11.9113807678, + -12.3241205215, + -13.5627841949 + ], + "content":"1. Introduction", + "postprocess_cls":"Section Header", + "postprocess_score":0.9995450377, + "detect_cls":"Body Text", + "detect_score":-1.8938975334 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 1074.0, + 1278.0, + 1755.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Section Header", + "Reference text", + "Page Footer", + "Abstract", + "Table Note", + "Figure Caption", + "Figure", + "Page Header", + "Other", + "Table", + "Table Caption", + "Equation" + ], + "scores":[ + 0.7251604199, + -15.622086525, + -15.7503271103, + -15.8251218796, + -16.0309772491, + -16.1873703003, + -16.934419632, + -17.0300006866, + -17.3174877167, + -19.9234809875, + -20.3943519592, + -24.590473175, + -24.6434822083, + -27.056306839 + ], + "content":"In the light of the COVID-19 pandemic, the Singapore government declared with effect as of 14 April 2020, an enforcement of compulsory mask wearing in public spaces, 89 days after the first case of COVID-19 was detected in Singapore. The usage of masks is known to effectively decrease the infection rate. It has shown success in limiting community spread of SARS 2003 [1], and more recently, in Taiwan's management of COVID-19 [2]. Recent hypothetical studies on masking by the states of New York and Washington suggests a potential prevention of up to 45% of their projected death rates [3]. In this study of potential face-mask usage for the general public, the authors investigated how public masking can control the infection, in the context of the USA. However, not much was mentioned about how the delayed enforcement of such a policy would affect the infection numbers. In another study on public masking [4], the authors studied how factors such as the filtering capability of different mask materials, as well as sociological behaviour patterns on masking, would affect the efficacy of this policy. A comprehensive data-driven study on COVID-19 waves worldwide and strategies to mitigate them conducted by Lai and Cheong [5] also did not provide detailed analysis of mask wearing policies and its effectiveness. Concluding this literature review, it is apparent that in-depth studies on the impact of delayed mask enforcement on the spread of COVID-19 in the community is limited. This paper thus seeks to investigate the relationship between delay in compulsory mask wearing and the Maximum Infected Values, through a series of scenario-based what- if analysis. We would be considering 3 scenarios using 2 compartmental models—the SEIR and the SEIRS model. The use of compartmental models for modelling the spread of COVID-19 has been explored recently, such as to study the lockdown measures [6,7], or with variant to include the effects of age-structure within the population [8] and different", + "postprocess_cls":"Body Text", + "postprocess_score":0.9998295307, + "detect_cls":"Body Text", + "detect_score":0.7251604199 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 81.0, + 1192.0, + 310.0, + 1208.0 + ], + "classes":[ + "Other", + "Page Footer", + "Section Header", + "Body Text", + "Equation label", + "Table Note", + "Reference text", + "Figure", + "Abstract", + "Page Header", + "Table", + "Table Caption", + "Equation", + "Figure Caption" + ], + "scores":[ + -2.9890294075, + -3.3959157467, + -4.593378067, + -6.244890213, + -6.5497121811, + -7.2422127724, + -7.3849005699, + -7.4488811493, + -7.4600481987, + -7.6431908607, + -7.7195529938, + -7.9713959694, + -7.9969091415, + -8.4315900803 + ], + "content":"Academic Editor: Jimmy T. Efird", + "postprocess_cls":"Section Header", + "postprocess_score":0.9993419051, + "detect_cls":"Other", + "detect_score":-2.9890294075 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 81.0, + 1247.0, + 268.0, + 1318.0 + ], + "classes":[ + "Other", + "Body Text", + "Section Header", + "Equation label", + "Reference text", + "Figure", + "Page Footer", + "Equation", + "Table Note", + "Table", + "Abstract", + "Page Header", + "Table Caption", + "Figure Caption" + ], + "scores":[ + -4.1823372841, + -5.1112661362, + -6.9629349709, + -7.0838446617, + -7.7467865944, + -7.8375759125, + -8.8564739227, + -8.9725866318, + -9.1548099518, + -9.5617437363, + -9.6012058258, + -11.4223642349, + -12.3504314423, + -12.5159215927 + ], + "content":"Received: 20 June 2021 Accepted: 24 August 2021 Published: 27 August 2021", + "postprocess_cls":"Body Text", + "postprocess_score":0.6687924266, + "detect_cls":"Other", + "detect_score":-4.1823372841 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 81.0, + 1359.0, + 351.0, + 1453.0 + ], + "classes":[ + "Section Header", + "Page Footer", + "Reference text", + "Body Text", + "Other", + "Table Note", + "Figure", + "Equation", + "Abstract", + "Figure Caption", + "Table Caption", + "Equation label", + "Table", + "Page Header" + ], + "scores":[ + -5.8428478241, + -6.3360619545, + -7.2266125679, + -7.5321187973, + -8.2308416367, + -9.9798364639, + -10.8188667297, + -11.5504598618, + -11.6129703522, + -11.9741849899, + -12.2181940079, + -12.3263959885, + -12.5641174316, + -13.806722641 + ], + "content":"Publisher's Note: MDPI stays neutral with regard to jurisdictional claims in published maps and institutional affil- iations.", + "postprocess_cls":"Body Text", + "postprocess_score":0.7294377089, + "detect_cls":"Section Header", + "detect_score":-5.8428478241 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 81.0, + 1500.0, + 350.0, + 1767.0 + ], + "classes":[ + "Section Header", + "Page Footer", + "Figure Caption", + "Other", + "Figure", + "Body Text", + "Abstract", + "Reference text", + "Table Note", + "Equation", + "Table Caption", + "Table", + "Equation label", + "Page Header" + ], + "scores":[ + -6.5802001953, + -7.0285143852, + -8.0855836868, + -8.2666950226, + -8.3461647034, + -8.6726207733, + -9.8244400024, + -10.4466161728, + -11.00852108, + -11.2992296219, + -11.4344749451, + -12.3009567261, + -12.8775424957, + -14.8131856918 + ], + "content":"Copyright: © 2021 by the authors. Licensee MDPI, Basel, Switzerland. This article is an open access article distributed under the terms and conditions of the Creative Commons Attribution (CC BY) license (https:// creativecommons.org/licenses/by/ 4.0/).", + "postprocess_cls":"Body Text", + "postprocess_score":0.4166562259, + "detect_cls":"Section Header", + "detect_score":-6.5802001953 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 1843.0, + 1275.0, + 1876.0 + ], + "classes":[ + "Page Footer", + "Page Header", + "Reference text", + "Equation label", + "Table", + "Other", + "Body Text", + "Table Note", + "Equation", + "Figure", + "Table Caption", + "Abstract", + "Figure Caption", + "Section Header" + ], + "scores":[ + -0.5714578032, + -4.4968333244, + -4.5759072304, + -4.8665537834, + -5.7643418312, + -5.7929019928, + -5.9571275711, + -6.7715325356, + -7.1043848991, + -7.6470108032, + -8.7554969788, + -9.1320457458, + -9.1481485367, + -9.5743207932 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027. https://doi.org/10.3390/ijerph18179027 https://www.mdpi.com/journal/ijerph", + "postprocess_cls":"Page Footer", + "postprocess_score":0.9999275208, + "detect_cls":"Page Footer", + "detect_score":-0.5714578032 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":2, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_2_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Page Header", + "Equation label", + "Body Text", + "Page Footer", + "Figure Caption", + "Section Header", + "Other", + "Reference text", + "Table", + "Figure", + "Table Note", + "Table Caption", + "Equation", + "Abstract" + ], + "scores":[ + -1.69619596, + -3.2141313553, + -3.9378855228, + -4.8566551208, + -5.4208545685, + -5.9383769035, + -6.2361469269, + -6.353307724, + -6.3739156723, + -6.5636873245, + -7.3287501335, + -7.3517103195, + -8.558930397, + -8.8238668442 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 2 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.9995732903, + "detect_cls":"Page Header", + "detect_score":-1.69619596 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":2, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_2_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 219.0, + 1276.0, + 529.0 + ], + "classes":[ + "Body Text", + "Figure Caption", + "Figure", + "Equation label", + "Page Footer", + "Section Header", + "Abstract", + "Table Note", + "Reference text", + "Page Header", + "Other", + "Table Caption", + "Equation", + "Table" + ], + "scores":[ + -0.5451325774, + -10.4853096008, + -12.1630077362, + -13.2492980957, + -13.500875473, + -13.7242078781, + -14.071103096, + -14.4545812607, + -14.7841234207, + -15.7971820831, + -18.4810504913, + -20.4726238251, + -22.414308548, + -22.4882659912 + ], + "content":"social settings [9]. For the SEIR model, we consider a complete compliance, and gradual noncompliance over time. Using an SEIRS model, we consider a third scenario taking into account time-limited immunity. Results from simulating these 3 scenarios would hopefully shed light on the effects of delaying the usage of masks and how the containment of epidemic could have been more effective in Singapore. To model the pandemic from a macroscopic view point, we use modified versions of the model, which consists of a number of compartments described by a system of differential equations in Sections 2 and 3. To solve these equations, we implemented the model in Python using the Odeint package. We then modify the Delay of Mask Enforcement by plotting several data sets and recording the resulting Maximum Infection Value predicted by our model. This was performed over 3 different scenarios:", + "postprocess_cls":"Body Text", + "postprocess_score":0.9443999529, + "detect_cls":"Body Text", + "detect_score":-0.5451325774 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":2, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_2_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 430.0, + 546.0, + 1278.0, + 1078.0 + ], + "classes":[ + "Body Text", + "Page Footer", + "Figure Caption", + "Equation label", + "Abstract", + "Reference text", + "Figure", + "Table Note", + "Page Header", + "Section Header", + "Other", + "Table", + "Table Caption", + "Equation" + ], + "scores":[ + -1.7037055492, + -12.2971372604, + -12.7130117416, + -14.0141639709, + -14.4679946899, + -14.7939186096, + -15.6933107376, + -16.0003376007, + -16.9068927765, + -19.4729213715, + -19.6528110504, + -23.4287376404, + -23.999332428, + -24.6993846893 + ], + "content":"Scenario 1: The first scenario considers the most basic case of complete compliance of the masking enforcement, from the day it was enforced throughout its duration. It also does not account for time-limited immunity [10], where infected individuals become susceptible again after a period of time. Scenario 2: The second scenario closely resembles the first, but with the addition of gradual noncompliance of the masking enforcement. The root of noncompliance stems from either lack of medical knowledge, wishful thinking that the pandemic will magically disappear, selfish behaviour of individuals, pandemic fatigue etc. Here, we assume that onset of the noncompliance is triggered by an event, for instance, changes in government policies. As an illustration, the Singapore government announced the Phase 2 of its gradual reopening plan on 18 June 2020 (154 days after the first case in Singapore) where members of the public were allowed to visit shopping malls and dine-in at food establishments, it was observed that a minority of individuals did not comply with the masking regulations. Scenario 3: The third scenario is almost identical to the first, but now accounts for time-limited immunity. After 90 days, it has been shown that a recovered individual may become susceptible to the virus again [11]. This scenario serves as a comparison to investigate if the immunity factor would worsen the effects of the delay of mask enforcement on the maximum infected values.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9966195822, + "detect_cls":"Body Text", + "detect_score":-1.7037055492 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":2, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_2_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 384.0, + 550.0, + 392.0, + 959.0 + ], + "classes":[ + "Figure", + "Page Footer", + "Body Text", + "Page Header", + "Equation", + "Equation label", + "Table", + "Other", + "Reference text", + "Section Header", + "Figure Caption", + "Table Note", + "Abstract", + "Table Caption" + ], + "scores":[ + -3.9439780712, + -5.3267054558, + -6.2526054382, + -7.1189422607, + -7.8562464714, + -8.1171293259, + -9.2266807556, + -9.8653507233, + -10.498093605, + -10.6506376266, + -11.1741914749, + -11.8317804337, + -13.3176107407, + -13.9674358368 + ], + "content":"• • •", + "postprocess_cls":"Figure", + "postprocess_score":0.52900666, + "detect_cls":"Figure", + "detect_score":-3.9439780712 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":2, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_2_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 1101.0, + 1278.0, + 1576.0 + ], + "classes":[ + "Body Text", + "Reference text", + "Equation label", + "Abstract", + "Page Footer", + "Section Header", + "Table Note", + "Other", + "Figure", + "Figure Caption", + "Page Header", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + -0.6825846434, + -15.3944978714, + -15.428196907, + -16.5312175751, + -16.6540126801, + -18.0022602081, + -20.0354576111, + -20.8560085297, + -21.1997718811, + -21.5778102875, + -21.596364975, + -28.5442733765, + -29.507566452, + -30.4051780701 + ], + "content":"Here we highlight that effective control of the COVID19 pandemic cannot be achieved by the universal masking enforcement alone, but a strong combination factors such as social distancing enforcement, rapid roll-out of mass testing, lockdowns and extensive quarantine measures. However, these are outside the scope of our analysis, as we aim to both model and investigate how the delay of public masking enforcement affects its effectiveness in controlling the pandemic. We have thus considered the effects of universal masking in isolation of the other factors for the purpose of this analysis. Sections 2 and 3 of this article describe and explain the SEIR and SEIRS mathematical models we implemented. Section 4 describes the mathematical modelling of the relation- ship between the mask wearing and the infection rate with respect to time t. Section 5 describes the epidemiological parameters implemented in our models. Brief justification of their values are also included. Section 6 comprises the results and discussion, and is divided into 3 sub-sections. Section 6.1 explains the dynamics of the delay in compulsory mask wearing, and discusses its effects as demonstrated by our models. Section 6.2 ex- plains the effects of this delay on the Maximum Infected Values for each of the 3 scenarios. Section 6.3 discusses the limitations of our study. Finally, Section 7 wraps up the discussion with a conclusion.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9997990727, + "detect_cls":"Body Text", + "detect_score":-0.6825846434 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":2, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_2_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 1610.0, + 531.0, + 1627.0 + ], + "classes":[ + "Body Text", + "Page Footer", + "Other", + "Section Header", + "Figure", + "Reference text", + "Equation label", + "Equation", + "Table Note", + "Table", + "Figure Caption", + "Page Header", + "Abstract", + "Table Caption" + ], + "scores":[ + -4.2576880455, + -5.7159318924, + -6.2077884674, + -6.4353137016, + -7.9118890762, + -8.0875310898, + -8.1936368942, + -8.9437570572, + -9.4237642288, + -9.8112573624, + -10.0816755295, + -10.3704032898, + -11.5863780975, + -11.9120559692 + ], + "content":"2. SEIR Model", + "postprocess_cls":"Section Header", + "postprocess_score":0.9992983341, + "detect_cls":"Body Text", + "detect_score":-4.2576880455 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":2, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_2_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 381.0, + 1645.0, + 1278.0, + 1783.0 + ], + "classes":[ + "Body Text", + "Abstract", + "Figure Caption", + "Page Footer", + "Reference text", + "Table Note", + "Figure", + "Section Header", + "Other", + "Page Header", + "Equation label", + "Table Caption", + "Table", + "Equation" + ], + "scores":[ + -6.8442792892, + -14.5340843201, + -15.9826402664, + -16.779340744, + -18.0857620239, + -19.8811759949, + -22.0744285583, + -24.9976997375, + -25.2601032257, + -25.4991168976, + -25.9981155396, + -26.0339317322, + -28.6102046967, + -34.445186615 + ], + "content":"Compartmentalized mathematical models have been regularly used to model infec- tious diseases. The most basic SIR (Susceptible, Infected, Removed) was developed in the early twentieth century by Ronald Ross, William Hamer, and many others [12], and has been heavily modified since, with the addition of new compartments and parameters. More recently, the use of similar models have resurfaced to model the COVID19 situation", + "postprocess_cls":"Body Text", + "postprocess_score":0.9988446236, + "detect_cls":"Body Text", + "detect_score":-6.8442792892 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Page Header", + "Equation label", + "Body Text", + "Page Footer", + "Figure Caption", + "Section Header", + "Other", + "Figure", + "Table", + "Reference text", + "Table Note", + "Table Caption", + "Abstract", + "Equation" + ], + "scores":[ + -2.3664302826, + -2.9404520988, + -3.2837388515, + -4.0985455513, + -4.7677974701, + -5.3199496269, + -5.6641254425, + -5.7271747589, + -5.8400988579, + -5.9454283714, + -6.2081561089, + -6.536760807, + -7.8253655434, + -8.1519069672 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 3 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.9991918206, + "detect_cls":"Page Header", + "detect_score":-2.3664302826 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 381.0, + 224.0, + 1277.0, + 418.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Reference text", + "Page Footer", + "Figure", + "Page Header", + "Section Header", + "Table Note", + "Abstract", + "Other", + "Figure Caption", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + 0.4304295182, + -10.1913642883, + -12.402302742, + -14.7456035614, + -15.7327041626, + -16.9917621613, + -17.6852760315, + -18.2479972839, + -18.9947147369, + -19.0640888214, + -19.0708618164, + -21.1419143677, + -24.5851593018, + -28.4060916901 + ], + "content":"in many countries. Recent epidemiological studies on China [13], Italy [14], India [15] for example, have been conducted with modified versions of such a model. For our study, we used the SEIR [16] and SEIRS [17] variant of the model, as described in Sections 2 and 3. The SEIR model consists of several compartments, namely Susceptible, Exposed, Infected and Removed. We expand the model by further differentiating the Removed compartment into 2 new Recovered and Death compartments. The flow between the 5 components are described by the following 5 differential equations:", + "postprocess_cls":"Body Text", + "postprocess_score":0.9962309003, + "detect_cls":"Body Text", + "detect_score":0.4304295182 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 752.0, + 716.0, + 1274.0, + 765.0 + ], + "classes":[ + "Equation label", + "Equation", + "Body Text", + "Figure", + "Page Header", + "Reference text", + "Table", + "Section Header", + "Other", + "Page Footer", + "Figure Caption", + "Table Note", + "Abstract", + "Table Caption" + ], + "scores":[ + 0.7596632242, + -6.09562397, + -6.2220053673, + -8.4025192261, + -11.1426048279, + -12.1553859711, + -13.1699972153, + -13.5358810425, + -14.4634923935, + -15.2270336151, + -15.240105629, + -16.8979148865, + -18.1654338837, + -19.4191036224 + ], + "content":"dD(t) = αρI(t) (5) dt", + "postprocess_cls":"Equation", + "postprocess_score":0.9998032451, + "detect_cls":"Equation label", + "detect_score":0.7596632242 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 723.0, + 651.0, + 1274.0, + 699.0 + ], + "classes":[ + "Equation label", + "Body Text", + "Equation", + "Page Header", + "Figure", + "Reference text", + "Section Header", + "Figure Caption", + "Other", + "Table", + "Page Footer", + "Table Note", + "Abstract", + "Table Caption" + ], + "scores":[ + -0.5282879472, + -3.2964746952, + -8.4707126617, + -8.9078521729, + -9.4237070084, + -12.070687294, + -12.3733644485, + -13.7526845932, + -14.542424202, + -15.080165863, + -16.516462326, + -16.5492744446, + -17.5699195862, + -20.0694351196 + ], + "content":"dR(t) = (1 − α)γI(t) (4) dt", + "postprocess_cls":"Equation", + "postprocess_score":0.9947794676, + "detect_cls":"Equation label", + "detect_score":-0.5282879472 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 640.0, + 585.0, + 1274.0, + 634.0 + ], + "classes":[ + "Equation label", + "Body Text", + "Equation", + "Figure", + "Page Header", + "Reference text", + "Section Header", + "Table", + "Figure Caption", + "Other", + "Table Note", + "Page Footer", + "Abstract", + "Table Caption" + ], + "scores":[ + 1.0624827147, + -3.953271389, + -8.6391658783, + -10.9951019287, + -11.2218170166, + -13.0829267502, + -13.9086027145, + -14.9607896805, + -15.1052751541, + -15.5159215927, + -16.6100692749, + -16.7282314301, + -18.5023384094, + -20.6325378418 + ], + "content":"dI(t) = δE(t) − (1 − α)γI(t) − αρI(t) (3) dt", + "postprocess_cls":"Equation", + "postprocess_score":0.9843853116, + "detect_cls":"Equation label", + "detect_score":1.0624827147 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 696.0, + 519.0, + 1274.0, + 568.0 + ], + "classes":[ + "Equation label", + "Body Text", + "Section Header", + "Equation", + "Figure", + "Figure Caption", + "Page Header", + "Reference text", + "Table Note", + "Other", + "Page Footer", + "Table", + "Abstract", + "Table Caption" + ], + "scores":[ + -1.777987957, + -2.7053332329, + -10.7096710205, + -10.9655132294, + -11.248005867, + -12.8873147964, + -13.0134782791, + -13.5010709763, + -15.5496406555, + -15.7924356461, + -16.4645557404, + -16.4778881073, + -17.3430652618, + -18.789352417 + ], + "content":"S(t) dE(t) = βI(t) − δE(t) (2) dt N", + "postprocess_cls":"Equation", + "postprocess_score":0.9568058848, + "detect_cls":"Equation label", + "detect_score":-1.777987957 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 681.0, + 1222.0, + 1274.0, + 1271.0 + ], + "classes":[ + "Equation label", + "Body Text", + "Equation", + "Reference text", + "Figure", + "Page Header", + "Section Header", + "Other", + "Table", + "Figure Caption", + "Abstract", + "Table Note", + "Page Footer", + "Table Caption" + ], + "scores":[ + -4.8503398895, + -5.2248268127, + -9.1185617447, + -11.5806236267, + -12.3339033127, + -12.5619077682, + -12.5990018845, + -15.5497922897, + -16.5331687927, + -16.9476299286, + -18.8042221069, + -20.0208435059, + -20.5148220062, + -22.381269455 + ], + "content":"dR(t) = (1 − α)γI(t) − R(t) (7) dt", + "postprocess_cls":"Equation", + "postprocess_score":0.8299534917, + "detect_cls":"Equation label", + "detect_score":-4.8503398895 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 686.0, + 1147.0, + 1274.0, + 1197.0 + ], + "classes":[ + "Equation label", + "Body Text", + "Page Header", + "Equation", + "Reference text", + "Figure", + "Section Header", + "Figure Caption", + "Table", + "Other", + "Page Footer", + "Table Note", + "Abstract", + "Table Caption" + ], + "scores":[ + 0.117642507, + -5.4621038437, + -7.5167608261, + -9.5665636063, + -10.4896383286, + -12.6301279068, + -13.0732145309, + -14.711019516, + -15.0971460342, + -15.5980558395, + -16.1236038208, + -18.3282203674, + -18.7492389679, + -20.926448822 + ], + "content":"dS(t) S(t) = −βI(t) + R(t) (6) dt N", + "postprocess_cls":"Equation", + "postprocess_score":0.9961049557, + "detect_cls":"Equation label", + "detect_score":0.117642507 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 728.0, + 444.0, + 1274.0, + 493.0 + ], + "classes":[ + "Equation label", + "Body Text", + "Reference text", + "Page Footer", + "Table Note", + "Other", + "Table", + "Figure", + "Section Header", + "Equation", + "Page Header", + "Abstract", + "Table Caption", + "Figure Caption" + ], + "scores":[ + -2.7598707676, + -2.888833046, + -5.524936676, + -5.6568017006, + -6.0531992912, + -6.1260838509, + -6.5165491104, + -7.3657631874, + -7.4578914642, + -8.0260257721, + -8.8127374649, + -9.0429992676, + -9.6294651031, + -9.9026927948 + ], + "content":"dS(t) S(t) = −βI(t) (1) dt N", + "postprocess_cls":"Equation", + "postprocess_score":0.6141163707, + "detect_cls":"Equation label", + "detect_score":-2.7598707676 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 782.0, + 1275.0, + 920.0 + ], + "classes":[ + "Body Text", + "Section Header", + "Figure Caption", + "Abstract", + "Equation label", + "Table Note", + "Page Footer", + "Reference text", + "Other", + "Figure", + "Table Caption", + "Page Header", + "Equation", + "Table" + ], + "scores":[ + -2.7215280533, + -10.4865884781, + -10.639998436, + -13.9466915131, + -15.7235155106, + -16.6665477753, + -16.8861198425, + -18.0406684875, + -18.3201999664, + -18.3763141632, + -20.1121368408, + -20.3940029144, + -24.6096229553, + -25.1321487427 + ], + "content":"where N is the total population, S(t), E(t), I(t), R(t) and D(t), are the number of people susceptible, exposed, infected, recovered and dead on day t. β is the expected number of people an infected person infects per day, γ is the proportion of recovery per day, δ is the incubation period, α is the fatality rate due to the infection and ρ is the inverse of the average number of days for an infected person to die if he does not recover.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9959763885, + "detect_cls":"Body Text", + "detect_score":-2.7215280533 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 949.0, + 545.0, + 965.0 + ], + "classes":[ + "Body Text", + "Page Footer", + "Figure", + "Equation label", + "Reference text", + "Other", + "Page Header", + "Section Header", + "Abstract", + "Figure Caption", + "Table Note", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + -5.2109236717, + -6.5942687988, + -8.2502479553, + -8.8928756714, + -9.0652112961, + -10.0970077515, + -10.5589427948, + -10.9189805984, + -12.2121772766, + -12.4608488083, + -12.7421483994, + -13.4477958679, + -13.8999729156, + -17.0868797302 + ], + "content":"3. SEIRS Model", + "postprocess_cls":"Section Header", + "postprocess_score":0.9996773005, + "detect_cls":"Body Text", + "detect_score":-5.2109236717 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 984.0, + 1275.0, + 1121.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Abstract", + "Reference text", + "Other", + "Table Note", + "Page Footer", + "Section Header", + "Figure", + "Figure Caption", + "Page Header", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + -2.9874308109, + -9.0950212479, + -10.8997097015, + -11.151506424, + -11.562748909, + -12.2840843201, + -13.4683017731, + -14.4899168015, + -16.8020267487, + -16.9602298737, + -17.6181564331, + -17.9680194855, + -18.2824897766, + -19.6447219849 + ], + "content":"The SEIRS model is similar to the SEIR model such that it has five components as well—Susceptible, Exposed, Infected, Recovered and Death. However, the SEIRS model takes time-limited immunity into account, whereby recovered individuals are prone to becoming susceptible to the disease again after a period of time. In the SEIRS model, Equations (1) and (4) are then modified to", + "postprocess_cls":"Body Text", + "postprocess_score":0.9993829727, + "detect_cls":"Body Text", + "detect_score":-2.9874308109 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 1288.0, + 1126.0, + 1311.0 + ], + "classes":[ + "Equation label", + "Body Text", + "Figure", + "Section Header", + "Reference text", + "Page Header", + "Equation", + "Figure Caption", + "Table", + "Other", + "Page Footer", + "Table Note", + "Abstract", + "Table Caption" + ], + "scores":[ + -2.6959555149, + -3.5594203472, + -6.703063488, + -7.6305561066, + -7.7114853859, + -7.9572868347, + -8.2868156433, + -10.5709295273, + -12.1454677582, + -12.3750295639, + -13.2707958221, + -13.6201553345, + -13.6786584854, + -15.3705368042 + ], + "content":"where is the rate at which a recovered person becomes susceptible again.", + "postprocess_cls":"Equation", + "postprocess_score":0.8025770187, + "detect_cls":"Equation label", + "detect_score":-2.6959555149 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 1339.0, + 1277.0, + 1712.0 + ], + "classes":[ + "Body Text", + "Reference text", + "Abstract", + "Equation label", + "Page Header", + "Section Header", + "Figure Caption", + "Page Footer", + "Figure", + "Other", + "Table Note", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + -3.1954927444, + -6.7487845421, + -12.9166879654, + -13.5890388489, + -14.0583839417, + -16.2690963745, + -16.9095211029, + -17.8277950287, + -19.5517063141, + -19.598072052, + -19.6363887787, + -21.2971973419, + -22.2141418457, + -24.7429199219 + ], + "content":"4. Time-Based Model for Compulsory Mask Wearing Masking is found to decrease the infection rate I(t) by reducing the transmission of respiratory droplets between individuals, which in turn reduces the number of individuals an infected person can infect. Kai et al. [18] showed that the infection rate can be reduced by 60% when universal masking is enforced. There have been other studies that reflect varying rates of infection rate reduction, such as 47% (estimate between 15% and 75%) in Germany [19] and 75% in Arizona during the 2020 summer surge [20], along with numerous others. The disparity of the figures are likely to be due to the influence of other policies such as enforced social distancing and lockdowns. For the purpose of our study, we felt 60% reduction in infection rate was a reasonable value, without being too optimistic or pessimistic.We thus model our infection rate as time-dependent β → β(t) and a function of m(t): β(t) = κm(t) (8)", + "postprocess_cls":"Body Text", + "postprocess_score":0.9998670816, + "detect_cls":"Body Text", + "detect_score":-3.1954927444 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":4, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_4_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Page Header", + "Equation label", + "Body Text", + "Page Footer", + "Section Header", + "Figure Caption", + "Other", + "Table", + "Reference text", + "Table Caption", + "Figure", + "Table Note", + "Equation", + "Abstract" + ], + "scores":[ + -1.7302033901, + -3.6377530098, + -4.4046735764, + -5.2347478867, + -5.5449490547, + -5.9033555984, + -5.9583358765, + -6.3729043007, + -6.5386605263, + -7.0557188988, + -7.2179327011, + -7.4130735397, + -8.6365003586, + -8.9389972687 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 4 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.9993817806, + "detect_cls":"Page Header", + "detect_score":-1.7302033901 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":4, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_4_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 224.0, + 741.0, + 246.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Section Header", + "Figure", + "Reference text", + "Equation", + "Figure Caption", + "Page Footer", + "Page Header", + "Table Note", + "Other", + "Abstract", + "Table", + "Table Caption" + ], + "scores":[ + -1.7804280519, + -8.1360397339, + -11.527100563, + -13.3830690384, + -13.5606451035, + -13.768409729, + -15.0057487488, + -17.1439228058, + -17.2342357635, + -17.2720603943, + -18.1832847595, + -18.4798774719, + -21.9602966309, + -22.6526908875 + ], + "content":"where κ is an arbitrary constant and", + "postprocess_cls":"Page Header", + "postprocess_score":0.9264364839, + "detect_cls":"Body Text", + "detect_score":-1.7804280519 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":4, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_4_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 694.0, + 273.0, + 1274.0, + 324.0 + ], + "classes":[ + "Equation", + "Equation label", + "Body Text", + "Figure", + "Section Header", + "Table", + "Reference text", + "Page Header", + "Other", + "Page Footer", + "Figure Caption", + "Table Note", + "Abstract", + "Table Caption" + ], + "scores":[ + -3.7837722301, + -4.4668540955, + -8.5332717896, + -9.7747631073, + -13.9771213531, + -14.2968702316, + -14.3140821457, + -14.3843383789, + -14.4104194641, + -16.5212039948, + -19.6543273926, + -20.2351646423, + -20.919095993, + -21.7818088531 + ], + "content":"βs − βc m(t) = (9) + βc 1 + e−k(−t+t0)", + "postprocess_cls":"Equation", + "postprocess_score":0.9999083281, + "detect_cls":"Equation", + "detect_score":-3.7837722301 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":4, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_4_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 350.0, + 1275.0, + 539.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Figure Caption", + "Figure", + "Page Footer", + "Table Note", + "Reference text", + "Abstract", + "Other", + "Section Header", + "Page Header", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + -0.5436022878, + -14.9844760895, + -15.4629774094, + -16.4936618805, + -18.1207199097, + -18.1337356567, + -19.5456314087, + -19.683921814, + -20.7252178192, + -21.2746753693, + -22.7573699951, + -27.0828914642, + -28.5530204773, + -29.5923461914 + ], + "content":"where a modified logistic function is used to model this transition by setting the infection before (i.e., at the start of the outbreak) and after the full compliance masking enforcement to be βs = 1 and βc = 0.4 respectively. t0 is the number of days after the first case where masking wearing is enforced. Figure 1 shows an example of such logistic function, where for the case of Singapore, we set t0 = 89, since the policy of compulsory mask wearing was implemented 89 days after the first case was uncovered. This model is used in both Scenarios 1 and 3.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9971863627, + "detect_cls":"Body Text", + "detect_score":-0.5436022878 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":4, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_4_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 404.0, + 580.0, + 1152.0, + 1079.0 + ], + "classes":[ + "Figure", + "Body Text", + "Page Header", + "Equation", + "Equation label", + "Figure Caption", + "Section Header", + "Other", + "Table", + "Page Footer", + "Table Note", + "Abstract", + "Reference text", + "Table Caption" + ], + "scores":[ + 4.1000723839, + -9.4325752258, + -12.4519081116, + -14.3672904968, + -14.5336322784, + -14.9966268539, + -15.9972295761, + -16.025396347, + -16.671836853, + -17.1014385223, + -19.9756145477, + -21.1269264221, + -22.4875679016, + -23.1718616486 + ], + "content":"", + "postprocess_cls":"Figure", + "postprocess_score":0.9999912977, + "detect_cls":"Figure", + "detect_score":4.1000723839 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":4, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_4_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 1104.0, + 1275.0, + 1149.0 + ], + "classes":[ + "Figure Caption", + "Page Header", + "Body Text", + "Table Caption", + "Section Header", + "Figure", + "Page Footer", + "Equation label", + "Table Note", + "Abstract", + "Other", + "Table", + "Reference text", + "Equation" + ], + "scores":[ + 2.9030091763, + -9.2282190323, + -13.6434030533, + -15.0287923813, + -16.2147197723, + -16.3651332855, + -17.4601249695, + -17.9541778564, + -18.631696701, + -18.9941577911, + -20.4291362762, + -22.0355434418, + -22.8392944336, + -23.8998527527 + ], + "content":"Figure 1. Logistic function to model the infection rate due to compulsory mask wearing m(t) for Scenarios 1 and 3.", + "postprocess_cls":"Figure Caption", + "postprocess_score":0.9999907017, + "detect_cls":"Figure Caption", + "detect_score":2.9030091763 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":4, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_4_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 1184.0, + 1275.0, + 1289.0 + ], + "classes":[ + "Figure", + "Page Header", + "Equation label", + "Equation", + "Body Text", + "Other", + "Section Header", + "Figure Caption", + "Table", + "Page Footer", + "Reference text", + "Abstract", + "Table Note", + "Table Caption" + ], + "scores":[ + -5.9238781929, + -7.8981151581, + -8.0480117798, + -8.0698204041, + -8.5796461105, + -10.6876716614, + -13.9410295486, + -14.1181249619, + -14.4374904633, + -15.9662275314, + -16.184179306, + -18.5673618317, + -18.7337665558, + -19.8033809662 + ], + "content":"To model the gradual noncompliance of universal masking, we make a modification to Equation (9). βs − βc βc − βnc + m(t) = (10) + βnc 1 + e−k1(−t+t0) 1 + e−k2(−t+t1)", + "postprocess_cls":"Body Text", + "postprocess_score":0.5503957272, + "detect_cls":"Figure", + "detect_score":-5.9238781929 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":4, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_4_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 1305.0, + 1278.0, + 1672.0 + ], + "classes":[ + "Body Text", + "Figure Caption", + "Table Note", + "Equation label", + "Page Header", + "Section Header", + "Abstract", + "Table Caption", + "Other", + "Page Footer", + "Reference text", + "Figure", + "Table", + "Equation" + ], + "scores":[ + -5.8830633163, + -9.0368585587, + -10.8957958221, + -13.3811073303, + -13.5485925674, + -14.8247318268, + -14.991435051, + -15.1697273254, + -15.8896350861, + -17.105091095, + -17.6960659027, + -18.4475955963, + -21.0349082947, + -23.3355693817 + ], + "content":"As individuals began to engage in noncompliance out of complacency and pandemic fatigue, the infection rate, βnc, would thus increase slightly. Furthermore, compared to quenching of the infection rate due to enforcement of the compulsory mask wearing, the noncompliance will be gradual. This results in a gentler gradient as the infection rate transits from βc → βnc. The gradients are tuned by the arbitrary constants k1 and k2, where k1 > k2. We further assume that the population are able to maintain compliance for a period of time before onset of noncompliance at t1, which may be triggered by an event, for example a change in the government's policy. Figure 2 illustrates one such example, where we have βnc = 0.5 and t1 = 154, taken in context to Singapore's shift from a full lockdown to gradual resumption of everyday activities 154 days after the first case. The infection rate βnc is expected to be lower than βs as even with the complacency and fatigue, as there is now a greater situational awareness of the severity and the population in general will take a more cautious outlook compared to pre-pandemic days.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9968757629, + "detect_cls":"Body Text", + "detect_score":-5.8830633163 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Page Header", + "Equation label", + "Body Text", + "Page Footer", + "Figure Caption", + "Section Header", + "Other", + "Reference text", + "Figure", + "Table", + "Table Note", + "Table Caption", + "Equation", + "Abstract" + ], + "scores":[ + -1.5087971687, + -3.3478233814, + -3.992017746, + -4.9614892006, + -5.4743070602, + -6.1402859688, + -6.2511262894, + -6.323946476, + -6.4941959381, + -6.5377807617, + -7.5381102562, + -7.6336975098, + -8.5953559875, + -8.9597167969 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 5 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.9994342923, + "detect_cls":"Page Header", + "detect_score":-1.5087971687 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 396.0, + 223.0, + 931.0, + 580.0 + ], + "classes":[ + "Figure", + "Body Text", + "Page Header", + "Figure Caption", + "Other", + "Section Header", + "Equation", + "Equation label", + "Page Footer", + "Table", + "Table Note", + "Abstract", + "Table Caption", + "Reference text" + ], + "scores":[ + 2.2623577118, + -10.2967786789, + -10.8714666367, + -12.8581047058, + -15.1635608673, + -15.8568058014, + -16.4230175018, + -17.6112575531, + -18.1314201355, + -18.4943618774, + -20.4085903168, + -20.733877182, + -22.6400165558, + -22.6574802399 + ], + "content":"", + "postprocess_cls":"Figure", + "postprocess_score":0.9999917746, + "detect_cls":"Figure", + "detect_score":2.2623577118 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 613.0, + 1275.0, + 664.0 + ], + "classes":[ + "Figure Caption", + "Body Text", + "Figure", + "Page Footer", + "Page Header", + "Table Caption", + "Abstract", + "Table Note", + "Section Header", + "Other", + "Equation label", + "Table", + "Reference text", + "Equation" + ], + "scores":[ + 0.9741205573, + -11.5788402557, + -12.8867588043, + -13.7339344025, + -14.8756866455, + -16.1689815521, + -16.255853653, + -16.4346809387, + -16.6110420227, + -16.6758804321, + -21.1135120392, + -21.5821495056, + -23.1135559082, + -24.8644714355 + ], + "content":"Figure 2. Logistic function to model the infection rate due to compulsory mask wearing m(t) for Scenario 2, where one takes into account the noncompliance.", + "postprocess_cls":"Figure Caption", + "postprocess_score":0.9999696016, + "detect_cls":"Figure Caption", + "detect_score":0.9741205573 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 688.0, + 1275.0, + 775.0 + ], + "classes":[ + "Other", + "Section Header", + "Page Footer", + "Figure Caption", + "Body Text", + "Figure", + "Page Header", + "Reference text", + "Equation", + "Table Note", + "Abstract", + "Table Caption", + "Table", + "Equation label" + ], + "scores":[ + -4.6291937828, + -6.0781207085, + -7.9622960091, + -8.5642433167, + -8.5854253769, + -8.9777555466, + -9.801366806, + -10.6661090851, + -10.904668808, + -11.2438554764, + -11.4593896866, + -11.8970451355, + -13.0903167725, + -13.5284023285 + ], + "content":"5. Epidemiological Parameters To conduct our analysis in the Singapore context, we estimate the epidemiological parameters described in the earlier sections for the Singapore's context:", + "postprocess_cls":"Other", + "postprocess_score":0.7580176592, + "detect_cls":"Other", + "detect_score":-4.6291937828 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 430.0, + 792.0, + 1277.0, + 1130.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Reference text", + "Figure Caption", + "Section Header", + "Figure", + "Abstract", + "Page Header", + "Page Footer", + "Table Note", + "Other", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + 1.5766657591, + -13.2020549774, + -16.4787559509, + -16.964302063, + -17.2969303131, + -18.2964859009, + -18.8807621002, + -19.0890674591, + -19.3149185181, + -21.8046360016, + -23.581987381, + -26.566526413, + -28.9885311127, + -30.0895500183 + ], + "content":"γ = 1/11: According to the position statement released by the National Centre of Disease Control Singapore [21], a person remains infectious for up to 11 days after first contracting COVID-19. δ = 1/5: The SARS-CoV2 virus has an incubation period of about 5 days [22]. α = 0.000064: Fatality rate is defined as the percentage of deaths among all previously infected individuals. At the time this work was conducted, the number of deaths in Singapore was 26, and the total number of Recovered and Dead compartments was 40,625. ρ = 1/9: As this number varies greatly across different demographics and is highly unpredictable, we are unable to obtain a proper average. Moreover, owing to the low numbers of COVID-19 deaths in Singapore, it would be inaccurate to calculate an average using this small sample size. Thus, for analysis purposes, we set it at 9 days.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9996544123, + "detect_cls":"Body Text", + "detect_score":1.5766657591 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 384.0, + 796.0, + 392.0, + 804.0 + ], + "classes":[ + "Page Footer", + "Figure", + "Section Header", + "Body Text", + "Equation", + "Other", + "Reference text", + "Table", + "Page Header", + "Table Note", + "Equation label", + "Figure Caption", + "Table Caption", + "Abstract" + ], + "scores":[ + -2.9053115845, + -4.5805282593, + -5.5827050209, + -6.5868663788, + -7.3583173752, + -7.4265518188, + -8.0279092789, + -8.2571277618, + -8.3638343811, + -8.5961027145, + -8.8530931473, + -9.2815132141, + -9.8112306595, + -10.4304542542 + ], + "content":"•", + "postprocess_cls":"Section Header", + "postprocess_score":0.9211617112, + "detect_cls":"Page Footer", + "detect_score":-2.9053115845 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 384.0, + 882.0, + 392.0, + 890.0 + ], + "classes":[ + "Page Footer", + "Section Header", + "Figure", + "Equation label", + "Equation", + "Reference text", + "Table", + "Other", + "Figure Caption", + "Page Header", + "Table Caption", + "Table Note", + "Abstract", + "Body Text" + ], + "scores":[ + -2.1900157928, + -5.3232288361, + -6.3310675621, + -6.538602829, + -6.8521265984, + -7.0864639282, + -7.6612892151, + -7.6977677345, + -7.7621526718, + -7.9629206657, + -8.4278831482, + -8.7660951614, + -9.2666406631, + -9.4148368835 + ], + "content":"•", + "postprocess_cls":"Section Header", + "postprocess_score":0.8286181688, + "detect_cls":"Page Footer", + "detect_score":-2.1900157928 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 384.0, + 911.0, + 392.0, + 919.0 + ], + "classes":[ + "Page Footer", + "Section Header", + "Equation label", + "Figure", + "Table", + "Other", + "Equation", + "Table Caption", + "Table Note", + "Figure Caption", + "Reference text", + "Page Header", + "Body Text", + "Abstract" + ], + "scores":[ + -1.6243486404, + -6.7012591362, + -6.9366807938, + -7.3323450089, + -7.9474105835, + -8.8363676071, + -8.8912086487, + -8.978302002, + -9.0530633926, + -9.4314546585, + -9.4526872635, + -9.770160675, + -9.8681192398, + -11.2481384277 + ], + "content":"•", + "postprocess_cls":"Section Header", + "postprocess_score":0.8768944144, + "detect_cls":"Page Footer", + "detect_score":-1.6243486404 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 384.0, + 1025.0, + 392.0, + 1033.0 + ], + "classes":[ + "Section Header", + "Body Text", + "Page Footer", + "Figure", + "Other", + "Figure Caption", + "Page Header", + "Equation", + "Equation label", + "Table Note", + "Reference text", + "Table Caption", + "Table", + "Abstract" + ], + "scores":[ + -3.8821780682, + -5.7434711456, + -10.7130403519, + -11.2477216721, + -12.108798027, + -13.4920969009, + -13.5678339005, + -14.0245628357, + -14.1262760162, + -16.1466751099, + -17.2123680115, + -17.515127182, + -18.4866218567, + -20.4881267548 + ], + "content":"•", + "postprocess_cls":"Section Header", + "postprocess_score":0.9993214607, + "detect_cls":"Section Header", + "detect_score":-3.8821780682 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 1158.0, + 1277.0, + 1791.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Section Header", + "Page Footer", + "Figure", + "Reference text", + "Figure Caption", + "Page Header", + "Table Note", + "Abstract", + "Other", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + 3.9174981117, + -29.6443309784, + -30.2645549774, + -30.7007331848, + -33.6453704834, + -33.8487052917, + -34.6866035461, + -36.0330162048, + -38.830997467, + -39.2242469788, + -41.6673774719, + -49.0738563538, + -51.2751731873, + -53.5775375366 + ], + "content":"6. Results and Discussion 6.1. Dynamics of Delay of Compulsory Mask Wearing Upon applying the SEIR models to the 3 scenarios described in the above sections, we are able to obtain Maximum Infected Values by simulating different values of delay in mask enforcement. Considering the most basic case of Scenario 1; where there is complete compliance throughout the duration of mask enforcement, and the absence of time-limited immunity, Figure 3 shows the cases where mask wearing were to be enforced (a) on the day the first case of COVID-19 was detected in Singapore; (b) after a 50 days delay; (c) after a 100 days delay; and (d) not enforced at all. From Figure 3, it can be deduced that earlier enforcement of mask wearing both reduces the Maximum Infected Value as well as increases the number of days taken to reach the Maximum Infected Value. This is reflected by right-ward shift of the maxima of the Infected compartment, as well as a lower maxima value of the infected curve. The infected number increases until it reaches a global maxima, before decreasing as predicted by compartmental models of such form. This global maxima is termed as the Maximum Infected Value. For the case of (a) 0 days of delay in mask enforcement, the maximum infected value is approximately 10.453%, and the peak occurs at day 291 after the first case was detected. For the case of a (b) 50 days delay, the maximum infected value is approximately 10.479%, and the peak occurs on day 195. For the case of a (c) 100 days delay, the maximum infected value is much higher, at approximately 27.474%, and the peak occurs much earlier, on day 103. This is very close to the case where (d) no public masking is enforced, where the maximum infected value is approximately 31.422% and", + "postprocess_cls":"Body Text", + "postprocess_score":0.9963091016, + "detect_cls":"Body Text", + "detect_score":3.9174981117 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":6, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_6_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Page Header", + "Equation label", + "Body Text", + "Page Footer", + "Figure Caption", + "Other", + "Figure", + "Section Header", + "Table", + "Reference text", + "Table Note", + "Table Caption", + "Abstract", + "Equation" + ], + "scores":[ + -2.5404891968, + -2.7208592892, + -3.2227096558, + -3.8342299461, + -4.8508319855, + -5.3711147308, + -5.4711380005, + -5.494038105, + -5.6461625099, + -5.8514742851, + -5.9516105652, + -6.5359797478, + -7.7324132919, + -7.8704433441 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 6 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.9993324876, + "detect_cls":"Page Header", + "detect_score":-2.5404891968 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":6, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_6_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 381.0, + 224.0, + 1275.0, + 304.0 + ], + "classes":[ + "Reference text", + "Body Text", + "Page Footer", + "Equation label", + "Table Note", + "Other", + "Abstract", + "Section Header", + "Page Header", + "Figure", + "Figure Caption", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + -2.41370368, + -2.449630022, + -6.9069609642, + -8.0799608231, + -9.8782691956, + -9.8951234818, + -10.0216999054, + -10.1125574112, + -11.3799171448, + -11.8693094254, + -12.6075954437, + -12.9540042877, + -13.3861627579, + -15.8635005951 + ], + "content":"the peak occurs on day 106. From a policy point of view, this suggests that early universal masking would indeed be an effective control, not only to reduce the infection, but more critically to flatten the curve so as to not overwhelm the medical resources.", + "postprocess_cls":"Reference text", + "postprocess_score":0.9266610146, + "detect_cls":"Reference text", + "detect_score":-2.41370368 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":6, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_6_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 250.0, + 363.0, + 1102.0, + 565.0 + ], + "classes":[ + "Figure", + "Page Header", + "Figure Caption", + "Section Header", + "Equation label", + "Body Text", + "Table", + "Equation", + "Table Caption", + "Page Footer", + "Other", + "Table Note", + "Reference text", + "Abstract" + ], + "scores":[ + -3.1873693466, + -4.8212738037, + -7.0536727905, + -10.2028875351, + -10.3731937408, + -12.6629772186, + -13.1024913788, + -13.3014593124, + -13.4798297882, + -14.02252388, + -14.8326330185, + -16.4965019226, + -16.7484340668, + -17.5182647705 + ], + "content":"", + "postprocess_cls":"Figure", + "postprocess_score":0.9992592931, + "detect_cls":"Figure", + "detect_score":-3.1873693466 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":6, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_6_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 250.0, + 590.0, + 1117.0, + 791.0 + ], + "classes":[ + "Page Header", + "Figure", + "Figure Caption", + "Body Text", + "Equation label", + "Page Footer", + "Equation", + "Table", + "Section Header", + "Other", + "Reference text", + "Table Caption", + "Table Note", + "Abstract" + ], + "scores":[ + -1.1635150909, + -4.8522176743, + -9.8937969208, + -9.9956798553, + -10.4784946442, + -12.4243450165, + -12.8667650223, + -13.4087505341, + -13.4521074295, + -14.8423604965, + -16.4829616547, + -16.5560760498, + -17.6497058868, + -19.2318267822 + ], + "content":"", + "postprocess_cls":"Figure", + "postprocess_score":0.9996366501, + "detect_cls":"Page Header", + "detect_score":-1.1635150909 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":6, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_6_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 129.0, + 840.0, + 1227.0, + 890.0 + ], + "classes":[ + "Figure Caption", + "Section Header", + "Table Caption", + "Body Text", + "Other", + "Page Header", + "Table Note", + "Figure", + "Page Footer", + "Abstract", + "Equation label", + "Reference text", + "Table", + "Equation" + ], + "scores":[ + 0.0527810045, + -5.8636431694, + -8.1322975159, + -9.1273422241, + -9.1603155136, + -9.2407836914, + -10.6179800034, + -10.9474830627, + -11.1488428116, + -11.6220417023, + -12.3708753586, + -13.761590004, + -14.0128669739, + -14.9243373871 + ], + "content":"Figure 3. SEIR Plots for delays of (a) 0 days, (b) 50 days, (c) 100 days. (d) corresponds to the control case where mask wearing is not enforced.", + "postprocess_cls":"Figure Caption", + "postprocess_score":0.9999295473, + "detect_cls":"Figure Caption", + "detect_score":0.0527810045 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":6, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_6_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 381.0, + 921.0, + 1275.0, + 1062.0 + ], + "classes":[ + "Figure Caption", + "Body Text", + "Section Header", + "Page Header", + "Equation label", + "Figure", + "Page Footer", + "Abstract", + "Table Note", + "Reference text", + "Other", + "Table Caption", + "Equation", + "Table" + ], + "scores":[ + -3.1065702438, + -4.7654337883, + -12.8439817429, + -13.8662433624, + -15.4319906235, + -15.5018615723, + -17.0974407196, + -18.2143917084, + -19.3625240326, + -19.7661495209, + -20.4133853912, + -21.4896030426, + -24.7576503754, + -25.5214538574 + ], + "content":"6.2. Effects of Delay of Mask Enforcement on Maximum Infected Value We further investigate this relationship by explicitly considering how the delay in mask enforcement will impact the corresponding Maximum Infected Values. Figure 4 shows the results of different enforcement delay values and their corresponding maximum infected values. Here, we considered 3 scenarios described in the introduction.", + "postprocess_cls":"Body Text", + "postprocess_score":0.5061179996, + "detect_cls":"Figure Caption", + "detect_score":-3.1065702438 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":6, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_6_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 393.0, + 1108.0, + 1030.0, + 1537.0 + ], + "classes":[ + "Figure", + "Body Text", + "Page Header", + "Section Header", + "Equation", + "Equation label", + "Other", + "Figure Caption", + "Table", + "Page Footer", + "Table Note", + "Abstract", + "Reference text", + "Table Caption" + ], + "scores":[ + 3.2385380268, + -9.2120409012, + -9.7329940796, + -12.2138414383, + -13.0309505463, + -13.1443042755, + -13.3979330063, + -13.8367948532, + -14.9413957596, + -17.6346092224, + -18.796453476, + -19.1195087433, + -20.0014133453, + -20.6520004272 + ], + "content":"", + "postprocess_cls":"Figure", + "postprocess_score":0.9999812841, + "detect_cls":"Figure", + "detect_score":3.2385380268 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":6, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_6_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 1572.0, + 1275.0, + 1622.0 + ], + "classes":[ + "Figure Caption", + "Table Caption", + "Abstract", + "Page Header", + "Page Footer", + "Section Header", + "Body Text", + "Figure", + "Table Note", + "Other", + "Equation label", + "Reference text", + "Table", + "Equation" + ], + "scores":[ + 4.4397335052, + -10.1999044418, + -10.8553724289, + -10.9445619583, + -11.1522703171, + -12.1556482315, + -12.263874054, + -12.4855384827, + -13.0420885086, + -13.5317106247, + -15.924665451, + -16.16979599, + -16.3548965454, + -18.4352684021 + ], + "content":"Figure 4. Maximum infection against delay in mask enforcement for Scenario 2: SEIR with full compliance and Scenario 3: SEIRS with time-limited immunity.", + "postprocess_cls":"Figure Caption", + "postprocess_score":0.9999933243, + "detect_cls":"Figure Caption", + "detect_score":4.4397335052 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":6, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_6_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 381.0, + 1651.0, + 1277.0, + 1788.0 + ], + "classes":[ + "Body Text", + "Figure", + "Figure Caption", + "Equation label", + "Page Header", + "Section Header", + "Page Footer", + "Reference text", + "Abstract", + "Other", + "Table Note", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + 0.9530130625, + -17.2154483795, + -18.4175643921, + -19.2814178467, + -20.2099666595, + -20.2442378998, + -22.9685268402, + -23.8366775513, + -24.1421489716, + -25.4540996552, + -26.7766017914, + -31.0241737366, + -32.9815940857, + -34.7086448669 + ], + "content":"Figure 4 suggests a transition from low maximum infection of about 15–16% to a high maximum infection of about 31%, with the transition occurring at between a delay of 80 to 100 days. This transition manifests itself as a point of inflection of the graphs in Figure 4, occurring at about 100 days of delay. Interestingly, this suggests that delaying public masking enforcement for greater than about 100 days results in the significant reduction in", + "postprocess_cls":"Figure Caption", + "postprocess_score":1.0, + "detect_cls":"Body Text", + "detect_score":0.9530130625 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":7, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_7_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Page Header", + "Equation label", + "Body Text", + "Page Footer", + "Figure Caption", + "Other", + "Reference text", + "Table", + "Section Header", + "Figure", + "Table Note", + "Table Caption", + "Equation", + "Abstract" + ], + "scores":[ + -1.5099077225, + -3.0049507618, + -4.360350132, + -5.7266712189, + -6.2218074799, + -6.3322916031, + -6.6689505577, + -6.7434539795, + -6.8281655312, + -7.1442403793, + -8.1997594833, + -8.2815227509, + -8.5703229904, + -9.537197113 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 7 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.9996254444, + "detect_cls":"Page Header", + "detect_score":-1.5099077225 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":7, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_7_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 224.0, + 1278.0, + 1134.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Page Footer", + "Figure Caption", + "Figure", + "Abstract", + "Table Note", + "Section Header", + "Reference text", + "Page Header", + "Other", + "Table", + "Equation", + "Table Caption" + ], + "scores":[ + -1.2279397249, + -14.3236656189, + -14.8038883209, + -17.3390235901, + -18.7345314026, + -19.0893936157, + -19.3613624573, + -19.4439258575, + -20.0368766785, + -21.6289806366, + -21.9084072113, + -28.8379039764, + -29.4303035736, + -29.6773681641 + ], + "content":"the effectiveness of public masking in controlling the maximum infection numbers. This is because after 100 days, most of the Exposed compartment has already been been infected, therefore this will no longer contribute to any further increase to the Infection compartment. Relating this to Singapore's context, compulsory mask wearing was introduced 89 days after the first case, hence this suggests that the introduction of compulsory mask wearing was timely to control the infection. Crucially, one should note that the point of inflection appears to be independent of the choice of our scenarios and in all three cases, the transition takes place at about the same 80 to 100 days of delay. The peak infection beyond 100 days of delay also yield similar results in all three cases. One would naively anticipate that the noncompliance in Scenario 2 resulting in a larger infection rate and the backflow of Recovered to Susceptible compartment after 90 days of time-limited immunity would have contributed positively to the Maximum Infected Values. While this is indeed the case for early intervention, beyond the transition point, the Infected compartment is already on track in reaching its maximum (see Figure 3d), the effectiveness of any intervention to change its trajectory and reduce the maximum is greatly reduced. This suggests the importance of early intervention by policy makers and governments, where this potential window to take action is about 3 months based on our analysis. However, we stress this does not mean that public masking is completely ineffective after the transition point, but rather that its initial effectiveness is significantly reduced beyond this point, when studying the effects of compulsory mask wearing in isolation. We further note that in Scenario 2 (see Figure 5), the results suggest that earlier enforce- ment of mask wearing leads to higher than expected Maximum Infected Values (compared to Scenario 1). This is apparent for delays in mask enforcement under approximately 50 days. It is likely that for such cases of early enforcement, the Susceptible population remains very high throughout. Consequently, when the agents begin to flout the rules after t1 = 154 days, the combination of both larger Susceptible compartment pool and higher βnc results in a greater amount of infection. In other words, the susceptible population must be sufficiently reduced before the implementation of the compulsory mask wearing for it to be effective in reducing the Maximum Infected Value. In practice, though not considered in this work, the susceptible population may be reduced or removed through other means, e.g., social distancing or lockdown.", + "postprocess_cls":"Body Text", + "postprocess_score":0.999740541, + "detect_cls":"Body Text", + "detect_score":-1.2279397249 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":7, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_7_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 396.0, + 1172.0, + 1048.0, + 1600.0 + ], + "classes":[ + "Figure", + "Equation label", + "Body Text", + "Equation", + "Section Header", + "Page Header", + "Figure Caption", + "Page Footer", + "Other", + "Table", + "Table Note", + "Abstract", + "Table Caption", + "Reference text" + ], + "scores":[ + 0.6478790641, + -8.1646146774, + -9.0933990479, + -10.5133371353, + -10.5431413651, + -10.6895513535, + -11.6505804062, + -12.4260349274, + -12.4875516891, + -13.2730197906, + -14.7135210037, + -16.0829792023, + -16.6395664215, + -16.8146400452 + ], + "content":"", + "postprocess_cls":"Figure", + "postprocess_score":0.9999837875, + "detect_cls":"Figure", + "detect_score":0.6478790641 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":7, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_7_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 381.0, + 1631.0, + 1278.0, + 1682.0 + ], + "classes":[ + "Figure Caption", + "Body Text", + "Figure", + "Page Header", + "Page Footer", + "Section Header", + "Equation label", + "Table Note", + "Table Caption", + "Equation", + "Other", + "Abstract", + "Reference text", + "Table" + ], + "scores":[ + -3.0298552513, + -7.7131061554, + -9.2794094086, + -10.4575004578, + -12.7215270996, + -13.0526819229, + -14.6363334656, + -17.4520072937, + -17.9454879761, + -18.4411945343, + -19.0718822479, + -21.2084636688, + -21.5699863434, + -22.0168647766 + ], + "content":"Figure 5. Maximum infection against delay in mask enforcement for Scenario 2: SEIR with grad- ual noncompliance.", + "postprocess_cls":"Figure Caption", + "postprocess_score":0.9999574423, + "detect_cls":"Figure Caption", + "detect_score":-3.0298552513 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":7, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_7_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 1710.0, + 1275.0, + 1790.0 + ], + "classes":[ + "Body Text", + "Figure Caption", + "Page Footer", + "Figure", + "Abstract", + "Page Header", + "Table Note", + "Other", + "Equation label", + "Section Header", + "Reference text", + "Table Caption", + "Table", + "Equation" + ], + "scores":[ + -4.3385715485, + -9.694486618, + -13.5871639252, + -14.2641153336, + -14.586853981, + -14.9624614716, + -17.6243057251, + -17.9860401154, + -19.1923599243, + -19.6803646088, + -19.8963279724, + -21.9928703308, + -22.4069385529, + -25.9891548157 + ], + "content":"At the time the initial study was conducted, we had modelled the COVID-19 situation in Singapore and its response to the initial strain of virus that was first detected at the start of 2020. However, the world is currently facing the second wave of infection. New", + "postprocess_cls":"Body Text", + "postprocess_score":0.9927651286, + "detect_cls":"Body Text", + "detect_score":-4.3385715485 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":8, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_8_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Equation label", + "Page Header", + "Body Text", + "Page Footer", + "Figure Caption", + "Section Header", + "Figure", + "Other", + "Table Note", + "Table", + "Reference text", + "Table Caption", + "Abstract", + "Equation" + ], + "scores":[ + -2.5124282837, + -2.9073629379, + -2.9385926723, + -3.376696825, + -4.5021634102, + -4.8872199059, + -5.1021184921, + -5.1072254181, + -5.364320755, + -5.3768672943, + -5.5889949799, + -6.0011315346, + -7.1411910057, + -7.5594658852 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 8 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.9993408322, + "detect_cls":"Equation label", + "detect_score":-2.5124282837 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":8, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_8_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 381.0, + 224.0, + 1278.0, + 476.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Figure Caption", + "Page Header", + "Page Footer", + "Section Header", + "Figure", + "Reference text", + "Table Note", + "Abstract", + "Other", + "Table Caption", + "Table", + "Equation" + ], + "scores":[ + 0.8267956972, + -16.0498313904, + -16.3773021698, + -17.3451595306, + -18.896944046, + -18.9894275665, + -20.2770938873, + -20.8690834045, + -21.1896896362, + -22.9311618805, + -25.2531299591, + -31.2778282166, + -31.8736000061, + -31.9162902832 + ], + "content":"strains, particularly the B117 variant, have been detected in many countries, including Sin- gapore [23]. B117 strained virus has acquired the D614G spike protein mutation, reportedly increasing its infectivity, with little difference to its lethality [24]. According to studies done in the UK, the R0 value of B117 has increased by up to 0.7 [25]. To investigate the impact of delay in public mask enforcement on controlling the Maximum Infected Numbers due to the B117 variant, we modelled a hypothetical scenario. In this scenario, the first case of COVID-19 detected in Singapore is of the B117 variant. We ran our simulation of the 3 scenarios described in the preceding sections with a new value of R0 reflecting that of B117. The resulting plots are shown in Figure 6 and 7.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9884775281, + "detect_cls":"Body Text", + "detect_score":0.8267956972 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":8, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_8_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 387.0, + 510.0, + 917.0, + 867.0 + ], + "classes":[ + "Figure", + "Body Text", + "Page Header", + "Section Header", + "Equation label", + "Equation", + "Other", + "Figure Caption", + "Table", + "Page Footer", + "Reference text", + "Table Note", + "Abstract", + "Table Caption" + ], + "scores":[ + -0.230891183, + -8.6101913452, + -9.6145172119, + -9.696855545, + -11.7993011475, + -12.3803157806, + -13.7472639084, + -15.1451997757, + -17.5577926636, + -19.1554222107, + -19.2288780212, + -20.2317199707, + -20.316783905, + -22.1437778473 + ], + "content":"", + "postprocess_cls":"Figure", + "postprocess_score":0.9999415874, + "detect_cls":"Figure", + "detect_score":-0.230891183 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":8, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_8_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 888.0, + 1275.0, + 938.0 + ], + "classes":[ + "Figure Caption", + "Page Header", + "Body Text", + "Page Footer", + "Equation label", + "Section Header", + "Other", + "Figure", + "Table Note", + "Table Caption", + "Abstract", + "Reference text", + "Table", + "Equation" + ], + "scores":[ + -1.7880330086, + -6.4670872688, + -9.6256151199, + -12.0806665421, + -12.514913559, + -13.9187374115, + -14.067481041, + -14.9008674622, + -15.2483606339, + -15.6128845215, + -16.4564361572, + -17.050868988, + -17.7882423401, + -18.8692626953 + ], + "content":"Figure 6. Maximum infection against delay in mask enforcement for Scenario 2: SEIR with full compliance and Scenario 3: SEIRS with time-limited immunity for the B117 variant case.", + "postprocess_cls":"Figure Caption", + "postprocess_score":0.999977231, + "detect_cls":"Figure Caption", + "detect_score":-1.7880330086 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":8, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_8_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 388.0, + 963.0, + 931.0, + 1320.0 + ], + "classes":[ + "Figure", + "Body Text", + "Page Header", + "Equation label", + "Equation", + "Page Footer", + "Section Header", + "Other", + "Figure Caption", + "Table", + "Table Note", + "Abstract", + "Table Caption", + "Reference text" + ], + "scores":[ + 0.5181251168, + -10.6063308716, + -10.9858551025, + -11.8891019821, + -13.6827697754, + -14.4328842163, + -14.7260141373, + -15.5658063889, + -16.0109653473, + -16.6873016357, + -19.8755321503, + -22.1069812775, + -22.613193512, + -22.6256523132 + ], + "content":"", + "postprocess_cls":"Figure", + "postprocess_score":0.9999915361, + "detect_cls":"Figure", + "detect_score":0.5181251168 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":8, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_8_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 381.0, + 1344.0, + 1275.0, + 1393.0 + ], + "classes":[ + "Figure Caption", + "Body Text", + "Section Header", + "Figure", + "Page Header", + "Table Caption", + "Abstract", + "Other", + "Page Footer", + "Equation label", + "Table Note", + "Reference text", + "Equation", + "Table" + ], + "scores":[ + -1.8838572502, + -7.2165436745, + -9.0215272903, + -13.0316390991, + -13.7898550034, + -14.0342931747, + -14.1680755615, + -14.3334932327, + -14.9199113846, + -15.0288934708, + -15.3022975922, + -18.7880439758, + -19.1882457733, + -20.1419277191 + ], + "content":"Figure 7. Maximum infection against delay in mask enforcement for Scenario 2: SEIR with gradual noncompliance for the B117 variant case.", + "postprocess_cls":"Figure Caption", + "postprocess_score":0.9999775887, + "detect_cls":"Figure Caption", + "detect_score":-1.8838572502 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":8, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_8_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 1417.0, + 563.0, + 1434.0 + ], + "classes":[ + "Equation label", + "Figure", + "Page Header", + "Section Header", + "Page Footer", + "Body Text", + "Equation", + "Other", + "Figure Caption", + "Reference text", + "Table", + "Table Note", + "Abstract", + "Table Caption" + ], + "scores":[ + -4.6576399803, + -4.7376022339, + -6.2408800125, + -7.512673378, + -8.4140415192, + -8.6492443085, + -9.2616262436, + -10.0734930038, + -11.7521343231, + -12.0373468399, + -12.5049133301, + -14.7412090302, + -15.3036937714, + -15.9025182724 + ], + "content":"6.3. Related Studies", + "postprocess_cls":"Section Header", + "postprocess_score":0.9907457829, + "detect_cls":"Equation label", + "detect_score":-4.6576399803 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":8, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_8_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 1453.0, + 1278.0, + 1791.0 + ], + "classes":[ + "Body Text", + "Abstract", + "Reference text", + "Page Header", + "Figure", + "Page Footer", + "Figure Caption", + "Equation label", + "Section Header", + "Other", + "Table Note", + "Table", + "Table Caption", + "Equation" + ], + "scores":[ + -1.564510107, + -15.4646940231, + -18.0718841553, + -19.3672237396, + -19.6613502502, + -19.7487621307, + -19.8751850128, + -20.4439563751, + -21.5015830994, + -22.3033504486, + -22.9334697723, + -28.0302295685, + -29.1530380249, + -30.0541973114 + ], + "content":"Juxtaposing our study against other similar studies that implement mathematical modelling on 'what-if' scenario based analysis, Eikenberry et al. [3] implemented a com- partmentalized models for their simulations, and concluded that if the population remains unmasked until mask enforcement after some discrete delay, and that the level of adoption is fixed, the delay initially had little impact on the hospitalized fraction or deaths, but states that a 'point of no return' can be crossed. While this study yields similar results to ours, it is contextualised in the US states of New York and Washington, whilst ours was conducted in the context of Singapore. Given the differences in epidemiological parameters, size and characteristics of these cities and Singapore, our study adds value in being a more accurate representation of smaller city states. Furthermore, this study did not take into consideration newer, more infectious strains of the virus such as the B117 variant and time-limited immunity, which we have considered in our study.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9997264743, + "detect_cls":"Body Text", + "detect_score":-1.564510107 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":9, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_9_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Page Header", + "Equation label", + "Body Text", + "Page Footer", + "Figure Caption", + "Section Header", + "Other", + "Reference text", + "Table", + "Figure", + "Table Note", + "Table Caption", + "Equation", + "Abstract" + ], + "scores":[ + -1.4972016811, + -3.5980913639, + -4.1209149361, + -5.4198904037, + -5.8428649902, + -6.1353282928, + -6.3139066696, + -6.4656472206, + -6.7573122978, + -6.9958362579, + -7.8635826111, + -7.8681206703, + -8.9311704636, + -9.2261962891 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 9 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.999494195, + "detect_cls":"Page Header", + "detect_score":-1.4972016811 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":9, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_9_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 224.0, + 1278.0, + 447.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Section Header", + "Page Footer", + "Other", + "Figure Caption", + "Figure", + "Table Note", + "Abstract", + "Reference text", + "Page Header", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + -0.033802636, + -11.9683914185, + -14.2329492569, + -14.8672418594, + -15.9906816483, + -16.032125473, + -16.0714359283, + -16.9485359192, + -16.9835414886, + -17.2661170959, + -17.9673995972, + -22.0706214905, + -25.2780094147, + -25.5011806488 + ], + "content":"Another study done by Tatapudi et al. [26] on the impact assessment of various containment measures, including public masking, contact tracing and stay-home orders revealed that masking was indeed effective in lowering the maximum infected value. The simulation was carried out using Agent-Based modelling, where individual agents were generated from the census data from Florida. This study, like many others mentioned throughout this paper, did not explicitly study the impact of the delay in enforcement of public masking. However, it adds validity to the effectiveness of face masks in controlling the spread of infection, by means of a very different mathematical model.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9984205961, + "detect_cls":"Body Text", + "detect_score":-0.033802636 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":9, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_9_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 475.0, + 1278.0, + 1307.0 + ], + "classes":[ + "Body Text", + "Page Footer", + "Equation label", + "Section Header", + "Reference text", + "Abstract", + "Figure", + "Table Note", + "Page Header", + "Figure Caption", + "Other", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + 0.1184755415, + -16.7590999603, + -17.7536563873, + -18.2873401642, + -18.5310287476, + -19.5538845062, + -19.7386474609, + -20.0910320282, + -20.1675662994, + -20.3564929962, + -20.5363483429, + -28.6993656158, + -28.8846244812, + -29.9321918488 + ], + "content":"6.4. Limitations of the Results We caution against exact quantitative predictions of the development of pandemic that are dependent on a multitude of factors other than universal mask wearing that we have considered here. What we have considered here is the what-if analysis of the effects of implementation of compulsory mask wearing on the dynamics of the pandemic. While the parameters chosen were based on estimates in Singapore's context, one should note that at the time of this writing, these estimates may change as we continue to deepen our understanding of the virus spread. Instead, this work should be interpreted as a numerical representation of the possible outcomes of delaying mask enforcement as a basis for the discussion of the general trends. We further note that, at the time of writing, the actual real-world figures for Maximum Infected Values fall below the ones discussed in this paper. This is due to the fact that we have only examined the policy of compulsory mask wearing in isolation, with minimum consideration of other factors. We expect that any countries or territories that are actively fighting the virus spread to implement an array of varying measures, all of which would collectively reduce the overall spread of the virus. While we acknowledge the limitations due to the rapidly changing nature of the ongoing pandemic and the presence of many contributing factors, some which are difficult to quantify, we cannot resort to waiting for sufficient data to present itself before drawing concrete solutions, as warned by Cheong and Jones [27], if we are to reduce its impact. Analysing the results, as we may intuitively anticipate, given the increased infectivity of the new strain, the Maximum Infected Numbers obtained were of a slightly greater mag- nitude compared to the original model. Surprisingly, we observe the same consistent trend across all the 6 scenarios, comprising a point of inflection beyond which, the effectiveness of public masking is significantly reduced. The key difference to note is that the point of inflection occurs for a smaller value of delay in enforcement, approximately 80 days as opposed to the 100 days of our initial model. Returning to Singapore's context, had the first case of COVID19 in Singapore been infected by the B117 variant, the delay of 89 days before public masking was enforced would have been costly.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9994818568, + "detect_cls":"Body Text", + "detect_score":0.1184755415 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":9, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_9_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 1335.0, + 1278.0, + 1765.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Reference text", + "Section Header", + "Page Footer", + "Figure", + "Page Header", + "Abstract", + "Figure Caption", + "Table Note", + "Other", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + -0.2975218594, + -10.6768226624, + -12.5905323029, + -13.6149492264, + -14.7963285446, + -15.056353569, + -15.9220352173, + -16.2165737152, + -16.3506851196, + -16.7049598694, + -16.7299537659, + -20.9412307739, + -21.7848720551, + -23.8551197052 + ], + "content":"7. Concluding Remarks At present, compulsory mask wearing has been widely accepted as a means of control- ling COVID-19 infection by reducing the infection rate through aerosol means. With this study, we hope to shed some light on whether the delay in enforcement of compulsory mask wearing will have detrimental effects on infection control when studied in isolation. Based on our results, it appears that a delay of 100 days and above would result in a transition where enforcement of public masking alone would result in little effect on the Maximum Infected Value. We considered 3 scenarios over 2 varied mathematical models. This result is consistent regardless of the level of compliance of the population, or the presence of time-limited immunity. Yet, if implemented early, our model shows that the Maximum Infected Values can be kept relatively low and under control, even after accounting for time-limited immunity and some level of noncompliance. We would like to point out that several studies on the effectiveness of community use of face masks. In one study carried out in the United States [28], the authors compared the percentage change in daily case rates between states enforcing public masking and", + "postprocess_cls":"Body Text", + "postprocess_score":0.9994643331, + "detect_cls":"Body Text", + "detect_score":-0.2975218594 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":10, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_10_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Equation label", + "Page Header", + "Body Text", + "Page Footer", + "Other", + "Table", + "Figure Caption", + "Section Header", + "Reference text", + "Figure", + "Table Note", + "Table Caption", + "Equation", + "Abstract" + ], + "scores":[ + -2.1286184788, + -2.5525627136, + -4.3450174332, + -5.460773468, + -6.0414304733, + -6.0501737595, + -6.8244686127, + -6.8993840218, + -6.9066138268, + -7.2508225441, + -7.6408367157, + -7.8270955086, + -8.0472068787, + -9.397228241 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 10 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.9996505976, + "detect_cls":"Equation label", + "detect_score":-2.1286184788 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":10, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_10_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 224.0, + 1278.0, + 767.0 + ], + "classes":[ + "Reference text", + "Page Footer", + "Other", + "Table Note", + "Abstract", + "Page Header", + "Body Text", + "Figure Caption", + "Section Header", + "Equation label", + "Table", + "Table Caption", + "Equation", + "Figure" + ], + "scores":[ + -4.4792351723, + -5.8750796318, + -9.2634401321, + -10.399969101, + -11.5218334198, + -11.8549585342, + -12.6806316376, + -13.4536104202, + -14.1460351944, + -14.8853416443, + -15.3292512894, + -15.9370336533, + -17.3129253387, + -17.6116294861 + ], + "content":"the states that do not. The results demonstrated that masking was indeed effective in reducing the number of infected cases daily. In their study, the states that enforced public masking did so between 8 April to 15 May 2020, approximately 78 days after the first case was detected in the US. Another study discussed the effectiveness of public masking by comparing countries that enforced public masking (Japan and Thailand) and countries that did not (Spain, Italy, UK, Germany and France) within 30 days after the first case was detected. The result of this study demonstrated that countries in the mask-wearing group had significantly better outcomes in containing the community spread of the virus [29]. These results therefore provide a basis to support our modelling and the conclusion that we have derived as a result of this study. Author Contributions: Conceptualization, D.Y.T.; methodology, D.Y.T.; investigation, B.K.T., J.WW. and C.A.R.; writing—original draft preparation, B.K.T., C.A.R. and J.W.W.; writing—review and editing, D.Y.T.; supervision, D.Y.T. All authors have read and agreed to the published version of the manuscript. Funding: This research received no external funding. Acknowledgments: The authors would like to acknowledge the support from the Singapore Univer- sity of Technology and Design's Undergraduate Research Opportunities Programme (UROP). Conflicts of Interest: The authors declare no conflict of interest.", + "postprocess_cls":"Reference text", + "postprocess_score":0.9100261927, + "detect_cls":"Reference text", + "detect_score":-4.4792351723 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":10, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_10_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 801.0, + 1278.0, + 1746.0 + ], + "classes":[ + "Reference text", + "Table", + "Figure", + "Equation", + "Page Header", + "Other", + "Abstract", + "Page Footer", + "Body Text", + "Section Header", + "Table Caption", + "Equation label", + "Figure Caption", + "Table Note" + ], + "scores":[ + -5.2637338638, + -10.4362211227, + -11.1962451935, + -15.3697137833, + -17.1162986755, + -17.5526657104, + -18.4909000397, + -19.0276966095, + -20.4897994995, + -20.7191085815, + -22.9876289368, + -23.9705295563, + -24.715429306, + -24.7433586121 + ], + "content":"References 1. Lau, J.T.; Tsui, H.; Lau, M.; Yang, X. SARS transmission, risk factors, and prevention in Hong Kong. Emerg. Infect. Dis. 2004, 10, 587. [CrossRef] [PubMed] 2. Wang, C.J.; Ng, C.Y.; Brook, R.H. Response to COVID-19 in Taiwan: Big data analytics, new technology, and proactive testing. JAMA 2020, 323, 1341–1342. [CrossRef] [PubMed] 3. Eikenberry, S.E.; Mancuso, M.; Iboi, E.; Phan, T.; Eikenberry, K.; Kuang, Y.; Kostelich, E.; Gumel, A.B. To mask or not to mask: Modeling the potential for face mask use by the general public to curtail the COVID-19 pandemic. Infect. Dis. Model. 2020, 5, 293–308. [CrossRef] [PubMed] 4. Howard, J.; Huang, A.; Li, Z.; Tufekci, Z.; Zdimal, V.; van der Westhuizen, H.M.; von Delft, A.; Price, A.; Fridman, L.; Tang, L.H.; et al. An evidence review of face masks against COVID-19. Proc. Natl. Acad. Sci. USA 2021, 118, e2014564118. [CrossRef] 5. Lai, J.W.; Cheong, K.H. Superposition of COVID-19 waves, anticipating a sustained wave, and lessons for the future. BioEssays 2020, 42, 2000178. [CrossRef] 6. Cheong, K.H.; Wen, T.; Lai, J.W. Relieving Cost of Epidemic by Parrondo's Paradox: A COVID-19 Case Study. Adv. Sci. 2020, 7, 2002324. [CrossRef] 7. Singh, R.; Adhikari, R. Age-structured impact of social distancing on the COVID-19 epidemic in India. arXiv 2020, arXiv:2003.12055. 8. Babajanyan, S.; Cheong, K.H. Age-structured SIR model and resource growth dynamics: A COVID-19 study. Nonlinear Dyn. 2021, 104, 2853–2864. [CrossRef] [PubMed] 9. Chung, N.N.; Chew, L.Y. Modelling Singapore COVID-19 pandemic with a SEIR multiplex network model. medRxiv 2020. [CrossRef] 10. Kosinski, R.J. The Influence of time-limited immunity on a COVID-19 epidemic: A simulation study. medRxiv 2020. [CrossRef] 11. Ibarrondo, F.J.; Fulcher, J.A.; Goodman-Meza, D.; Elliott, J.; Hofmann, C.; Hausner, M.A.; Ferbas, K.G.; Tobin, N.H.; Aldrovandi, G.M.; Yang, O.O. Rapid decay of anti–SARS-CoV-2 antibodies in persons with mild Covid-19. N. Engl. J. Med. 2020, 383, 1085–1087. [CrossRef] 12. Rodrigues, H.S. Application of SIR epidemiological model: New trends. arXiv 2016, arXiv:1611.02565. 13. Wang, K.; Lu, Z.; Wang, X.; Li, H.; Li, H.; Lin, D.; Cai, Y.; Feng, X.; Song, Y.; Feng, Z.; et al. Current trends and future prediction of novel coronavirus disease (COVID-19) epidemic in China: A dynamical modeling analysis. Math. Biosci. Eng. 2020, 17, 3052–3061. [CrossRef] 14. Mangoni, L.; Pistilli, M. Epidemic Analysis of Covid-19 in Italy by Dynamical Modelling. Available at SSRN 3567770 2020. Available online: https://ssrn.com/abstract=3567770 (accessed on 23 August 2021). 15. Gopal, R.; Chandrasekar, V.; Lakshmanan, M. Dynamical modelling and analysis of COVID-19 in India. arXiv 2020, arXiv:2005.08255. 16. Li, M.Y.; Muldowney, J.S. Global stability for the SEIR model in epidemiology. Math. Biosci. 1995, 125, 155–164. [CrossRef] 17. Zhang, T.; Teng, Z. On a nonautonomous SEIRS model in epidemiology. Bull. Math. Biol. 2007, 69, 2537–2559. [CrossRef] 18. Kai, D.; Goldstein, G.P.; Morgunov, A.; Nangalia, V.; Rotkirch, A. Universal masking is urgent in the covid-19 pandemic: SEIR and agent based models, empirical validation, policy recommendations. arXiv 2020, arXiv:2004.13553. 19. Mitze, T.; Kosfeld, R.; Rode, J.; Wälde, K. Face masks considerably reduce COVID-19 cases in Germany. Proc. Natl. Acad. Sci. USA 2020, 117, 32293–32301. [CrossRef]", + "postprocess_cls":"Reference text", + "postprocess_score":0.9976608753, + "detect_cls":"Reference text", + "detect_score":-5.2637338638 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Page Header", + "Equation label", + "Body Text", + "Page Footer", + "Other", + "Table", + "Figure Caption", + "Section Header", + "Reference text", + "Figure", + "Table Note", + "Table Caption", + "Equation", + "Abstract" + ], + "scores":[ + -2.2996273041, + -2.3671371937, + -4.4680614471, + -5.5041670799, + -6.2934904099, + -6.4199304581, + -6.7679276466, + -6.9881262779, + -7.0698127747, + -7.3234291077, + -7.9510364532, + -8.1306085587, + -8.3906087875, + -9.6790676117 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 11 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.9996753931, + "detect_cls":"Page Header", + "detect_score":-2.2996273041 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 130.0, + 225.0, + 1277.0, + 874.0 + ], + "classes":[ + "Body Text", + "Reference text", + "Page Footer", + "Abstract", + "Figure Caption", + "Equation label", + "Table Note", + "Other", + "Figure", + "Section Header", + "Page Header", + "Table", + "Table Caption", + "Equation" + ], + "scores":[ + -4.7601032257, + -9.4670934677, + -10.9610319138, + -11.9751634598, + -14.2404241562, + -15.3232097626, + -15.8145160675, + -16.3493461609, + -16.5256557465, + -17.0123806, + -17.5166454315, + -18.5880489349, + -20.83177948, + -21.2527580261 + ], + "content":"20. Gallaway, M.S.; Rigler, J.; Robinson, S.; Herrick, K.; Livar, E.; Komatsu, K.K.; Brady, S.; Cunico, J.; Christ, C.M. Trends in COVID-19 incidence after implementation of mitigation measures—Arizona, January 22–August 7, 2020. Morb. Mortal. Wkly. Rep. 2020, 69, 1460. [CrossRef] 21. Ong, C.W.M. Position Statement from the National Centre for Infectious Diseases and the Chapter of Infectious Disease Physicians, Academy of Medicine; Period of Infectivity to Inform Strategies for De-isolation for COVID-19 Patients: Singapore, 2020. 22. Lauer, S.A.; Grantz, K.H.; Bi, Q.; Jones, F.K.; Zheng, Q.; Meredith, H.R.; Azman, A.S.; Reich, N.G.; Lessler, J. The incubation period of coronavirus disease 2019 (COVID-19) from publicly reported confirmed cases: Estimation and application. Ann. Intern. Med. 2020, 172, 577–582. [CrossRef] 23. Chew, H.M. 25 COVID-19 Cases with B117 Variant Found in Singapore; MOH: Singapore, 2021. Available online: https://www.channelnewsasia.com/singapore/covid-19-b117-uk-variant-south-africa-singapore-25-cases-440536 (accessed on 29 January 2021). 24. Korber, B.; Fischer, W.M.; Gnanakaran, S.; Yoon, H.; Theiler, J.; Abfalterer, W.; Hengartner, N.; Giorgi, E.E.; Bhattacharya, T.; Foley, B.; et al. Tracking changes in SARS-CoV-2 Spike: Evidence that D614G increases infectivity of the COVID-19 virus. Cell 2020, 182, 812–827. [CrossRef] 25. Volz, E.; Mishra, S.; Chand, M.; Barrett, J.C.; Johnson, R.; Geidelberg, L.; Hinsley, W.R.; Laydon, D.J.; Dabrera, G.; O'Toole, Á.; et al. Assessing transmissibility of SARS-CoV-2 lineage B. 1.1. 7 in England. Nature 2021, 593, 266–269. [CrossRef] 26. Tatapudi, H.; Das, R.; Das, T.K. Impact assessment of full and partial stay-at-home orders, face mask usage, and contact tracing: An agent-based simulation study of COVID-19 for an urban region. Glob. Epidemiol. 2020, 2, 100036. [CrossRef] 27. Cheong, K.H.; Jones, M.C. Introducing the 21st century's new four horsemen of the coronapocalypse. BioEssays 2020, 42, 2000063. [CrossRef] 28. Lyu, W.; Wehby, G.L. Community Use Of Face Masks And COVID-19: Evidence From A Natural Experiment Of State Mandates In The US: Study examines impact on COVID-19 growth rates associated with state government mandates requiring face mask use in public. Health Aff. 2020, 39, 1419–1425. [CrossRef] 29. Li, T.; Liu, Y.; Li, M.; Qian, X.; Dai, S.Y. Mask or no mask for COVID-19: A public health and market study. PLoS ONE 2020, 15, e0237691. [CrossRef]", + "postprocess_cls":"Body Text", + "postprocess_score":0.9981245399, + "detect_cls":"Body Text", + "detect_score":-4.7601032257 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 226.0, + 106.0, + 241.0 + ], + "classes":[ + "Page Footer", + "Section Header", + "Body Text", + "Table Note", + "Table", + "Reference text", + "Other", + "Table Caption", + "Figure Caption", + "Figure", + "Abstract", + "Equation", + "Equation label", + "Page Header" + ], + "scores":[ + -1.851089716, + -10.8925466537, + -11.7394094467, + -11.7497529984, + -12.2353801727, + -12.6273412704, + -12.7355203629, + -13.1808538437, + -15.4802007675, + -16.7650165558, + -17.4654884338, + -18.0173988342, + -18.0899581909, + -18.6022014618 + ], + "content":"20. Gallaway, M.S.; Rigler, J.; Robinson, S.; Herrick, K.; Livar, E.; Komatsu, K.K.; Brady, S.; Cunico, J.; Christ, C.M. Trends in", + "postprocess_cls":"Page Header", + "postprocess_score":0.9084485769, + "detect_cls":"Page Footer", + "detect_score":-1.851089716 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 305.0, + 106.0, + 319.0 + ], + "classes":[ + "Section Header", + "Page Footer", + "Table", + "Table Caption", + "Figure Caption", + "Reference text", + "Figure", + "Body Text", + "Equation label", + "Table Note", + "Page Header", + "Other", + "Abstract", + "Equation" + ], + "scores":[ + -5.4302558899, + -5.7566809654, + -6.1677641869, + -6.598048687, + -6.9456167221, + -7.3625130653, + -7.5950479507, + -7.6754937172, + -7.7477765083, + -8.2904005051, + -9.1980991364, + -9.3429536819, + -10.2163305283, + -10.8249101639 + ], + "content":"21. Ong, C.W.M. Position Statement from the National Centre for Infectious Diseases and the Chapter of Infectious Disease Physicians, Academy", + "postprocess_cls":"Section Header", + "postprocess_score":0.5326701403, + "detect_cls":"Section Header", + "detect_score":-5.4302558899 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 357.0, + 106.0, + 371.0 + ], + "classes":[ + "Page Footer", + "Body Text", + "Section Header", + "Reference text", + "Equation label", + "Figure Caption", + "Table", + "Page Header", + "Figure", + "Other", + "Table Note", + "Table Caption", + "Abstract", + "Equation" + ], + "scores":[ + -6.4768805504, + -6.7679481506, + -7.2823166847, + -8.2708215714, + -8.9002933502, + -9.1431245804, + -9.6290407181, + -10.2670984268, + -10.5139226913, + -11.409579277, + -12.2689943314, + -12.5410804749, + -12.988152504, + -14.3310165405 + ], + "content":"22. Lauer, S.A.; Grantz, K.H.; Bi, Q.; Jones, F.K.; Zheng, Q.; Meredith, H.R.; Azman, A.S.; Reich, N.G.; Lessler, J. The incubation", + "postprocess_cls":"Section Header", + "postprocess_score":0.9309452772, + "detect_cls":"Page Footer", + "detect_score":-6.4768805504 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 436.0, + 106.0, + 450.0 + ], + "classes":[ + "Page Footer", + "Section Header", + "Table", + "Table Caption", + "Reference text", + "Body Text", + "Table Note", + "Figure Caption", + "Other", + "Figure", + "Page Header", + "Equation", + "Abstract", + "Equation label" + ], + "scores":[ + -3.496566534, + -9.5050992966, + -9.7342357635, + -10.2700252533, + -11.2513341904, + -11.5373458862, + -12.158996582, + -12.8558330536, + -14.528758049, + -15.6536645889, + -15.9913797379, + -16.1821022034, + -16.3788452148, + -16.4374637604 + ], + "content":"23. Chew, H.M.", + "postprocess_cls":"Section Header", + "postprocess_score":0.7352595925, + "detect_cls":"Page Footer", + "detect_score":-3.496566534 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 515.0, + 106.0, + 529.0 + ], + "classes":[ + "Page Footer", + "Section Header", + "Table", + "Table Caption", + "Reference text", + "Body Text", + "Table Note", + "Figure Caption", + "Other", + "Figure", + "Page Header", + "Equation", + "Equation label", + "Abstract" + ], + "scores":[ + -2.9842100143, + -8.1079778671, + -10.445807457, + -10.6652832031, + -10.9143419266, + -11.022693634, + -12.1219301224, + -12.1974458694, + -14.2189302444, + -14.3394756317, + -15.2413625717, + -15.5436220169, + -15.5829076767, + -16.182598114 + ], + "content":"24. Korber, B.; Fischer, W.M.; Gnanakaran, S.; Yoon, H.; Theiler, J.; Abfalterer, W.; Hengartner, N.; Giorgi, E.E.; Bhattacharya, T.; Foley,", + "postprocess_cls":"Section Header", + "postprocess_score":0.8648951054, + "detect_cls":"Page Footer", + "detect_score":-2.9842100143 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 593.0, + 106.0, + 608.0 + ], + "classes":[ + "Reference text", + "Page Footer", + "Equation label", + "Page Header", + "Table", + "Figure", + "Section Header", + "Body Text", + "Figure Caption", + "Equation", + "Other", + "Abstract", + "Table Caption", + "Table Note" + ], + "scores":[ + -3.2157504559, + -5.9369740486, + -7.2776136398, + -8.3296689987, + -8.4969367981, + -9.8472499847, + -9.9758882523, + -10.5557136536, + -10.9103212357, + -11.1909446716, + -12.7159738541, + -13.0712471008, + -13.1726398468, + -14.0420751572 + ], + "content":"25. Volz, E.; Mishra, S.; Chand, M.; Barrett, J.C.; Johnson, R.; Geidelberg, L.; Hinsley, W.R.; Laydon, D.J.; Dabrera, G.; O'Toole, Á.; et al.", + "postprocess_cls":"Section Header", + "postprocess_score":0.7926460505, + "detect_cls":"Reference text", + "detect_score":-3.2157504559 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 646.0, + 106.0, + 660.0 + ], + "classes":[ + "Reference text", + "Table", + "Page Footer", + "Figure", + "Equation label", + "Section Header", + "Body Text", + "Page Header", + "Table Caption", + "Figure Caption", + "Table Note", + "Other", + "Equation", + "Abstract" + ], + "scores":[ + -5.1539878845, + -5.3020939827, + -6.9158682823, + -7.072804451, + -7.7035703659, + -7.8148822784, + -8.001584053, + -9.2741355896, + -9.3537960052, + -10.146490097, + -10.2882575989, + -10.3166122437, + -10.6294994354, + -11.5169849396 + ], + "content":"26. Tatapudi, H.; Das, R.; Das, T.K. Impact assessment of full and partial stay-at-home orders, face mask usage, and contact tracing:", + "postprocess_cls":"Page Footer", + "postprocess_score":0.4009010494, + "detect_cls":"Reference text", + "detect_score":-5.1539878845 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 698.0, + 106.0, + 713.0 + ], + "classes":[ + "Reference text", + "Page Footer", + "Table", + "Equation label", + "Figure", + "Section Header", + "Other", + "Equation", + "Body Text", + "Abstract", + "Page Header", + "Table Note", + "Table Caption", + "Figure Caption" + ], + "scores":[ + -3.8052105904, + -5.8814787865, + -6.645819664, + -7.7170886993, + -7.9209699631, + -8.677359581, + -9.5824327469, + -9.9282016754, + -10.7273035049, + -11.025844574, + -11.6131811142, + -11.6515989304, + -11.6976509094, + -12.218706131 + ], + "content":"27. Cheong, K.H.; Jones, M.C. Introducing the 21st century's new four horsemen of the coronapocalypse. BioEssays 2020, 42, 2000063.", + "postprocess_cls":"Section Header", + "postprocess_score":0.4258098304, + "detect_cls":"Reference text", + "detect_score":-3.8052105904 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 751.0, + 106.0, + 765.0 + ], + "classes":[ + "Table", + "Page Footer", + "Reference text", + "Figure", + "Equation label", + "Other", + "Body Text", + "Section Header", + "Table Caption", + "Table Note", + "Equation", + "Abstract", + "Page Header", + "Figure Caption" + ], + "scores":[ + -5.3406186104, + -5.631975174, + -5.8069086075, + -8.7242069244, + -9.6082000732, + -10.5158557892, + -11.0335350037, + -11.4187889099, + -11.4762125015, + -11.7414340973, + -12.0791625977, + -12.2578773499, + -13.2365760803, + -13.7983856201 + ], + "content":"28. Lyu, W.; Wehby, G.L. Community Use Of Face Masks And COVID-19: Evidence From A Natural Experiment Of State Mandates", + "postprocess_cls":"Section Header", + "postprocess_score":0.7025460005, + "detect_cls":"Table", + "detect_score":-5.3406186104 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 829.0, + 106.0, + 844.0 + ], + "classes":[ + "Page Footer", + "Section Header", + "Body Text", + "Reference text", + "Table", + "Table Caption", + "Table Note", + "Figure Caption", + "Other", + "Figure", + "Equation label", + "Equation", + "Page Header", + "Abstract" + ], + "scores":[ + -3.1696989536, + -8.4708032608, + -11.0811958313, + -11.2829618454, + -11.8613004684, + -12.4573526382, + -12.8267974854, + -14.4768972397, + -14.9625282288, + -15.8552246094, + -16.0115203857, + -16.6108016968, + -16.9140644073, + -17.5206813812 + ], + "content":"29. Li, T.; Liu, Y.; Li, M.; Qian, X.; Dai, S.Y. Mask or no mask for COVID-19: A public health and market study. PLoS ONE 2020,", + "postprocess_cls":"Section Header", + "postprocess_score":0.7363973856, + "detect_cls":"Page Footer", + "detect_score":-3.1696989536 + } +] \ No newline at end of file diff --git a/tests/resources/basic_profile_model/amr.json b/tests/resources/basic_profile_model/amr.json new file mode 100644 index 0000000..b4b0079 --- /dev/null +++ b/tests/resources/basic_profile_model/amr.json @@ -0,0 +1,254 @@ +{ + "name": "LaTex Model", + "schema": "https://github.com/DARPA-ASKEM/Model-Representations/blob/main/petrinet/petrinet_schema.json", + "schema_name": "PetriNet", + "description": "Example LaTeX model", + "model_version": "0.1", + "model": { + "states": [ + { + "id": "D", + "name": "D" + }, + { + "id": "E", + "name": "E" + }, + { + "id": "H", + "name": "H" + }, + { + "id": "I", + "name": "I" + }, + { + "id": "R", + "name": "R" + }, + { + "id": "S", + "name": "S" + } + ], + "transitions": [ + { + "id": "t0", + "input": [ + "S", + "I" + ], + "output": [ + "E", + "I" + ], + "grounding": null + }, + { + "id": "t1", + "input": [ + "E" + ], + "output": [ + "I" + ], + "grounding": null + }, + { + "id": "t2", + "input": [ + "I" + ], + "output": [ + "H" + ], + "grounding": null + }, + { + "id": "t3", + "input": [ + "I" + ], + "output": [ + "R" + ], + "grounding": null + }, + { + "id": "t4", + "input": [ + "H" + ], + "output": [ + "R" + ], + "grounding": null + }, + { + "id": "t5", + "input": [ + "H" + ], + "output": [ + "D" + ], + "grounding": null + } + ] + }, + "semantics": { + "ode": { + "rates": [ + { + "target": "t0", + "expression": "β*N*S*I", + "expression_mathml": "SβIN" + }, + { + "target": "t1", + "expression": "r_{EI}*E*", + "expression_mathml": "r_{EI}E" + }, + { + "target": "t2", + "expression": "r_{IH}*p_{IH}*I*", + "expression_mathml": "Ir_{IH}p_{IH}" + }, + { + "target": "t3", + "expression": "r_{IR}*p_{IR}*I*", + "expression_mathml": "Ir_{IR}p_{IR}" + }, + { + "target": "t4", + "expression": "r_{HR}*p_{HR}*H*", + "expression_mathml": "Hr_{HR}p_{HR}" + }, + { + "target": "t5", + "expression": "r_{HD}*p_{HD}*H*", + "expression_mathml": "Hr_{HD}p_{HD}" + } + ], + "initials": [ + { + "target": "S", + "expression": "S0", + "expression_mathml": "" + }, + { + "target": "E", + "expression": "E0", + "expression_mathml": "" + }, + { + "target": "I", + "expression": "I0", + "expression_mathml": "" + }, + { + "target": "H", + "expression": "H0", + "expression_mathml": "" + }, + { + "target": "R", + "expression": "R0", + "expression_mathml": "" + }, + { + "target": "D", + "expression": "D0", + "expression_mathml": "" + } + ], + "parameters": [ + { + "id": "D0", + "name": "D0", + "description": "The total D population at timestep 0" + }, + { + "id": "E0", + "name": "E0", + "description": "The total E population at timestep 0" + }, + { + "id": "H0", + "name": "H0", + "description": "The total H population at timestep 0" + }, + { + "id": "I0", + "name": "I0", + "description": "The total I population at timestep 0" + }, + { + "id": "N", + "name": "N", + "description": "N rate" + }, + { + "id": "R0", + "name": "R0", + "description": "The total R population at timestep 0" + }, + { + "id": "S0", + "name": "S0", + "description": "The total S population at timestep 0" + }, + { + "id": "p_{HD}", + "name": "p_{HD}", + "description": "p_{HD} rate" + }, + { + "id": "p_{HR}", + "name": "p_{HR}", + "description": "p_{HR} rate" + }, + { + "id": "p_{IH}", + "name": "p_{IH}", + "description": "p_{IH} rate" + }, + { + "id": "p_{IR}", + "name": "p_{IR}", + "description": "p_{IR} rate" + }, + { + "id": "r_{EI}", + "name": "r_{EI}", + "description": "r_{EI} rate" + }, + { + "id": "r_{HD}", + "name": "r_{HD}", + "description": "r_{HD} rate" + }, + { + "id": "r_{HR}", + "name": "r_{HR}", + "description": "r_{HR} rate" + }, + { + "id": "r_{IH}", + "name": "r_{IH}", + "description": "r_{IH} rate" + }, + { + "id": "r_{IR}", + "name": "r_{IR}", + "description": "r_{IR} rate" + }, + { + "id": "β", + "name": "β", + "description": "β rate" + } + ] + } + } + } \ No newline at end of file diff --git a/tests/resources/basic_profile_model/code.py b/tests/resources/basic_profile_model/code.py new file mode 100644 index 0000000..521b729 --- /dev/null +++ b/tests/resources/basic_profile_model/code.py @@ -0,0 +1,9 @@ +def sir( + s: float, i: float, r: float, beta: float, gamma: float, n: float +) -> Tuple[float, float, float]: + """The SIR model, one time step.""" + s_n = (-beta * s * i) + s + i_n = (beta * s * i - gamma * i) + i + r_n = gamma * i + r + scale = n / (s_n + i_n + r_n) + return s_n * scale, i_n * scale, r_n * scale diff --git a/tests/test_profile_model/model_card.json b/tests/resources/basic_profile_model/model_card.json similarity index 100% rename from tests/test_profile_model/model_card.json rename to tests/resources/basic_profile_model/model_card.json diff --git a/tests/resources/basic_profile_model/text.json b/tests/resources/basic_profile_model/text.json new file mode 100644 index 0000000..5eaa7d7 --- /dev/null +++ b/tests/resources/basic_profile_model/text.json @@ -0,0 +1,5172 @@ +[ + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 107.0, + 1275.0, + 195.0 + ], + "classes":[ + "Equation label", + "Section Header", + "Page Header", + "Body Text", + "Figure", + "Other", + "Equation", + "Reference text", + "Figure Caption", + "Table", + "Page Footer", + "Table Note", + "Table Caption", + "Abstract" + ], + "scores":[ + -5.158577919, + -8.3714532852, + -10.0183992386, + -10.2071590424, + -11.1120090485, + -11.1143541336, + -11.2161874771, + -13.0983781815, + -15.0558624268, + -15.1471719742, + -15.9366912842, + -18.405462265, + -18.7139511108, + -18.9916629791 + ], + "content":"", + "postprocess_cls":"Page Header", + "postprocess_score":0.9985458851, + "detect_cls":"Equation label", + "detect_score":-5.158577919 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 80.0, + 234.0, + 1197.0, + 305.0 + ], + "classes":[ + "Body Text", + "Other", + "Equation label", + "Section Header", + "Reference text", + "Table Note", + "Page Footer", + "Figure", + "Abstract", + "Equation", + "Page Header", + "Table", + "Figure Caption", + "Table Caption" + ], + "scores":[ + -1.9848747253, + -7.259475708, + -11.0177192688, + -12.7866334915, + -13.10891819, + -14.0849218369, + -14.3103981018, + -14.6399879456, + -14.7027568817, + -15.8481864929, + -16.2041015625, + -17.3444747925, + -17.9344902039, + -20.9808273315 + ], + "content":"Article Dynamical Analysis of Universal Masking on the Pandemic", + "postprocess_cls":"Body Text", + "postprocess_score":0.9914546013, + "detect_cls":"Body Text", + "detect_score":-1.9848747253 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 83.0, + 343.0, + 1044.0, + 370.0 + ], + "classes":[ + "Section Header", + "Other", + "Equation label", + "Equation", + "Body Text", + "Page Footer", + "Figure", + "Reference text", + "Abstract", + "Table Note", + "Table Caption", + "Table", + "Figure Caption", + "Page Header" + ], + "scores":[ + -2.0326740742, + -2.7304286957, + -4.5183801651, + -5.2259273529, + -6.2282066345, + -6.3734707832, + -6.7899360657, + -7.0165834427, + -7.4191837311, + -7.4662895203, + -7.9870581627, + -8.0286159515, + -8.2380943298, + -8.6224336624 + ], + "content":"Brandon Kaiheng Tay † , Carvalho Andrea Roby †, Jodi Wenjiang Wu † and Da Yang Tan *", + "postprocess_cls":"Section Header", + "postprocess_score":0.9072340131, + "detect_cls":"Section Header", + "detect_score":-2.0326740742 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 418.0, + 1226.0, + 535.0 + ], + "classes":[ + "Page Footer", + "Other", + "Table Note", + "Table", + "Page Header", + "Figure", + "Body Text", + "Table Caption", + "Figure Caption", + "Reference text", + "Abstract", + "Section Header", + "Equation label", + "Equation" + ], + "scores":[ + -2.5388700962, + -3.7671117783, + -5.0030655861, + -5.7867355347, + -6.5778765678, + -6.8421964645, + -6.8604774475, + -7.6586065292, + -7.836004734, + -7.9547429085, + -8.0516815186, + -9.3464565277, + -9.8778991699, + -10.1746559143 + ], + "content":"Science, Mathematics and Technology, Singapore University of Technology and Design, 8 Somapah Road, Singapore 487372, Singapore; brandontay6@gmail.com (B.K.T.); andwea3@gmail.com (C.A.R.); jodiwwj@gmail.com (J.W.W.) * Correspondence: dayang_tan@sutd.edu.sg † These authors contributed equally to this work.", + "postprocess_cls":"Other", + "postprocess_score":0.6949161887, + "detect_cls":"Page Footer", + "detect_score":-2.5388700962 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 381.0, + 573.0, + 1278.0, + 890.0 + ], + "classes":[ + "Abstract", + "Other", + "Section Header", + "Body Text", + "Equation label", + "Reference text", + "Table Note", + "Table", + "Figure Caption", + "Figure", + "Page Footer", + "Table Caption", + "Page Header", + "Equation" + ], + "scores":[ + -6.553381443, + -7.0592031479, + -7.5321784019, + -8.1746530533, + -9.3305721283, + -9.5875043869, + -10.8356370926, + -10.9991464615, + -11.3415498734, + -11.5023822784, + -11.6590452194, + -11.7893009186, + -12.5354270935, + -14.5688781738 + ], + "content":"Abstract: We investigate the impact of the delay in compulsory mask wearing on the spread of COVID-19 in the community, set in the Singapore context. By using modified SEIR-based compart- mental models, we focus on macroscopic population-level analysis of the relationships between the delay in compulsory mask wearing and the maximum infection, through a series of scenario-based analysis. Our analysis suggests that collective masking can meaningfully reduce the transmission of COVID-19 in the community, but only if implemented within a critical time window of approximately before 80–100 days delay after the first infection is detected, coupled with strict enforcement to ensure compliance throughout the duration. We also identify a delay threshold of about 100 days that results in masking enforcement having little significant impact on the Maximum Infected Values. The results therefore highlight the necessity for rapid implementation of compulsory mask wearing to curb the spread of the pandemic.", + "postprocess_cls":"Abstract", + "postprocess_score":0.9484135509, + "detect_cls":"Abstract", + "detect_score":-6.553381443 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 926.0, + 1275.0, + 984.0 + ], + "classes":[ + "Body Text", + "Page Header", + "Other", + "Equation label", + "Figure", + "Section Header", + "Equation", + "Table", + "Figure Caption", + "Page Footer", + "Reference text", + "Abstract", + "Table Caption", + "Table Note" + ], + "scores":[ + -5.5984277725, + -6.6887278557, + -7.2796764374, + -7.5727577209, + -8.1192560196, + -8.3920602798, + -9.5373849869, + -9.6610832214, + -10.6693582535, + -11.2980852127, + -12.0429611206, + -12.0956077576, + -12.9813222885, + -13.2261285782 + ], + "content":"Keywords: SEIR model; SEIS model; mask wearing; compartmental model; epidemic modelling", + "postprocess_cls":"Body Text", + "postprocess_score":0.7085515261, + "detect_cls":"Body Text", + "detect_score":-5.5984277725 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 81.0, + 1002.0, + 345.0, + 1154.0 + ], + "classes":[ + "Body Text", + "Section Header", + "Figure", + "Other", + "Page Header", + "Figure Caption", + "Reference text", + "Equation label", + "Abstract", + "Table Note", + "Page Footer", + "Table", + "Table Caption", + "Equation" + ], + "scores":[ + -0.4976767898, + -7.6454410553, + -9.3069028854, + -9.428153038, + -9.6553201675, + -10.0410013199, + -10.3448381424, + -10.689655304, + -11.2578315735, + -11.2712049484, + -11.7054204941, + -15.0347061157, + -15.1838083267, + -15.3739404678 + ], + "content":"Citation: Tay, B.K.; Roby, C.A.; Wu, J.W.; Tan, D.Y. Dynamical Analysis of Universal Masking on the Pandemic. Int. J. Environ. Res. Public Health 2021, 18, 9027. https:// doi.org/10.3390/ijerph18179027", + "postprocess_cls":"Body Text", + "postprocess_score":0.8970527649, + "detect_cls":"Body Text", + "detect_score":-0.4976767898 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 1038.0, + 536.0, + 1055.0 + ], + "classes":[ + "Body Text", + "Section Header", + "Page Header", + "Figure", + "Reference text", + "Other", + "Page Footer", + "Equation label", + "Figure Caption", + "Equation", + "Table Note", + "Abstract", + "Table", + "Table Caption" + ], + "scores":[ + -1.8938975334, + -4.3468050957, + -5.930565834, + -7.1995210648, + -7.2024521828, + -7.6047611237, + -8.6509456635, + -9.3752946854, + -9.4793462753, + -11.2701282501, + -11.3327894211, + -11.9113807678, + -12.3241205215, + -13.5627841949 + ], + "content":"1. Introduction", + "postprocess_cls":"Section Header", + "postprocess_score":0.9995450377, + "detect_cls":"Body Text", + "detect_score":-1.8938975334 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 1074.0, + 1278.0, + 1755.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Section Header", + "Reference text", + "Page Footer", + "Abstract", + "Table Note", + "Figure Caption", + "Figure", + "Page Header", + "Other", + "Table", + "Table Caption", + "Equation" + ], + "scores":[ + 0.7251604199, + -15.622086525, + -15.7503271103, + -15.8251218796, + -16.0309772491, + -16.1873703003, + -16.934419632, + -17.0300006866, + -17.3174877167, + -19.9234809875, + -20.3943519592, + -24.590473175, + -24.6434822083, + -27.056306839 + ], + "content":"In the light of the COVID-19 pandemic, the Singapore government declared with effect as of 14 April 2020, an enforcement of compulsory mask wearing in public spaces, 89 days after the first case of COVID-19 was detected in Singapore. The usage of masks is known to effectively decrease the infection rate. It has shown success in limiting community spread of SARS 2003 [1], and more recently, in Taiwan's management of COVID-19 [2]. Recent hypothetical studies on masking by the states of New York and Washington suggests a potential prevention of up to 45% of their projected death rates [3]. In this study of potential face-mask usage for the general public, the authors investigated how public masking can control the infection, in the context of the USA. However, not much was mentioned about how the delayed enforcement of such a policy would affect the infection numbers. In another study on public masking [4], the authors studied how factors such as the filtering capability of different mask materials, as well as sociological behaviour patterns on masking, would affect the efficacy of this policy. A comprehensive data-driven study on COVID-19 waves worldwide and strategies to mitigate them conducted by Lai and Cheong [5] also did not provide detailed analysis of mask wearing policies and its effectiveness. Concluding this literature review, it is apparent that in-depth studies on the impact of delayed mask enforcement on the spread of COVID-19 in the community is limited. This paper thus seeks to investigate the relationship between delay in compulsory mask wearing and the Maximum Infected Values, through a series of scenario-based what- if analysis. We would be considering 3 scenarios using 2 compartmental models—the SEIR and the SEIRS model. The use of compartmental models for modelling the spread of COVID-19 has been explored recently, such as to study the lockdown measures [6,7], or with variant to include the effects of age-structure within the population [8] and different", + "postprocess_cls":"Body Text", + "postprocess_score":0.9998295307, + "detect_cls":"Body Text", + "detect_score":0.7251604199 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 81.0, + 1192.0, + 310.0, + 1208.0 + ], + "classes":[ + "Other", + "Page Footer", + "Section Header", + "Body Text", + "Equation label", + "Table Note", + "Reference text", + "Figure", + "Abstract", + "Page Header", + "Table", + "Table Caption", + "Equation", + "Figure Caption" + ], + "scores":[ + -2.9890294075, + -3.3959157467, + -4.593378067, + -6.244890213, + -6.5497121811, + -7.2422127724, + -7.3849005699, + -7.4488811493, + -7.4600481987, + -7.6431908607, + -7.7195529938, + -7.9713959694, + -7.9969091415, + -8.4315900803 + ], + "content":"Academic Editor: Jimmy T. Efird", + "postprocess_cls":"Section Header", + "postprocess_score":0.9993419051, + "detect_cls":"Other", + "detect_score":-2.9890294075 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 81.0, + 1247.0, + 268.0, + 1318.0 + ], + "classes":[ + "Other", + "Body Text", + "Section Header", + "Equation label", + "Reference text", + "Figure", + "Page Footer", + "Equation", + "Table Note", + "Table", + "Abstract", + "Page Header", + "Table Caption", + "Figure Caption" + ], + "scores":[ + -4.1823372841, + -5.1112661362, + -6.9629349709, + -7.0838446617, + -7.7467865944, + -7.8375759125, + -8.8564739227, + -8.9725866318, + -9.1548099518, + -9.5617437363, + -9.6012058258, + -11.4223642349, + -12.3504314423, + -12.5159215927 + ], + "content":"Received: 20 June 2021 Accepted: 24 August 2021 Published: 27 August 2021", + "postprocess_cls":"Body Text", + "postprocess_score":0.6687924266, + "detect_cls":"Other", + "detect_score":-4.1823372841 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 81.0, + 1359.0, + 351.0, + 1453.0 + ], + "classes":[ + "Section Header", + "Page Footer", + "Reference text", + "Body Text", + "Other", + "Table Note", + "Figure", + "Equation", + "Abstract", + "Figure Caption", + "Table Caption", + "Equation label", + "Table", + "Page Header" + ], + "scores":[ + -5.8428478241, + -6.3360619545, + -7.2266125679, + -7.5321187973, + -8.2308416367, + -9.9798364639, + -10.8188667297, + -11.5504598618, + -11.6129703522, + -11.9741849899, + -12.2181940079, + -12.3263959885, + -12.5641174316, + -13.806722641 + ], + "content":"Publisher's Note: MDPI stays neutral with regard to jurisdictional claims in published maps and institutional affil- iations.", + "postprocess_cls":"Body Text", + "postprocess_score":0.7294377089, + "detect_cls":"Section Header", + "detect_score":-5.8428478241 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 81.0, + 1500.0, + 350.0, + 1767.0 + ], + "classes":[ + "Section Header", + "Page Footer", + "Figure Caption", + "Other", + "Figure", + "Body Text", + "Abstract", + "Reference text", + "Table Note", + "Equation", + "Table Caption", + "Table", + "Equation label", + "Page Header" + ], + "scores":[ + -6.5802001953, + -7.0285143852, + -8.0855836868, + -8.2666950226, + -8.3461647034, + -8.6726207733, + -9.8244400024, + -10.4466161728, + -11.00852108, + -11.2992296219, + -11.4344749451, + -12.3009567261, + -12.8775424957, + -14.8131856918 + ], + "content":"Copyright: © 2021 by the authors. Licensee MDPI, Basel, Switzerland. This article is an open access article distributed under the terms and conditions of the Creative Commons Attribution (CC BY) license (https:// creativecommons.org/licenses/by/ 4.0/).", + "postprocess_cls":"Body Text", + "postprocess_score":0.4166562259, + "detect_cls":"Section Header", + "detect_score":-6.5802001953 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":1, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_1_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 1843.0, + 1275.0, + 1876.0 + ], + "classes":[ + "Page Footer", + "Page Header", + "Reference text", + "Equation label", + "Table", + "Other", + "Body Text", + "Table Note", + "Equation", + "Figure", + "Table Caption", + "Abstract", + "Figure Caption", + "Section Header" + ], + "scores":[ + -0.5714578032, + -4.4968333244, + -4.5759072304, + -4.8665537834, + -5.7643418312, + -5.7929019928, + -5.9571275711, + -6.7715325356, + -7.1043848991, + -7.6470108032, + -8.7554969788, + -9.1320457458, + -9.1481485367, + -9.5743207932 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027. https://doi.org/10.3390/ijerph18179027 https://www.mdpi.com/journal/ijerph", + "postprocess_cls":"Page Footer", + "postprocess_score":0.9999275208, + "detect_cls":"Page Footer", + "detect_score":-0.5714578032 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":2, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_2_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Page Header", + "Equation label", + "Body Text", + "Page Footer", + "Figure Caption", + "Section Header", + "Other", + "Reference text", + "Table", + "Figure", + "Table Note", + "Table Caption", + "Equation", + "Abstract" + ], + "scores":[ + -1.69619596, + -3.2141313553, + -3.9378855228, + -4.8566551208, + -5.4208545685, + -5.9383769035, + -6.2361469269, + -6.353307724, + -6.3739156723, + -6.5636873245, + -7.3287501335, + -7.3517103195, + -8.558930397, + -8.8238668442 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 2 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.9995732903, + "detect_cls":"Page Header", + "detect_score":-1.69619596 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":2, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_2_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 219.0, + 1276.0, + 529.0 + ], + "classes":[ + "Body Text", + "Figure Caption", + "Figure", + "Equation label", + "Page Footer", + "Section Header", + "Abstract", + "Table Note", + "Reference text", + "Page Header", + "Other", + "Table Caption", + "Equation", + "Table" + ], + "scores":[ + -0.5451325774, + -10.4853096008, + -12.1630077362, + -13.2492980957, + -13.500875473, + -13.7242078781, + -14.071103096, + -14.4545812607, + -14.7841234207, + -15.7971820831, + -18.4810504913, + -20.4726238251, + -22.414308548, + -22.4882659912 + ], + "content":"social settings [9]. For the SEIR model, we consider a complete compliance, and gradual noncompliance over time. Using an SEIRS model, we consider a third scenario taking into account time-limited immunity. Results from simulating these 3 scenarios would hopefully shed light on the effects of delaying the usage of masks and how the containment of epidemic could have been more effective in Singapore. To model the pandemic from a macroscopic view point, we use modified versions of the model, which consists of a number of compartments described by a system of differential equations in Sections 2 and 3. To solve these equations, we implemented the model in Python using the Odeint package. We then modify the Delay of Mask Enforcement by plotting several data sets and recording the resulting Maximum Infection Value predicted by our model. This was performed over 3 different scenarios:", + "postprocess_cls":"Body Text", + "postprocess_score":0.9443999529, + "detect_cls":"Body Text", + "detect_score":-0.5451325774 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":2, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_2_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 430.0, + 546.0, + 1278.0, + 1078.0 + ], + "classes":[ + "Body Text", + "Page Footer", + "Figure Caption", + "Equation label", + "Abstract", + "Reference text", + "Figure", + "Table Note", + "Page Header", + "Section Header", + "Other", + "Table", + "Table Caption", + "Equation" + ], + "scores":[ + -1.7037055492, + -12.2971372604, + -12.7130117416, + -14.0141639709, + -14.4679946899, + -14.7939186096, + -15.6933107376, + -16.0003376007, + -16.9068927765, + -19.4729213715, + -19.6528110504, + -23.4287376404, + -23.999332428, + -24.6993846893 + ], + "content":"Scenario 1: The first scenario considers the most basic case of complete compliance of the masking enforcement, from the day it was enforced throughout its duration. It also does not account for time-limited immunity [10], where infected individuals become susceptible again after a period of time. Scenario 2: The second scenario closely resembles the first, but with the addition of gradual noncompliance of the masking enforcement. The root of noncompliance stems from either lack of medical knowledge, wishful thinking that the pandemic will magically disappear, selfish behaviour of individuals, pandemic fatigue etc. Here, we assume that onset of the noncompliance is triggered by an event, for instance, changes in government policies. As an illustration, the Singapore government announced the Phase 2 of its gradual reopening plan on 18 June 2020 (154 days after the first case in Singapore) where members of the public were allowed to visit shopping malls and dine-in at food establishments, it was observed that a minority of individuals did not comply with the masking regulations. Scenario 3: The third scenario is almost identical to the first, but now accounts for time-limited immunity. After 90 days, it has been shown that a recovered individual may become susceptible to the virus again [11]. This scenario serves as a comparison to investigate if the immunity factor would worsen the effects of the delay of mask enforcement on the maximum infected values.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9966195822, + "detect_cls":"Body Text", + "detect_score":-1.7037055492 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":2, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_2_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 384.0, + 550.0, + 392.0, + 959.0 + ], + "classes":[ + "Figure", + "Page Footer", + "Body Text", + "Page Header", + "Equation", + "Equation label", + "Table", + "Other", + "Reference text", + "Section Header", + "Figure Caption", + "Table Note", + "Abstract", + "Table Caption" + ], + "scores":[ + -3.9439780712, + -5.3267054558, + -6.2526054382, + -7.1189422607, + -7.8562464714, + -8.1171293259, + -9.2266807556, + -9.8653507233, + -10.498093605, + -10.6506376266, + -11.1741914749, + -11.8317804337, + -13.3176107407, + -13.9674358368 + ], + "content":"• • •", + "postprocess_cls":"Figure", + "postprocess_score":0.52900666, + "detect_cls":"Figure", + "detect_score":-3.9439780712 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":2, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_2_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 1101.0, + 1278.0, + 1576.0 + ], + "classes":[ + "Body Text", + "Reference text", + "Equation label", + "Abstract", + "Page Footer", + "Section Header", + "Table Note", + "Other", + "Figure", + "Figure Caption", + "Page Header", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + -0.6825846434, + -15.3944978714, + -15.428196907, + -16.5312175751, + -16.6540126801, + -18.0022602081, + -20.0354576111, + -20.8560085297, + -21.1997718811, + -21.5778102875, + -21.596364975, + -28.5442733765, + -29.507566452, + -30.4051780701 + ], + "content":"Here we highlight that effective control of the COVID19 pandemic cannot be achieved by the universal masking enforcement alone, but a strong combination factors such as social distancing enforcement, rapid roll-out of mass testing, lockdowns and extensive quarantine measures. However, these are outside the scope of our analysis, as we aim to both model and investigate how the delay of public masking enforcement affects its effectiveness in controlling the pandemic. We have thus considered the effects of universal masking in isolation of the other factors for the purpose of this analysis. Sections 2 and 3 of this article describe and explain the SEIR and SEIRS mathematical models we implemented. Section 4 describes the mathematical modelling of the relation- ship between the mask wearing and the infection rate with respect to time t. Section 5 describes the epidemiological parameters implemented in our models. Brief justification of their values are also included. Section 6 comprises the results and discussion, and is divided into 3 sub-sections. Section 6.1 explains the dynamics of the delay in compulsory mask wearing, and discusses its effects as demonstrated by our models. Section 6.2 ex- plains the effects of this delay on the Maximum Infected Values for each of the 3 scenarios. Section 6.3 discusses the limitations of our study. Finally, Section 7 wraps up the discussion with a conclusion.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9997990727, + "detect_cls":"Body Text", + "detect_score":-0.6825846434 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":2, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_2_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 1610.0, + 531.0, + 1627.0 + ], + "classes":[ + "Body Text", + "Page Footer", + "Other", + "Section Header", + "Figure", + "Reference text", + "Equation label", + "Equation", + "Table Note", + "Table", + "Figure Caption", + "Page Header", + "Abstract", + "Table Caption" + ], + "scores":[ + -4.2576880455, + -5.7159318924, + -6.2077884674, + -6.4353137016, + -7.9118890762, + -8.0875310898, + -8.1936368942, + -8.9437570572, + -9.4237642288, + -9.8112573624, + -10.0816755295, + -10.3704032898, + -11.5863780975, + -11.9120559692 + ], + "content":"2. SEIR Model", + "postprocess_cls":"Section Header", + "postprocess_score":0.9992983341, + "detect_cls":"Body Text", + "detect_score":-4.2576880455 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":2, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_2_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 381.0, + 1645.0, + 1278.0, + 1783.0 + ], + "classes":[ + "Body Text", + "Abstract", + "Figure Caption", + "Page Footer", + "Reference text", + "Table Note", + "Figure", + "Section Header", + "Other", + "Page Header", + "Equation label", + "Table Caption", + "Table", + "Equation" + ], + "scores":[ + -6.8442792892, + -14.5340843201, + -15.9826402664, + -16.779340744, + -18.0857620239, + -19.8811759949, + -22.0744285583, + -24.9976997375, + -25.2601032257, + -25.4991168976, + -25.9981155396, + -26.0339317322, + -28.6102046967, + -34.445186615 + ], + "content":"Compartmentalized mathematical models have been regularly used to model infec- tious diseases. The most basic SIR (Susceptible, Infected, Removed) was developed in the early twentieth century by Ronald Ross, William Hamer, and many others [12], and has been heavily modified since, with the addition of new compartments and parameters. More recently, the use of similar models have resurfaced to model the COVID19 situation", + "postprocess_cls":"Body Text", + "postprocess_score":0.9988446236, + "detect_cls":"Body Text", + "detect_score":-6.8442792892 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Page Header", + "Equation label", + "Body Text", + "Page Footer", + "Figure Caption", + "Section Header", + "Other", + "Figure", + "Table", + "Reference text", + "Table Note", + "Table Caption", + "Abstract", + "Equation" + ], + "scores":[ + -2.3664302826, + -2.9404520988, + -3.2837388515, + -4.0985455513, + -4.7677974701, + -5.3199496269, + -5.6641254425, + -5.7271747589, + -5.8400988579, + -5.9454283714, + -6.2081561089, + -6.536760807, + -7.8253655434, + -8.1519069672 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 3 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.9991918206, + "detect_cls":"Page Header", + "detect_score":-2.3664302826 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 381.0, + 224.0, + 1277.0, + 418.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Reference text", + "Page Footer", + "Figure", + "Page Header", + "Section Header", + "Table Note", + "Abstract", + "Other", + "Figure Caption", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + 0.4304295182, + -10.1913642883, + -12.402302742, + -14.7456035614, + -15.7327041626, + -16.9917621613, + -17.6852760315, + -18.2479972839, + -18.9947147369, + -19.0640888214, + -19.0708618164, + -21.1419143677, + -24.5851593018, + -28.4060916901 + ], + "content":"in many countries. Recent epidemiological studies on China [13], Italy [14], India [15] for example, have been conducted with modified versions of such a model. For our study, we used the SEIR [16] and SEIRS [17] variant of the model, as described in Sections 2 and 3. The SEIR model consists of several compartments, namely Susceptible, Exposed, Infected and Removed. We expand the model by further differentiating the Removed compartment into 2 new Recovered and Death compartments. The flow between the 5 components are described by the following 5 differential equations:", + "postprocess_cls":"Body Text", + "postprocess_score":0.9962309003, + "detect_cls":"Body Text", + "detect_score":0.4304295182 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 752.0, + 716.0, + 1274.0, + 765.0 + ], + "classes":[ + "Equation label", + "Equation", + "Body Text", + "Figure", + "Page Header", + "Reference text", + "Table", + "Section Header", + "Other", + "Page Footer", + "Figure Caption", + "Table Note", + "Abstract", + "Table Caption" + ], + "scores":[ + 0.7596632242, + -6.09562397, + -6.2220053673, + -8.4025192261, + -11.1426048279, + -12.1553859711, + -13.1699972153, + -13.5358810425, + -14.4634923935, + -15.2270336151, + -15.240105629, + -16.8979148865, + -18.1654338837, + -19.4191036224 + ], + "content":"dD(t) = αρI(t) (5) dt", + "postprocess_cls":"Equation", + "postprocess_score":0.9998032451, + "detect_cls":"Equation label", + "detect_score":0.7596632242 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 723.0, + 651.0, + 1274.0, + 699.0 + ], + "classes":[ + "Equation label", + "Body Text", + "Equation", + "Page Header", + "Figure", + "Reference text", + "Section Header", + "Figure Caption", + "Other", + "Table", + "Page Footer", + "Table Note", + "Abstract", + "Table Caption" + ], + "scores":[ + -0.5282879472, + -3.2964746952, + -8.4707126617, + -8.9078521729, + -9.4237070084, + -12.070687294, + -12.3733644485, + -13.7526845932, + -14.542424202, + -15.080165863, + -16.516462326, + -16.5492744446, + -17.5699195862, + -20.0694351196 + ], + "content":"dR(t) = (1 − α)γI(t) (4) dt", + "postprocess_cls":"Equation", + "postprocess_score":0.9947794676, + "detect_cls":"Equation label", + "detect_score":-0.5282879472 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 640.0, + 585.0, + 1274.0, + 634.0 + ], + "classes":[ + "Equation label", + "Body Text", + "Equation", + "Figure", + "Page Header", + "Reference text", + "Section Header", + "Table", + "Figure Caption", + "Other", + "Table Note", + "Page Footer", + "Abstract", + "Table Caption" + ], + "scores":[ + 1.0624827147, + -3.953271389, + -8.6391658783, + -10.9951019287, + -11.2218170166, + -13.0829267502, + -13.9086027145, + -14.9607896805, + -15.1052751541, + -15.5159215927, + -16.6100692749, + -16.7282314301, + -18.5023384094, + -20.6325378418 + ], + "content":"dI(t) = δE(t) − (1 − α)γI(t) − αρI(t) (3) dt", + "postprocess_cls":"Equation", + "postprocess_score":0.9843853116, + "detect_cls":"Equation label", + "detect_score":1.0624827147 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 696.0, + 519.0, + 1274.0, + 568.0 + ], + "classes":[ + "Equation label", + "Body Text", + "Section Header", + "Equation", + "Figure", + "Figure Caption", + "Page Header", + "Reference text", + "Table Note", + "Other", + "Page Footer", + "Table", + "Abstract", + "Table Caption" + ], + "scores":[ + -1.777987957, + -2.7053332329, + -10.7096710205, + -10.9655132294, + -11.248005867, + -12.8873147964, + -13.0134782791, + -13.5010709763, + -15.5496406555, + -15.7924356461, + -16.4645557404, + -16.4778881073, + -17.3430652618, + -18.789352417 + ], + "content":"S(t) dE(t) = βI(t) − δE(t) (2) dt N", + "postprocess_cls":"Equation", + "postprocess_score":0.9568058848, + "detect_cls":"Equation label", + "detect_score":-1.777987957 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 681.0, + 1222.0, + 1274.0, + 1271.0 + ], + "classes":[ + "Equation label", + "Body Text", + "Equation", + "Reference text", + "Figure", + "Page Header", + "Section Header", + "Other", + "Table", + "Figure Caption", + "Abstract", + "Table Note", + "Page Footer", + "Table Caption" + ], + "scores":[ + -4.8503398895, + -5.2248268127, + -9.1185617447, + -11.5806236267, + -12.3339033127, + -12.5619077682, + -12.5990018845, + -15.5497922897, + -16.5331687927, + -16.9476299286, + -18.8042221069, + -20.0208435059, + -20.5148220062, + -22.381269455 + ], + "content":"dR(t) = (1 − α)γI(t) − R(t) (7) dt", + "postprocess_cls":"Equation", + "postprocess_score":0.8299534917, + "detect_cls":"Equation label", + "detect_score":-4.8503398895 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 686.0, + 1147.0, + 1274.0, + 1197.0 + ], + "classes":[ + "Equation label", + "Body Text", + "Page Header", + "Equation", + "Reference text", + "Figure", + "Section Header", + "Figure Caption", + "Table", + "Other", + "Page Footer", + "Table Note", + "Abstract", + "Table Caption" + ], + "scores":[ + 0.117642507, + -5.4621038437, + -7.5167608261, + -9.5665636063, + -10.4896383286, + -12.6301279068, + -13.0732145309, + -14.711019516, + -15.0971460342, + -15.5980558395, + -16.1236038208, + -18.3282203674, + -18.7492389679, + -20.926448822 + ], + "content":"dS(t) S(t) = −βI(t) + R(t) (6) dt N", + "postprocess_cls":"Equation", + "postprocess_score":0.9961049557, + "detect_cls":"Equation label", + "detect_score":0.117642507 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 728.0, + 444.0, + 1274.0, + 493.0 + ], + "classes":[ + "Equation label", + "Body Text", + "Reference text", + "Page Footer", + "Table Note", + "Other", + "Table", + "Figure", + "Section Header", + "Equation", + "Page Header", + "Abstract", + "Table Caption", + "Figure Caption" + ], + "scores":[ + -2.7598707676, + -2.888833046, + -5.524936676, + -5.6568017006, + -6.0531992912, + -6.1260838509, + -6.5165491104, + -7.3657631874, + -7.4578914642, + -8.0260257721, + -8.8127374649, + -9.0429992676, + -9.6294651031, + -9.9026927948 + ], + "content":"dS(t) S(t) = −βI(t) (1) dt N", + "postprocess_cls":"Equation", + "postprocess_score":0.6141163707, + "detect_cls":"Equation label", + "detect_score":-2.7598707676 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 782.0, + 1275.0, + 920.0 + ], + "classes":[ + "Body Text", + "Section Header", + "Figure Caption", + "Abstract", + "Equation label", + "Table Note", + "Page Footer", + "Reference text", + "Other", + "Figure", + "Table Caption", + "Page Header", + "Equation", + "Table" + ], + "scores":[ + -2.7215280533, + -10.4865884781, + -10.639998436, + -13.9466915131, + -15.7235155106, + -16.6665477753, + -16.8861198425, + -18.0406684875, + -18.3201999664, + -18.3763141632, + -20.1121368408, + -20.3940029144, + -24.6096229553, + -25.1321487427 + ], + "content":"where N is the total population, S(t), E(t), I(t), R(t) and D(t), are the number of people susceptible, exposed, infected, recovered and dead on day t. β is the expected number of people an infected person infects per day, γ is the proportion of recovery per day, δ is the incubation period, α is the fatality rate due to the infection and ρ is the inverse of the average number of days for an infected person to die if he does not recover.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9959763885, + "detect_cls":"Body Text", + "detect_score":-2.7215280533 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 949.0, + 545.0, + 965.0 + ], + "classes":[ + "Body Text", + "Page Footer", + "Figure", + "Equation label", + "Reference text", + "Other", + "Page Header", + "Section Header", + "Abstract", + "Figure Caption", + "Table Note", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + -5.2109236717, + -6.5942687988, + -8.2502479553, + -8.8928756714, + -9.0652112961, + -10.0970077515, + -10.5589427948, + -10.9189805984, + -12.2121772766, + -12.4608488083, + -12.7421483994, + -13.4477958679, + -13.8999729156, + -17.0868797302 + ], + "content":"3. SEIRS Model", + "postprocess_cls":"Section Header", + "postprocess_score":0.9996773005, + "detect_cls":"Body Text", + "detect_score":-5.2109236717 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 984.0, + 1275.0, + 1121.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Abstract", + "Reference text", + "Other", + "Table Note", + "Page Footer", + "Section Header", + "Figure", + "Figure Caption", + "Page Header", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + -2.9874308109, + -9.0950212479, + -10.8997097015, + -11.151506424, + -11.562748909, + -12.2840843201, + -13.4683017731, + -14.4899168015, + -16.8020267487, + -16.9602298737, + -17.6181564331, + -17.9680194855, + -18.2824897766, + -19.6447219849 + ], + "content":"The SEIRS model is similar to the SEIR model such that it has five components as well—Susceptible, Exposed, Infected, Recovered and Death. However, the SEIRS model takes time-limited immunity into account, whereby recovered individuals are prone to becoming susceptible to the disease again after a period of time. In the SEIRS model, Equations (1) and (4) are then modified to", + "postprocess_cls":"Body Text", + "postprocess_score":0.9993829727, + "detect_cls":"Body Text", + "detect_score":-2.9874308109 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 1288.0, + 1126.0, + 1311.0 + ], + "classes":[ + "Equation label", + "Body Text", + "Figure", + "Section Header", + "Reference text", + "Page Header", + "Equation", + "Figure Caption", + "Table", + "Other", + "Page Footer", + "Table Note", + "Abstract", + "Table Caption" + ], + "scores":[ + -2.6959555149, + -3.5594203472, + -6.703063488, + -7.6305561066, + -7.7114853859, + -7.9572868347, + -8.2868156433, + -10.5709295273, + -12.1454677582, + -12.3750295639, + -13.2707958221, + -13.6201553345, + -13.6786584854, + -15.3705368042 + ], + "content":"where is the rate at which a recovered person becomes susceptible again.", + "postprocess_cls":"Equation", + "postprocess_score":0.8025770187, + "detect_cls":"Equation label", + "detect_score":-2.6959555149 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":3, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_3_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 1339.0, + 1277.0, + 1712.0 + ], + "classes":[ + "Body Text", + "Reference text", + "Abstract", + "Equation label", + "Page Header", + "Section Header", + "Figure Caption", + "Page Footer", + "Figure", + "Other", + "Table Note", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + -3.1954927444, + -6.7487845421, + -12.9166879654, + -13.5890388489, + -14.0583839417, + -16.2690963745, + -16.9095211029, + -17.8277950287, + -19.5517063141, + -19.598072052, + -19.6363887787, + -21.2971973419, + -22.2141418457, + -24.7429199219 + ], + "content":"4. Time-Based Model for Compulsory Mask Wearing Masking is found to decrease the infection rate I(t) by reducing the transmission of respiratory droplets between individuals, which in turn reduces the number of individuals an infected person can infect. Kai et al. [18] showed that the infection rate can be reduced by 60% when universal masking is enforced. There have been other studies that reflect varying rates of infection rate reduction, such as 47% (estimate between 15% and 75%) in Germany [19] and 75% in Arizona during the 2020 summer surge [20], along with numerous others. The disparity of the figures are likely to be due to the influence of other policies such as enforced social distancing and lockdowns. For the purpose of our study, we felt 60% reduction in infection rate was a reasonable value, without being too optimistic or pessimistic.We thus model our infection rate as time-dependent β → β(t) and a function of m(t): β(t) = κm(t) (8)", + "postprocess_cls":"Body Text", + "postprocess_score":0.9998670816, + "detect_cls":"Body Text", + "detect_score":-3.1954927444 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":4, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_4_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Page Header", + "Equation label", + "Body Text", + "Page Footer", + "Section Header", + "Figure Caption", + "Other", + "Table", + "Reference text", + "Table Caption", + "Figure", + "Table Note", + "Equation", + "Abstract" + ], + "scores":[ + -1.7302033901, + -3.6377530098, + -4.4046735764, + -5.2347478867, + -5.5449490547, + -5.9033555984, + -5.9583358765, + -6.3729043007, + -6.5386605263, + -7.0557188988, + -7.2179327011, + -7.4130735397, + -8.6365003586, + -8.9389972687 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 4 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.9993817806, + "detect_cls":"Page Header", + "detect_score":-1.7302033901 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":4, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_4_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 224.0, + 741.0, + 246.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Section Header", + "Figure", + "Reference text", + "Equation", + "Figure Caption", + "Page Footer", + "Page Header", + "Table Note", + "Other", + "Abstract", + "Table", + "Table Caption" + ], + "scores":[ + -1.7804280519, + -8.1360397339, + -11.527100563, + -13.3830690384, + -13.5606451035, + -13.768409729, + -15.0057487488, + -17.1439228058, + -17.2342357635, + -17.2720603943, + -18.1832847595, + -18.4798774719, + -21.9602966309, + -22.6526908875 + ], + "content":"where κ is an arbitrary constant and", + "postprocess_cls":"Page Header", + "postprocess_score":0.9264364839, + "detect_cls":"Body Text", + "detect_score":-1.7804280519 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":4, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_4_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 694.0, + 273.0, + 1274.0, + 324.0 + ], + "classes":[ + "Equation", + "Equation label", + "Body Text", + "Figure", + "Section Header", + "Table", + "Reference text", + "Page Header", + "Other", + "Page Footer", + "Figure Caption", + "Table Note", + "Abstract", + "Table Caption" + ], + "scores":[ + -3.7837722301, + -4.4668540955, + -8.5332717896, + -9.7747631073, + -13.9771213531, + -14.2968702316, + -14.3140821457, + -14.3843383789, + -14.4104194641, + -16.5212039948, + -19.6543273926, + -20.2351646423, + -20.919095993, + -21.7818088531 + ], + "content":"βs − βc m(t) = (9) + βc 1 + e−k(−t+t0)", + "postprocess_cls":"Equation", + "postprocess_score":0.9999083281, + "detect_cls":"Equation", + "detect_score":-3.7837722301 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":4, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_4_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 350.0, + 1275.0, + 539.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Figure Caption", + "Figure", + "Page Footer", + "Table Note", + "Reference text", + "Abstract", + "Other", + "Section Header", + "Page Header", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + -0.5436022878, + -14.9844760895, + -15.4629774094, + -16.4936618805, + -18.1207199097, + -18.1337356567, + -19.5456314087, + -19.683921814, + -20.7252178192, + -21.2746753693, + -22.7573699951, + -27.0828914642, + -28.5530204773, + -29.5923461914 + ], + "content":"where a modified logistic function is used to model this transition by setting the infection before (i.e., at the start of the outbreak) and after the full compliance masking enforcement to be βs = 1 and βc = 0.4 respectively. t0 is the number of days after the first case where masking wearing is enforced. Figure 1 shows an example of such logistic function, where for the case of Singapore, we set t0 = 89, since the policy of compulsory mask wearing was implemented 89 days after the first case was uncovered. This model is used in both Scenarios 1 and 3.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9971863627, + "detect_cls":"Body Text", + "detect_score":-0.5436022878 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":4, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_4_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 404.0, + 580.0, + 1152.0, + 1079.0 + ], + "classes":[ + "Figure", + "Body Text", + "Page Header", + "Equation", + "Equation label", + "Figure Caption", + "Section Header", + "Other", + "Table", + "Page Footer", + "Table Note", + "Abstract", + "Reference text", + "Table Caption" + ], + "scores":[ + 4.1000723839, + -9.4325752258, + -12.4519081116, + -14.3672904968, + -14.5336322784, + -14.9966268539, + -15.9972295761, + -16.025396347, + -16.671836853, + -17.1014385223, + -19.9756145477, + -21.1269264221, + -22.4875679016, + -23.1718616486 + ], + "content":"", + "postprocess_cls":"Figure", + "postprocess_score":0.9999912977, + "detect_cls":"Figure", + "detect_score":4.1000723839 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":4, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_4_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 1104.0, + 1275.0, + 1149.0 + ], + "classes":[ + "Figure Caption", + "Page Header", + "Body Text", + "Table Caption", + "Section Header", + "Figure", + "Page Footer", + "Equation label", + "Table Note", + "Abstract", + "Other", + "Table", + "Reference text", + "Equation" + ], + "scores":[ + 2.9030091763, + -9.2282190323, + -13.6434030533, + -15.0287923813, + -16.2147197723, + -16.3651332855, + -17.4601249695, + -17.9541778564, + -18.631696701, + -18.9941577911, + -20.4291362762, + -22.0355434418, + -22.8392944336, + -23.8998527527 + ], + "content":"Figure 1. Logistic function to model the infection rate due to compulsory mask wearing m(t) for Scenarios 1 and 3.", + "postprocess_cls":"Figure Caption", + "postprocess_score":0.9999907017, + "detect_cls":"Figure Caption", + "detect_score":2.9030091763 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":4, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_4_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 1184.0, + 1275.0, + 1289.0 + ], + "classes":[ + "Figure", + "Page Header", + "Equation label", + "Equation", + "Body Text", + "Other", + "Section Header", + "Figure Caption", + "Table", + "Page Footer", + "Reference text", + "Abstract", + "Table Note", + "Table Caption" + ], + "scores":[ + -5.9238781929, + -7.8981151581, + -8.0480117798, + -8.0698204041, + -8.5796461105, + -10.6876716614, + -13.9410295486, + -14.1181249619, + -14.4374904633, + -15.9662275314, + -16.184179306, + -18.5673618317, + -18.7337665558, + -19.8033809662 + ], + "content":"To model the gradual noncompliance of universal masking, we make a modification to Equation (9). βs − βc βc − βnc + m(t) = (10) + βnc 1 + e−k1(−t+t0) 1 + e−k2(−t+t1)", + "postprocess_cls":"Body Text", + "postprocess_score":0.5503957272, + "detect_cls":"Figure", + "detect_score":-5.9238781929 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":4, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_4_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 1305.0, + 1278.0, + 1672.0 + ], + "classes":[ + "Body Text", + "Figure Caption", + "Table Note", + "Equation label", + "Page Header", + "Section Header", + "Abstract", + "Table Caption", + "Other", + "Page Footer", + "Reference text", + "Figure", + "Table", + "Equation" + ], + "scores":[ + -5.8830633163, + -9.0368585587, + -10.8957958221, + -13.3811073303, + -13.5485925674, + -14.8247318268, + -14.991435051, + -15.1697273254, + -15.8896350861, + -17.105091095, + -17.6960659027, + -18.4475955963, + -21.0349082947, + -23.3355693817 + ], + "content":"As individuals began to engage in noncompliance out of complacency and pandemic fatigue, the infection rate, βnc, would thus increase slightly. Furthermore, compared to quenching of the infection rate due to enforcement of the compulsory mask wearing, the noncompliance will be gradual. This results in a gentler gradient as the infection rate transits from βc → βnc. The gradients are tuned by the arbitrary constants k1 and k2, where k1 > k2. We further assume that the population are able to maintain compliance for a period of time before onset of noncompliance at t1, which may be triggered by an event, for example a change in the government's policy. Figure 2 illustrates one such example, where we have βnc = 0.5 and t1 = 154, taken in context to Singapore's shift from a full lockdown to gradual resumption of everyday activities 154 days after the first case. The infection rate βnc is expected to be lower than βs as even with the complacency and fatigue, as there is now a greater situational awareness of the severity and the population in general will take a more cautious outlook compared to pre-pandemic days.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9968757629, + "detect_cls":"Body Text", + "detect_score":-5.8830633163 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Page Header", + "Equation label", + "Body Text", + "Page Footer", + "Figure Caption", + "Section Header", + "Other", + "Reference text", + "Figure", + "Table", + "Table Note", + "Table Caption", + "Equation", + "Abstract" + ], + "scores":[ + -1.5087971687, + -3.3478233814, + -3.992017746, + -4.9614892006, + -5.4743070602, + -6.1402859688, + -6.2511262894, + -6.323946476, + -6.4941959381, + -6.5377807617, + -7.5381102562, + -7.6336975098, + -8.5953559875, + -8.9597167969 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 5 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.9994342923, + "detect_cls":"Page Header", + "detect_score":-1.5087971687 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 396.0, + 223.0, + 931.0, + 580.0 + ], + "classes":[ + "Figure", + "Body Text", + "Page Header", + "Figure Caption", + "Other", + "Section Header", + "Equation", + "Equation label", + "Page Footer", + "Table", + "Table Note", + "Abstract", + "Table Caption", + "Reference text" + ], + "scores":[ + 2.2623577118, + -10.2967786789, + -10.8714666367, + -12.8581047058, + -15.1635608673, + -15.8568058014, + -16.4230175018, + -17.6112575531, + -18.1314201355, + -18.4943618774, + -20.4085903168, + -20.733877182, + -22.6400165558, + -22.6574802399 + ], + "content":"", + "postprocess_cls":"Figure", + "postprocess_score":0.9999917746, + "detect_cls":"Figure", + "detect_score":2.2623577118 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 613.0, + 1275.0, + 664.0 + ], + "classes":[ + "Figure Caption", + "Body Text", + "Figure", + "Page Footer", + "Page Header", + "Table Caption", + "Abstract", + "Table Note", + "Section Header", + "Other", + "Equation label", + "Table", + "Reference text", + "Equation" + ], + "scores":[ + 0.9741205573, + -11.5788402557, + -12.8867588043, + -13.7339344025, + -14.8756866455, + -16.1689815521, + -16.255853653, + -16.4346809387, + -16.6110420227, + -16.6758804321, + -21.1135120392, + -21.5821495056, + -23.1135559082, + -24.8644714355 + ], + "content":"Figure 2. Logistic function to model the infection rate due to compulsory mask wearing m(t) for Scenario 2, where one takes into account the noncompliance.", + "postprocess_cls":"Figure Caption", + "postprocess_score":0.9999696016, + "detect_cls":"Figure Caption", + "detect_score":0.9741205573 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 688.0, + 1275.0, + 775.0 + ], + "classes":[ + "Other", + "Section Header", + "Page Footer", + "Figure Caption", + "Body Text", + "Figure", + "Page Header", + "Reference text", + "Equation", + "Table Note", + "Abstract", + "Table Caption", + "Table", + "Equation label" + ], + "scores":[ + -4.6291937828, + -6.0781207085, + -7.9622960091, + -8.5642433167, + -8.5854253769, + -8.9777555466, + -9.801366806, + -10.6661090851, + -10.904668808, + -11.2438554764, + -11.4593896866, + -11.8970451355, + -13.0903167725, + -13.5284023285 + ], + "content":"5. Epidemiological Parameters To conduct our analysis in the Singapore context, we estimate the epidemiological parameters described in the earlier sections for the Singapore's context:", + "postprocess_cls":"Other", + "postprocess_score":0.7580176592, + "detect_cls":"Other", + "detect_score":-4.6291937828 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 430.0, + 792.0, + 1277.0, + 1130.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Reference text", + "Figure Caption", + "Section Header", + "Figure", + "Abstract", + "Page Header", + "Page Footer", + "Table Note", + "Other", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + 1.5766657591, + -13.2020549774, + -16.4787559509, + -16.964302063, + -17.2969303131, + -18.2964859009, + -18.8807621002, + -19.0890674591, + -19.3149185181, + -21.8046360016, + -23.581987381, + -26.566526413, + -28.9885311127, + -30.0895500183 + ], + "content":"γ = 1/11: According to the position statement released by the National Centre of Disease Control Singapore [21], a person remains infectious for up to 11 days after first contracting COVID-19. δ = 1/5: The SARS-CoV2 virus has an incubation period of about 5 days [22]. α = 0.000064: Fatality rate is defined as the percentage of deaths among all previously infected individuals. At the time this work was conducted, the number of deaths in Singapore was 26, and the total number of Recovered and Dead compartments was 40,625. ρ = 1/9: As this number varies greatly across different demographics and is highly unpredictable, we are unable to obtain a proper average. Moreover, owing to the low numbers of COVID-19 deaths in Singapore, it would be inaccurate to calculate an average using this small sample size. Thus, for analysis purposes, we set it at 9 days.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9996544123, + "detect_cls":"Body Text", + "detect_score":1.5766657591 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 384.0, + 796.0, + 392.0, + 804.0 + ], + "classes":[ + "Page Footer", + "Figure", + "Section Header", + "Body Text", + "Equation", + "Other", + "Reference text", + "Table", + "Page Header", + "Table Note", + "Equation label", + "Figure Caption", + "Table Caption", + "Abstract" + ], + "scores":[ + -2.9053115845, + -4.5805282593, + -5.5827050209, + -6.5868663788, + -7.3583173752, + -7.4265518188, + -8.0279092789, + -8.2571277618, + -8.3638343811, + -8.5961027145, + -8.8530931473, + -9.2815132141, + -9.8112306595, + -10.4304542542 + ], + "content":"•", + "postprocess_cls":"Section Header", + "postprocess_score":0.9211617112, + "detect_cls":"Page Footer", + "detect_score":-2.9053115845 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 384.0, + 882.0, + 392.0, + 890.0 + ], + "classes":[ + "Page Footer", + "Section Header", + "Figure", + "Equation label", + "Equation", + "Reference text", + "Table", + "Other", + "Figure Caption", + "Page Header", + "Table Caption", + "Table Note", + "Abstract", + "Body Text" + ], + "scores":[ + -2.1900157928, + -5.3232288361, + -6.3310675621, + -6.538602829, + -6.8521265984, + -7.0864639282, + -7.6612892151, + -7.6977677345, + -7.7621526718, + -7.9629206657, + -8.4278831482, + -8.7660951614, + -9.2666406631, + -9.4148368835 + ], + "content":"•", + "postprocess_cls":"Section Header", + "postprocess_score":0.8286181688, + "detect_cls":"Page Footer", + "detect_score":-2.1900157928 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 384.0, + 911.0, + 392.0, + 919.0 + ], + "classes":[ + "Page Footer", + "Section Header", + "Equation label", + "Figure", + "Table", + "Other", + "Equation", + "Table Caption", + "Table Note", + "Figure Caption", + "Reference text", + "Page Header", + "Body Text", + "Abstract" + ], + "scores":[ + -1.6243486404, + -6.7012591362, + -6.9366807938, + -7.3323450089, + -7.9474105835, + -8.8363676071, + -8.8912086487, + -8.978302002, + -9.0530633926, + -9.4314546585, + -9.4526872635, + -9.770160675, + -9.8681192398, + -11.2481384277 + ], + "content":"•", + "postprocess_cls":"Section Header", + "postprocess_score":0.8768944144, + "detect_cls":"Page Footer", + "detect_score":-1.6243486404 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 384.0, + 1025.0, + 392.0, + 1033.0 + ], + "classes":[ + "Section Header", + "Body Text", + "Page Footer", + "Figure", + "Other", + "Figure Caption", + "Page Header", + "Equation", + "Equation label", + "Table Note", + "Reference text", + "Table Caption", + "Table", + "Abstract" + ], + "scores":[ + -3.8821780682, + -5.7434711456, + -10.7130403519, + -11.2477216721, + -12.108798027, + -13.4920969009, + -13.5678339005, + -14.0245628357, + -14.1262760162, + -16.1466751099, + -17.2123680115, + -17.515127182, + -18.4866218567, + -20.4881267548 + ], + "content":"•", + "postprocess_cls":"Section Header", + "postprocess_score":0.9993214607, + "detect_cls":"Section Header", + "detect_score":-3.8821780682 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":5, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_5_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 1158.0, + 1277.0, + 1791.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Section Header", + "Page Footer", + "Figure", + "Reference text", + "Figure Caption", + "Page Header", + "Table Note", + "Abstract", + "Other", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + 3.9174981117, + -29.6443309784, + -30.2645549774, + -30.7007331848, + -33.6453704834, + -33.8487052917, + -34.6866035461, + -36.0330162048, + -38.830997467, + -39.2242469788, + -41.6673774719, + -49.0738563538, + -51.2751731873, + -53.5775375366 + ], + "content":"6. Results and Discussion 6.1. Dynamics of Delay of Compulsory Mask Wearing Upon applying the SEIR models to the 3 scenarios described in the above sections, we are able to obtain Maximum Infected Values by simulating different values of delay in mask enforcement. Considering the most basic case of Scenario 1; where there is complete compliance throughout the duration of mask enforcement, and the absence of time-limited immunity, Figure 3 shows the cases where mask wearing were to be enforced (a) on the day the first case of COVID-19 was detected in Singapore; (b) after a 50 days delay; (c) after a 100 days delay; and (d) not enforced at all. From Figure 3, it can be deduced that earlier enforcement of mask wearing both reduces the Maximum Infected Value as well as increases the number of days taken to reach the Maximum Infected Value. This is reflected by right-ward shift of the maxima of the Infected compartment, as well as a lower maxima value of the infected curve. The infected number increases until it reaches a global maxima, before decreasing as predicted by compartmental models of such form. This global maxima is termed as the Maximum Infected Value. For the case of (a) 0 days of delay in mask enforcement, the maximum infected value is approximately 10.453%, and the peak occurs at day 291 after the first case was detected. For the case of a (b) 50 days delay, the maximum infected value is approximately 10.479%, and the peak occurs on day 195. For the case of a (c) 100 days delay, the maximum infected value is much higher, at approximately 27.474%, and the peak occurs much earlier, on day 103. This is very close to the case where (d) no public masking is enforced, where the maximum infected value is approximately 31.422% and", + "postprocess_cls":"Body Text", + "postprocess_score":0.9963091016, + "detect_cls":"Body Text", + "detect_score":3.9174981117 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":6, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_6_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Page Header", + "Equation label", + "Body Text", + "Page Footer", + "Figure Caption", + "Other", + "Figure", + "Section Header", + "Table", + "Reference text", + "Table Note", + "Table Caption", + "Abstract", + "Equation" + ], + "scores":[ + -2.5404891968, + -2.7208592892, + -3.2227096558, + -3.8342299461, + -4.8508319855, + -5.3711147308, + -5.4711380005, + -5.494038105, + -5.6461625099, + -5.8514742851, + -5.9516105652, + -6.5359797478, + -7.7324132919, + -7.8704433441 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 6 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.9993324876, + "detect_cls":"Page Header", + "detect_score":-2.5404891968 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":6, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_6_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 381.0, + 224.0, + 1275.0, + 304.0 + ], + "classes":[ + "Reference text", + "Body Text", + "Page Footer", + "Equation label", + "Table Note", + "Other", + "Abstract", + "Section Header", + "Page Header", + "Figure", + "Figure Caption", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + -2.41370368, + -2.449630022, + -6.9069609642, + -8.0799608231, + -9.8782691956, + -9.8951234818, + -10.0216999054, + -10.1125574112, + -11.3799171448, + -11.8693094254, + -12.6075954437, + -12.9540042877, + -13.3861627579, + -15.8635005951 + ], + "content":"the peak occurs on day 106. From a policy point of view, this suggests that early universal masking would indeed be an effective control, not only to reduce the infection, but more critically to flatten the curve so as to not overwhelm the medical resources.", + "postprocess_cls":"Reference text", + "postprocess_score":0.9266610146, + "detect_cls":"Reference text", + "detect_score":-2.41370368 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":6, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_6_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 250.0, + 363.0, + 1102.0, + 565.0 + ], + "classes":[ + "Figure", + "Page Header", + "Figure Caption", + "Section Header", + "Equation label", + "Body Text", + "Table", + "Equation", + "Table Caption", + "Page Footer", + "Other", + "Table Note", + "Reference text", + "Abstract" + ], + "scores":[ + -3.1873693466, + -4.8212738037, + -7.0536727905, + -10.2028875351, + -10.3731937408, + -12.6629772186, + -13.1024913788, + -13.3014593124, + -13.4798297882, + -14.02252388, + -14.8326330185, + -16.4965019226, + -16.7484340668, + -17.5182647705 + ], + "content":"", + "postprocess_cls":"Figure", + "postprocess_score":0.9992592931, + "detect_cls":"Figure", + "detect_score":-3.1873693466 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":6, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_6_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 250.0, + 590.0, + 1117.0, + 791.0 + ], + "classes":[ + "Page Header", + "Figure", + "Figure Caption", + "Body Text", + "Equation label", + "Page Footer", + "Equation", + "Table", + "Section Header", + "Other", + "Reference text", + "Table Caption", + "Table Note", + "Abstract" + ], + "scores":[ + -1.1635150909, + -4.8522176743, + -9.8937969208, + -9.9956798553, + -10.4784946442, + -12.4243450165, + -12.8667650223, + -13.4087505341, + -13.4521074295, + -14.8423604965, + -16.4829616547, + -16.5560760498, + -17.6497058868, + -19.2318267822 + ], + "content":"", + "postprocess_cls":"Figure", + "postprocess_score":0.9996366501, + "detect_cls":"Page Header", + "detect_score":-1.1635150909 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":6, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_6_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 129.0, + 840.0, + 1227.0, + 890.0 + ], + "classes":[ + "Figure Caption", + "Section Header", + "Table Caption", + "Body Text", + "Other", + "Page Header", + "Table Note", + "Figure", + "Page Footer", + "Abstract", + "Equation label", + "Reference text", + "Table", + "Equation" + ], + "scores":[ + 0.0527810045, + -5.8636431694, + -8.1322975159, + -9.1273422241, + -9.1603155136, + -9.2407836914, + -10.6179800034, + -10.9474830627, + -11.1488428116, + -11.6220417023, + -12.3708753586, + -13.761590004, + -14.0128669739, + -14.9243373871 + ], + "content":"Figure 3. SEIR Plots for delays of (a) 0 days, (b) 50 days, (c) 100 days. (d) corresponds to the control case where mask wearing is not enforced.", + "postprocess_cls":"Figure Caption", + "postprocess_score":0.9999295473, + "detect_cls":"Figure Caption", + "detect_score":0.0527810045 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":6, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_6_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 381.0, + 921.0, + 1275.0, + 1062.0 + ], + "classes":[ + "Figure Caption", + "Body Text", + "Section Header", + "Page Header", + "Equation label", + "Figure", + "Page Footer", + "Abstract", + "Table Note", + "Reference text", + "Other", + "Table Caption", + "Equation", + "Table" + ], + "scores":[ + -3.1065702438, + -4.7654337883, + -12.8439817429, + -13.8662433624, + -15.4319906235, + -15.5018615723, + -17.0974407196, + -18.2143917084, + -19.3625240326, + -19.7661495209, + -20.4133853912, + -21.4896030426, + -24.7576503754, + -25.5214538574 + ], + "content":"6.2. Effects of Delay of Mask Enforcement on Maximum Infected Value We further investigate this relationship by explicitly considering how the delay in mask enforcement will impact the corresponding Maximum Infected Values. Figure 4 shows the results of different enforcement delay values and their corresponding maximum infected values. Here, we considered 3 scenarios described in the introduction.", + "postprocess_cls":"Body Text", + "postprocess_score":0.5061179996, + "detect_cls":"Figure Caption", + "detect_score":-3.1065702438 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":6, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_6_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 393.0, + 1108.0, + 1030.0, + 1537.0 + ], + "classes":[ + "Figure", + "Body Text", + "Page Header", + "Section Header", + "Equation", + "Equation label", + "Other", + "Figure Caption", + "Table", + "Page Footer", + "Table Note", + "Abstract", + "Reference text", + "Table Caption" + ], + "scores":[ + 3.2385380268, + -9.2120409012, + -9.7329940796, + -12.2138414383, + -13.0309505463, + -13.1443042755, + -13.3979330063, + -13.8367948532, + -14.9413957596, + -17.6346092224, + -18.796453476, + -19.1195087433, + -20.0014133453, + -20.6520004272 + ], + "content":"", + "postprocess_cls":"Figure", + "postprocess_score":0.9999812841, + "detect_cls":"Figure", + "detect_score":3.2385380268 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":6, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_6_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 1572.0, + 1275.0, + 1622.0 + ], + "classes":[ + "Figure Caption", + "Table Caption", + "Abstract", + "Page Header", + "Page Footer", + "Section Header", + "Body Text", + "Figure", + "Table Note", + "Other", + "Equation label", + "Reference text", + "Table", + "Equation" + ], + "scores":[ + 4.4397335052, + -10.1999044418, + -10.8553724289, + -10.9445619583, + -11.1522703171, + -12.1556482315, + -12.263874054, + -12.4855384827, + -13.0420885086, + -13.5317106247, + -15.924665451, + -16.16979599, + -16.3548965454, + -18.4352684021 + ], + "content":"Figure 4. Maximum infection against delay in mask enforcement for Scenario 2: SEIR with full compliance and Scenario 3: SEIRS with time-limited immunity.", + "postprocess_cls":"Figure Caption", + "postprocess_score":0.9999933243, + "detect_cls":"Figure Caption", + "detect_score":4.4397335052 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":6, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_6_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 381.0, + 1651.0, + 1277.0, + 1788.0 + ], + "classes":[ + "Body Text", + "Figure", + "Figure Caption", + "Equation label", + "Page Header", + "Section Header", + "Page Footer", + "Reference text", + "Abstract", + "Other", + "Table Note", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + 0.9530130625, + -17.2154483795, + -18.4175643921, + -19.2814178467, + -20.2099666595, + -20.2442378998, + -22.9685268402, + -23.8366775513, + -24.1421489716, + -25.4540996552, + -26.7766017914, + -31.0241737366, + -32.9815940857, + -34.7086448669 + ], + "content":"Figure 4 suggests a transition from low maximum infection of about 15–16% to a high maximum infection of about 31%, with the transition occurring at between a delay of 80 to 100 days. This transition manifests itself as a point of inflection of the graphs in Figure 4, occurring at about 100 days of delay. Interestingly, this suggests that delaying public masking enforcement for greater than about 100 days results in the significant reduction in", + "postprocess_cls":"Figure Caption", + "postprocess_score":1.0, + "detect_cls":"Body Text", + "detect_score":0.9530130625 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":7, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_7_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Page Header", + "Equation label", + "Body Text", + "Page Footer", + "Figure Caption", + "Other", + "Reference text", + "Table", + "Section Header", + "Figure", + "Table Note", + "Table Caption", + "Equation", + "Abstract" + ], + "scores":[ + -1.5099077225, + -3.0049507618, + -4.360350132, + -5.7266712189, + -6.2218074799, + -6.3322916031, + -6.6689505577, + -6.7434539795, + -6.8281655312, + -7.1442403793, + -8.1997594833, + -8.2815227509, + -8.5703229904, + -9.537197113 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 7 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.9996254444, + "detect_cls":"Page Header", + "detect_score":-1.5099077225 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":7, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_7_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 224.0, + 1278.0, + 1134.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Page Footer", + "Figure Caption", + "Figure", + "Abstract", + "Table Note", + "Section Header", + "Reference text", + "Page Header", + "Other", + "Table", + "Equation", + "Table Caption" + ], + "scores":[ + -1.2279397249, + -14.3236656189, + -14.8038883209, + -17.3390235901, + -18.7345314026, + -19.0893936157, + -19.3613624573, + -19.4439258575, + -20.0368766785, + -21.6289806366, + -21.9084072113, + -28.8379039764, + -29.4303035736, + -29.6773681641 + ], + "content":"the effectiveness of public masking in controlling the maximum infection numbers. This is because after 100 days, most of the Exposed compartment has already been been infected, therefore this will no longer contribute to any further increase to the Infection compartment. Relating this to Singapore's context, compulsory mask wearing was introduced 89 days after the first case, hence this suggests that the introduction of compulsory mask wearing was timely to control the infection. Crucially, one should note that the point of inflection appears to be independent of the choice of our scenarios and in all three cases, the transition takes place at about the same 80 to 100 days of delay. The peak infection beyond 100 days of delay also yield similar results in all three cases. One would naively anticipate that the noncompliance in Scenario 2 resulting in a larger infection rate and the backflow of Recovered to Susceptible compartment after 90 days of time-limited immunity would have contributed positively to the Maximum Infected Values. While this is indeed the case for early intervention, beyond the transition point, the Infected compartment is already on track in reaching its maximum (see Figure 3d), the effectiveness of any intervention to change its trajectory and reduce the maximum is greatly reduced. This suggests the importance of early intervention by policy makers and governments, where this potential window to take action is about 3 months based on our analysis. However, we stress this does not mean that public masking is completely ineffective after the transition point, but rather that its initial effectiveness is significantly reduced beyond this point, when studying the effects of compulsory mask wearing in isolation. We further note that in Scenario 2 (see Figure 5), the results suggest that earlier enforce- ment of mask wearing leads to higher than expected Maximum Infected Values (compared to Scenario 1). This is apparent for delays in mask enforcement under approximately 50 days. It is likely that for such cases of early enforcement, the Susceptible population remains very high throughout. Consequently, when the agents begin to flout the rules after t1 = 154 days, the combination of both larger Susceptible compartment pool and higher βnc results in a greater amount of infection. In other words, the susceptible population must be sufficiently reduced before the implementation of the compulsory mask wearing for it to be effective in reducing the Maximum Infected Value. In practice, though not considered in this work, the susceptible population may be reduced or removed through other means, e.g., social distancing or lockdown.", + "postprocess_cls":"Body Text", + "postprocess_score":0.999740541, + "detect_cls":"Body Text", + "detect_score":-1.2279397249 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":7, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_7_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 396.0, + 1172.0, + 1048.0, + 1600.0 + ], + "classes":[ + "Figure", + "Equation label", + "Body Text", + "Equation", + "Section Header", + "Page Header", + "Figure Caption", + "Page Footer", + "Other", + "Table", + "Table Note", + "Abstract", + "Table Caption", + "Reference text" + ], + "scores":[ + 0.6478790641, + -8.1646146774, + -9.0933990479, + -10.5133371353, + -10.5431413651, + -10.6895513535, + -11.6505804062, + -12.4260349274, + -12.4875516891, + -13.2730197906, + -14.7135210037, + -16.0829792023, + -16.6395664215, + -16.8146400452 + ], + "content":"", + "postprocess_cls":"Figure", + "postprocess_score":0.9999837875, + "detect_cls":"Figure", + "detect_score":0.6478790641 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":7, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_7_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 381.0, + 1631.0, + 1278.0, + 1682.0 + ], + "classes":[ + "Figure Caption", + "Body Text", + "Figure", + "Page Header", + "Page Footer", + "Section Header", + "Equation label", + "Table Note", + "Table Caption", + "Equation", + "Other", + "Abstract", + "Reference text", + "Table" + ], + "scores":[ + -3.0298552513, + -7.7131061554, + -9.2794094086, + -10.4575004578, + -12.7215270996, + -13.0526819229, + -14.6363334656, + -17.4520072937, + -17.9454879761, + -18.4411945343, + -19.0718822479, + -21.2084636688, + -21.5699863434, + -22.0168647766 + ], + "content":"Figure 5. Maximum infection against delay in mask enforcement for Scenario 2: SEIR with grad- ual noncompliance.", + "postprocess_cls":"Figure Caption", + "postprocess_score":0.9999574423, + "detect_cls":"Figure Caption", + "detect_score":-3.0298552513 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":7, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_7_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 1710.0, + 1275.0, + 1790.0 + ], + "classes":[ + "Body Text", + "Figure Caption", + "Page Footer", + "Figure", + "Abstract", + "Page Header", + "Table Note", + "Other", + "Equation label", + "Section Header", + "Reference text", + "Table Caption", + "Table", + "Equation" + ], + "scores":[ + -4.3385715485, + -9.694486618, + -13.5871639252, + -14.2641153336, + -14.586853981, + -14.9624614716, + -17.6243057251, + -17.9860401154, + -19.1923599243, + -19.6803646088, + -19.8963279724, + -21.9928703308, + -22.4069385529, + -25.9891548157 + ], + "content":"At the time the initial study was conducted, we had modelled the COVID-19 situation in Singapore and its response to the initial strain of virus that was first detected at the start of 2020. However, the world is currently facing the second wave of infection. New", + "postprocess_cls":"Body Text", + "postprocess_score":0.9927651286, + "detect_cls":"Body Text", + "detect_score":-4.3385715485 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":8, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_8_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Equation label", + "Page Header", + "Body Text", + "Page Footer", + "Figure Caption", + "Section Header", + "Figure", + "Other", + "Table Note", + "Table", + "Reference text", + "Table Caption", + "Abstract", + "Equation" + ], + "scores":[ + -2.5124282837, + -2.9073629379, + -2.9385926723, + -3.376696825, + -4.5021634102, + -4.8872199059, + -5.1021184921, + -5.1072254181, + -5.364320755, + -5.3768672943, + -5.5889949799, + -6.0011315346, + -7.1411910057, + -7.5594658852 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 8 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.9993408322, + "detect_cls":"Equation label", + "detect_score":-2.5124282837 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":8, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_8_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 381.0, + 224.0, + 1278.0, + 476.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Figure Caption", + "Page Header", + "Page Footer", + "Section Header", + "Figure", + "Reference text", + "Table Note", + "Abstract", + "Other", + "Table Caption", + "Table", + "Equation" + ], + "scores":[ + 0.8267956972, + -16.0498313904, + -16.3773021698, + -17.3451595306, + -18.896944046, + -18.9894275665, + -20.2770938873, + -20.8690834045, + -21.1896896362, + -22.9311618805, + -25.2531299591, + -31.2778282166, + -31.8736000061, + -31.9162902832 + ], + "content":"strains, particularly the B117 variant, have been detected in many countries, including Sin- gapore [23]. B117 strained virus has acquired the D614G spike protein mutation, reportedly increasing its infectivity, with little difference to its lethality [24]. According to studies done in the UK, the R0 value of B117 has increased by up to 0.7 [25]. To investigate the impact of delay in public mask enforcement on controlling the Maximum Infected Numbers due to the B117 variant, we modelled a hypothetical scenario. In this scenario, the first case of COVID-19 detected in Singapore is of the B117 variant. We ran our simulation of the 3 scenarios described in the preceding sections with a new value of R0 reflecting that of B117. The resulting plots are shown in Figure 6 and 7.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9884775281, + "detect_cls":"Body Text", + "detect_score":0.8267956972 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":8, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_8_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 387.0, + 510.0, + 917.0, + 867.0 + ], + "classes":[ + "Figure", + "Body Text", + "Page Header", + "Section Header", + "Equation label", + "Equation", + "Other", + "Figure Caption", + "Table", + "Page Footer", + "Reference text", + "Table Note", + "Abstract", + "Table Caption" + ], + "scores":[ + -0.230891183, + -8.6101913452, + -9.6145172119, + -9.696855545, + -11.7993011475, + -12.3803157806, + -13.7472639084, + -15.1451997757, + -17.5577926636, + -19.1554222107, + -19.2288780212, + -20.2317199707, + -20.316783905, + -22.1437778473 + ], + "content":"", + "postprocess_cls":"Figure", + "postprocess_score":0.9999415874, + "detect_cls":"Figure", + "detect_score":-0.230891183 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":8, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_8_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 888.0, + 1275.0, + 938.0 + ], + "classes":[ + "Figure Caption", + "Page Header", + "Body Text", + "Page Footer", + "Equation label", + "Section Header", + "Other", + "Figure", + "Table Note", + "Table Caption", + "Abstract", + "Reference text", + "Table", + "Equation" + ], + "scores":[ + -1.7880330086, + -6.4670872688, + -9.6256151199, + -12.0806665421, + -12.514913559, + -13.9187374115, + -14.067481041, + -14.9008674622, + -15.2483606339, + -15.6128845215, + -16.4564361572, + -17.050868988, + -17.7882423401, + -18.8692626953 + ], + "content":"Figure 6. Maximum infection against delay in mask enforcement for Scenario 2: SEIR with full compliance and Scenario 3: SEIRS with time-limited immunity for the B117 variant case.", + "postprocess_cls":"Figure Caption", + "postprocess_score":0.999977231, + "detect_cls":"Figure Caption", + "detect_score":-1.7880330086 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":8, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_8_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 388.0, + 963.0, + 931.0, + 1320.0 + ], + "classes":[ + "Figure", + "Body Text", + "Page Header", + "Equation label", + "Equation", + "Page Footer", + "Section Header", + "Other", + "Figure Caption", + "Table", + "Table Note", + "Abstract", + "Table Caption", + "Reference text" + ], + "scores":[ + 0.5181251168, + -10.6063308716, + -10.9858551025, + -11.8891019821, + -13.6827697754, + -14.4328842163, + -14.7260141373, + -15.5658063889, + -16.0109653473, + -16.6873016357, + -19.8755321503, + -22.1069812775, + -22.613193512, + -22.6256523132 + ], + "content":"", + "postprocess_cls":"Figure", + "postprocess_score":0.9999915361, + "detect_cls":"Figure", + "detect_score":0.5181251168 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":8, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_8_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 381.0, + 1344.0, + 1275.0, + 1393.0 + ], + "classes":[ + "Figure Caption", + "Body Text", + "Section Header", + "Figure", + "Page Header", + "Table Caption", + "Abstract", + "Other", + "Page Footer", + "Equation label", + "Table Note", + "Reference text", + "Equation", + "Table" + ], + "scores":[ + -1.8838572502, + -7.2165436745, + -9.0215272903, + -13.0316390991, + -13.7898550034, + -14.0342931747, + -14.1680755615, + -14.3334932327, + -14.9199113846, + -15.0288934708, + -15.3022975922, + -18.7880439758, + -19.1882457733, + -20.1419277191 + ], + "content":"Figure 7. Maximum infection against delay in mask enforcement for Scenario 2: SEIR with gradual noncompliance for the B117 variant case.", + "postprocess_cls":"Figure Caption", + "postprocess_score":0.9999775887, + "detect_cls":"Figure Caption", + "detect_score":-1.8838572502 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":8, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_8_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 382.0, + 1417.0, + 563.0, + 1434.0 + ], + "classes":[ + "Equation label", + "Figure", + "Page Header", + "Section Header", + "Page Footer", + "Body Text", + "Equation", + "Other", + "Figure Caption", + "Reference text", + "Table", + "Table Note", + "Abstract", + "Table Caption" + ], + "scores":[ + -4.6576399803, + -4.7376022339, + -6.2408800125, + -7.512673378, + -8.4140415192, + -8.6492443085, + -9.2616262436, + -10.0734930038, + -11.7521343231, + -12.0373468399, + -12.5049133301, + -14.7412090302, + -15.3036937714, + -15.9025182724 + ], + "content":"6.3. Related Studies", + "postprocess_cls":"Section Header", + "postprocess_score":0.9907457829, + "detect_cls":"Equation label", + "detect_score":-4.6576399803 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":8, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_8_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 1453.0, + 1278.0, + 1791.0 + ], + "classes":[ + "Body Text", + "Abstract", + "Reference text", + "Page Header", + "Figure", + "Page Footer", + "Figure Caption", + "Equation label", + "Section Header", + "Other", + "Table Note", + "Table", + "Table Caption", + "Equation" + ], + "scores":[ + -1.564510107, + -15.4646940231, + -18.0718841553, + -19.3672237396, + -19.6613502502, + -19.7487621307, + -19.8751850128, + -20.4439563751, + -21.5015830994, + -22.3033504486, + -22.9334697723, + -28.0302295685, + -29.1530380249, + -30.0541973114 + ], + "content":"Juxtaposing our study against other similar studies that implement mathematical modelling on 'what-if' scenario based analysis, Eikenberry et al. [3] implemented a com- partmentalized models for their simulations, and concluded that if the population remains unmasked until mask enforcement after some discrete delay, and that the level of adoption is fixed, the delay initially had little impact on the hospitalized fraction or deaths, but states that a 'point of no return' can be crossed. While this study yields similar results to ours, it is contextualised in the US states of New York and Washington, whilst ours was conducted in the context of Singapore. Given the differences in epidemiological parameters, size and characteristics of these cities and Singapore, our study adds value in being a more accurate representation of smaller city states. Furthermore, this study did not take into consideration newer, more infectious strains of the virus such as the B117 variant and time-limited immunity, which we have considered in our study.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9997264743, + "detect_cls":"Body Text", + "detect_score":-1.564510107 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":9, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_9_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Page Header", + "Equation label", + "Body Text", + "Page Footer", + "Figure Caption", + "Section Header", + "Other", + "Reference text", + "Table", + "Figure", + "Table Note", + "Table Caption", + "Equation", + "Abstract" + ], + "scores":[ + -1.4972016811, + -3.5980913639, + -4.1209149361, + -5.4198904037, + -5.8428649902, + -6.1353282928, + -6.3139066696, + -6.4656472206, + -6.7573122978, + -6.9958362579, + -7.8635826111, + -7.8681206703, + -8.9311704636, + -9.2261962891 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 9 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.999494195, + "detect_cls":"Page Header", + "detect_score":-1.4972016811 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":9, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_9_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 224.0, + 1278.0, + 447.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Section Header", + "Page Footer", + "Other", + "Figure Caption", + "Figure", + "Table Note", + "Abstract", + "Reference text", + "Page Header", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + -0.033802636, + -11.9683914185, + -14.2329492569, + -14.8672418594, + -15.9906816483, + -16.032125473, + -16.0714359283, + -16.9485359192, + -16.9835414886, + -17.2661170959, + -17.9673995972, + -22.0706214905, + -25.2780094147, + -25.5011806488 + ], + "content":"Another study done by Tatapudi et al. [26] on the impact assessment of various containment measures, including public masking, contact tracing and stay-home orders revealed that masking was indeed effective in lowering the maximum infected value. The simulation was carried out using Agent-Based modelling, where individual agents were generated from the census data from Florida. This study, like many others mentioned throughout this paper, did not explicitly study the impact of the delay in enforcement of public masking. However, it adds validity to the effectiveness of face masks in controlling the spread of infection, by means of a very different mathematical model.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9984205961, + "detect_cls":"Body Text", + "detect_score":-0.033802636 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":9, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_9_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 475.0, + 1278.0, + 1307.0 + ], + "classes":[ + "Body Text", + "Page Footer", + "Equation label", + "Section Header", + "Reference text", + "Abstract", + "Figure", + "Table Note", + "Page Header", + "Figure Caption", + "Other", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + 0.1184755415, + -16.7590999603, + -17.7536563873, + -18.2873401642, + -18.5310287476, + -19.5538845062, + -19.7386474609, + -20.0910320282, + -20.1675662994, + -20.3564929962, + -20.5363483429, + -28.6993656158, + -28.8846244812, + -29.9321918488 + ], + "content":"6.4. Limitations of the Results We caution against exact quantitative predictions of the development of pandemic that are dependent on a multitude of factors other than universal mask wearing that we have considered here. What we have considered here is the what-if analysis of the effects of implementation of compulsory mask wearing on the dynamics of the pandemic. While the parameters chosen were based on estimates in Singapore's context, one should note that at the time of this writing, these estimates may change as we continue to deepen our understanding of the virus spread. Instead, this work should be interpreted as a numerical representation of the possible outcomes of delaying mask enforcement as a basis for the discussion of the general trends. We further note that, at the time of writing, the actual real-world figures for Maximum Infected Values fall below the ones discussed in this paper. This is due to the fact that we have only examined the policy of compulsory mask wearing in isolation, with minimum consideration of other factors. We expect that any countries or territories that are actively fighting the virus spread to implement an array of varying measures, all of which would collectively reduce the overall spread of the virus. While we acknowledge the limitations due to the rapidly changing nature of the ongoing pandemic and the presence of many contributing factors, some which are difficult to quantify, we cannot resort to waiting for sufficient data to present itself before drawing concrete solutions, as warned by Cheong and Jones [27], if we are to reduce its impact. Analysing the results, as we may intuitively anticipate, given the increased infectivity of the new strain, the Maximum Infected Numbers obtained were of a slightly greater mag- nitude compared to the original model. Surprisingly, we observe the same consistent trend across all the 6 scenarios, comprising a point of inflection beyond which, the effectiveness of public masking is significantly reduced. The key difference to note is that the point of inflection occurs for a smaller value of delay in enforcement, approximately 80 days as opposed to the 100 days of our initial model. Returning to Singapore's context, had the first case of COVID19 in Singapore been infected by the B117 variant, the delay of 89 days before public masking was enforced would have been costly.", + "postprocess_cls":"Body Text", + "postprocess_score":0.9994818568, + "detect_cls":"Body Text", + "detect_score":0.1184755415 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":9, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_9_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 1335.0, + 1278.0, + 1765.0 + ], + "classes":[ + "Body Text", + "Equation label", + "Reference text", + "Section Header", + "Page Footer", + "Figure", + "Page Header", + "Abstract", + "Figure Caption", + "Table Note", + "Other", + "Equation", + "Table", + "Table Caption" + ], + "scores":[ + -0.2975218594, + -10.6768226624, + -12.5905323029, + -13.6149492264, + -14.7963285446, + -15.056353569, + -15.9220352173, + -16.2165737152, + -16.3506851196, + -16.7049598694, + -16.7299537659, + -20.9412307739, + -21.7848720551, + -23.8551197052 + ], + "content":"7. Concluding Remarks At present, compulsory mask wearing has been widely accepted as a means of control- ling COVID-19 infection by reducing the infection rate through aerosol means. With this study, we hope to shed some light on whether the delay in enforcement of compulsory mask wearing will have detrimental effects on infection control when studied in isolation. Based on our results, it appears that a delay of 100 days and above would result in a transition where enforcement of public masking alone would result in little effect on the Maximum Infected Value. We considered 3 scenarios over 2 varied mathematical models. This result is consistent regardless of the level of compliance of the population, or the presence of time-limited immunity. Yet, if implemented early, our model shows that the Maximum Infected Values can be kept relatively low and under control, even after accounting for time-limited immunity and some level of noncompliance. We would like to point out that several studies on the effectiveness of community use of face masks. In one study carried out in the United States [28], the authors compared the percentage change in daily case rates between states enforcing public masking and", + "postprocess_cls":"Body Text", + "postprocess_score":0.9994643331, + "detect_cls":"Body Text", + "detect_score":-0.2975218594 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":10, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_10_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Equation label", + "Page Header", + "Body Text", + "Page Footer", + "Other", + "Table", + "Figure Caption", + "Section Header", + "Reference text", + "Figure", + "Table Note", + "Table Caption", + "Equation", + "Abstract" + ], + "scores":[ + -2.1286184788, + -2.5525627136, + -4.3450174332, + -5.460773468, + -6.0414304733, + -6.0501737595, + -6.8244686127, + -6.8993840218, + -6.9066138268, + -7.2508225441, + -7.6408367157, + -7.8270955086, + -8.0472068787, + -9.397228241 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 10 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.9996505976, + "detect_cls":"Equation label", + "detect_score":-2.1286184788 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":10, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_10_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 380.0, + 224.0, + 1278.0, + 767.0 + ], + "classes":[ + "Reference text", + "Page Footer", + "Other", + "Table Note", + "Abstract", + "Page Header", + "Body Text", + "Figure Caption", + "Section Header", + "Equation label", + "Table", + "Table Caption", + "Equation", + "Figure" + ], + "scores":[ + -4.4792351723, + -5.8750796318, + -9.2634401321, + -10.399969101, + -11.5218334198, + -11.8549585342, + -12.6806316376, + -13.4536104202, + -14.1460351944, + -14.8853416443, + -15.3292512894, + -15.9370336533, + -17.3129253387, + -17.6116294861 + ], + "content":"the states that do not. The results demonstrated that masking was indeed effective in reducing the number of infected cases daily. In their study, the states that enforced public masking did so between 8 April to 15 May 2020, approximately 78 days after the first case was detected in the US. Another study discussed the effectiveness of public masking by comparing countries that enforced public masking (Japan and Thailand) and countries that did not (Spain, Italy, UK, Germany and France) within 30 days after the first case was detected. The result of this study demonstrated that countries in the mask-wearing group had significantly better outcomes in containing the community spread of the virus [29]. These results therefore provide a basis to support our modelling and the conclusion that we have derived as a result of this study. Author Contributions: Conceptualization, D.Y.T.; methodology, D.Y.T.; investigation, B.K.T., J.WW. and C.A.R.; writing—original draft preparation, B.K.T., C.A.R. and J.W.W.; writing—review and editing, D.Y.T.; supervision, D.Y.T. All authors have read and agreed to the published version of the manuscript. Funding: This research received no external funding. Acknowledgments: The authors would like to acknowledge the support from the Singapore Univer- sity of Technology and Design's Undergraduate Research Opportunities Programme (UROP). Conflicts of Interest: The authors declare no conflict of interest.", + "postprocess_cls":"Reference text", + "postprocess_score":0.9100261927, + "detect_cls":"Reference text", + "detect_score":-4.4792351723 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":10, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_10_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 801.0, + 1278.0, + 1746.0 + ], + "classes":[ + "Reference text", + "Table", + "Figure", + "Equation", + "Page Header", + "Other", + "Abstract", + "Page Footer", + "Body Text", + "Section Header", + "Table Caption", + "Equation label", + "Figure Caption", + "Table Note" + ], + "scores":[ + -5.2637338638, + -10.4362211227, + -11.1962451935, + -15.3697137833, + -17.1162986755, + -17.5526657104, + -18.4909000397, + -19.0276966095, + -20.4897994995, + -20.7191085815, + -22.9876289368, + -23.9705295563, + -24.715429306, + -24.7433586121 + ], + "content":"References 1. Lau, J.T.; Tsui, H.; Lau, M.; Yang, X. SARS transmission, risk factors, and prevention in Hong Kong. Emerg. Infect. Dis. 2004, 10, 587. [CrossRef] [PubMed] 2. Wang, C.J.; Ng, C.Y.; Brook, R.H. Response to COVID-19 in Taiwan: Big data analytics, new technology, and proactive testing. JAMA 2020, 323, 1341–1342. [CrossRef] [PubMed] 3. Eikenberry, S.E.; Mancuso, M.; Iboi, E.; Phan, T.; Eikenberry, K.; Kuang, Y.; Kostelich, E.; Gumel, A.B. To mask or not to mask: Modeling the potential for face mask use by the general public to curtail the COVID-19 pandemic. Infect. Dis. Model. 2020, 5, 293–308. [CrossRef] [PubMed] 4. Howard, J.; Huang, A.; Li, Z.; Tufekci, Z.; Zdimal, V.; van der Westhuizen, H.M.; von Delft, A.; Price, A.; Fridman, L.; Tang, L.H.; et al. An evidence review of face masks against COVID-19. Proc. Natl. Acad. Sci. USA 2021, 118, e2014564118. [CrossRef] 5. Lai, J.W.; Cheong, K.H. Superposition of COVID-19 waves, anticipating a sustained wave, and lessons for the future. BioEssays 2020, 42, 2000178. [CrossRef] 6. Cheong, K.H.; Wen, T.; Lai, J.W. Relieving Cost of Epidemic by Parrondo's Paradox: A COVID-19 Case Study. Adv. Sci. 2020, 7, 2002324. [CrossRef] 7. Singh, R.; Adhikari, R. Age-structured impact of social distancing on the COVID-19 epidemic in India. arXiv 2020, arXiv:2003.12055. 8. Babajanyan, S.; Cheong, K.H. Age-structured SIR model and resource growth dynamics: A COVID-19 study. Nonlinear Dyn. 2021, 104, 2853–2864. [CrossRef] [PubMed] 9. Chung, N.N.; Chew, L.Y. Modelling Singapore COVID-19 pandemic with a SEIR multiplex network model. medRxiv 2020. [CrossRef] 10. Kosinski, R.J. The Influence of time-limited immunity on a COVID-19 epidemic: A simulation study. medRxiv 2020. [CrossRef] 11. Ibarrondo, F.J.; Fulcher, J.A.; Goodman-Meza, D.; Elliott, J.; Hofmann, C.; Hausner, M.A.; Ferbas, K.G.; Tobin, N.H.; Aldrovandi, G.M.; Yang, O.O. Rapid decay of anti–SARS-CoV-2 antibodies in persons with mild Covid-19. N. Engl. J. Med. 2020, 383, 1085–1087. [CrossRef] 12. Rodrigues, H.S. Application of SIR epidemiological model: New trends. arXiv 2016, arXiv:1611.02565. 13. Wang, K.; Lu, Z.; Wang, X.; Li, H.; Li, H.; Lin, D.; Cai, Y.; Feng, X.; Song, Y.; Feng, Z.; et al. Current trends and future prediction of novel coronavirus disease (COVID-19) epidemic in China: A dynamical modeling analysis. Math. Biosci. Eng. 2020, 17, 3052–3061. [CrossRef] 14. Mangoni, L.; Pistilli, M. Epidemic Analysis of Covid-19 in Italy by Dynamical Modelling. Available at SSRN 3567770 2020. Available online: https://ssrn.com/abstract=3567770 (accessed on 23 August 2021). 15. Gopal, R.; Chandrasekar, V.; Lakshmanan, M. Dynamical modelling and analysis of COVID-19 in India. arXiv 2020, arXiv:2005.08255. 16. Li, M.Y.; Muldowney, J.S. Global stability for the SEIR model in epidemiology. Math. Biosci. 1995, 125, 155–164. [CrossRef] 17. Zhang, T.; Teng, Z. On a nonautonomous SEIRS model in epidemiology. Bull. Math. Biol. 2007, 69, 2537–2559. [CrossRef] 18. Kai, D.; Goldstein, G.P.; Morgunov, A.; Nangalia, V.; Rotkirch, A. Universal masking is urgent in the covid-19 pandemic: SEIR and agent based models, empirical validation, policy recommendations. arXiv 2020, arXiv:2004.13553. 19. Mitze, T.; Kosfeld, R.; Rode, J.; Wälde, K. Face masks considerably reduce COVID-19 cases in Germany. Proc. Natl. Acad. Sci. USA 2020, 117, 32293–32301. [CrossRef]", + "postprocess_cls":"Reference text", + "postprocess_score":0.9976608753, + "detect_cls":"Reference text", + "detect_score":-5.2637338638 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 122.0, + 1275.0, + 154.0 + ], + "classes":[ + "Page Header", + "Equation label", + "Body Text", + "Page Footer", + "Other", + "Table", + "Figure Caption", + "Section Header", + "Reference text", + "Figure", + "Table Note", + "Table Caption", + "Equation", + "Abstract" + ], + "scores":[ + -2.2996273041, + -2.3671371937, + -4.4680614471, + -5.5041670799, + -6.2934904099, + -6.4199304581, + -6.7679276466, + -6.9881262779, + -7.0698127747, + -7.3234291077, + -7.9510364532, + -8.1306085587, + -8.3906087875, + -9.6790676117 + ], + "content":"Int. J. Environ. Res. Public Health 2021, 18, 9027 11 of 11", + "postprocess_cls":"Page Header", + "postprocess_score":0.9996753931, + "detect_cls":"Page Header", + "detect_score":-2.2996273041 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 130.0, + 225.0, + 1277.0, + 874.0 + ], + "classes":[ + "Body Text", + "Reference text", + "Page Footer", + "Abstract", + "Figure Caption", + "Equation label", + "Table Note", + "Other", + "Figure", + "Section Header", + "Page Header", + "Table", + "Table Caption", + "Equation" + ], + "scores":[ + -4.7601032257, + -9.4670934677, + -10.9610319138, + -11.9751634598, + -14.2404241562, + -15.3232097626, + -15.8145160675, + -16.3493461609, + -16.5256557465, + -17.0123806, + -17.5166454315, + -18.5880489349, + -20.83177948, + -21.2527580261 + ], + "content":"20. Gallaway, M.S.; Rigler, J.; Robinson, S.; Herrick, K.; Livar, E.; Komatsu, K.K.; Brady, S.; Cunico, J.; Christ, C.M. Trends in COVID-19 incidence after implementation of mitigation measures—Arizona, January 22–August 7, 2020. Morb. Mortal. Wkly. Rep. 2020, 69, 1460. [CrossRef] 21. Ong, C.W.M. Position Statement from the National Centre for Infectious Diseases and the Chapter of Infectious Disease Physicians, Academy of Medicine; Period of Infectivity to Inform Strategies for De-isolation for COVID-19 Patients: Singapore, 2020. 22. Lauer, S.A.; Grantz, K.H.; Bi, Q.; Jones, F.K.; Zheng, Q.; Meredith, H.R.; Azman, A.S.; Reich, N.G.; Lessler, J. The incubation period of coronavirus disease 2019 (COVID-19) from publicly reported confirmed cases: Estimation and application. Ann. Intern. Med. 2020, 172, 577–582. [CrossRef] 23. Chew, H.M. 25 COVID-19 Cases with B117 Variant Found in Singapore; MOH: Singapore, 2021. Available online: https://www.channelnewsasia.com/singapore/covid-19-b117-uk-variant-south-africa-singapore-25-cases-440536 (accessed on 29 January 2021). 24. Korber, B.; Fischer, W.M.; Gnanakaran, S.; Yoon, H.; Theiler, J.; Abfalterer, W.; Hengartner, N.; Giorgi, E.E.; Bhattacharya, T.; Foley, B.; et al. Tracking changes in SARS-CoV-2 Spike: Evidence that D614G increases infectivity of the COVID-19 virus. Cell 2020, 182, 812–827. [CrossRef] 25. Volz, E.; Mishra, S.; Chand, M.; Barrett, J.C.; Johnson, R.; Geidelberg, L.; Hinsley, W.R.; Laydon, D.J.; Dabrera, G.; O'Toole, Á.; et al. Assessing transmissibility of SARS-CoV-2 lineage B. 1.1. 7 in England. Nature 2021, 593, 266–269. [CrossRef] 26. Tatapudi, H.; Das, R.; Das, T.K. Impact assessment of full and partial stay-at-home orders, face mask usage, and contact tracing: An agent-based simulation study of COVID-19 for an urban region. Glob. Epidemiol. 2020, 2, 100036. [CrossRef] 27. Cheong, K.H.; Jones, M.C. Introducing the 21st century's new four horsemen of the coronapocalypse. BioEssays 2020, 42, 2000063. [CrossRef] 28. Lyu, W.; Wehby, G.L. Community Use Of Face Masks And COVID-19: Evidence From A Natural Experiment Of State Mandates In The US: Study examines impact on COVID-19 growth rates associated with state government mandates requiring face mask use in public. Health Aff. 2020, 39, 1419–1425. [CrossRef] 29. Li, T.; Liu, Y.; Li, M.; Qian, X.; Dai, S.Y. Mask or no mask for COVID-19: A public health and market study. PLoS ONE 2020, 15, e0237691. [CrossRef]", + "postprocess_cls":"Body Text", + "postprocess_score":0.9981245399, + "detect_cls":"Body Text", + "detect_score":-4.7601032257 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 226.0, + 106.0, + 241.0 + ], + "classes":[ + "Page Footer", + "Section Header", + "Body Text", + "Table Note", + "Table", + "Reference text", + "Other", + "Table Caption", + "Figure Caption", + "Figure", + "Abstract", + "Equation", + "Equation label", + "Page Header" + ], + "scores":[ + -1.851089716, + -10.8925466537, + -11.7394094467, + -11.7497529984, + -12.2353801727, + -12.6273412704, + -12.7355203629, + -13.1808538437, + -15.4802007675, + -16.7650165558, + -17.4654884338, + -18.0173988342, + -18.0899581909, + -18.6022014618 + ], + "content":"20. Gallaway, M.S.; Rigler, J.; Robinson, S.; Herrick, K.; Livar, E.; Komatsu, K.K.; Brady, S.; Cunico, J.; Christ, C.M. Trends in", + "postprocess_cls":"Page Header", + "postprocess_score":0.9084485769, + "detect_cls":"Page Footer", + "detect_score":-1.851089716 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 305.0, + 106.0, + 319.0 + ], + "classes":[ + "Section Header", + "Page Footer", + "Table", + "Table Caption", + "Figure Caption", + "Reference text", + "Figure", + "Body Text", + "Equation label", + "Table Note", + "Page Header", + "Other", + "Abstract", + "Equation" + ], + "scores":[ + -5.4302558899, + -5.7566809654, + -6.1677641869, + -6.598048687, + -6.9456167221, + -7.3625130653, + -7.5950479507, + -7.6754937172, + -7.7477765083, + -8.2904005051, + -9.1980991364, + -9.3429536819, + -10.2163305283, + -10.8249101639 + ], + "content":"21. Ong, C.W.M. Position Statement from the National Centre for Infectious Diseases and the Chapter of Infectious Disease Physicians, Academy", + "postprocess_cls":"Section Header", + "postprocess_score":0.5326701403, + "detect_cls":"Section Header", + "detect_score":-5.4302558899 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 357.0, + 106.0, + 371.0 + ], + "classes":[ + "Page Footer", + "Body Text", + "Section Header", + "Reference text", + "Equation label", + "Figure Caption", + "Table", + "Page Header", + "Figure", + "Other", + "Table Note", + "Table Caption", + "Abstract", + "Equation" + ], + "scores":[ + -6.4768805504, + -6.7679481506, + -7.2823166847, + -8.2708215714, + -8.9002933502, + -9.1431245804, + -9.6290407181, + -10.2670984268, + -10.5139226913, + -11.409579277, + -12.2689943314, + -12.5410804749, + -12.988152504, + -14.3310165405 + ], + "content":"22. Lauer, S.A.; Grantz, K.H.; Bi, Q.; Jones, F.K.; Zheng, Q.; Meredith, H.R.; Azman, A.S.; Reich, N.G.; Lessler, J. The incubation", + "postprocess_cls":"Section Header", + "postprocess_score":0.9309452772, + "detect_cls":"Page Footer", + "detect_score":-6.4768805504 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 436.0, + 106.0, + 450.0 + ], + "classes":[ + "Page Footer", + "Section Header", + "Table", + "Table Caption", + "Reference text", + "Body Text", + "Table Note", + "Figure Caption", + "Other", + "Figure", + "Page Header", + "Equation", + "Abstract", + "Equation label" + ], + "scores":[ + -3.496566534, + -9.5050992966, + -9.7342357635, + -10.2700252533, + -11.2513341904, + -11.5373458862, + -12.158996582, + -12.8558330536, + -14.528758049, + -15.6536645889, + -15.9913797379, + -16.1821022034, + -16.3788452148, + -16.4374637604 + ], + "content":"23. Chew, H.M.", + "postprocess_cls":"Section Header", + "postprocess_score":0.7352595925, + "detect_cls":"Page Footer", + "detect_score":-3.496566534 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 515.0, + 106.0, + 529.0 + ], + "classes":[ + "Page Footer", + "Section Header", + "Table", + "Table Caption", + "Reference text", + "Body Text", + "Table Note", + "Figure Caption", + "Other", + "Figure", + "Page Header", + "Equation", + "Equation label", + "Abstract" + ], + "scores":[ + -2.9842100143, + -8.1079778671, + -10.445807457, + -10.6652832031, + -10.9143419266, + -11.022693634, + -12.1219301224, + -12.1974458694, + -14.2189302444, + -14.3394756317, + -15.2413625717, + -15.5436220169, + -15.5829076767, + -16.182598114 + ], + "content":"24. Korber, B.; Fischer, W.M.; Gnanakaran, S.; Yoon, H.; Theiler, J.; Abfalterer, W.; Hengartner, N.; Giorgi, E.E.; Bhattacharya, T.; Foley,", + "postprocess_cls":"Section Header", + "postprocess_score":0.8648951054, + "detect_cls":"Page Footer", + "detect_score":-2.9842100143 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 593.0, + 106.0, + 608.0 + ], + "classes":[ + "Reference text", + "Page Footer", + "Equation label", + "Page Header", + "Table", + "Figure", + "Section Header", + "Body Text", + "Figure Caption", + "Equation", + "Other", + "Abstract", + "Table Caption", + "Table Note" + ], + "scores":[ + -3.2157504559, + -5.9369740486, + -7.2776136398, + -8.3296689987, + -8.4969367981, + -9.8472499847, + -9.9758882523, + -10.5557136536, + -10.9103212357, + -11.1909446716, + -12.7159738541, + -13.0712471008, + -13.1726398468, + -14.0420751572 + ], + "content":"25. Volz, E.; Mishra, S.; Chand, M.; Barrett, J.C.; Johnson, R.; Geidelberg, L.; Hinsley, W.R.; Laydon, D.J.; Dabrera, G.; O'Toole, Á.; et al.", + "postprocess_cls":"Section Header", + "postprocess_score":0.7926460505, + "detect_cls":"Reference text", + "detect_score":-3.2157504559 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 646.0, + 106.0, + 660.0 + ], + "classes":[ + "Reference text", + "Table", + "Page Footer", + "Figure", + "Equation label", + "Section Header", + "Body Text", + "Page Header", + "Table Caption", + "Figure Caption", + "Table Note", + "Other", + "Equation", + "Abstract" + ], + "scores":[ + -5.1539878845, + -5.3020939827, + -6.9158682823, + -7.072804451, + -7.7035703659, + -7.8148822784, + -8.001584053, + -9.2741355896, + -9.3537960052, + -10.146490097, + -10.2882575989, + -10.3166122437, + -10.6294994354, + -11.5169849396 + ], + "content":"26. Tatapudi, H.; Das, R.; Das, T.K. Impact assessment of full and partial stay-at-home orders, face mask usage, and contact tracing:", + "postprocess_cls":"Page Footer", + "postprocess_score":0.4009010494, + "detect_cls":"Reference text", + "detect_score":-5.1539878845 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 698.0, + 106.0, + 713.0 + ], + "classes":[ + "Reference text", + "Page Footer", + "Table", + "Equation label", + "Figure", + "Section Header", + "Other", + "Equation", + "Body Text", + "Abstract", + "Page Header", + "Table Note", + "Table Caption", + "Figure Caption" + ], + "scores":[ + -3.8052105904, + -5.8814787865, + -6.645819664, + -7.7170886993, + -7.9209699631, + -8.677359581, + -9.5824327469, + -9.9282016754, + -10.7273035049, + -11.025844574, + -11.6131811142, + -11.6515989304, + -11.6976509094, + -12.218706131 + ], + "content":"27. Cheong, K.H.; Jones, M.C. Introducing the 21st century's new four horsemen of the coronapocalypse. BioEssays 2020, 42, 2000063.", + "postprocess_cls":"Section Header", + "postprocess_score":0.4258098304, + "detect_cls":"Reference text", + "detect_score":-3.8052105904 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 751.0, + 106.0, + 765.0 + ], + "classes":[ + "Table", + "Page Footer", + "Reference text", + "Figure", + "Equation label", + "Other", + "Body Text", + "Section Header", + "Table Caption", + "Table Note", + "Equation", + "Abstract", + "Page Header", + "Figure Caption" + ], + "scores":[ + -5.3406186104, + -5.631975174, + -5.8069086075, + -8.7242069244, + -9.6082000732, + -10.5158557892, + -11.0335350037, + -11.4187889099, + -11.4762125015, + -11.7414340973, + -12.0791625977, + -12.2578773499, + -13.2365760803, + -13.7983856201 + ], + "content":"28. Lyu, W.; Wehby, G.L. Community Use Of Face Masks And COVID-19: Evidence From A Natural Experiment Of State Mandates", + "postprocess_cls":"Section Header", + "postprocess_score":0.7025460005, + "detect_cls":"Table", + "detect_score":-5.3406186104 + }, + { + "pdf_name":"ijerp.pdf", + "dataset_id":"ijerp", + "page_num":11, + "img_pth":"/tmp/tmpciodhkjm/ijerp.pdf_11_pad", + "pdf_dims":[ + 0.0, + 0.0, + 595.276, + 841.89 + ], + "bounding_box":[ + 82.0, + 829.0, + 106.0, + 844.0 + ], + "classes":[ + "Page Footer", + "Section Header", + "Body Text", + "Reference text", + "Table", + "Table Caption", + "Table Note", + "Figure Caption", + "Other", + "Figure", + "Equation label", + "Equation", + "Page Header", + "Abstract" + ], + "scores":[ + -3.1696989536, + -8.4708032608, + -11.0811958313, + -11.2829618454, + -11.8613004684, + -12.4573526382, + -12.8267974854, + -14.4768972397, + -14.9625282288, + -15.8552246094, + -16.0115203857, + -16.6108016968, + -16.9140644073, + -17.5206813812 + ], + "content":"29. Li, T.; Liu, Y.; Li, M.; Qian, X.; Dai, S.Y. Mask or no mask for COVID-19: A public health and market study. PLoS ONE 2020,", + "postprocess_cls":"Section Header", + "postprocess_score":0.7363973856, + "detect_cls":"Page Footer", + "detect_score":-3.1696989536 + } +] \ No newline at end of file diff --git a/tests/test_code_to_amr/test_code_to_amr.py b/tests/test_code_to_amr/test_code_to_amr.py deleted file mode 100644 index 51561a7..0000000 --- a/tests/test_code_to_amr/test_code_to_amr.py +++ /dev/null @@ -1,179 +0,0 @@ -import json -from unittest.mock import Mock, patch -import os -import requests -import sys - -import logging - -logger = logging.getLogger(__name__) - -from tests.test_utils import AMR - -sys.path.append(os.path.join(os.path.dirname(__file__), "../..", "workers")) - -# Create a test application -from fastapi.testclient import TestClient -from api.server import app - -client = TestClient(app) - -# Create a fake redis server and a fake redis instance -from fakeredis import FakeStrictRedis -from rq import Queue - -queue = Queue(is_async=False, connection=FakeStrictRedis()) - -live = os.environ.get("LIVE", "FALSE") - -############################## -##### The mock responses ##### -############################## - -# Mock the TDS artifact -mock_tds_artifact = Mock() -artifact_id = "artifact-123" -artifact = { - "id": artifact_id, - "name": "code", - "description": "test code", - "timestamp": "2023-07-17T19:11:43", - "file_names": ["code.py"], - "metadata": {}, -} -mock_tds_artifact.json.return_value = artifact -mock_tds_artifact.text = json.dumps(artifact) -mock_tds_artifact.status_code = 200 - -# Mock the pre-signed download URL -mock_presigned_download_url = Mock() -mock_presigned_download_url.json.return_value = { - "url": "http://localhost:1000", - "method": "GET", -} - -# Mock the downloaded code -mock_code = Mock() -mock_code.content = open("tests/test_code_to_amr/code.py").read().encode() -mock_code.status_code = 200 - -mock_ta1_response = Mock() -amr = json.loads(open("tests/test_code_to_amr/amr.json").read()) -mock_ta1_response.json.return_value = amr -mock_ta1_response.text = json.dumps(amr) -mock_ta1_response.status_code = 200 - -# Note: this mock response is used for both POSTs -# made by TDS including a POST to /models and to /model_configurations -model_id = 123 -mock_tds_response = Mock() -tds_response = {"id": model_id} -mock_tds_response.json.return_value = tds_response -mock_tds_response.status_code = 200 - -# Mock the TDS artifact -mock_updated_tds_artifact = Mock() -artifact = { - "id": artifact_id, - "name": "code", - "description": "test code", - "timestamp": "2023-07-17T19:11:43", - "file_names": ["code.py"], - "metadata": {"model_id": model_id}, -} -mock_updated_tds_artifact.json.return_value = artifact -mock_updated_tds_artifact.text = json.dumps(artifact) -mock_updated_tds_artifact.status_code = 200 - - -####################################### -##### Setup for Integration Tests ##### -####################################### - -original_post = requests.post - - -def decide_post_response(*args, **kwargs): - """ - This function redefines `requests.post` and optionally allows for overrides - to be sent out (e.g. to TA1 live service) for true integration testing. - """ - url = args[0] # Assuming the first argument to requests.post is the URL - if "tds" in url: - logger.info("Mocking response from TDS") - return mock_tds_response - if "ta1" in url and live == "FALSE": - logger.info("Mocking response from TA1") - return mock_ta1_response - elif live == "TRUE": - logger.info("Sending request to LIVE TA1 Service") - return original_post(*args, **kwargs) # Call the original - - -####################################### -############## Run Tests ############## -####################################### - - -# Note that the patches have to be in reverse order of the -# test function arguments -@patch("requests.put") # patch anytime a PUT is made -@patch( - "requests.post", side_effect=decide_post_response -) # patch anytime a POST is made -@patch("api.utils.get_queue", return_value=queue) # mock the redis queue -def test_code_to_amr(mock_queue, mock_post, mock_put): - # Added patch on requests.get internal to the function via a `with` - # so we can end the patch prior to validating the AMR response - # in the event we are running LIVE - with patch("requests.get") as mock_get: # patch anytime a GET is made - # response from TDS for artifact - # response from TDS for presigned URL - # response from S3 to pull down the code file - mock_get.side_effect = [ - mock_tds_artifact, - mock_presigned_download_url, - mock_code, - ] - - # response from TDS after updating artifact - mock_put.side_effect = [mock_updated_tds_artifact] - - # Define the query parameters - query_params = { - "artifact_id": artifact_id, - "name": "test model", - "description": "test description", - } - - # Call the endpoint - response = client.post( - "/code_to_amr", - params=query_params, - headers={"Content-Type": "application/json"}, - ) - results = response.json() - - # Assert the status code and response - assert response.status_code == 200 - assert results.get("status") == "finished", results.get("result", {}).get( - "job_error" - ) - assert results.get("result", {}).get("job_error") == None - - if live == "FALSE": - assert results.get("result", {}).get("job_result") == { - "status_code": 200, - "amr": amr, - "tds_model_id": tds_response.get("id"), - "tds_configuration_id": tds_response.get("id"), - "error": None, - } - - # If testing live, we focus on validating the AMR against its provided JSON Schema - elif live == "TRUE": - result_amr = results.get("result", {}).get("job_result", {}).get("amr", None) - amr_instance = AMR(result_amr) - assert ( - amr_instance.is_valid() - ), f"AMR failed to validate to its provided schema: {amr_instance.get_validation_error()}" diff --git a/tests/test_e2e.py b/tests/test_e2e.py new file mode 100644 index 0000000..c42b7db --- /dev/null +++ b/tests/test_e2e.py @@ -0,0 +1,255 @@ +import json +import os +import requests + +import pytest +import logging + +from lib.settings import settings + +logger = logging.getLogger(__name__) + +@pytest.mark.resource("basic_pdf_extraction") +def test_pdf_extractions(context_dir, http_mock, client, worker, gen_tds_artifact, file_storage): + #### ARRANGE #### + text_json = json.load(open(f"{context_dir}/text.json")) + text = "" + for d in text_json: + text += f"{d['content']}\n" + tds_artifact = gen_tds_artifact() + tds_artifact["file_names"] = ["paper.pdf"] + tds_artifact["metadata"] = {"text": text} + file_storage.upload("paper.pdf", "TEST TEXT") + + extractions = json.load(open(f"{context_dir}/extractions.json")) + if not settings.LIVE: + http_mock.post(f"{settings.TA1_UNIFIED_URL}/text-reading/integrated-text-extractions?annotate_skema=True&annotate_mit=True", json=extractions) + + query_params = { + "artifact_id": tds_artifact["id"], + "annotate_skema": True, + "annotate_mit": True, + "name": None, + "description": None, + } + + #### ACT #### + response = client.post( + "/pdf_extractions", + params=query_params, + headers={"Content-Type": "application/json"}, + ) + results = response.json() + job_id = results.get("id") + worker.work(burst=True) + status_response = client.get(f"/status/{job_id}") + + #### ASSERT #### + assert results.get("status") == "queued" + assert status_response.status_code == 200 + assert status_response.json().get("status") == "finished" + + +@pytest.mark.resource("basic_pdf_to_text") +def test_pdf_to_text(context_dir, http_mock, client, worker, gen_tds_artifact, file_storage): + #### ARRANGE #### + text_json = json.load(open(f"{context_dir}/text.json")) + text = "" + for d in text_json: + text += f"{d['content']}\n" + tds_artifact = gen_tds_artifact() + tds_artifact["file_names"] = ["paper.pdf"] + file_storage.upload("paper.pdf", "TEST TEXT") + + query_params = { + "artifact_id": tds_artifact["id"], + } + + extractions = json.load(open(f"{context_dir}/text.json")) + if not settings.LIVE: + http_mock.post(f"{settings.TA1_UNIFIED_URL}/text-reading/cosmos_to_json", json=extractions) + + #### ACT #### + response = client.post( + "/pdf_to_text", + params=query_params, + headers={"Content-Type": "application/json"}, + ) + results = response.json() + job_id = results.get("id") + worker.work(burst=True) + status_response = client.get(f"/status/{job_id}") + + #### ASSERT #### + assert results.get("status") == "queued" + assert status_response.status_code == 200 + assert status_response.json().get("status") == "finished" + + +@pytest.mark.resource("basic_code_to_amr") +def test_code_to_amr(context_dir, http_mock, client, worker, gen_tds_artifact, file_storage): + #### ARRANGE #### + code = open(f"{context_dir}/code.py").read() + tds_artifact = gen_tds_artifact() + tds_artifact["file_names"] = ["code.py"] + file_storage.upload("code.py", code) + + query_params = { + "artifact_id": tds_artifact["id"], + "name": "test model", + "description": "test description", + } + + amr = json.load(open(f"{context_dir}/amr.json")) + http_mock.post(f"{settings.TDS_URL}/provenance", json={}) + http_mock.post(f"{settings.TDS_URL}/models", json={"id": "test"}) + http_mock.post(f"{settings.TDS_URL}/model_configurations", json={"id": "test"}) + if not settings.LIVE: + http_mock.post(f"{settings.TA1_UNIFIED_URL}/workflows/code/snippets-to-pn-amr", json=amr) + + #### ACT #### + response = client.post( + "/code_to_amr", + params=query_params, + headers={"Content-Type": "application/json"}, + ) + results = response.json() + job_id = results.get("id") + worker.work(burst=True) + status_response = client.get(f"/status/{job_id}") + + #### ASSERT #### + assert results.get("status") == "queued" + assert status_response.status_code == 200 + assert status_response.json().get("status") == "finished" + + +@pytest.mark.resource("basic_equations_to_amr") +def test_equations_to_amr(context_dir, http_mock, client, worker, file_storage): + #### ARRANGE #### + equations = open(f"{context_dir}/equations.txt").read() + + query_params = { + "equation_type": "latex", + "model": "petrinet", + "name": "test model", + "description": "test description", + } + + + amr = json.load(open(f"{context_dir}/amr.json")) + http_mock.post(f"{settings.TDS_URL}/models", json={"id": "test"}) + http_mock.post(f"{settings.TDS_URL}/model_configurations", json={"id": "test"}) + if not settings.LIVE: + http_mock.post(f"{settings.TA1_UNIFIED_URL}/workflows/latex/equations-to-amr", json=amr) + + #### ACT #### + response = client.post( + "/equations_to_amr", + params=query_params, + data=equations, + headers={"Content-Type": "application/json"}, + ) + results = response.json() + job_id = results.get("id") + worker.work(burst=True) + status_response = client.get(f"/status/{job_id}") + + #### ASSERT #### + assert results.get("status") == "queued" + assert status_response.status_code == 200 + assert status_response.json().get("status") == "finished" + + +@pytest.mark.resource("basic_profile_dataset") +def test_profile_dataset(context_dir, http_mock, client, worker, gen_tds_artifact, file_storage): + #### ARRANGE #### + CHAR_LIMIT = 250 + text_json = json.load(open(f"{context_dir}/text.json")) + text = "" + for d in text_json: + text += f"{d['content']}\n" + tds_artifact = gen_tds_artifact() + tds_artifact["file_names"] = ["paper.pdf"] + tds_artifact["metadata"] = {"text": text[:CHAR_LIMIT]} + query_params = { + "artifact_id": tds_artifact["id"], + } + csvfile = open(f"{context_dir}/data.csv").read() + file_storage.upload("paper.pdf", "TEST TEXT") + file_storage.upload("data.csv", csvfile) + + + dataset = { + "id": tds_artifact["id"], + "name": "data", + "description": "test data", + "timestamp": "2023-07-17T19:11:43", + "file_names": ["data.csv"], + "metadata": {}, + } + http_mock.get(f"{settings.TDS_URL}/datasets/{dataset['id']}", json=dataset) + http_mock.put(f"{settings.TDS_URL}/datasets/{dataset['id']}", json={"id": dataset["id"]}) + data_card = json.load(open(f"{context_dir}/data_card.json")) + if not settings.LIVE: + http_mock.post(f"{settings.MIT_TR_URL}/cards/get_data_card", json=data_card) + + #### ACT #### + response = client.post( + f"/profile_dataset/{tds_artifact['id']}", + params=query_params, + headers={"Content-Type": "application/json"}, + ) + results = response.json() + job_id = results.get("id") + worker.work(burst=True) + status_response = client.get(f"/status/{job_id}") + + #### ASSERT #### + assert results.get("status") == "queued" + assert status_response.status_code == 200 + assert status_response.json().get("status") == "finished" + + +@pytest.mark.resource("basic_profile_model") +def test_profile_model(context_dir, http_mock, client, worker, gen_tds_artifact, file_storage): + #### ARRANGE #### + text_json = json.load(open(f"{context_dir}/text.json")) + text = "" + for d in text_json: + text += f"{d['content']}\n" + text_artifact = gen_tds_artifact() + text_artifact["file_names"] = ["paper.pdf"] + text_artifact["metadata"] = {"text": text} + file_storage.upload("paper.pdf", "TEST TEXT") + + code = open(f"{context_dir}/code.py").read() + code_artifact = gen_tds_artifact() + code_artifact["file_names"] = ["code.py"] + file_storage.upload("code.py", code) + + amr = json.load(open(f"{context_dir}/amr.json")) + http_mock.post(f"{settings.TDS_URL}/provenance/search?search_type=models_from_code", json={"result": [text_artifact["id"]]}) + http_mock.get(f"{settings.TDS_URL}/models/{text_artifact['id']}", json={"id":text_artifact["id"], "model": amr}) + http_mock.put(f"{settings.TDS_URL}/models/{text_artifact['id']}", json={"id": text_artifact["id"]}) + model_card = json.load(open(f"{context_dir}/model_card.json")) + if not settings.LIVE: + http_mock.post(f"{settings.MIT_TR_URL}/cards/get_model_card", json=model_card) + + query_params = {"paper_artifact_id": text_artifact["id"]} + + #### ACT #### + response = client.post( + f"/profile_model/{text_artifact['id']}", + params=query_params, + headers={"Content-Type": "application/json"}, + ) + results = response.json() + job_id = results.get("id") + worker.work(burst=True) + status_response = client.get(f"/status/{job_id}") + + #### ASSERT #### + assert results.get("status") == "queued" + assert status_response.status_code == 200 + assert status_response.json().get("status") == "finished" diff --git a/tests/test_equations_to_amr/test_equations_to_amr.py b/tests/test_equations_to_amr/test_equations_to_amr.py deleted file mode 100644 index 9dff716..0000000 --- a/tests/test_equations_to_amr/test_equations_to_amr.py +++ /dev/null @@ -1,124 +0,0 @@ -import json -from unittest.mock import Mock, patch -import requests -import os -import sys - -import logging - -logger = logging.getLogger(__name__) - -from tests.test_utils import AMR - -sys.path.append(os.path.join(os.path.dirname(__file__), "../..", "workers")) - -# Create a test application -from fastapi.testclient import TestClient -from api.server import app - -client = TestClient(app) - -# Create a fake redis server and a fake redis instance -from fakeredis import FakeStrictRedis -from rq import Queue - -queue = Queue(is_async=False, connection=FakeStrictRedis()) - -live = os.environ.get("LIVE", "FALSE") - -############################## -##### The mock responses ##### -############################## - -mock_ta1_response = Mock() -amr = json.loads(open("tests/test_equations_to_amr/amr.json").read()) -mock_ta1_response.json.return_value = amr -mock_ta1_response.text = json.dumps(amr) -mock_ta1_response.status_code = 200 - -# Note: this mock response is used for both POSTs -# made by TDS including a POST to /models and to /model_configurations -mock_tds_response = Mock() -tds_response = {"id": "123"} -mock_tds_response.json.return_value = tds_response -mock_tds_response.status_code = 200 - -####################################### -##### Setup for Integration Tests ##### -####################################### - -original_post = requests.post - - -def decide_post_response(*args, **kwargs): - """ - This function redefines `requests.post` and optionally allows for overrides - to be sent out (e.g. to TA1 live service) for true integration testing. - """ - url = args[0] # Assuming the first argument to requests.post is the URL - if "tds" in url: - logger.info("Mocking response from TDS") - return mock_tds_response - if "ta1" in url: - logger.info("Mocking response from TA1") - return mock_ta1_response - elif live == "TRUE": - logger.info("Sending request to LIVE TA1 Service") - return original_post(*args, **kwargs) # Call the original - - -####################################### -############## Run Tests ############## -####################################### - - -# Note that the patches have to be in reverse order of the -# test function arguments -@patch( - "requests.post", side_effect=decide_post_response -) # patch anytime a POST is made -@patch("api.utils.get_queue", return_value=queue) # mock the redis queue -def test_equations_to_amr(mock_queue, mock_post): - # The endpoint parameters - payload = open("tests/test_equations_to_amr/equations.txt").read() - - # Define the query parameters - query_params = { - "equation_type": "latex", - "model": "petrinet", - "name": "test model", - "description": "test description", - } - - # Call the endpoint - response = client.post( - "/equations_to_amr", - params=query_params, - data=payload, - headers={"Content-Type": "application/json"}, - ) - results = response.json() - - # Assert the status code and response - assert response.status_code == 200 - assert results.get("status") == "finished", results.get("result", {}).get( - "job_error" - ) - assert results.get("result", {}).get("job_error") == None - - if live == "FALSE": - assert results.get("result", {}).get("job_result") == { - "status_code": 200, - "amr": amr, - "tds_model_id": tds_response.get("id"), - "tds_configuration_id": tds_response.get("id"), - "error": None, - } - - # If testing live, we focus on validating the AMR against its provided JSON Schema - elif live == "TRUE": - result_amr = results.get("result", {}).get("job_result", {}).get("amr", None) - amr_instance = AMR(result_amr) - assert ( - amr_instance.is_valid() - ), f"AMR failed to validate to its provided schema: {amr_instance.get_validation_error()}" diff --git a/tests/test_pdf_extractions/test_pdf_extractions.py b/tests/test_pdf_extractions/test_pdf_extractions.py deleted file mode 100644 index ec82cdb..0000000 --- a/tests/test_pdf_extractions/test_pdf_extractions.py +++ /dev/null @@ -1,144 +0,0 @@ -import json -from unittest.mock import Mock, patch -import os -import requests -import sys - -import logging - -logger = logging.getLogger(__name__) - -sys.path.append(os.path.join(os.path.dirname(__file__), "../..", "workers")) - -# Create a test application -from fastapi.testclient import TestClient -from api.server import app - -client = TestClient(app) - -# Create a fake redis server and a fake redis instance -from fakeredis import FakeStrictRedis -from rq import Queue - -queue = Queue(is_async=False, connection=FakeStrictRedis()) - -live = os.environ.get("LIVE", "FALSE") - -############################## -##### The mock responses ##### -############################## - -text_json = json.loads(open("tests/test_pdf_extractions/text.json").read()) -text = "" -for d in text_json: - text += f"{d['content']}\n" - -# Mock the TDS artifact -mock_tds_artifact = Mock() -artifact_id = "artifact-123" -artifact = { - "id": artifact_id, - "name": "paper", - "description": "test paper", - "timestamp": "2023-07-17T19:11:43", - "file_names": ["paper.pdf"], - "metadata": {"text": text}, -} -mock_tds_artifact.json.return_value = artifact -mock_tds_artifact.text = json.dumps(artifact) -mock_tds_artifact.status_code = 200 - -# Mock the pre-signed download URL -mock_presigned_download_url = Mock() -mock_presigned_download_url.json.return_value = { - "url": "http://localhost:1000", - "method": "GET", -} - -# Mock the downloaded paper -mock_paper = Mock() -mock_paper.content = "some encoded PDF content goes here".encode() -mock_paper.status_code = 200 - -mock_ta1_response = Mock() -extractions = json.loads(open("tests/test_pdf_extractions/extractions.json").read()) -mock_ta1_response.json.return_value = extractions -mock_ta1_response.text = json.dumps(extractions) -mock_ta1_response.status_code = 200 - -# Mock the TDS artifact -mock_updated_tds_artifact = Mock() -ex = extractions["outputs"][0]["data"] -ex["text"] = text -artifact["metadata"] = ex -mock_updated_tds_artifact.json.return_value = artifact -mock_updated_tds_artifact.text = json.dumps(artifact) -mock_updated_tds_artifact.status_code = 200 - -####################################### -##### Setup for Integration Tests ##### -####################################### - -original_post = requests.post - - -def decide_post_response(*args, **kwargs): - """ - This function redefines `requests.post` and optionally allows for overrides - to be sent out (e.g. to TA1 live service) for true integration testing. - """ - url = args[0] # Assuming the first argument to requests.post is the URL - if "ta1" in url: - logger.info("Mocking response from TA1") - return mock_ta1_response - elif live == "TRUE": - logger.info("Sending request to LIVE TA1 Service") - return original_post(*args, **kwargs) # Call the original - - -# Note that the patches have to be in reverse order of the -# test function arguments -@patch("requests.put") # patch anytime a PUT is made -@patch("requests.get") # patch anytime a GET is made -@patch( - "requests.post", side_effect=decide_post_response -) # patch anytime a POST is made -@patch("api.utils.get_queue", return_value=queue) # mock the redis queue -def test_pdf_extractions(mock_queue, mock_post, mock_get, mock_put): - # Mock all gets with side effects - mock_get.side_effect = [mock_tds_artifact, mock_presigned_download_url, mock_paper] - - # Mock all puts with side effects - mock_put.side_effect = [mock_updated_tds_artifact] - - # Define the query parameters - query_params = { - "artifact_id": artifact_id, - "annotate_skema": True, - "annotate_mit": True, - "name": None, - "description": None, - } - - # Call the endpoint - response = client.post( - "/pdf_extractions", - params=query_params, - headers={"Content-Type": "application/json"}, - ) - results = response.json() - - # Assert the status code and response - assert response.status_code == 200 - assert results.get("status") == "finished", results.get("result", {}).get( - "job_error" - ) - assert results.get("result", {}).get("job_error") == None - - if live == "FALSE": - assert results.get("result", {}).get("job_result") == { - "extraction_status_code": mock_ta1_response.status_code, - "extraction": [extractions["outputs"][0]["data"]], - "tds_status_code": mock_updated_tds_artifact.status_code, - "error": None, - } diff --git a/tests/test_pdf_to_text/test_pdf_to_text.py b/tests/test_pdf_to_text/test_pdf_to_text.py deleted file mode 100644 index c4723f6..0000000 --- a/tests/test_pdf_to_text/test_pdf_to_text.py +++ /dev/null @@ -1,129 +0,0 @@ -import json -from unittest.mock import Mock, patch -import os -import requests -import sys - -import logging - -logger = logging.getLogger(__name__) - -sys.path.append(os.path.join(os.path.dirname(__file__), "../..", "workers")) - -# Create a test application -from fastapi.testclient import TestClient -from api.server import app - -client = TestClient(app) - -# Create a fake redis server and a fake redis instance -from fakeredis import FakeStrictRedis -from rq import Queue - -queue = Queue(is_async=False, connection=FakeStrictRedis()) - -live = os.environ.get("LIVE", "FALSE") - -############################## -##### The mock responses ##### -############################## - -# Mock the TDS artifact -mock_tds_artifact = Mock() -artifact_id = "artifact-123" -artifact = { - "id": artifact_id, - "name": "paper", - "description": "test paper", - "timestamp": "2023-07-17T19:11:43", - "file_names": ["paper.pdf"], - "metadata": {}, -} -mock_tds_artifact.json.return_value = artifact -mock_tds_artifact.text = json.dumps(artifact) -mock_tds_artifact.status_code = 200 - -# Mock the pre-signed download URL -mock_presigned_download_url = Mock() -mock_presigned_download_url.json.return_value = { - "url": "http://localhost:1000", - "method": "GET", -} - -# Mock the downloaded code -mock_paper = Mock() -mock_paper.content = "some encoded PDF content goes here".encode() -mock_paper.status_code = 200 - -mock_ta1_response = Mock() -text = json.loads(open("tests/test_pdf_to_text/text.json").read()) -mock_ta1_response.json.return_value = text -mock_ta1_response.text = json.dumps(text) -mock_ta1_response.status_code = 200 - -# Mock the TDS artifact -mock_updated_tds_artifact = Mock() -artifact["metadata"] = {"text": "extracted pdf text content here"} -mock_updated_tds_artifact.json.return_value = artifact -mock_updated_tds_artifact.text = json.dumps(artifact) -mock_updated_tds_artifact.status_code = 200 - - -####################################### -##### Setup for Integration Tests ##### -####################################### - -original_post = requests.post - - -def decide_post_response(*args, **kwargs): - """ - This function redefines `requests.post` and optionally allows for overrides - to be sent out (e.g. to TA1 live service) for true integration testing. - """ - url = args[0] # Assuming the first argument to requests.post is the URL - if "ta1" in url: - logger.info("Mocking response from TA1") - return mock_ta1_response - elif live == "TRUE": - logger.info("Sending request to LIVE TA1 Service") - return original_post(*args, **kwargs) # Call the original - - -# Note that the patches have to be in reverse order of the -# test function arguments -@patch("requests.put") # patch anytime a PUT is made -@patch("requests.get") # patch anytime a GET is made -@patch( - "requests.post", side_effect=decide_post_response -) # patch anytime a POST is made -@patch("api.utils.get_queue", return_value=queue) # mock the redis queue -def test_pdf_to_text(mock_queue, mock_post, mock_get, mock_put): - # Mock all gets with side effects - mock_get.side_effect = [mock_tds_artifact, mock_presigned_download_url, mock_paper] - - # Mock all puts with side effects - mock_put.side_effect = [mock_updated_tds_artifact] - - # Define the query parameters - query_params = {"artifact_id": artifact_id} - - # Call the endpoint - response = client.post( - "/pdf_to_text", - params=query_params, - headers={"Content-Type": "application/json"}, - ) - results = response.json() - - # Assert the status code and response - assert response.status_code == 200 - assert results.get("status") == "finished" - assert results.get("job_error") == None - - if live == "FALSE": - assert results.get("result", {}).get("job_result") == { - "extraction_status_code": mock_ta1_response.status_code, - "extraction": mock_ta1_response.json(), - "tds_status_code": mock_updated_tds_artifact.status_code, - } diff --git a/tests/test_profile_dataset/test_profile_dataset.py b/tests/test_profile_dataset/test_profile_dataset.py deleted file mode 100644 index cadb235..0000000 --- a/tests/test_profile_dataset/test_profile_dataset.py +++ /dev/null @@ -1,168 +0,0 @@ -import json -from unittest.mock import Mock, patch -import os -import requests -import sys - -import logging - -logger = logging.getLogger(__name__) - -from tests.test_utils import AMR - -sys.path.append(os.path.join(os.path.dirname(__file__), "../..", "workers")) - -# Create a test application -from fastapi.testclient import TestClient -from api.server import app - -client = TestClient(app) - -# Create a fake redis server and a fake redis instance -from fakeredis import FakeStrictRedis -from rq import Queue - -queue = Queue(is_async=False, connection=FakeStrictRedis()) - -live = os.environ.get("LIVE", "FALSE") - -############################## -##### The mock responses ##### -############################## - -char_limit = 250 - -# Mock the TDS document/paper artifact -text_json = json.loads(open("tests/test_pdf_extractions/text.json").read()) -text = "" -for d in text_json: - text += f"{d['content']}\n" - -mock_tds_artifact = Mock() -artifact_id = "artifact-paper-123" -artifact = { - "id": artifact_id, - "name": "paper", - "description": "test paper", - "timestamp": "2023-07-17T19:11:43", - "file_names": ["paper.pdf"], - "metadata": {"text": text[:char_limit]}, -} -mock_tds_artifact.json.return_value = artifact -mock_tds_artifact.text = json.dumps(artifact) -mock_tds_artifact.status_code = 200 - -# Mock the pre-signed download URL -mock_presigned_download_url = Mock() -mock_presigned_download_url.json.return_value = { - "url": "http://localhost:1000", - "method": "GET", -} - -# Mock the TDS dataset artifact -mock_tds_dataset = Mock() -dataset_id = "artifact-dataset-123" -dataset = { - "id": dataset_id, - "name": "data", - "description": "test data", - "timestamp": "2023-07-17T19:11:43", - "file_names": ["data.csv"], - "metadata": {}, -} -mock_tds_dataset.json.return_value = dataset -mock_tds_dataset.text = json.dumps(dataset) -mock_tds_dataset.status_code = 200 - -# Mock the downloaded data -mock_data = Mock() -mock_data.content = open("tests/test_profile_dataset/data.csv").read().encode() -mock_data.status_code = 200 - -# Mock the downloaded code -mock_paper = Mock() -mock_paper.content = "some encoded PDF content goes here".encode() -mock_paper.status_code = 200 - -mock_ta1_response = Mock() -data_card = json.loads(open("tests/test_profile_dataset/data_card.json").read()) -mock_ta1_response.json.return_value = data_card -mock_ta1_response.text = json.dumps(data_card) -mock_ta1_response.status_code = 200 - -# Mock the updated TDS dataset artifact -mock_tds_dataset_update_put = Mock() -tds_response = {"id": dataset_id} -mock_tds_dataset_update_put.json.return_value = tds_response -mock_tds_dataset_update_put.text = json.dumps(tds_response) -mock_tds_dataset_update_put.status_code = 200 - - -####################################### -##### Setup for Integration Tests ##### -####################################### - -original_post = requests.post - - -def decide_post_response(*args, **kwargs): - """ - This function redefines `requests.post` and optionally allows for overrides - to be sent out (e.g. to TA1 live service) for true integration testing. - """ - url = args[0] # Assuming the first argument to requests.post is the URL - if "mit" in url and live == "FALSE": - logger.info("Mocking response from TA1") - return mock_ta1_response - elif live == "TRUE": - logger.info("Sending request to LIVE TA1 Service") - return original_post(*args, **kwargs) # Call the original - - -####################################### -############## Run Tests ############## -####################################### - - -# Note that the patches have to be in reverse order of the -# test function arguments -@patch("requests.get") # patch anytime a GET is made -@patch("requests.put") # patch anytime a PUT is made -@patch( - "requests.post", side_effect=decide_post_response -) # patch anytime a POST is made -@patch("api.utils.get_queue", return_value=queue) # mock the redis queue -def test_profile_dataset(mock_queue, mock_post, mock_put, mock_get): - logging.info( - f"Testing with {char_limit} set on the document submission to avoid context overruns with the LLM" - ) - - mock_get.side_effect = [ - mock_tds_artifact, - mock_presigned_download_url, - mock_paper, - mock_tds_dataset, - mock_presigned_download_url, - mock_data, - ] - - # response from TDS after updating artifact - mock_put.side_effect = [mock_tds_dataset_update_put] - - # Define the query parameters - query_params = {"artifact_id": artifact_id} - - # Call the endpoint - response = client.post("/profile_dataset/{dataset_id}", params=query_params) - results = response.json() - - # Assert the status code and response - assert response.status_code == 200 - assert results.get("status") == "finished", results.get("result", {}).get( - "job_error" - ) - assert results.get("result", {}).get("job_error") == None - assert ( - results.get("result", {}).get("job_result", {}).get("message", None) - == "Data card generated and updated in TDS" - ) diff --git a/tests/test_profile_model/test_profile_model.py b/tests/test_profile_model/test_profile_model.py deleted file mode 100644 index bd1dce4..0000000 --- a/tests/test_profile_model/test_profile_model.py +++ /dev/null @@ -1,191 +0,0 @@ -import json -from unittest.mock import Mock, patch -import os -import requests -import sys - -import logging - -logger = logging.getLogger(__name__) - -from tests.test_utils import AMR - -sys.path.append(os.path.join(os.path.dirname(__file__), "../..", "workers")) - -# Create a test application -from fastapi.testclient import TestClient -from api.server import app - -client = TestClient(app) - -# Create a fake redis server and a fake redis instance -from fakeredis import FakeStrictRedis -from rq import Queue - -queue = Queue(is_async=False, connection=FakeStrictRedis()) - -live = os.environ.get("LIVE", "FALSE") - -############################## -##### The mock responses ##### -############################## - -char_limit = 250 - -# Mock the TDS document/paper artifact -text_json = json.loads(open("tests/test_pdf_extractions/text.json").read()) -text = "" -for d in text_json: - text += f"{d['content']}\n" - -mock_tds_paper_artifact = Mock() -artifact_id = "artifact-paper-123" -artifact = { - "id": artifact_id, - "name": "paper", - "description": "test paper", - "timestamp": "2023-07-17T19:11:43", - "file_names": ["paper.pdf"], - "metadata": {"text": text[:char_limit]}, -} -mock_tds_paper_artifact.json.return_value = artifact -mock_tds_paper_artifact.text = json.dumps(artifact) -mock_tds_paper_artifact.status_code = 200 - -# Mock the pre-signed download URL -mock_presigned_download_url = Mock() -mock_presigned_download_url.json.return_value = { - "url": "http://localhost:1000", - "method": "GET", -} - -# Mock the TDS dataset artifact -mock_tds_code_artifact = Mock() -code_id = "artifact-code-123" -code_artifact = { - "id": code_id, - "name": "code", - "description": "test code", - "timestamp": "2023-07-17T19:11:43", - "file_names": ["code.py"], - "metadata": {}, -} -mock_tds_code_artifact.json.return_value = code_artifact -mock_tds_code_artifact.text = json.dumps(code_artifact) -mock_tds_code_artifact.status_code = 200 - -# Mock the downloaded code -mock_code = Mock() -mock_code.content = open("tests/test_code_to_amr/code.py").read().encode() -mock_code.status_code = 200 - -# Mock the downloaded data -mock_data = Mock() -mock_data.content = open("tests/test_profile_dataset/data.csv").read().encode() -mock_data.status_code = 200 - -# Mock the model -mock_model = Mock() -amr = json.loads(open("tests/test_equations_to_amr/amr.json").read()) -model_id = "model-123" -amr["id"] = model_id -mock_model.json.return_value = amr -mock_model.text = json.dumps(amr) -mock_model.status_code = 200 - -# Mock the TDS provenance response -mock_provenance = Mock() -mock_provenance.content = code_id -mock_provenance.status_code = 200 - -# Mock the downloaded pdf -mock_paper = Mock() -mock_paper.content = "some encoded PDF content goes here".encode() -mock_paper.status_code = 200 - -mock_ta1_response = Mock() -model_card = json.loads(open("tests/test_profile_model/model_card.json").read()) -mock_ta1_response.json.return_value = model_card -mock_ta1_response.text = json.dumps(model_card) -mock_ta1_response.status_code = 200 - -# Mock the updated TDS dataset artifact -mock_tds_model_update_put = Mock() -tds_response = {"id": model_id} -mock_tds_model_update_put.json.return_value = tds_response -mock_tds_model_update_put.text = json.dumps(tds_response) -mock_tds_model_update_put.status_code = 200 - - -####################################### -##### Setup for Integration Tests ##### -####################################### - -original_post = requests.post - - -def decide_post_response(*args, **kwargs): - """ - This function redefines `requests.post` and optionally allows for overrides - to be sent out (e.g. to TA1 live service) for true integration testing. - """ - url = args[0] # Assuming the first argument to requests.post is the URL - if "tds" in url and "provenance" in url: - logger.info("Mocking response from TDS") - return mock_provenance - if "mit" in url and live == "FALSE": - logger.info("Mocking response from TA1") - return mock_ta1_response - elif live == "TRUE": - logger.info("Sending request to LIVE TA1 Service") - return original_post(*args, **kwargs) # Call the original - - -####################################### -############## Run Tests ############## -####################################### - - -# Note that the patches have to be in reverse order of the -# test function arguments -@patch("requests.get") # patch anytime a GET is made -@patch("requests.put") # patch anytime a PUT is made -@patch( - "requests.post", side_effect=decide_post_response -) # patch anytime a POST is made -@patch("api.utils.get_queue", return_value=queue) # mock the redis queue -def test_profile_model(mock_queue, mock_post, mock_put, mock_get): - logging.info( - f"Testing with {char_limit} set on the document submission to avoid context overruns with the LLM" - ) - - mock_get.side_effect = [ - mock_tds_code_artifact, - mock_presigned_download_url, - mock_code, - mock_tds_paper_artifact, - mock_presigned_download_url, - mock_paper, - ] - - # response from TDS after updating artifact - mock_put.side_effect = [mock_tds_model_update_put] - - # Define the query parameters - query_params = {"paper_artifact_id": artifact_id} - - # Call the endpoint - response = client.post("/profile_model/{model_id}", params=query_params) - results = response.json() - print(results) - - # Assert the status code and response - assert response.status_code == 200 - assert results.get("status") == "finished", results.get("result", {}).get( - "job_error" - ) - assert results.get("result", {}).get("job_error") == None - assert ( - results.get("result", {}).get("job_result", {}).get("message", None) - == "Model card generated and updated in TDS" - ) diff --git a/workers/Dockerfile b/worker/Dockerfile similarity index 91% rename from workers/Dockerfile rename to worker/Dockerfile index 44aea8b..562425b 100644 --- a/workers/Dockerfile +++ b/worker/Dockerfile @@ -18,6 +18,6 @@ RUN poetry config virtualenvs.create false && \ ENV REDIS_HOST redis ENV REDIS_PORT 6379 -COPY workers workers -WORKDIR /workers +COPY worker worker +WORKDIR /worker CMD rq worker --url redis://$REDIS_HOST:$REDIS_PORT high default low \ No newline at end of file diff --git a/worker/__init__.py b/worker/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/workers/operations.py b/worker/operations.py similarity index 98% rename from workers/operations.py rename to worker/operations.py index 43e7133..986f1d0 100644 --- a/workers/operations.py +++ b/worker/operations.py @@ -4,7 +4,7 @@ import sys import requests -from utils import ( +from worker.utils import ( find_source_code, get_artifact_from_tds, get_dataset_from_tds, @@ -13,12 +13,13 @@ put_artifact_extraction_to_tds, set_provenance, ) +from lib.settings import settings -TDS_API = os.getenv("TDS_URL") -SKEMA_API = os.getenv("SKEMA_RS_URL") -UNIFIED_API = os.getenv("TA1_UNIFIED_URL") -MIT_API = os.getenv("MIT_TR_URL") -LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO").upper() # default to INFO if not set +TDS_API = settings.TDS_URL +SKEMA_API = settings.SKEMA_RS_URL +UNIFIED_API = settings.TA1_UNIFIED_URL +MIT_API = settings.MIT_TR_URL +LOG_LEVEL = settings.LOG_LEVEL.upper() import logging @@ -227,7 +228,7 @@ def pdf_extractions(*args, **kwargs): def data_card(*args, **kwargs): - openai_key = os.getenv("OPENAI_API_KEY") + openai_key = settings.OPENAI_API_KEY dataset_id = kwargs.get("dataset_id") artifact_id = kwargs.get("artifact_id") @@ -308,7 +309,7 @@ def data_card(*args, **kwargs): def model_card(*args, **kwargs): - openai_key = os.getenv("OPENAI_API_KEY") + openai_key = settings.OPENAI_API_KEY model_id = kwargs.get("model_id") paper_artifact_id = kwargs.get("paper_artifact_id") diff --git a/workers/utils.py b/worker/utils.py similarity index 98% rename from workers/utils.py rename to worker/utils.py index 2d75f7b..a6a1ab1 100644 --- a/workers/utils.py +++ b/worker/utils.py @@ -2,13 +2,15 @@ import json import os import sys +import logging import pandas import requests -LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO").upper() # default to INFO if not set +from lib.settings import settings + +LOG_LEVEL = settings.LOG_LEVEL.upper() -import logging numeric_level = getattr(logging, LOG_LEVEL, None) if not isinstance(numeric_level, int): @@ -23,7 +25,7 @@ handler.setFormatter(formatter) logger.addHandler(handler) -TDS_API = os.getenv("TDS_URL") +TDS_API = settings.TDS_URL def put_amr_to_tds(amr_payload, name=None, description=None):