From 46e80dd50933e563712e9ce90fc536f02b3c983c Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Sun, 30 Jul 2023 23:43:04 -0400 Subject: [PATCH 01/89] Rename URL_(WHITE|BLACK)LIST to URL_(ALLOW|DENY)LIST Retain aliases for old configuration files --- archivebox/config.py | 8 ++++---- archivebox/config_stubs.py | 2 +- archivebox/core/forms.py | 2 +- archivebox/index/__init__.py | 8 ++++---- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/archivebox/config.py b/archivebox/config.py index 739d7f12..f5eef758 100644 --- a/archivebox/config.py +++ b/archivebox/config.py @@ -82,8 +82,8 @@ CONFIG_SCHEMA: Dict[str, ConfigDefaultDict] = { 'MEDIA_TIMEOUT': {'type': int, 'default': 3600}, 'OUTPUT_PERMISSIONS': {'type': str, 'default': '644'}, 'RESTRICT_FILE_NAMES': {'type': str, 'default': 'windows'}, - 'URL_BLACKLIST': {'type': str, 'default': r'\.(css|js|otf|ttf|woff|woff2|gstatic\.com|googleapis\.com/css)(\?.*)?$'}, # to avoid downloading code assets as their own pages - 'URL_WHITELIST': {'type': str, 'default': None}, + 'URL_DENYLIST': {'type': str, 'default': r'\.(css|js|otf|ttf|woff|woff2|gstatic\.com|googleapis\.com/css)(\?.*)?$', 'aliases': ('URL_BLACKLIST',)}, # to avoid downloading code assets as their own pages + 'URL_ALLOWLIST': {'type': str, 'default': None, 'aliases': ('URL_WHITELIST',)}, 'ENFORCE_ATOMIC_WRITES': {'type': bool, 'default': True}, 'TAG_SEPARATOR_PATTERN': {'type': str, 'default': r'[,]'}, }, @@ -371,8 +371,8 @@ DYNAMIC_CONFIG_SCHEMA: ConfigDefaultDict = { 'CONFIG_FILE': {'default': lambda c: Path(c['CONFIG_FILE']).resolve() if c['CONFIG_FILE'] else c['OUTPUT_DIR'] / CONFIG_FILENAME}, 'COOKIES_FILE': {'default': lambda c: c['COOKIES_FILE'] and Path(c['COOKIES_FILE']).resolve()}, 'CHROME_USER_DATA_DIR': {'default': lambda c: find_chrome_data_dir() if c['CHROME_USER_DATA_DIR'] is None else (Path(c['CHROME_USER_DATA_DIR']).resolve() if c['CHROME_USER_DATA_DIR'] else None)}, # None means unset, so we autodetect it with find_chrome_Data_dir(), but emptystring '' means user manually set it to '', and we should store it as None - 'URL_BLACKLIST_PTN': {'default': lambda c: c['URL_BLACKLIST'] and re.compile(c['URL_BLACKLIST'] or '', re.IGNORECASE | re.UNICODE | re.MULTILINE)}, - 'URL_WHITELIST_PTN': {'default': lambda c: c['URL_WHITELIST'] and re.compile(c['URL_WHITELIST'] or '', re.IGNORECASE | re.UNICODE | re.MULTILINE)}, + 'URL_DENYLIST_PTN': {'default': lambda c: c['URL_DENYLIST'] and re.compile(c['URL_DENYLIST'] or '', re.IGNORECASE | re.UNICODE | re.MULTILINE)}, + 'URL_ALLOWLIST_PTN': {'default': lambda c: c['URL_ALLOWLIST'] and re.compile(c['URL_ALLOWLIST'] or '', re.IGNORECASE | re.UNICODE | re.MULTILINE)}, 'DIR_OUTPUT_PERMISSIONS': {'default': lambda c: c['OUTPUT_PERMISSIONS'].replace('6', '7').replace('4', '5')}, 'ARCHIVEBOX_BINARY': {'default': lambda c: sys.argv[0] or bin_path('archivebox')}, diff --git a/archivebox/config_stubs.py b/archivebox/config_stubs.py index 2c42e808..c8cc9ecb 100644 --- a/archivebox/config_stubs.py +++ b/archivebox/config_stubs.py @@ -41,7 +41,7 @@ class ConfigDict(BaseConfig, total=False): MEDIA_TIMEOUT: int OUTPUT_PERMISSIONS: str RESTRICT_FILE_NAMES: str - URL_BLACKLIST: str + URL_DENYLIST: str SECRET_KEY: Optional[str] BIND_ADDR: str diff --git a/archivebox/core/forms.py b/archivebox/core/forms.py index 99f4d02e..193c0d05 100644 --- a/archivebox/core/forms.py +++ b/archivebox/core/forms.py @@ -41,7 +41,7 @@ class AddLinkForm(forms.Form): # label="Exclude patterns", # min_length='1', # required=False, - # initial=URL_BLACKLIST, + # initial=URL_DENYLIST, # ) # timeout = forms.IntegerField( # initial=TIMEOUT, diff --git a/archivebox/index/__init__.py b/archivebox/index/__init__.py index f631430c..b9d57aeb 100644 --- a/archivebox/index/__init__.py +++ b/archivebox/index/__init__.py @@ -22,8 +22,8 @@ from ..config import ( JSON_INDEX_FILENAME, OUTPUT_DIR, TIMEOUT, - URL_BLACKLIST_PTN, - URL_WHITELIST_PTN, + URL_DENYLIST_PTN, + URL_ALLOWLIST_PTN, stderr, OUTPUT_PERMISSIONS ) @@ -142,9 +142,9 @@ def archivable_links(links: Iterable[Link]) -> Iterable[Link]: continue if scheme(link.url) not in ('http', 'https', 'ftp'): continue - if URL_BLACKLIST_PTN and URL_BLACKLIST_PTN.search(link.url): + if URL_DENYLIST_PTN and URL_DENYLIST_PTN.search(link.url): continue - if URL_WHITELIST_PTN and (not URL_WHITELIST_PTN.search(link.url)): + if URL_ALLOWLIST_PTN and (not URL_ALLOWLIST_PTN.search(link.url)): continue yield link From b44f7e68b180276aff61fcd918b0ef96d9b9fa28 Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Mon, 31 Jul 2023 11:34:03 -0400 Subject: [PATCH 02/89] Add URL-specific method allow/deny lists Allows enabling only allow-listed extractors or disabling specific deny-listed extractors for a regular expression matched against an added site's URL. --- archivebox/config.py | 11 ++++++-- archivebox/extractors/__init__.py | 47 +++++++++++++++++++++++-------- tests/test_extractors.py | 43 ++++++++++++++++++++++++++-- 3 files changed, 85 insertions(+), 16 deletions(-) diff --git a/archivebox/config.py b/archivebox/config.py index f5eef758..7334b169 100644 --- a/archivebox/config.py +++ b/archivebox/config.py @@ -124,6 +124,8 @@ CONFIG_SCHEMA: Dict[str, ConfigDefaultDict] = { 'SAVE_GIT': {'type': bool, 'default': True, 'aliases': ('FETCH_GIT',)}, 'SAVE_MEDIA': {'type': bool, 'default': True, 'aliases': ('FETCH_MEDIA',)}, 'SAVE_ARCHIVE_DOT_ORG': {'type': bool, 'default': True, 'aliases': ('SUBMIT_ARCHIVE_DOT_ORG',)}, + 'SAVE_ALLOWLIST': {'type': dict, 'default': {},}, + 'SAVE_DENYLIST': {'type': dict, 'default': {},}, }, 'ARCHIVE_METHOD_OPTIONS': { @@ -355,6 +357,8 @@ def get_commit_hash(config): ############################## Derived Config ################################## +ALLOWDENYLIST_REGEX_FLAGS: int = re.IGNORECASE | re.UNICODE | re.MULTILINE + DYNAMIC_CONFIG_SCHEMA: ConfigDefaultDict = { 'TERM_WIDTH': {'default': lambda c: lambda: shutil.get_terminal_size((100, 10)).columns}, 'USER': {'default': lambda c: SYSTEM_USER}, @@ -371,8 +375,8 @@ DYNAMIC_CONFIG_SCHEMA: ConfigDefaultDict = { 'CONFIG_FILE': {'default': lambda c: Path(c['CONFIG_FILE']).resolve() if c['CONFIG_FILE'] else c['OUTPUT_DIR'] / CONFIG_FILENAME}, 'COOKIES_FILE': {'default': lambda c: c['COOKIES_FILE'] and Path(c['COOKIES_FILE']).resolve()}, 'CHROME_USER_DATA_DIR': {'default': lambda c: find_chrome_data_dir() if c['CHROME_USER_DATA_DIR'] is None else (Path(c['CHROME_USER_DATA_DIR']).resolve() if c['CHROME_USER_DATA_DIR'] else None)}, # None means unset, so we autodetect it with find_chrome_Data_dir(), but emptystring '' means user manually set it to '', and we should store it as None - 'URL_DENYLIST_PTN': {'default': lambda c: c['URL_DENYLIST'] and re.compile(c['URL_DENYLIST'] or '', re.IGNORECASE | re.UNICODE | re.MULTILINE)}, - 'URL_ALLOWLIST_PTN': {'default': lambda c: c['URL_ALLOWLIST'] and re.compile(c['URL_ALLOWLIST'] or '', re.IGNORECASE | re.UNICODE | re.MULTILINE)}, + 'URL_DENYLIST_PTN': {'default': lambda c: c['URL_DENYLIST'] and re.compile(c['URL_DENYLIST'] or '', ALLOWDENYLIST_REGEX_FLAGS)}, + 'URL_ALLOWLIST_PTN': {'default': lambda c: c['URL_ALLOWLIST'] and re.compile(c['URL_ALLOWLIST'] or '', ALLOWDENYLIST_REGEX_FLAGS)}, 'DIR_OUTPUT_PERMISSIONS': {'default': lambda c: c['OUTPUT_PERMISSIONS'].replace('6', '7').replace('4', '5')}, 'ARCHIVEBOX_BINARY': {'default': lambda c: sys.argv[0] or bin_path('archivebox')}, @@ -446,10 +450,11 @@ DYNAMIC_CONFIG_SCHEMA: ConfigDefaultDict = { 'EXTERNAL_LOCATIONS': {'default': lambda c: get_external_locations(c)}, 'DATA_LOCATIONS': {'default': lambda c: get_data_locations(c)}, 'CHROME_OPTIONS': {'default': lambda c: get_chrome_info(c)}, + 'SAVE_ALLOWLIST_PTN': {'default': lambda c: c['SAVE_ALLOWLIST'] and {re.compile(k, ALLOWDENYLIST_REGEX_FLAGS): v for k, v in c['SAVE_ALLOWLIST'].items()}}, + 'SAVE_DENYLIST_PTN': {'default': lambda c: c['SAVE_DENYLIST'] and {re.compile(k, ALLOWDENYLIST_REGEX_FLAGS): v for k, v in c['SAVE_DENYLIST'].items()}}, } - ################################### Helpers #################################### diff --git a/archivebox/extractors/__init__.py b/archivebox/extractors/__init__.py index 3ca9cfa7..5f09931e 100644 --- a/archivebox/extractors/__init__.py +++ b/archivebox/extractors/__init__.py @@ -4,12 +4,16 @@ import os import sys from pathlib import Path -from typing import Optional, List, Iterable, Union +from typing import Callable, Optional, List, Iterable, TypeAlias, Union from datetime import datetime, timezone from django.db.models import QuerySet +from ..config import ( + SAVE_ALLOWLIST_PTN, + SAVE_DENYLIST_PTN, +) from ..core.settings import ERROR_LOG -from ..index.schema import Link +from ..index.schema import ArchiveResult, Link from ..index.sql import write_link_to_sql_index from ..index import ( load_link_details, @@ -42,7 +46,11 @@ from .archive_org import should_save_archive_dot_org, save_archive_dot_org from .headers import should_save_headers, save_headers -def get_default_archive_methods(): +ShouldSaveFunction: TypeAlias = Callable[[Link, Optional[Path], Optional[bool]], bool] +SaveFunction: TypeAlias = Callable[[Link, Optional[Path], int], ArchiveResult] +ArchiveMethodEntry: TypeAlias = tuple[str, ShouldSaveFunction, SaveFunction] + +def get_default_archive_methods() -> List[ArchiveMethodEntry]: return [ ('favicon', should_save_favicon, save_favicon), ('headers', should_save_headers, save_headers), @@ -59,14 +67,31 @@ def get_default_archive_methods(): ('archive_org', should_save_archive_dot_org, save_archive_dot_org), ] +@enforce_types +def get_archive_methods_for_link(link: Link) -> Iterable[ArchiveMethodEntry]: + DEFAULT_METHODS = get_default_archive_methods() + allowed_methods = { + m for pat, methods in + SAVE_ALLOWLIST_PTN.items() + if pat.search(link.url) + for m in methods + } or { m[0] for m in DEFAULT_METHODS } + denied_methods = { + m for pat, methods in + SAVE_DENYLIST_PTN.items() + if pat.search(link.url) + for m in methods + } + allowed_methods -= denied_methods + + return (m for m in DEFAULT_METHODS if m[0] in allowed_methods) + ARCHIVE_METHODS_INDEXING_PRECEDENCE = [('readability', 1), ('singlefile', 2), ('dom', 3), ('wget', 4)] @enforce_types -def ignore_methods(to_ignore: List[str]): +def ignore_methods(to_ignore: List[str]) -> Iterable[str]: ARCHIVE_METHODS = get_default_archive_methods() - methods = filter(lambda x: x[0] not in to_ignore, ARCHIVE_METHODS) - methods = map(lambda x: x[0], methods) - return list(methods) + return [x[0] for x in ARCHIVE_METHODS if x[0] not in to_ignore] @enforce_types def archive_link(link: Link, overwrite: bool=False, methods: Optional[Iterable[str]]=None, out_dir: Optional[Path]=None) -> Link: @@ -79,11 +104,11 @@ def archive_link(link: Link, overwrite: bool=False, methods: Optional[Iterable[s except Snapshot.DoesNotExist: snapshot = write_link_to_sql_index(link) - ARCHIVE_METHODS = get_default_archive_methods() + active_methods = get_archive_methods_for_link(link) if methods: - ARCHIVE_METHODS = [ - method for method in ARCHIVE_METHODS + active_methods = [ + method for method in active_methods if method[0] in methods ] @@ -100,7 +125,7 @@ def archive_link(link: Link, overwrite: bool=False, methods: Optional[Iterable[s stats = {'skipped': 0, 'succeeded': 0, 'failed': 0} start_ts = datetime.now(timezone.utc) - for method_name, should_run, method_function in ARCHIVE_METHODS: + for method_name, should_run, method_function in active_methods: try: if method_name not in link.history: link.history[method_name] = [] diff --git a/tests/test_extractors.py b/tests/test_extractors.py index 86b50d51..bd6d2775 100644 --- a/tests/test_extractors.py +++ b/tests/test_extractors.py @@ -13,12 +13,51 @@ def test_ignore_methods(): Takes the passed method out of the default methods list and returns that value """ ignored = ignore_methods(['title']) - assert should_save_title not in ignored + assert "title" not in ignored + +def test_save_allowdenylist_works(tmp_path, process, disable_extractors_dict): + allow_list = { + r'/static': ["headers", "singlefile"], + r'example\.com\.html$': ["headers"], + } + deny_list = { + "/static": ["singlefile"], + } + disable_extractors_dict.update({ + "SAVE_HEADERS": "true", + "USE_SINGLEFILE": "true", + "SAVE_ALLOWLIST": pyjson.dumps(allow_list), + "SAVE_DENYLIST": pyjson.dumps(deny_list), + }) + add_process = subprocess.run(['archivebox', 'add', 'http://127.0.0.1:8080/static/example.com.html'], + capture_output=True, env=disable_extractors_dict) + archived_item_path = list(tmp_path.glob('archive/**/*'))[0] + singlefile_file = archived_item_path / "singlefile.html" + assert not singlefile_file.exists() + headers_file = archived_item_path / "headers.json" + assert headers_file.exists() + +def test_save_denylist_works(tmp_path, process, disable_extractors_dict): + deny_list = { + "/static": ["singlefile"], + } + disable_extractors_dict.update({ + "SAVE_HEADERS": "true", + "USE_SINGLEFILE": "true", + "SAVE_DENYLIST": pyjson.dumps(deny_list), + }) + add_process = subprocess.run(['archivebox', 'add', 'http://127.0.0.1:8080/static/example.com.html'], + capture_output=True, env=disable_extractors_dict) + archived_item_path = list(tmp_path.glob('archive/**/*'))[0] + singlefile_file = archived_item_path / "singlefile.html" + assert not singlefile_file.exists() + headers_file = archived_item_path / "headers.json" + assert headers_file.exists() def test_singlefile_works(tmp_path, process, disable_extractors_dict): disable_extractors_dict.update({"USE_SINGLEFILE": "true"}) add_process = subprocess.run(['archivebox', 'add', 'http://127.0.0.1:8080/static/example.com.html'], - capture_output=True, env=disable_extractors_dict) + capture_output=True, env=disable_extractors_dict) archived_item_path = list(tmp_path.glob('archive/**/*'))[0] output_file = archived_item_path / "singlefile.html" assert output_file.exists() From 207647425292f703ae5cd21e41a980c1cb0d939e Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Wed, 2 Aug 2023 10:56:48 -0400 Subject: [PATCH 03/89] Drop use of TypeAlias to maintain Python 3.9 compat TypeAlias annotation was introduced in Python 3.10, and is not strictly necessary. Drop use of it to maintain Python 3.9 compatibility. --- archivebox/extractors/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/archivebox/extractors/__init__.py b/archivebox/extractors/__init__.py index 5f09931e..38710182 100644 --- a/archivebox/extractors/__init__.py +++ b/archivebox/extractors/__init__.py @@ -4,7 +4,7 @@ import os import sys from pathlib import Path -from typing import Callable, Optional, List, Iterable, TypeAlias, Union +from typing import Callable, Optional, List, Iterable, Union from datetime import datetime, timezone from django.db.models import QuerySet @@ -46,9 +46,9 @@ from .archive_org import should_save_archive_dot_org, save_archive_dot_org from .headers import should_save_headers, save_headers -ShouldSaveFunction: TypeAlias = Callable[[Link, Optional[Path], Optional[bool]], bool] -SaveFunction: TypeAlias = Callable[[Link, Optional[Path], int], ArchiveResult] -ArchiveMethodEntry: TypeAlias = tuple[str, ShouldSaveFunction, SaveFunction] +ShouldSaveFunction = Callable[[Link, Optional[Path], Optional[bool]], bool] +SaveFunction = Callable[[Link, Optional[Path], int], ArchiveResult] +ArchiveMethodEntry = tuple[str, ShouldSaveFunction, SaveFunction] def get_default_archive_methods() -> List[ArchiveMethodEntry]: return [ From b28b3b7e67b7c1a25840660e950122788c4a604b Mon Sep 17 00:00:00 2001 From: James O'Beirne Date: Mon, 18 Sep 2023 10:37:35 -0400 Subject: [PATCH 04/89] README: update outdated links Most frustratingly, the outdated docker-compose link prompts users to download an older version of the docker-compose.yml file, which packages a broken YouTube retrieval method. --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d170b3d7..964def84 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ curl -sSL 'https://get.archivebox.io' | sh - +   @@ -86,7 +86,7 @@ ls ./archive/*/index.json # or browse directly via the filesyste ## Key Features -- [**Free & open source**](https://github.com/ArchiveBox/ArchiveBox/blob/master/LICENSE), doesn't require signing up online, stores all data locally +- [**Free & open source**](https://github.com/ArchiveBox/ArchiveBox/blob/dev/LICENSE), doesn't require signing up online, stores all data locally - [**Powerful, intuitive command line interface**](https://github.com/ArchiveBox/ArchiveBox/wiki/Usage#CLI-Usage) with [modular optional dependencies](#dependencies) - [**Comprehensive documentation**](https://github.com/ArchiveBox/ArchiveBox/wiki), [active development](https://github.com/ArchiveBox/ArchiveBox/wiki/Roadmap), and [rich community](https://github.com/ArchiveBox/ArchiveBox/wiki/Web-Archiving-Community) - [**Extracts a wide variety of content out-of-the-box**](https://github.com/ArchiveBox/ArchiveBox/issues/51): [media (youtube-dl or yt-dlp), articles (readability), code (git), etc.](#output-formats) @@ -119,9 +119,9 @@ ls ./archive/*/index.json # or browse directly via the filesyste

  1. Install Docker and Docker Compose on your system (if not already installed).
  2. -
  3. Download the docker-compose.yml file into a new empty directory (can be anywhere). +
  4. Download the docker-compose.yml file into a new empty directory (can be anywhere).
    mkdir ~/archivebox && cd ~/archivebox
    -curl -O 'https://raw.githubusercontent.com/ArchiveBox/ArchiveBox/master/docker-compose.yml'
    +curl -O 'https://raw.githubusercontent.com/ArchiveBox/ArchiveBox/dev/docker-compose.yml'
     
  5. Run the initial setup and create an admin user.
    docker compose run archivebox init --setup
    @@ -499,7 +499,7 @@ env CHROME_BINARY=chromium archivebox ...       # run with a one-off config
     
     These methods also work the same way when run inside Docker, see the Docker Configuration wiki page for details.
     
    -**The config loading logic with all the options defined is here: [`archivebox/config.py`](https://github.com/ArchiveBox/ArchiveBox/blob/master/archivebox/config.py).**
    +**The config loading logic with all the options defined is here: [`archivebox/config.py`](https://github.com/ArchiveBox/ArchiveBox/blob/dev/archivebox/config.py).**
     
     Most options are also documented on the **[Configuration Wiki page](https://github.com/ArchiveBox/ArchiveBox/wiki/Configuration)**.
     
    @@ -867,7 +867,7 @@ All contributions to ArchiveBox are welcomed! Check our [issues](https://github.
     
     For low hanging fruit / easy first tickets, see: ArchiveBox/Issues `#good first ticket` `#help wanted`.
     
    -**Python API Documentation:** https://docs.archivebox.io/en/master/archivebox.html#module-archivebox.main
    +**Python API Documentation:** https://docs.archivebox.io/en/dev/archivebox.html#module-archivebox.main
     
     ### Setup the dev environment
     
    
    From 77917e9b5527cae659604286aec96760e409bf21 Mon Sep 17 00:00:00 2001
    From: Ben Muthalaly 
    Date: Mon, 9 Oct 2023 02:00:01 -0500
    Subject: [PATCH 05/89] Fix HTML title parsing bugs.
    
    This slightly modifies the HTML_TITLE_REGEX to fix two parsing errors.
    The first occurred when title tags were empty (e.g. "")
    which was parsed as "A") which was not matched by the
    regex, and so would fall back to link.base_url.
    
    Now when tags are empty, it falls back to link.base_url, and single
    character titles are parsed correctly.
    
    The way the regex works now is still a bit wonky for some edge cases.
    I couldn't find any cases of incorrect behavior, but it still might be
    worth reworking more completely for robustness.
    ---
     archivebox/extractors/title.py | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/archivebox/extractors/title.py b/archivebox/extractors/title.py
    index 19a78591..dc496c4e 100644
    --- a/archivebox/extractors/title.py
    +++ b/archivebox/extractors/title.py
    @@ -26,7 +26,7 @@ from ..logging_util import TimedProgress
     
     HTML_TITLE_REGEX = re.compile(
         r''                      # start matching text after  tag
    -    r'(.[^<>]+)',                      # get everything up to these symbols
    +    r'([^<>]+)',                      # get everything up to these symbols
         re.IGNORECASE | re.MULTILINE | re.DOTALL | re.UNICODE,
     )
     
    
    From d7b883b04963673474f1f4d51ea5516eb767f326 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Thu, 12 Oct 2023 00:22:47 -0700
    Subject: [PATCH 06/89] fix broken link
    
    ---
     README.md | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/README.md b/README.md
    index 964def84..c524b59c 100644
    --- a/README.md
    +++ b/README.md
    @@ -796,7 +796,7 @@ Whether you want to learn which organizations are the big players in the web arc
       - [Communities](https://github.com/ArchiveBox/ArchiveBox/wiki/Web-Archiving-Community#communities)  
         _A collection of the most active internet archiving communities and initiatives._
     - Check out the ArchiveBox [Roadmap](https://github.com/ArchiveBox/ArchiveBox/wiki/Roadmap) and [Changelog](https://github.com/ArchiveBox/ArchiveBox/wiki/Changelog)
    -- Learn why archiving the internet is important by reading the "[On the Importance of Web Archiving](https://parameters.ssrc.org/2018/09/on-the-importance-of-web-archiving/)" blog post.
    +- Learn why archiving the internet is important by reading the "[On the Importance of Web Archiving](https://items.ssrc.org/parameters/on-the-importance-of-web-archiving/)" blog post.
     - Reach out to me for questions and comments via [@ArchiveBoxApp](https://twitter.com/ArchiveBoxApp) or [@theSquashSH](https://twitter.com/thesquashSH) on Twitter
     
     <br/>
    
    From 11d473e536e080a539ab738db0dd93c335dfae2c Mon Sep 17 00:00:00 2001
    From: Ben Muthalaly <benmuthalaly@gmail.com>
    Date: Sat, 14 Oct 2023 00:38:04 -0500
    Subject: [PATCH 07/89] Add config options to add admin user on first run
    
    ---
     archivebox/config.py | 2 ++
     archivebox/main.py   | 7 ++++++-
     2 files changed, 8 insertions(+), 1 deletion(-)
    
    diff --git a/archivebox/config.py b/archivebox/config.py
    index 795b98e9..6fd6621c 100644
    --- a/archivebox/config.py
    +++ b/archivebox/config.py
    @@ -91,6 +91,8 @@ CONFIG_SCHEMA: Dict[str, ConfigDefaultDict] = {
             'OUTPUT_PERMISSIONS':       {'type': str,   'default': '644'},
             'RESTRICT_FILE_NAMES':      {'type': str,   'default': 'windows'},
             'URL_BLACKLIST':            {'type': str,   'default': r'\.(css|js|otf|ttf|woff|woff2|gstatic\.com|googleapis\.com/css)(\?.*)?$'},  # to avoid downloading code assets as their own pages
    +        'ARCHIVEBOX_USERNAME':      {'type': str,   'default': None},
    +        'ARCHIVEBOX_PASSWORD':      {'type': str,   'default': None},
             'URL_WHITELIST':            {'type': str,   'default': None},
             'ENFORCE_ATOMIC_WRITES':    {'type': bool,  'default': True},
             'TAG_SEPARATOR_PATTERN':    {'type': str,   'default': r'[,]'},
    diff --git a/archivebox/main.py b/archivebox/main.py
    index 5878185c..87dd8899 100755
    --- a/archivebox/main.py
    +++ b/archivebox/main.py
    @@ -112,6 +112,8 @@ from .config import (
         load_all_config,
         CONFIG,
         USER_CONFIG,
    +    ARCHIVEBOX_USERNAME,
    +    ARCHIVEBOX_PASSWORD,
         get_real_name,
         setup_django,
     )
    @@ -422,7 +424,10 @@ def init(force: bool=False, quick: bool=False, setup: bool=False, out_dir: Path=
         if existing_index:
             print('{green}[√] Done. Verified and updated the existing ArchiveBox collection.{reset}'.format(**ANSI))
         else:
    -        # TODO: allow creating new supersuer via env vars on first init
    +        if ARCHIVEBOX_USERNAME and ARCHIVEBOX_PASSWORD:
    +            print('{green}[+] ARCHIVEBOX_USERNAME and  ARCHIVEBOX_PASSWORD configuration options found. Creating new admin user with username {} and password {}.{reset}'.format(ARCHIVEBOX_USERNAME, ARCHIVEBOX_PASSWORD, **ANSI))
    +            from django.contrib.auth.models import User
    +            User.objects.create_superuser(username=ARCHIVEBOX_USERNAME, password=ARCHIVEBOX_PASSWORD)
             # if config.HTTP_USER and config.HTTP_PASS:
             #     from django.contrib.auth.models import User
             #     User.objects.create_superuser(HTTP_USER, '', HTTP_PASS)
    
    From 44a94157beaa319f04efacd06a7a20daf7443e6f Mon Sep 17 00:00:00 2001
    From: Ben Muthalaly <benmuthalaly@gmail.com>
    Date: Sun, 15 Oct 2023 23:36:47 -0500
    Subject: [PATCH 08/89] Remove logging of configured username and password
    
    ---
     archivebox/main.py | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/archivebox/main.py b/archivebox/main.py
    index 87dd8899..5c6a3fd7 100755
    --- a/archivebox/main.py
    +++ b/archivebox/main.py
    @@ -425,7 +425,7 @@ def init(force: bool=False, quick: bool=False, setup: bool=False, out_dir: Path=
             print('{green}[√] Done. Verified and updated the existing ArchiveBox collection.{reset}'.format(**ANSI))
         else:
             if ARCHIVEBOX_USERNAME and ARCHIVEBOX_PASSWORD:
    -            print('{green}[+] ARCHIVEBOX_USERNAME and  ARCHIVEBOX_PASSWORD configuration options found. Creating new admin user with username {} and password {}.{reset}'.format(ARCHIVEBOX_USERNAME, ARCHIVEBOX_PASSWORD, **ANSI))
    +            print('{green}[+] ARCHIVEBOX_USERNAME and  ARCHIVEBOX_PASSWORD configuration options found. Creating new admin user.{reset}'.format(**ANSI))
                 from django.contrib.auth.models import User
                 User.objects.create_superuser(username=ARCHIVEBOX_USERNAME, password=ARCHIVEBOX_PASSWORD)
             # if config.HTTP_USER and config.HTTP_PASS:
    
    From c53ec45a296b264ca4d0a1301f33b580e88b4c3f Mon Sep 17 00:00:00 2001
    From: Ross Williams <ross@ross-williams.net>
    Date: Sun, 8 Oct 2023 15:01:59 -0400
    Subject: [PATCH 09/89] WIP: add sqlite search backend boilerplate
    
    ---
     archivebox/search/backends/sqlite.py | 15 +++++++++++++++
     1 file changed, 15 insertions(+)
     create mode 100644 archivebox/search/backends/sqlite.py
    
    diff --git a/archivebox/search/backends/sqlite.py b/archivebox/search/backends/sqlite.py
    new file mode 100644
    index 00000000..622673b7
    --- /dev/null
    +++ b/archivebox/search/backends/sqlite.py
    @@ -0,0 +1,15 @@
    +from typing import List, Generator
    +
    +from archivebox.util import enforce_types
    +
    +@enforce_types
    +def index(snapshot_id: str, texts: List[str]):
    +    pass
    +
    +@enforce_types
    +def search(text: str) -> List[str]:
    +    pass
    +
    +@enforce_types
    +def flush(snapshot_ids: Generator[str, None, None]):
    +    pass
    
    From 8fe5faf4d062da9de8c0d4f9261287b691bc3193 Mon Sep 17 00:00:00 2001
    From: Ross Williams <ross@ross-williams.net>
    Date: Mon, 9 Oct 2023 16:43:08 -0400
    Subject: [PATCH 10/89] Introduce SQLite FTS5-powered search backend
    
    Use SQLite's FTS5 extension to power full-text search without any
    additional dependencies. FTS5 was introduced in SQLite 3.9.0,
    [released][1] in 2015 so should be available on most SQLite
    installations at this point in time.
    
    [1]: https://www.sqlite.org/changes.html#version_3_9_0
    ---
     archivebox/config.py                 |   6 +
     archivebox/search/backends/sqlite.py | 157 ++++++++++++++++++++++++++-
     2 files changed, 159 insertions(+), 4 deletions(-)
    
    diff --git a/archivebox/config.py b/archivebox/config.py
    index 795b98e9..eaf0b6bf 100644
    --- a/archivebox/config.py
    +++ b/archivebox/config.py
    @@ -213,6 +213,11 @@ CONFIG_SCHEMA: Dict[str, ConfigDefaultDict] = {
             'SONIC_COLLECTION':         {'type': str,   'default': 'archivebox'},
             'SONIC_BUCKET':             {'type': str,   'default': 'snapshots'},
             'SEARCH_BACKEND_TIMEOUT':   {'type': int,   'default': 90},
    +        # SQLite3 FTS5
    +        'FTS_SEPARATE_DATABASE':    {'type': bool,  'default': True},
    +        'FTS_TOKENIZERS':           {'type': str,   'default': 'porter unicode61 remove_diacritics 2'},
    +        # Default from https://www.sqlite.org/limits.html#max_length
    +        'FTS_SQLITE_MAX_LENGTH':    {'type': int,   'default': int(1e9)},
         },
     
         'DEPENDENCY_CONFIG': {
    @@ -345,6 +350,7 @@ ALLOWED_IN_OUTPUT_DIR = {
         'yarn.lock',
         'static',
         'sonic',
    +    'search.sqlite3',
         ARCHIVE_DIR_NAME,
         SOURCES_DIR_NAME,
         LOGS_DIR_NAME,
    diff --git a/archivebox/search/backends/sqlite.py b/archivebox/search/backends/sqlite.py
    index 622673b7..ef93522f 100644
    --- a/archivebox/search/backends/sqlite.py
    +++ b/archivebox/search/backends/sqlite.py
    @@ -1,15 +1,164 @@
    -from typing import List, Generator
    +import codecs
    +from typing import List, Optional, Generator
    +import sqlite3
     
     from archivebox.util import enforce_types
    +from archivebox.config import (
    +    FTS_SEPARATE_DATABASE,
    +    FTS_TOKENIZERS,
    +    FTS_SQLITE_MAX_LENGTH
    +)
    +
    +FTS_TABLE = "snapshot_fts"
    +FTS_ID_TABLE = "snapshot_id_fts"
    +FTS_COLUMN = "texts"
    +
    +if FTS_SEPARATE_DATABASE:
    +    database = sqlite3.connect("search.sqlite3")
    +    # Make connection callable, because `django.db.connection.cursor()`
    +    # has to be called to get a context manager, but sqlite3.Connection
    +    # is a context manager without being called.
    +    def connection():
    +        return database
    +    SQLITE_BIND = "?"
    +else:
    +    from django.db import connection as database
    +    connection = database.cursor
    +    SQLITE_BIND = "%s"
    +
    +# Only Python >= 3.11 supports sqlite3.Connection.getlimit(),
    +# so fall back to the default if the API to get the real value isn't present
    +try:
    +    limit_id = sqlite3.SQLITE_LIMIT_LENGTH
    +    try:
    +        with database.temporary_connection() as cursor:
    +            SQLITE_LIMIT_LENGTH = cursor.connection.getlimit(limit_id)
    +    except AttributeError:
    +        SQLITE_LIMIT_LENGTH = database.getlimit(limit_id)
    +except AttributeError:
    +    SQLITE_LIMIT_LENGTH = FTS_SQLITE_MAX_LENGTH
    +
    +
    +def _escape_sqlite3(value: str, *, quote: str, errors='strict') -> str:
    +    assert isinstance(quote, str), "quote is not a str"
    +    assert len(quote) == 1, "quote must be a single character"
    +
    +    encodable = value.encode('utf-8', errors).decode('utf-8')
    +
    +    nul_index = encodable.find("\x00")
    +    if nul_index >= 0:
    +        error = UnicodeEncodeError("NUL-terminated utf-8", encodable,
    +                                   nul_index, nul_index + 1, "NUL not allowed")
    +        error_handler = codecs.lookup_error(errors)
    +        replacement, _ = error_handler(error)
    +        encodable = encodable.replace("\x00", replacement)
    +
    +    return quote + encodable.replace(quote, quote * 2) + quote
    +
    +def _escape_sqlite3_value(value: str, errors='strict') -> str:
    +    return _escape_sqlite3(value, quote="'", errors=errors)
    +
    +def _escape_sqlite3_identifier(value: str) -> str:
    +    return _escape_sqlite3(value, quote='"', errors='strict')
    +
    +@enforce_types
    +def _create_tables():
    +    table = _escape_sqlite3_identifier(FTS_TABLE)
    +    # Escape as value, because fts5() expects
    +    # string literal column names
    +    column = _escape_sqlite3_value(FTS_COLUMN)
    +    id_table = _escape_sqlite3_identifier(FTS_ID_TABLE)
    +    tokenizers = _escape_sqlite3_value(FTS_TOKENIZERS)
    +    trigger_name = _escape_sqlite3_identifier(f"{FTS_ID_TABLE}_ad")
    +
    +    with connection() as cursor:
    +        # Create a contentless-delete FTS5 table that indexes
    +        # but does not store the texts of snapshots
    +        cursor.execute(
    +            f"CREATE VIRTUAL TABLE {table}"
    +            f" USING fts5({column},"
    +            f" tokenize={tokenizers},"
    +            " content='', contentless_delete=1);"
    +            )
    +        # Create a one-to-one mapping between ArchiveBox snapshot_id
    +        # and FTS5 rowid, because the column type of rowid can't be
    +        # customized.
    +        cursor.execute(
    +            f"CREATE TABLE {id_table}("
    +            " rowid INTEGER PRIMARY KEY AUTOINCREMENT,"
    +            " snapshot_id char(32) NOT NULL UNIQUE"
    +            ");"
    +            )
    +        # Create a trigger to delete items from the FTS5 index when
    +        # the snapshot_id is deleted from the mapping, to maintain
    +        # consistency and make the `flush()` query simpler.
    +        cursor.execute(
    +            f"CREATE TRIGGER {trigger_name}"
    +            f" AFTER DELETE ON {id_table} BEGIN"
    +            f" DELETE FROM {table} WHERE rowid=old.rowid;"
    +            " END;"
    +            )
     
     @enforce_types
     def index(snapshot_id: str, texts: List[str]):
    -    pass
    +    text = ' '.join(texts)[:SQLITE_LIMIT_LENGTH]
    +
    +    table = _escape_sqlite3_identifier(FTS_TABLE)
    +    column = _escape_sqlite3_identifier(FTS_COLUMN)
    +    id_table = _escape_sqlite3_identifier(FTS_ID_TABLE)
    +
    +    with connection() as cursor:
    +        retries = 2
    +        while retries > 0:
    +            retries -= 1
    +            try:
    +                # If there is already an FTS index rowid to snapshot_id mapping,
    +                # then don't insert a new one, silently ignoring the operation.
    +                # {id_table}.rowid is AUTOINCREMENT, so will generate an unused
    +                # rowid for the index if it is an unindexed snapshot_id.
    +                cursor.execute(
    +                    f"INSERT OR IGNORE INTO {id_table}(snapshot_id) VALUES({SQLITE_BIND})",
    +                    [snapshot_id])
    +                # Fetch the FTS index rowid for the given snapshot_id
    +                id_res = cursor.execute(
    +                    f"SELECT rowid FROM {id_table} WHERE snapshot_id = {SQLITE_BIND}",
    +                    [snapshot_id])
    +                rowid = id_res.fetchone()[0]
    +                # (Re-)index the content
    +                cursor.execute(
    +                    "INSERT OR REPLACE INTO"
    +                    f" {table}(rowid, {column}) VALUES ({SQLITE_BIND}, {SQLITE_BIND})",
    +                    [rowid, text])
    +                # All statements succeeded; break retry loop
    +                break
    +            except Exception as e:
    +                if str(e).startswith(f"no such table:"):
    +                    _create_tables()
    +                else:
    +                    raise
     
     @enforce_types
     def search(text: str) -> List[str]:
    -    pass
    +    table = _escape_sqlite3_identifier(FTS_TABLE)
    +    id_table = _escape_sqlite3_identifier(FTS_ID_TABLE)
    +
    +    with connection() as cursor:
    +        res = cursor.execute(
    +            f"SELECT snapshot_id FROM {table}"
    +            f" INNER JOIN {id_table}"
    +            f" ON {id_table}.rowid = {table}.rowid"
    +            f" WHERE {table} MATCH {SQLITE_BIND}",
    +            [text])
    +        snap_ids = [row[0] for row in res.fetchall()]
    +    return snap_ids
     
     @enforce_types
     def flush(snapshot_ids: Generator[str, None, None]):
    -    pass
    +    snapshot_ids = list(snapshot_ids)
    +
    +    id_table = _escape_sqlite3_identifier(FTS_ID_TABLE)
    +
    +    with connection() as cursor:
    +        cursor.executemany(
    +            f"DELETE FROM {id_table} WHERE snapshot_id={SQLITE_BIND}",
    +            [snapshot_ids])
    
    From e0f8eeeaa77b581756d32f6525374695610d3c37 Mon Sep 17 00:00:00 2001
    From: Ross Williams <ross@ross-williams.net>
    Date: Tue, 10 Oct 2023 10:30:52 -0400
    Subject: [PATCH 11/89] Improve search.backends.sqlite retry logic
    
    Retry with table creation should fail if it is attempted for a second
    time.
    ---
     archivebox/search/backends/sqlite.py | 8 +++++---
     1 file changed, 5 insertions(+), 3 deletions(-)
    
    diff --git a/archivebox/search/backends/sqlite.py b/archivebox/search/backends/sqlite.py
    index ef93522f..b2c75bba 100644
    --- a/archivebox/search/backends/sqlite.py
    +++ b/archivebox/search/backends/sqlite.py
    @@ -129,14 +129,16 @@ def index(snapshot_id: str, texts: List[str]):
                         "INSERT OR REPLACE INTO"
                         f" {table}(rowid, {column}) VALUES ({SQLITE_BIND}, {SQLITE_BIND})",
                         [rowid, text])
    -                # All statements succeeded; break retry loop
    -                break
    +                # All statements succeeded; return
    +                return
                 except Exception as e:
    -                if str(e).startswith(f"no such table:"):
    +                if str(e).startswith("no such table:") and retries > 0:
                         _create_tables()
                     else:
                         raise
     
    +    raise RuntimeError("Failed to create tables for SQLite FTS5 search")
    +
     @enforce_types
     def search(text: str) -> List[str]:
         table = _escape_sqlite3_identifier(FTS_TABLE)
    
    From adb9f0ecc9f0f8edee49ccfb2c3f966367c2bce3 Mon Sep 17 00:00:00 2001
    From: Ross Williams <ross@ross-williams.net>
    Date: Fri, 13 Oct 2023 09:26:50 -0400
    Subject: [PATCH 12/89] sqlite search: Rename `connection` to `get_connection`
    
    `connection` could cause confusion with `django.db.connection` and
    `get_connection` is a better callable name.
    ---
     archivebox/search/backends/sqlite.py | 14 +++++++-------
     1 file changed, 7 insertions(+), 7 deletions(-)
    
    diff --git a/archivebox/search/backends/sqlite.py b/archivebox/search/backends/sqlite.py
    index b2c75bba..4ed9e79c 100644
    --- a/archivebox/search/backends/sqlite.py
    +++ b/archivebox/search/backends/sqlite.py
    @@ -15,15 +15,15 @@ FTS_COLUMN = "texts"
     
     if FTS_SEPARATE_DATABASE:
         database = sqlite3.connect("search.sqlite3")
    -    # Make connection callable, because `django.db.connection.cursor()`
    +    # Make get_connection callable, because `django.db.connection.cursor()`
         # has to be called to get a context manager, but sqlite3.Connection
         # is a context manager without being called.
    -    def connection():
    +    def get_connection():
             return database
         SQLITE_BIND = "?"
     else:
         from django.db import connection as database
    -    connection = database.cursor
    +    get_connection = database.cursor
         SQLITE_BIND = "%s"
     
     # Only Python >= 3.11 supports sqlite3.Connection.getlimit(),
    @@ -71,7 +71,7 @@ def _create_tables():
         tokenizers = _escape_sqlite3_value(FTS_TOKENIZERS)
         trigger_name = _escape_sqlite3_identifier(f"{FTS_ID_TABLE}_ad")
     
    -    with connection() as cursor:
    +    with get_connection() as cursor:
             # Create a contentless-delete FTS5 table that indexes
             # but does not store the texts of snapshots
             cursor.execute(
    @@ -107,7 +107,7 @@ def index(snapshot_id: str, texts: List[str]):
         column = _escape_sqlite3_identifier(FTS_COLUMN)
         id_table = _escape_sqlite3_identifier(FTS_ID_TABLE)
     
    -    with connection() as cursor:
    +    with get_connection() as cursor:
             retries = 2
             while retries > 0:
                 retries -= 1
    @@ -144,7 +144,7 @@ def search(text: str) -> List[str]:
         table = _escape_sqlite3_identifier(FTS_TABLE)
         id_table = _escape_sqlite3_identifier(FTS_ID_TABLE)
     
    -    with connection() as cursor:
    +    with get_connection() as cursor:
             res = cursor.execute(
                 f"SELECT snapshot_id FROM {table}"
                 f" INNER JOIN {id_table}"
    @@ -160,7 +160,7 @@ def flush(snapshot_ids: Generator[str, None, None]):
     
         id_table = _escape_sqlite3_identifier(FTS_ID_TABLE)
     
    -    with connection() as cursor:
    +    with get_connection() as cursor:
             cursor.executemany(
                 f"DELETE FROM {id_table} WHERE snapshot_id={SQLITE_BIND}",
                 [snapshot_ids])
    
    From 1e604a1352cfd838d2b7504dad3d92fd3c79e3d3 Mon Sep 17 00:00:00 2001
    From: Ross Williams <ross@ross-williams.net>
    Date: Mon, 16 Oct 2023 14:31:52 -0400
    Subject: [PATCH 13/89] sqlite search: clean up errors and type-checking
    
    Clean up error handling, and report a better error message
    on search and flush if FTS5 tables haven't yet been created.
    
    Add some mypy comments to clean up type-checking errors.
    ---
     archivebox/search/backends/sqlite.py | 44 ++++++++++++++++++++--------
     1 file changed, 31 insertions(+), 13 deletions(-)
    
    diff --git a/archivebox/search/backends/sqlite.py b/archivebox/search/backends/sqlite.py
    index 4ed9e79c..b4c61efb 100644
    --- a/archivebox/search/backends/sqlite.py
    +++ b/archivebox/search/backends/sqlite.py
    @@ -1,5 +1,5 @@
     import codecs
    -from typing import List, Optional, Generator
    +from typing import List, Generator
     import sqlite3
     
     from archivebox.util import enforce_types
    @@ -22,7 +22,7 @@ if FTS_SEPARATE_DATABASE:
             return database
         SQLITE_BIND = "?"
     else:
    -    from django.db import connection as database
    +    from django.db import connection as database  # type: ignore[no-redef, assignment]
         get_connection = database.cursor
         SQLITE_BIND = "%s"
     
    @@ -31,7 +31,7 @@ else:
     try:
         limit_id = sqlite3.SQLITE_LIMIT_LENGTH
         try:
    -        with database.temporary_connection() as cursor:
    +        with database.temporary_connection() as cursor:  # type: ignore[attr-defined]
                 SQLITE_LIMIT_LENGTH = cursor.connection.getlimit(limit_id)
         except AttributeError:
             SQLITE_LIMIT_LENGTH = database.getlimit(limit_id)
    @@ -51,6 +51,7 @@ def _escape_sqlite3(value: str, *, quote: str, errors='strict') -> str:
                                        nul_index, nul_index + 1, "NUL not allowed")
             error_handler = codecs.lookup_error(errors)
             replacement, _ = error_handler(error)
    +        assert isinstance(replacement, str), "handling a UnicodeEncodeError should return a str replacement"
             encodable = encodable.replace("\x00", replacement)
     
         return quote + encodable.replace(quote, quote * 2) + quote
    @@ -99,6 +100,16 @@ def _create_tables():
                 " END;"
                 )
     
    +def _handle_query_exception(exc: Exception):
    +    message = str(exc)
    +    if message.startswith("no such table:"):
    +        raise RuntimeError(
    +            "SQLite full-text search index has not yet"
    +            " been created; run `archivebox update --index-only`."
    +        )
    +    else:
    +        raise exc
    +
     @enforce_types
     def index(snapshot_id: str, texts: List[str]):
         text = ' '.join(texts)[:SQLITE_LIMIT_LENGTH]
    @@ -145,22 +156,29 @@ def search(text: str) -> List[str]:
         id_table = _escape_sqlite3_identifier(FTS_ID_TABLE)
     
         with get_connection() as cursor:
    -        res = cursor.execute(
    -            f"SELECT snapshot_id FROM {table}"
    -            f" INNER JOIN {id_table}"
    -            f" ON {id_table}.rowid = {table}.rowid"
    -            f" WHERE {table} MATCH {SQLITE_BIND}",
    -            [text])
    +        try:
    +            res = cursor.execute(
    +                f"SELECT snapshot_id FROM {table}"
    +                f" INNER JOIN {id_table}"
    +                f" ON {id_table}.rowid = {table}.rowid"
    +                f" WHERE {table} MATCH {SQLITE_BIND}",
    +                [text])
    +        except Exception as e:
    +            _handle_query_exception(e)
    +
             snap_ids = [row[0] for row in res.fetchall()]
         return snap_ids
     
     @enforce_types
     def flush(snapshot_ids: Generator[str, None, None]):
    -    snapshot_ids = list(snapshot_ids)
    +    snapshot_ids = list(snapshot_ids)  # type: ignore[assignment]
     
         id_table = _escape_sqlite3_identifier(FTS_ID_TABLE)
     
         with get_connection() as cursor:
    -        cursor.executemany(
    -            f"DELETE FROM {id_table} WHERE snapshot_id={SQLITE_BIND}",
    -            [snapshot_ids])
    +        try:
    +            cursor.executemany(
    +                f"DELETE FROM {id_table} WHERE snapshot_id={SQLITE_BIND}",
    +                [snapshot_ids])
    +        except Exception as e:
    +            _handle_query_exception(e)
    
    From 9b85f35b63c874fcc738aed1966490f397adaf0b Mon Sep 17 00:00:00 2001
    From: Ross Williams <ross@ross-williams.net>
    Date: Mon, 16 Oct 2023 14:50:48 -0400
    Subject: [PATCH 14/89] sqlite search: check SQLite version when indexing
    
    If creating the FTS5 tables fails due to a known version
    incompatiblity, report the required version to the user.
    ---
     archivebox/search/backends/sqlite.py | 23 +++++++++++++++++------
     1 file changed, 17 insertions(+), 6 deletions(-)
    
    diff --git a/archivebox/search/backends/sqlite.py b/archivebox/search/backends/sqlite.py
    index b4c61efb..2fee789a 100644
    --- a/archivebox/search/backends/sqlite.py
    +++ b/archivebox/search/backends/sqlite.py
    @@ -75,12 +75,23 @@ def _create_tables():
         with get_connection() as cursor:
             # Create a contentless-delete FTS5 table that indexes
             # but does not store the texts of snapshots
    -        cursor.execute(
    -            f"CREATE VIRTUAL TABLE {table}"
    -            f" USING fts5({column},"
    -            f" tokenize={tokenizers},"
    -            " content='', contentless_delete=1);"
    -            )
    +        try:
    +            cursor.execute(
    +                f"CREATE VIRTUAL TABLE {table}"
    +                f" USING fts5({column},"
    +                f" tokenize={tokenizers},"
    +                " content='', contentless_delete=1);"
    +                )
    +        except Exception as e:
    +            msg = str(e)
    +            if 'unrecognized option: "contentlessdelete"' in msg:
    +                sqlite_version = getattr(sqlite3, "sqlite_version", "Unknown")
    +                raise RuntimeError(
    +                    "SQLite full-text search requires SQLite >= 3.43.0;"
    +                    f" the running version is {sqlite_version}"
    +                ) from e
    +            else:
    +                raise
             # Create a one-to-one mapping between ArchiveBox snapshot_id
             # and FTS5 rowid, because the column type of rowid can't be
             # customized.
    
    From 521ea70e0cdf209dde850661e17a6bb3de3e9d34 Mon Sep 17 00:00:00 2001
    From: Ben Muthalaly <benmuthalaly@gmail.com>
    Date: Wed, 18 Oct 2023 03:07:54 -0500
    Subject: [PATCH 15/89] Add check for existing user, change varable names
    
    ---
     archivebox/config.py |  4 ++--
     archivebox/main.py   | 19 +++++++++----------
     2 files changed, 11 insertions(+), 12 deletions(-)
    
    diff --git a/archivebox/config.py b/archivebox/config.py
    index 6fd6621c..719ee34a 100644
    --- a/archivebox/config.py
    +++ b/archivebox/config.py
    @@ -91,8 +91,8 @@ CONFIG_SCHEMA: Dict[str, ConfigDefaultDict] = {
             'OUTPUT_PERMISSIONS':       {'type': str,   'default': '644'},
             'RESTRICT_FILE_NAMES':      {'type': str,   'default': 'windows'},
             'URL_BLACKLIST':            {'type': str,   'default': r'\.(css|js|otf|ttf|woff|woff2|gstatic\.com|googleapis\.com/css)(\?.*)?$'},  # to avoid downloading code assets as their own pages
    -        'ARCHIVEBOX_USERNAME':      {'type': str,   'default': None},
    -        'ARCHIVEBOX_PASSWORD':      {'type': str,   'default': None},
    +        'ADMIN_USERNAME':      {'type': str,   'default': None},
    +        'ADMIN_PASSWORD':      {'type': str,   'default': None},
             'URL_WHITELIST':            {'type': str,   'default': None},
             'ENFORCE_ATOMIC_WRITES':    {'type': bool,  'default': True},
             'TAG_SEPARATOR_PATTERN':    {'type': str,   'default': r'[,]'},
    diff --git a/archivebox/main.py b/archivebox/main.py
    index 5c6a3fd7..e811a496 100755
    --- a/archivebox/main.py
    +++ b/archivebox/main.py
    @@ -112,8 +112,8 @@ from .config import (
         load_all_config,
         CONFIG,
         USER_CONFIG,
    -    ARCHIVEBOX_USERNAME,
    -    ARCHIVEBOX_PASSWORD,
    +    ADMIN_USERNAME,
    +    ADMIN_PASSWORD,
         get_real_name,
         setup_django,
     )
    @@ -421,17 +421,16 @@ def init(force: bool=False, quick: bool=False, setup: bool=False, out_dir: Path=
             write_main_index(list(pending_links.values()), out_dir=out_dir)
     
         print('\n{green}----------------------------------------------------------------------{reset}'.format(**ANSI))
    +
    +    from django.contrib.auth.models import User
    +
    +    if (ADMIN_USERNAME and ADMIN_PASSWORD) and not User.objects.filter(username=ADMIN_USERNAME, is_superuser=True).exists():
    +        User.objects.create_superuser(username=ADMIN_USERNAME, password=ADMIN_PASSWORD)
    +        print('{green}[+] New ADMIN_USERNAME and  ADMIN_PASSWORD configuration options found. Creating new admin user.{reset}'.format(ADMIN_USERNAME, ADMIN_PASSWORD, **ANSI))
    +
         if existing_index:
             print('{green}[√] Done. Verified and updated the existing ArchiveBox collection.{reset}'.format(**ANSI))
         else:
    -        if ARCHIVEBOX_USERNAME and ARCHIVEBOX_PASSWORD:
    -            print('{green}[+] ARCHIVEBOX_USERNAME and  ARCHIVEBOX_PASSWORD configuration options found. Creating new admin user.{reset}'.format(**ANSI))
    -            from django.contrib.auth.models import User
    -            User.objects.create_superuser(username=ARCHIVEBOX_USERNAME, password=ARCHIVEBOX_PASSWORD)
    -        # if config.HTTP_USER and config.HTTP_PASS:
    -        #     from django.contrib.auth.models import User
    -        #     User.objects.create_superuser(HTTP_USER, '', HTTP_PASS)
    -
             print('{green}[√] Done. A new ArchiveBox collection was initialized ({} links).{reset}'.format(len(all_links) + len(pending_links), **ANSI))
     
         json_index = out_dir / JSON_INDEX_FILENAME
    
    From 9e6a87114b4b550e814856a00d1ab38bb030b2cc Mon Sep 17 00:00:00 2001
    From: Ben Muthalaly <benmuthalaly@gmail.com>
    Date: Wed, 18 Oct 2023 12:07:36 -0500
    Subject: [PATCH 16/89] Fix formatting, logging, logic issues
    
    ---
     archivebox/config.py | 4 ++--
     archivebox/main.py   | 4 ++--
     2 files changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/archivebox/config.py b/archivebox/config.py
    index 719ee34a..64d3d0a2 100644
    --- a/archivebox/config.py
    +++ b/archivebox/config.py
    @@ -91,8 +91,8 @@ CONFIG_SCHEMA: Dict[str, ConfigDefaultDict] = {
             'OUTPUT_PERMISSIONS':       {'type': str,   'default': '644'},
             'RESTRICT_FILE_NAMES':      {'type': str,   'default': 'windows'},
             'URL_BLACKLIST':            {'type': str,   'default': r'\.(css|js|otf|ttf|woff|woff2|gstatic\.com|googleapis\.com/css)(\?.*)?$'},  # to avoid downloading code assets as their own pages
    -        'ADMIN_USERNAME':      {'type': str,   'default': None},
    -        'ADMIN_PASSWORD':      {'type': str,   'default': None},
    +        'ADMIN_USERNAME':           {'type': str,   'default': None},
    +        'ADMIN_PASSWORD':           {'type': str,   'default': None},
             'URL_WHITELIST':            {'type': str,   'default': None},
             'ENFORCE_ATOMIC_WRITES':    {'type': bool,  'default': True},
             'TAG_SEPARATOR_PATTERN':    {'type': str,   'default': r'[,]'},
    diff --git a/archivebox/main.py b/archivebox/main.py
    index e811a496..b3c59633 100755
    --- a/archivebox/main.py
    +++ b/archivebox/main.py
    @@ -424,9 +424,9 @@ def init(force: bool=False, quick: bool=False, setup: bool=False, out_dir: Path=
     
         from django.contrib.auth.models import User
     
    -    if (ADMIN_USERNAME and ADMIN_PASSWORD) and not User.objects.filter(username=ADMIN_USERNAME, is_superuser=True).exists():
    +    if (ADMIN_USERNAME and ADMIN_PASSWORD) and not User.objects.filter(username=ADMIN_USERNAME).exists():
             User.objects.create_superuser(username=ADMIN_USERNAME, password=ADMIN_PASSWORD)
    -        print('{green}[+] New ADMIN_USERNAME and  ADMIN_PASSWORD configuration options found. Creating new admin user.{reset}'.format(ADMIN_USERNAME, ADMIN_PASSWORD, **ANSI))
    +        print('{green}[+] Found ADMIN_USERNAME and ADMIN_PASSWORD configuration options, creating new admin user.{reset}'.format(**ANSI))
     
         if existing_index:
             print('{green}[√] Done. Verified and updated the existing ArchiveBox collection.{reset}'.format(**ANSI))
    
    From d286dca925fc0f96ba1d7fbb04961b2783283022 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Wed, 18 Oct 2023 11:47:55 -0700
    Subject: [PATCH 17/89] better to log before doing a thing than after
    
    ---
     archivebox/main.py | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/archivebox/main.py b/archivebox/main.py
    index b3c59633..5268691b 100755
    --- a/archivebox/main.py
    +++ b/archivebox/main.py
    @@ -425,8 +425,8 @@ def init(force: bool=False, quick: bool=False, setup: bool=False, out_dir: Path=
         from django.contrib.auth.models import User
     
         if (ADMIN_USERNAME and ADMIN_PASSWORD) and not User.objects.filter(username=ADMIN_USERNAME).exists():
    -        User.objects.create_superuser(username=ADMIN_USERNAME, password=ADMIN_PASSWORD)
             print('{green}[+] Found ADMIN_USERNAME and ADMIN_PASSWORD configuration options, creating new admin user.{reset}'.format(**ANSI))
    +        User.objects.create_superuser(username=ADMIN_USERNAME, password=ADMIN_PASSWORD)
     
         if existing_index:
             print('{green}[√] Done. Verified and updated the existing ArchiveBox collection.{reset}'.format(**ANSI))
    
    From 6f4a7e4e6800652f14ada1d7b980c4be8cff7e30 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Wed, 18 Oct 2023 11:53:13 -0700
    Subject: [PATCH 18/89] Add ADMIN_USERNAME and ADMIN_PASSWORD to example
     options
    
    ---
     docker-compose.yml | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/docker-compose.yml b/docker-compose.yml
    index f437ae9a..f3b539a1 100644
    --- a/docker-compose.yml
    +++ b/docker-compose.yml
    @@ -34,6 +34,8 @@ services:
                 # - PUBLIC_ADD_VIEW=False           # set to True to allow anonymous users to submit new URLs to archive
                 # - PUID=1000                       # set to your host user's UID & GID if you encounter permissions issues
                 # - PGID=1000
    +            # - ADMIN_USERNAME=admin            # create an admin user on first run with the given user/pass combo
    +            # - ADMIN_PASSWORD=SomeSecretPassword
                 # - SEARCH_BACKEND_ENGINE=sonic     # uncomment these and sonic container below for better full-text search
                 # - SEARCH_BACKEND_HOST_NAME=sonic
                 # - SEARCH_BACKEND_PASSWORD=SomeSecretPassword
    
    From e9c85aa812a107a317089b3ab31cace8b932cc2d Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Wed, 18 Oct 2023 17:53:49 -0700
    Subject: [PATCH 19/89] Update README.md
    
    ---
     README.md | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/README.md b/README.md
    index c524b59c..cbf33061 100644
    --- a/README.md
    +++ b/README.md
    @@ -10,7 +10,7 @@
     <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Web-Archiving-Community">Community</a> |
     <a href="https://github.com/ArchiveBox/ArchiveBox/wiki/Roadmap">Roadmap</a>
     
    -<pre lang="bash"><code style="white-space: pre-line">"Your own personal internet archive" (网站存档 / 爬虫)
    +<pre lang="bash" align="center"><code style="white-space: pre-line; text-align: center" align="center">"Your own personal internet archive" (网站存档 / 爬虫)
     curl -sSL 'https://get.archivebox.io' | sh
     </code></pre>
     
    
    From 4f655fc4a1fc21759fe21f13b354d940ca53b4a2 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Wed, 18 Oct 2023 18:24:43 -0700
    Subject: [PATCH 20/89] Replace chown of entire data directory when ownership
     mismatch detected
    
    ---
     bin/docker_entrypoint.sh | 21 +++++++++++++--------
     1 file changed, 13 insertions(+), 8 deletions(-)
    
    diff --git a/bin/docker_entrypoint.sh b/bin/docker_entrypoint.sh
    index 62ec7cfb..71abc2bc 100755
    --- a/bin/docker_entrypoint.sh
    +++ b/bin/docker_entrypoint.sh
    @@ -12,21 +12,26 @@ if [[ -n "$PGID" && "$PGID" != 0 ]]; then
         groupmod -g "$PGID" "$ARCHIVEBOX_USER" > /dev/null 2>&1
     fi
     
    +PUID="$(id -u archivebox)"
    +PGID="$(id -g archivebox)"
     
    -# Set the permissions of the data dir to match the archivebox user
    +# Check the permissions of the data dir (or create if it doesn't exist)
     if [[ -d "$DATA_DIR/archive" ]]; then
    -    # check data directory permissions
    -    if [[ ! "$(stat -c %u $DATA_DIR/archive)" = "$(id -u archivebox)" ]]; then
    -        echo "Change in ownership detected, please be patient while we chown existing files"
    -        echo "This could take some time..."
    -        chown $ARCHIVEBOX_USER:$ARCHIVEBOX_USER -R "$DATA_DIR"
    +    if touch "$DATA_DIR/archive/.permissions_test_safe_to_delete"; then
    +        # It's fine, we are able to write to the data directory
    +        rm "$DATA_DIR/archive/.permissions_test_safe_to_delete"
    +        # echo "[√] Permissions are correct"
    +    else
    +        echo "[X] Permissions Error: ArchiveBox is not able to write to your data dir. You need to fix the data dir ownership and retry:" >2
    +        echo "    chown -R $PUID:$PGID data" >2
    +        echo "    https://docs.linuxserver.io/general/understanding-puid-and-pgid" >2
    +        exit 1
         fi
     else
         # create data directory
         mkdir -p "$DATA_DIR/logs"
    -    chown -R $ARCHIVEBOX_USER:$ARCHIVEBOX_USER "$DATA_DIR"
     fi
    -chown $ARCHIVEBOX_USER:$ARCHIVEBOX_USER "$DATA_DIR"
    +chown $ARCHIVEBOX_USER:$ARCHIVEBOX_USER "$DATA_DIR" "$DATA_DIR"/*
     
     
     # Drop permissions to run commands as the archivebox user
    
    From 0e3475a0eb8eea07a75f3746d475f6c49f701a98 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Wed, 18 Oct 2023 18:40:58 -0700
    Subject: [PATCH 21/89] Create SECURITY.md policy
    
    ---
     SECURITY.md | 34 ++++++++++++++++++++++++++++++++++
     1 file changed, 34 insertions(+)
     create mode 100644 SECURITY.md
    
    diff --git a/SECURITY.md b/SECURITY.md
    new file mode 100644
    index 00000000..8a5e1605
    --- /dev/null
    +++ b/SECURITY.md
    @@ -0,0 +1,34 @@
    +# Security Policy
    +
    +---
    +
    +## Security Information
    +
    +Please see this wiki page for important notices about ArchiveBox security, publishing your archives securely, and the dangers of executing archived JS:
    +
    +https://github.com/ArchiveBox/ArchiveBox/wiki/Security-Overview
    +
    +Also see this section of the README about important caveats when running ArchiveBox:
    +
    +https://github.com/ArchiveBox/ArchiveBox?tab=readme-ov-file#caveats
    +
    +You can also read these pages for more information about ArchiveBox's internals, development environment, DB schema, and more:
    +
    +- https://github.com/ArchiveBox/ArchiveBox#archive-layout
    +- https://github.com/ArchiveBox/ArchiveBox#archivebox-development
    +- https://github.com/ArchiveBox/ArchiveBox/wiki/Upgrading-or-Merging-Archives
    +- https://github.com/ArchiveBox/ArchiveBox/wiki/Troubleshooting
    +
    +---
    +
    +## Reporting a Vulnerability
    +
    +We use Github's built-in [Private Reporting](https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability) feature to accept vulnerability reports.
    +
    +1. Go to the Security tab on our Github repo: https://github.com/ArchiveBox/ArchiveBox/security
    +
    +2. Click "Report a Vulnerability"
    +
    +3. Fill out the form to submit the details of the report and it will be securely sent to the maintainers
    +
    +You can also contact the maintainers via our public [Zulip Chat Server zulip.archivebox.io](https://zulip.archivebox.io) or [Twitter DMs @ArchiveBoxApp](https://twitter.com/ArchiveBoxApp).
    
    From a8ce927937a334eb5bf8208b3a1d87525f83dfbf Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Thu, 19 Oct 2023 12:57:05 -0700
    Subject: [PATCH 22/89] fix markdown formatting
    
    ---
     README.md | 9 +++++++--
     1 file changed, 7 insertions(+), 2 deletions(-)
    
    diff --git a/README.md b/README.md
    index cbf33061..f0fed51a 100644
    --- a/README.md
    +++ b/README.md
    @@ -588,7 +588,8 @@ Each snapshot subfolder `./archive/<timestamp>/` includes a static `index.json`
     
     You can export the main index to browse it statically without needing to run a server.
     
    -*Note about large exports: These exports are not paginated, exporting many URLs or the entire archive at once may be slow. Use the filtering CLI flags on the `archivebox list` command to export specific Snapshots or ranges.*
    +> **Note**
    +> These exports are not paginated, exporting many URLs or the entire archive at once may be slow. Use the filtering CLI flags on the `archivebox list` command to export specific Snapshots or ranges.
     
     ```bash
     # archivebox list --help
    @@ -985,6 +986,7 @@ archivebox init --setup
     <details><summary><i>Click to expand...</i></summary>
     
     Make sure to run this whenever you change things in `models.py`.
    +
     ```bash
     cd archivebox/
     ./manage.py makemigrations
    @@ -993,6 +995,7 @@ cd path/to/test/data/
     archivebox shell
     archivebox manage dbshell
     ```
    +
     (uses `pytest -s`)  
     https://stackoverflow.com/questions/1074212/how-can-i-see-the-raw-sql-queries-django-is-running
     
    @@ -1000,7 +1003,9 @@ https://stackoverflow.com/questions/1074212/how-can-i-see-the-raw-sql-queries-dj
     
     #### Contributing a new extractor
     
    -<details><summary><i>Click to expand...</i></summary><br/><br/>
    +<details><summary><i>Click to expand...</i></summary>
    +
    +<br/><br/>
     
     ArchiveBox [`extractors`](https://github.com/ArchiveBox/ArchiveBox/blob/dev/archivebox/extractors/media.py) are external binaries or Python/Node scripts that ArchiveBox runs to archive content on a page.
     
    
    From edde40898b3af05872a26f81452d1c73dbbffa01 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Thu, 19 Oct 2023 12:58:38 -0700
    Subject: [PATCH 23/89] fix markdown underlining everything as link
    
    ---
     README.md | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/README.md b/README.md
    index f0fed51a..20dac770 100644
    --- a/README.md
    +++ b/README.md
    @@ -616,7 +616,7 @@ The paths in the static exports are relative, make sure to keep them next to you
     
     ### Archiving Private Content
     
    -<a id="archiving-private-urls"/>
    +<a id="archiving-private-urls"></a>
     
     If you're importing pages with private content or URLs containing secret tokens you don't want public (e.g Google Docs, paywalled content, unlisted videos, etc.), **you may want to disable some of the extractor methods to avoid leaking that content to 3rd party APIs or the public**.
     
    
    From a61f5445473597b1efbf55c4e95fd513ee284c6f Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Thu, 19 Oct 2023 16:18:32 -0700
    Subject: [PATCH 24/89] Update SECURITY.md
    
    ---
     SECURITY.md | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/SECURITY.md b/SECURITY.md
    index 8a5e1605..8fae71e1 100644
    --- a/SECURITY.md
    +++ b/SECURITY.md
    @@ -27,7 +27,7 @@ We use Github's built-in [Private Reporting](https://docs.github.com/en/code-sec
     
     1. Go to the Security tab on our Github repo: https://github.com/ArchiveBox/ArchiveBox/security
     
    -2. Click "Report a Vulnerability"
    +2. Click the ["Report a Vulnerability"](https://github.com/ArchiveBox/ArchiveBox/security/advisories/new) button
     
     3. Fill out the form to submit the details of the report and it will be securely sent to the maintainers
     
    
    From 6619e8005eb9cee666102d2e673f6443b834a87f Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Thu, 19 Oct 2023 16:20:43 -0700
    Subject: [PATCH 25/89] Update pip.yml github action python version
    
    ---
     .github/workflows/pip.yml | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/.github/workflows/pip.yml b/.github/workflows/pip.yml
    index 7c2d341d..8052bb60 100644
    --- a/.github/workflows/pip.yml
    +++ b/.github/workflows/pip.yml
    @@ -7,7 +7,7 @@ on:
     
     jobs:
       build:
    -    runs-on: ubuntu-20.04
    +    runs-on: ubuntu-22.04
     
         steps:
           - uses: actions/checkout@v2
    @@ -18,7 +18,7 @@ jobs:
           - name: Set up Python
             uses: actions/setup-python@v1
             with:
    -          python-version: 3.9
    +          python-version: 3.11
               architecture: x64
     
           - name: Build Python Package
    
    From 748363e685c10489f729f874c69f100969dba374 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Thu, 19 Oct 2023 16:21:32 -0700
    Subject: [PATCH 26/89] Bump required Python version to 3.9
    
    ---
     setup.py | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/setup.py b/setup.py
    index 46310ef3..6f1848d7 100755
    --- a/setup.py
    +++ b/setup.py
    @@ -28,7 +28,7 @@ PACKAGE_DIR = ROOT_DIR / PKG_NAME
     README = (PACKAGE_DIR / "README.md").read_text(encoding='utf-8', errors='ignore')
     VERSION = json.loads((PACKAGE_DIR / "package.json").read_text().strip())['version']
     
    -PYTHON_REQUIRES = ">=3.7"
    +PYTHON_REQUIRES = ">=3.9"
     SETUP_REQUIRES = ["wheel"]
     INSTALL_REQUIRES = [
         # only add things here that have corresponding apt python3-packages available
    
    From 9fa210515e9251b657430d116fbf2a2fc96425fe Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Thu, 19 Oct 2023 16:22:06 -0700
    Subject: [PATCH 27/89] Bump required python version to 3.9 in stdeb.cfg
    
    ---
     stdeb.cfg | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/stdeb.cfg b/stdeb.cfg
    index 571d4245..21bd4f1f 100644
    --- a/stdeb.cfg
    +++ b/stdeb.cfg
    @@ -6,6 +6,6 @@ Suite: focal
     Suite3: focal
     Build-Depends: debhelper, dh-python, python3-all, python3-pip, python3-setuptools, python3-wheel, python3-stdeb
     Depends3: nodejs, wget, curl, git, ffmpeg, youtube-dl, yt-dlp, python3-all, python3-pip, python3-setuptools, python3-croniter, python3-crontab, python3-dateparser, python3-django, python3-django-extensions, python3-django-jsonfield, python3-mypy-extensions, python3-requests, python3-w3lib, ripgrep
    -X-Python3-Version: >= 3.7
    -XS-Python-Version: >= 3.7
    +X-Python3-Version: >= 3.9
    +XS-Python-Version: >= 3.9
     Setup-Env-Vars: DEB_BUILD_OPTIONS=nocheck
    
    From 4b26ab9d1f11d4a311ef7d292765c11a73a57265 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Thu, 19 Oct 2023 16:29:49 -0700
    Subject: [PATCH 28/89] only load image into docker when building, and push on
     deploy
    
    ---
     bin/build_docker.sh | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/bin/build_docker.sh b/bin/build_docker.sh
    index 9377e201..1b9d32fc 100755
    --- a/bin/build_docker.sh
    +++ b/bin/build_docker.sh
    @@ -66,7 +66,7 @@ check_platforms || (recreate_builder && check_platforms) || exit 1
     
     echo "[+] Building archivebox:$VERSION docker image..."
     #docker build . \
    -docker buildx build --platform "$REQUIRED_PLATFORMS" --push . \
    +docker buildx build --platform "$REQUIRED_PLATFORMS" --load . \
                    -t archivebox \
                    -t archivebox:$TAG_NAME \
                    -t archivebox:$VERSION \
    
    From b6113cc00ced886c43cc7ae9e1fa9d8d42ac0a17 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Thu, 19 Oct 2023 16:44:44 -0700
    Subject: [PATCH 29/89] use pypa build instead of setup.py build and move ldap
     to extras
    
    ---
     bin/build_pip.sh | 11 +++++++----
     setup.py         |  5 ++++-
     2 files changed, 11 insertions(+), 5 deletions(-)
    
    diff --git a/bin/build_pip.sh b/bin/build_pip.sh
    index 532a8058..e2edace2 100755
    --- a/bin/build_pip.sh
    +++ b/bin/build_pip.sh
    @@ -25,7 +25,10 @@ cd "$REPO_DIR"
     rm -Rf build dist
     
     echo "[+] Building sdist, bdist_wheel, and egg_info"
    -python3 setup.py \
    -    sdist --dist-dir=./pip_dist \
    -    bdist_wheel --dist-dir=./pip_dist \
    -    egg_info --egg-base=./pip_dist
    +# python3 setup.py \
    +#     sdist --dist-dir=./pip_dist \
    +#     bdist_wheel --dist-dir=./pip_dist \
    +#     egg_info --egg-base=./pip_dist
    +
    +# pip install --upgrade pip setuptools build
    +python -m build
    diff --git a/setup.py b/setup.py
    index 6f1848d7..218aec47 100755
    --- a/setup.py
    +++ b/setup.py
    @@ -47,13 +47,16 @@ INSTALL_REQUIRES = [
         "croniter>=0.3.34",
         "w3lib>=1.22.0",
         "ipython>5.0.0",
    -    "django-auth-ldap>=4.1.0"
     ]
     EXTRAS_REQUIRE = {
         'sonic': [
             "sonic-client>=0.0.5",
         ],
    +    'ldap': [
    +        "django-auth-ldap>=4.1.0",
    +    ],
         'dev': [
    +        "build",
             "setuptools",
             "twine",
             "wheel",
    
    From 8caffc4b4e761750c3fb56c826103b98f15be190 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Thu, 19 Oct 2023 17:09:48 -0700
    Subject: [PATCH 30/89] ignore .pdm-python file
    
    ---
     .gitignore | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/.gitignore b/.gitignore
    index f8fefbfb..a615433e 100644
    --- a/.gitignore
    +++ b/.gitignore
    @@ -13,6 +13,7 @@ venv/
     node_modules/
     
     # Packaging artifacts
    +.pdm-python
     archivebox.egg-info
     archivebox-*.tar.gz
     build/
    
    From 53cff45ec0cb378ae2bb3f632024a1c56e1f4348 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Thu, 19 Oct 2023 17:49:06 -0700
    Subject: [PATCH 31/89] switch from pipenv and setup.py to PDM for python
     packaging
    
    ---
     package.json   |    3 +-
     pdm.lock       | 2077 ++++++++++++++++++++++++++++++++++++++++++++++++
     pyproject.toml |  118 +++
     setup.py       |  269 +++----
     4 files changed, 2331 insertions(+), 136 deletions(-)
     create mode 100644 pdm.lock
     create mode 100644 pyproject.toml
    
    diff --git a/package.json b/package.json
    index bed564cc..4eb06c3d 100644
    --- a/package.json
    +++ b/package.json
    @@ -1,13 +1,12 @@
     {
       "name": "archivebox",
    -  "version": "0.6.3",
    +  "version": "0.7.0",
       "description": "ArchiveBox: The self-hosted internet archive",
       "author": "Nick Sweeting <archivebox-npm@sweeting.me>",
       "repository": "github:ArchiveBox/ArchiveBox",
       "license": "MIT",
       "dependencies": {
         "@postlight/mercury-parser": "git+https://github.com/postlight/mercury-parser.git",
    -    "playwright": "^1.37.1",
         "readability-extractor": "git+https://github.com/ArchiveBox/readability-extractor.git",
         "single-file-cli": "^1.0.63"
       }
    diff --git a/pdm.lock b/pdm.lock
    new file mode 100644
    index 00000000..daa74436
    --- /dev/null
    +++ b/pdm.lock
    @@ -0,0 +1,2077 @@
    +# This file is @generated by PDM.
    +# It is not intended for manual editing.
    +
    +[metadata]
    +groups = ["default", "build", "debug", "doc", "ldap", "lint", "sonic", "test"]
    +cross_platform = true
    +static_urls = false
    +lock_version = "4.3"
    +content_hash = "sha256:ae301f566235b00b28cb62a560f1ff1e30f2e0f3e16b0ddae12e97502214b02c"
    +
    +[[package]]
    +name = "alabaster"
    +version = "0.7.13"
    +requires_python = ">=3.6"
    +summary = "A configurable sidebar-enabled Sphinx theme"
    +files = [
    +    {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"},
    +    {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"},
    +]
    +
    +[[package]]
    +name = "appnope"
    +version = "0.1.3"
    +summary = "Disable App Nap on macOS >= 10.9"
    +files = [
    +    {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"},
    +    {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"},
    +]
    +
    +[[package]]
    +name = "asgiref"
    +version = "3.7.2"
    +requires_python = ">=3.7"
    +summary = "ASGI specs, helper code, and adapters"
    +dependencies = [
    +    "typing-extensions>=4; python_version < \"3.11\"",
    +]
    +files = [
    +    {file = "asgiref-3.7.2-py3-none-any.whl", hash = "sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e"},
    +    {file = "asgiref-3.7.2.tar.gz", hash = "sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed"},
    +]
    +
    +[[package]]
    +name = "asttokens"
    +version = "2.4.0"
    +summary = "Annotate AST trees with source code positions"
    +dependencies = [
    +    "six>=1.12.0",
    +]
    +files = [
    +    {file = "asttokens-2.4.0-py2.py3-none-any.whl", hash = "sha256:cf8fc9e61a86461aa9fb161a14a0841a03c405fa829ac6b202670b3495d2ce69"},
    +    {file = "asttokens-2.4.0.tar.gz", hash = "sha256:2e0171b991b2c959acc6c49318049236844a5da1d65ba2672c4880c1c894834e"},
    +]
    +
    +[[package]]
    +name = "babel"
    +version = "2.13.0"
    +requires_python = ">=3.7"
    +summary = "Internationalization utilities"
    +files = [
    +    {file = "Babel-2.13.0-py3-none-any.whl", hash = "sha256:fbfcae1575ff78e26c7449136f1abbefc3c13ce542eeb13d43d50d8b047216ec"},
    +    {file = "Babel-2.13.0.tar.gz", hash = "sha256:04c3e2d28d2b7681644508f836be388ae49e0cfe91465095340395b60d00f210"},
    +]
    +
    +[[package]]
    +name = "backcall"
    +version = "0.2.0"
    +summary = "Specifications for callback functions passed in to an API"
    +files = [
    +    {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"},
    +    {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"},
    +]
    +
    +[[package]]
    +name = "blinker"
    +version = "1.6.3"
    +requires_python = ">=3.7"
    +summary = "Fast, simple object-to-object and broadcast signaling"
    +files = [
    +    {file = "blinker-1.6.3-py3-none-any.whl", hash = "sha256:296320d6c28b006eb5e32d4712202dbcdcbf5dc482da298c2f44881c43884aaa"},
    +    {file = "blinker-1.6.3.tar.gz", hash = "sha256:152090d27c1c5c722ee7e48504b02d76502811ce02e1523553b4cf8c8b3d3a8d"},
    +]
    +
    +[[package]]
    +name = "bottle"
    +version = "0.12.25"
    +summary = "Fast and simple WSGI-framework for small web-applications."
    +files = [
    +    {file = "bottle-0.12.25-py3-none-any.whl", hash = "sha256:d6f15f9d422670b7c073d63bd8d287b135388da187a0f3e3c19293626ce034ea"},
    +    {file = "bottle-0.12.25.tar.gz", hash = "sha256:e1a9c94970ae6d710b3fb4526294dfeb86f2cb4a81eff3a4b98dc40fb0e5e021"},
    +]
    +
    +[[package]]
    +name = "brotli"
    +version = "1.1.0"
    +summary = "Python bindings for the Brotli compression library"
    +files = [
    +    {file = "Brotli-1.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e1140c64812cb9b06c922e77f1c26a75ec5e3f0fb2bf92cc8c58720dec276752"},
    +    {file = "Brotli-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c8fd5270e906eef71d4a8d19b7c6a43760c6abcfcc10c9101d14eb2357418de9"},
    +    {file = "Brotli-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ae56aca0402a0f9a3431cddda62ad71666ca9d4dc3a10a142b9dce2e3c0cda3"},
    +    {file = "Brotli-1.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43ce1b9935bfa1ede40028054d7f48b5469cd02733a365eec8a329ffd342915d"},
    +    {file = "Brotli-1.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:7c4855522edb2e6ae7fdb58e07c3ba9111e7621a8956f481c68d5d979c93032e"},
    +    {file = "Brotli-1.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:38025d9f30cf4634f8309c6874ef871b841eb3c347e90b0851f63d1ded5212da"},
    +    {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e6a904cb26bfefc2f0a6f240bdf5233be78cd2488900a2f846f3c3ac8489ab80"},
    +    {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d"},
    +    {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0"},
    +    {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e"},
    +    {file = "Brotli-1.1.0-cp310-cp310-win32.whl", hash = "sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2"},
    +    {file = "Brotli-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128"},
    +    {file = "Brotli-1.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc"},
    +    {file = "Brotli-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c8146669223164fc87a7e3de9f81e9423c67a79d6b3447994dfb9c95da16e2d6"},
    +    {file = "Brotli-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30924eb4c57903d5a7526b08ef4a584acc22ab1ffa085faceb521521d2de32dd"},
    +    {file = "Brotli-1.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ceb64bbc6eac5a140ca649003756940f8d6a7c444a68af170b3187623b43bebf"},
    +    {file = "Brotli-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a469274ad18dc0e4d316eefa616d1d0c2ff9da369af19fa6f3daa4f09671fd61"},
    +    {file = "Brotli-1.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:524f35912131cc2cabb00edfd8d573b07f2d9f21fa824bd3fb19725a9cf06327"},
    +    {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5b3cc074004d968722f51e550b41a27be656ec48f8afaeeb45ebf65b561481dd"},
    +    {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9"},
    +    {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265"},
    +    {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a1fd8a29719ccce974d523580987b7f8229aeace506952fa9ce1d53a033873c8"},
    +    {file = "Brotli-1.1.0-cp311-cp311-win32.whl", hash = "sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50"},
    +    {file = "Brotli-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1"},
    +    {file = "Brotli-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409"},
    +    {file = "Brotli-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2"},
    +    {file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451"},
    +    {file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7f4bf76817c14aa98cc6697ac02f3972cb8c3da93e9ef16b9c66573a68014f91"},
    +    {file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0c5516f0aed654134a2fc936325cc2e642f8a0e096d075209672eb321cff408"},
    +    {file = "Brotli-1.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c3020404e0b5eefd7c9485ccf8393cfb75ec38ce75586e046573c9dc29967a0"},
    +    {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4ed11165dd45ce798d99a136808a794a748d5dc38511303239d4e2363c0695dc"},
    +    {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180"},
    +    {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248"},
    +    {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966"},
    +    {file = "Brotli-1.1.0-cp312-cp312-win32.whl", hash = "sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0"},
    +    {file = "Brotli-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951"},
    +    {file = "Brotli-1.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5fb2ce4b8045c78ebbc7b8f3c15062e435d47e7393cc57c25115cfd49883747a"},
    +    {file = "Brotli-1.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7905193081db9bfa73b1219140b3d315831cbff0d8941f22da695832f0dd188f"},
    +    {file = "Brotli-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a77def80806c421b4b0af06f45d65a136e7ac0bdca3c09d9e2ea4e515367c7e9"},
    +    {file = "Brotli-1.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dadd1314583ec0bf2d1379f7008ad627cd6336625d6679cf2f8e67081b83acf"},
    +    {file = "Brotli-1.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:901032ff242d479a0efa956d853d16875d42157f98951c0230f69e69f9c09bac"},
    +    {file = "Brotli-1.1.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:22fc2a8549ffe699bfba2256ab2ed0421a7b8fadff114a3d201794e45a9ff578"},
    +    {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ae15b066e5ad21366600ebec29a7ccbc86812ed267e4b28e860b8ca16a2bc474"},
    +    {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:949f3b7c29912693cee0afcf09acd6ebc04c57af949d9bf77d6101ebb61e388c"},
    +    {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:89f4988c7203739d48c6f806f1e87a1d96e0806d44f0fba61dba81392c9e474d"},
    +    {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:de6551e370ef19f8de1807d0a9aa2cdfdce2e85ce88b122fe9f6b2b076837e59"},
    +    {file = "Brotli-1.1.0-cp39-cp39-win32.whl", hash = "sha256:f0d8a7a6b5983c2496e364b969f0e526647a06b075d034f3297dc66f3b360c64"},
    +    {file = "Brotli-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:cdad5b9014d83ca68c25d2e9444e28e967ef16e80f6b436918c700c117a85467"},
    +    {file = "Brotli-1.1.0.tar.gz", hash = "sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724"},
    +]
    +
    +[[package]]
    +name = "brotlicffi"
    +version = "1.1.0.0"
    +requires_python = ">=3.7"
    +summary = "Python CFFI bindings to the Brotli library"
    +dependencies = [
    +    "cffi>=1.0.0",
    +]
    +files = [
    +    {file = "brotlicffi-1.1.0.0-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9b7ae6bd1a3f0df532b6d67ff674099a96d22bc0948955cb338488c31bfb8851"},
    +    {file = "brotlicffi-1.1.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19ffc919fa4fc6ace69286e0a23b3789b4219058313cf9b45625016bf7ff996b"},
    +    {file = "brotlicffi-1.1.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9feb210d932ffe7798ee62e6145d3a757eb6233aa9a4e7db78dd3690d7755814"},
    +    {file = "brotlicffi-1.1.0.0-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84763dbdef5dd5c24b75597a77e1b30c66604725707565188ba54bab4f114820"},
    +    {file = "brotlicffi-1.1.0.0-cp37-abi3-win32.whl", hash = "sha256:1b12b50e07c3911e1efa3a8971543e7648100713d4e0971b13631cce22c587eb"},
    +    {file = "brotlicffi-1.1.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:994a4f0681bb6c6c3b0925530a1926b7a189d878e6e5e38fae8efa47c5d9c613"},
    +    {file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2e4aeb0bd2540cb91b069dbdd54d458da8c4334ceaf2d25df2f4af576d6766ca"},
    +    {file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b7b0033b0d37bb33009fb2fef73310e432e76f688af76c156b3594389d81391"},
    +    {file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54a07bb2374a1eba8ebb52b6fafffa2afd3c4df85ddd38fcc0511f2bb387c2a8"},
    +    {file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7901a7dc4b88f1c1475de59ae9be59799db1007b7d059817948d8e4f12e24e35"},
    +    {file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ce01c7316aebc7fce59da734286148b1d1b9455f89cf2c8a4dfce7d41db55c2d"},
    +    {file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:246f1d1a90279bb6069de3de8d75a8856e073b8ff0b09dcca18ccc14cec85979"},
    +    {file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc4bc5d82bc56ebd8b514fb8350cfac4627d6b0743382e46d033976a5f80fab6"},
    +    {file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37c26ecb14386a44b118ce36e546ce307f4810bc9598a6e6cb4f7fca725ae7e6"},
    +    {file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca72968ae4eaf6470498d5c2887073f7efe3b1e7d7ec8be11a06a79cc810e990"},
    +    {file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:add0de5b9ad9e9aa293c3aa4e9deb2b61e99ad6c1634e01d01d98c03e6a354cc"},
    +    {file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9b6068e0f3769992d6b622a1cd2e7835eae3cf8d9da123d7f51ca9c1e9c333e5"},
    +    {file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8557a8559509b61e65083f8782329188a250102372576093c88930c875a69838"},
    +    {file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a7ae37e5d79c5bdfb5b4b99f2715a6035e6c5bf538c3746abc8e26694f92f33"},
    +    {file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:391151ec86bb1c683835980f4816272a87eaddc46bb91cbf44f62228b84d8cca"},
    +    {file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2f3711be9290f0453de8eed5275d93d286abe26b08ab4a35d7452caa1fef532f"},
    +    {file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1a807d760763e398bbf2c6394ae9da5815901aa93ee0a37bca5efe78d4ee3171"},
    +    {file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa8ca0623b26c94fccc3a1fdd895be1743b838f3917300506d04aa3346fd2a14"},
    +    {file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3de0cf28a53a3238b252aca9fed1593e9d36c1d116748013339f0949bfc84112"},
    +    {file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6be5ec0e88a4925c91f3dea2bb0013b3a2accda6f77238f76a34a1ea532a1cb0"},
    +    {file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d9eb71bb1085d996244439154387266fd23d6ad37161f6f52f1cd41dd95a3808"},
    +    {file = "brotlicffi-1.1.0.0.tar.gz", hash = "sha256:b77827a689905143f87915310b93b273ab17888fd43ef350d4832c4a71083c13"},
    +]
    +
    +[[package]]
    +name = "cachecontrol"
    +version = "0.13.1"
    +requires_python = ">=3.7"
    +summary = "httplib2 caching for requests"
    +dependencies = [
    +    "msgpack>=0.5.2",
    +    "requests>=2.16.0",
    +]
    +files = [
    +    {file = "cachecontrol-0.13.1-py3-none-any.whl", hash = "sha256:95dedbec849f46dda3137866dc28b9d133fc9af55f5b805ab1291833e4457aa4"},
    +    {file = "cachecontrol-0.13.1.tar.gz", hash = "sha256:f012366b79d2243a6118309ce73151bf52a38d4a5dac8ea57f09bd29087e506b"},
    +]
    +
    +[[package]]
    +name = "cachecontrol"
    +version = "0.13.1"
    +extras = ["filecache"]
    +requires_python = ">=3.7"
    +summary = "httplib2 caching for requests"
    +dependencies = [
    +    "cachecontrol==0.13.1",
    +    "filelock>=3.8.0",
    +]
    +files = [
    +    {file = "cachecontrol-0.13.1-py3-none-any.whl", hash = "sha256:95dedbec849f46dda3137866dc28b9d133fc9af55f5b805ab1291833e4457aa4"},
    +    {file = "cachecontrol-0.13.1.tar.gz", hash = "sha256:f012366b79d2243a6118309ce73151bf52a38d4a5dac8ea57f09bd29087e506b"},
    +]
    +
    +[[package]]
    +name = "certifi"
    +version = "2023.7.22"
    +requires_python = ">=3.6"
    +summary = "Python package for providing Mozilla's CA Bundle."
    +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 = "cffi"
    +version = "1.16.0"
    +requires_python = ">=3.8"
    +summary = "Foreign Function Interface for Python calling C code."
    +dependencies = [
    +    "pycparser",
    +]
    +files = [
    +    {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"},
    +    {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"},
    +    {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"},
    +    {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"},
    +    {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"},
    +    {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"},
    +    {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"},
    +    {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"},
    +    {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"},
    +    {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"},
    +    {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"},
    +    {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"},
    +    {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"},
    +    {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"},
    +    {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"},
    +    {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"},
    +    {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"},
    +    {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"},
    +    {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"},
    +    {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"},
    +    {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"},
    +    {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"},
    +    {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"},
    +    {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"},
    +    {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"},
    +    {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"},
    +    {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"},
    +    {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"},
    +    {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"},
    +    {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"},
    +    {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"},
    +    {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"},
    +    {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"},
    +    {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"},
    +    {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"},
    +    {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"},
    +    {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"},
    +    {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"},
    +    {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"},
    +    {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"},
    +    {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"},
    +    {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"},
    +    {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"},
    +    {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"},
    +]
    +
    +[[package]]
    +name = "charset-normalizer"
    +version = "3.3.0"
    +requires_python = ">=3.7.0"
    +summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
    +files = [
    +    {file = "charset-normalizer-3.3.0.tar.gz", hash = "sha256:63563193aec44bce707e0c5ca64ff69fa72ed7cf34ce6e11d5127555756fd2f6"},
    +    {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:effe5406c9bd748a871dbcaf3ac69167c38d72db8c9baf3ff954c344f31c4cbe"},
    +    {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4162918ef3098851fcd8a628bf9b6a98d10c380725df9e04caf5ca6dd48c847a"},
    +    {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0570d21da019941634a531444364f2482e8db0b3425fcd5ac0c36565a64142c8"},
    +    {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5707a746c6083a3a74b46b3a631d78d129edab06195a92a8ece755aac25a3f3d"},
    +    {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:278c296c6f96fa686d74eb449ea1697f3c03dc28b75f873b65b5201806346a69"},
    +    {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a4b71f4d1765639372a3b32d2638197f5cd5221b19531f9245fcc9ee62d38f56"},
    +    {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5969baeaea61c97efa706b9b107dcba02784b1601c74ac84f2a532ea079403e"},
    +    {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3f93dab657839dfa61025056606600a11d0b696d79386f974e459a3fbc568ec"},
    +    {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:db756e48f9c5c607b5e33dd36b1d5872d0422e960145b08ab0ec7fd420e9d649"},
    +    {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:232ac332403e37e4a03d209a3f92ed9071f7d3dbda70e2a5e9cff1c4ba9f0678"},
    +    {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e5c1502d4ace69a179305abb3f0bb6141cbe4714bc9b31d427329a95acfc8bdd"},
    +    {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:2502dd2a736c879c0f0d3e2161e74d9907231e25d35794584b1ca5284e43f596"},
    +    {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23e8565ab7ff33218530bc817922fae827420f143479b753104ab801145b1d5b"},
    +    {file = "charset_normalizer-3.3.0-cp310-cp310-win32.whl", hash = "sha256:1872d01ac8c618a8da634e232f24793883d6e456a66593135aeafe3784b0848d"},
    +    {file = "charset_normalizer-3.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:557b21a44ceac6c6b9773bc65aa1b4cc3e248a5ad2f5b914b91579a32e22204d"},
    +    {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d7eff0f27edc5afa9e405f7165f85a6d782d308f3b6b9d96016c010597958e63"},
    +    {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a685067d05e46641d5d1623d7c7fdf15a357546cbb2f71b0ebde91b175ffc3e"},
    +    {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0d3d5b7db9ed8a2b11a774db2bbea7ba1884430a205dbd54a32d61d7c2a190fa"},
    +    {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2935ffc78db9645cb2086c2f8f4cfd23d9b73cc0dc80334bc30aac6f03f68f8c"},
    +    {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fe359b2e3a7729010060fbca442ca225280c16e923b37db0e955ac2a2b72a05"},
    +    {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:380c4bde80bce25c6e4f77b19386f5ec9db230df9f2f2ac1e5ad7af2caa70459"},
    +    {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0d1e3732768fecb052d90d62b220af62ead5748ac51ef61e7b32c266cac9293"},
    +    {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1b2919306936ac6efb3aed1fbf81039f7087ddadb3160882a57ee2ff74fd2382"},
    +    {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f8888e31e3a85943743f8fc15e71536bda1c81d5aa36d014a3c0c44481d7db6e"},
    +    {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:82eb849f085624f6a607538ee7b83a6d8126df6d2f7d3b319cb837b289123078"},
    +    {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7b8b8bf1189b3ba9b8de5c8db4d541b406611a71a955bbbd7385bbc45fcb786c"},
    +    {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5adf257bd58c1b8632046bbe43ee38c04e1038e9d37de9c57a94d6bd6ce5da34"},
    +    {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c350354efb159b8767a6244c166f66e67506e06c8924ed74669b2c70bc8735b1"},
    +    {file = "charset_normalizer-3.3.0-cp311-cp311-win32.whl", hash = "sha256:02af06682e3590ab952599fbadac535ede5d60d78848e555aa58d0c0abbde786"},
    +    {file = "charset_normalizer-3.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:86d1f65ac145e2c9ed71d8ffb1905e9bba3a91ae29ba55b4c46ae6fc31d7c0d4"},
    +    {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3b447982ad46348c02cb90d230b75ac34e9886273df3a93eec0539308a6296d7"},
    +    {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:abf0d9f45ea5fb95051c8bfe43cb40cda383772f7e5023a83cc481ca2604d74e"},
    +    {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b09719a17a2301178fac4470d54b1680b18a5048b481cb8890e1ef820cb80455"},
    +    {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3d9b48ee6e3967b7901c052b670c7dda6deb812c309439adaffdec55c6d7b78"},
    +    {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:edfe077ab09442d4ef3c52cb1f9dab89bff02f4524afc0acf2d46be17dc479f5"},
    +    {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3debd1150027933210c2fc321527c2299118aa929c2f5a0a80ab6953e3bd1908"},
    +    {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86f63face3a527284f7bb8a9d4f78988e3c06823f7bea2bd6f0e0e9298ca0403"},
    +    {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24817cb02cbef7cd499f7c9a2735286b4782bd47a5b3516a0e84c50eab44b98e"},
    +    {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c71f16da1ed8949774ef79f4a0260d28b83b3a50c6576f8f4f0288d109777989"},
    +    {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9cf3126b85822c4e53aa28c7ec9869b924d6fcfb76e77a45c44b83d91afd74f9"},
    +    {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:b3b2316b25644b23b54a6f6401074cebcecd1244c0b8e80111c9a3f1c8e83d65"},
    +    {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:03680bb39035fbcffe828eae9c3f8afc0428c91d38e7d61aa992ef7a59fb120e"},
    +    {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cc152c5dd831641e995764f9f0b6589519f6f5123258ccaca8c6d34572fefa8"},
    +    {file = "charset_normalizer-3.3.0-cp312-cp312-win32.whl", hash = "sha256:b8f3307af845803fb0b060ab76cf6dd3a13adc15b6b451f54281d25911eb92df"},
    +    {file = "charset_normalizer-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:8eaf82f0eccd1505cf39a45a6bd0a8cf1c70dcfc30dba338207a969d91b965c0"},
    +    {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e0fc42822278451bc13a2e8626cf2218ba570f27856b536e00cfa53099724828"},
    +    {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:09c77f964f351a7369cc343911e0df63e762e42bac24cd7d18525961c81754f4"},
    +    {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12ebea541c44fdc88ccb794a13fe861cc5e35d64ed689513a5c03d05b53b7c82"},
    +    {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:805dfea4ca10411a5296bcc75638017215a93ffb584c9e344731eef0dcfb026a"},
    +    {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96c2b49eb6a72c0e4991d62406e365d87067ca14c1a729a870d22354e6f68115"},
    +    {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aaf7b34c5bc56b38c931a54f7952f1ff0ae77a2e82496583b247f7c969eb1479"},
    +    {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:619d1c96099be5823db34fe89e2582b336b5b074a7f47f819d6b3a57ff7bdb86"},
    +    {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0ac5e7015a5920cfce654c06618ec40c33e12801711da6b4258af59a8eff00a"},
    +    {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:93aa7eef6ee71c629b51ef873991d6911b906d7312c6e8e99790c0f33c576f89"},
    +    {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7966951325782121e67c81299a031f4c115615e68046f79b85856b86ebffc4cd"},
    +    {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:02673e456dc5ab13659f85196c534dc596d4ef260e4d86e856c3b2773ce09843"},
    +    {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:c2af80fb58f0f24b3f3adcb9148e6203fa67dd3f61c4af146ecad033024dde43"},
    +    {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:153e7b6e724761741e0974fc4dcd406d35ba70b92bfe3fedcb497226c93b9da7"},
    +    {file = "charset_normalizer-3.3.0-cp39-cp39-win32.whl", hash = "sha256:d47ecf253780c90ee181d4d871cd655a789da937454045b17b5798da9393901a"},
    +    {file = "charset_normalizer-3.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:d97d85fa63f315a8bdaba2af9a6a686e0eceab77b3089af45133252618e70884"},
    +    {file = "charset_normalizer-3.3.0-py3-none-any.whl", hash = "sha256:e46cd37076971c1040fc8c41273a8b3e2c624ce4f2be3f5dfcb7a430c1d3acc2"},
    +]
    +
    +[[package]]
    +name = "colorama"
    +version = "0.4.6"
    +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
    +summary = "Cross-platform colored terminal text."
    +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 = "commonmark"
    +version = "0.9.1"
    +summary = "Python parser for the CommonMark Markdown spec"
    +files = [
    +    {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"},
    +    {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"},
    +]
    +
    +[[package]]
    +name = "croniter"
    +version = "2.0.1"
    +requires_python = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
    +summary = "croniter provides iteration for datetime object with cron like format"
    +dependencies = [
    +    "python-dateutil",
    +    "pytz>2021.1",
    +]
    +files = [
    +    {file = "croniter-2.0.1-py2.py3-none-any.whl", hash = "sha256:4cb064ce2d8f695b3b078be36ff50115cf8ac306c10a7e8653ee2a5b534673d7"},
    +    {file = "croniter-2.0.1.tar.gz", hash = "sha256:d199b2ec3ea5e82988d1f72022433c5f9302b3b3ea9e6bfd6a1518f6ea5e700a"},
    +]
    +
    +[[package]]
    +name = "cryptography"
    +version = "41.0.4"
    +requires_python = ">=3.7"
    +summary = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
    +dependencies = [
    +    "cffi>=1.12",
    +]
    +files = [
    +    {file = "cryptography-41.0.4-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:80907d3faa55dc5434a16579952ac6da800935cd98d14dbd62f6f042c7f5e839"},
    +    {file = "cryptography-41.0.4-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:35c00f637cd0b9d5b6c6bd11b6c3359194a8eba9c46d4e875a3660e3b400005f"},
    +    {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cecfefa17042941f94ab54f769c8ce0fe14beff2694e9ac684176a2535bf9714"},
    +    {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e40211b4923ba5a6dc9769eab704bdb3fbb58d56c5b336d30996c24fcf12aadb"},
    +    {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:23a25c09dfd0d9f28da2352503b23e086f8e78096b9fd585d1d14eca01613e13"},
    +    {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2ed09183922d66c4ec5fdaa59b4d14e105c084dd0febd27452de8f6f74704143"},
    +    {file = "cryptography-41.0.4-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5a0f09cefded00e648a127048119f77bc2b2ec61e736660b5789e638f43cc397"},
    +    {file = "cryptography-41.0.4-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:9eeb77214afae972a00dee47382d2591abe77bdae166bda672fb1e24702a3860"},
    +    {file = "cryptography-41.0.4-cp37-abi3-win32.whl", hash = "sha256:3b224890962a2d7b57cf5eeb16ccaafba6083f7b811829f00476309bce2fe0fd"},
    +    {file = "cryptography-41.0.4-cp37-abi3-win_amd64.whl", hash = "sha256:c880eba5175f4307129784eca96f4e70b88e57aa3f680aeba3bab0e980b0f37d"},
    +    {file = "cryptography-41.0.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:004b6ccc95943f6a9ad3142cfabcc769d7ee38a3f60fb0dddbfb431f818c3a67"},
    +    {file = "cryptography-41.0.4-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:86defa8d248c3fa029da68ce61fe735432b047e32179883bdb1e79ed9bb8195e"},
    +    {file = "cryptography-41.0.4-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:37480760ae08065437e6573d14be973112c9e6dcaf5f11d00147ee74f37a3829"},
    +    {file = "cryptography-41.0.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b5f4dfe950ff0479f1f00eda09c18798d4f49b98f4e2006d644b3301682ebdca"},
    +    {file = "cryptography-41.0.4-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7e53db173370dea832190870e975a1e09c86a879b613948f09eb49324218c14d"},
    +    {file = "cryptography-41.0.4-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5b72205a360f3b6176485a333256b9bcd48700fc755fef51c8e7e67c4b63e3ac"},
    +    {file = "cryptography-41.0.4-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:93530900d14c37a46ce3d6c9e6fd35dbe5f5601bf6b3a5c325c7bffc030344d9"},
    +    {file = "cryptography-41.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efc8ad4e6fc4f1752ebfb58aefece8b4e3c4cae940b0994d43649bdfce8d0d4f"},
    +    {file = "cryptography-41.0.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c3391bd8e6de35f6f1140e50aaeb3e2b3d6a9012536ca23ab0d9c35ec18c8a91"},
    +    {file = "cryptography-41.0.4-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:0d9409894f495d465fe6fda92cb70e8323e9648af912d5b9141d616df40a87b8"},
    +    {file = "cryptography-41.0.4-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:8ac4f9ead4bbd0bc8ab2d318f97d85147167a488be0e08814a37eb2f439d5cf6"},
    +    {file = "cryptography-41.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:047c4603aeb4bbd8db2756e38f5b8bd7e94318c047cfe4efeb5d715e08b49311"},
    +    {file = "cryptography-41.0.4.tar.gz", hash = "sha256:7febc3094125fc126a7f6fb1f420d0da639f3f32cb15c8ff0dc3997c4549f51a"},
    +]
    +
    +[[package]]
    +name = "dateparser"
    +version = "1.1.8"
    +requires_python = ">=3.7"
    +summary = "Date parsing library designed to parse dates from HTML pages"
    +dependencies = [
    +    "python-dateutil",
    +    "pytz",
    +    "regex!=2019.02.19,!=2021.8.27",
    +    "tzlocal",
    +]
    +files = [
    +    {file = "dateparser-1.1.8-py2.py3-none-any.whl", hash = "sha256:070b29b5bbf4b1ec2cd51c96ea040dc68a614de703910a91ad1abba18f9f379f"},
    +    {file = "dateparser-1.1.8.tar.gz", hash = "sha256:86b8b7517efcc558f085a142cdb7620f0921543fcabdb538c8a4c4001d8178e3"},
    +]
    +
    +[[package]]
    +name = "decorator"
    +version = "5.1.1"
    +requires_python = ">=3.5"
    +summary = "Decorators for Humans"
    +files = [
    +    {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"},
    +    {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"},
    +]
    +
    +[[package]]
    +name = "distlib"
    +version = "0.3.7"
    +summary = "Distribution utilities"
    +files = [
    +    {file = "distlib-0.3.7-py2.py3-none-any.whl", hash = "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057"},
    +    {file = "distlib-0.3.7.tar.gz", hash = "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8"},
    +]
    +
    +[[package]]
    +name = "django"
    +version = "3.1.14"
    +requires_python = ">=3.6"
    +summary = "A high-level Python Web framework that encourages rapid development and clean, pragmatic design."
    +dependencies = [
    +    "asgiref<4,>=3.2.10",
    +    "pytz",
    +    "sqlparse>=0.2.2",
    +]
    +files = [
    +    {file = "Django-3.1.14-py3-none-any.whl", hash = "sha256:0fabc786489af16ad87a8c170ba9d42bfd23f7b699bd5ef05675864e8d012859"},
    +    {file = "Django-3.1.14.tar.gz", hash = "sha256:72a4a5a136a214c39cf016ccdd6b69e2aa08c7479c66d93f3a9b5e4bb9d8a347"},
    +]
    +
    +[[package]]
    +name = "django-auth-ldap"
    +version = "4.1.0"
    +requires_python = ">=3.7"
    +summary = "Django LDAP authentication backend."
    +dependencies = [
    +    "Django>=2.2",
    +    "python-ldap>=3.1",
    +]
    +files = [
    +    {file = "django-auth-ldap-4.1.0.tar.gz", hash = "sha256:77f749d3b17807ce8eb56a9c9c8e5746ff316567f81d5ba613495d9c7495a949"},
    +    {file = "django_auth_ldap-4.1.0-py3-none-any.whl", hash = "sha256:68870e7921e84b1a9867e268a9c8a3e573e8a0d95ea08bcf31be178f5826ff36"},
    +]
    +
    +[[package]]
    +name = "django-debug-toolbar"
    +version = "3.2.4"
    +requires_python = ">=3.6"
    +summary = "A configurable set of panels that display various debug information about the current request/response."
    +dependencies = [
    +    "Django>=2.2",
    +    "sqlparse>=0.2.0",
    +]
    +files = [
    +    {file = "django-debug-toolbar-3.2.4.tar.gz", hash = "sha256:644bbd5c428d3283aa9115722471769cac1bec189edf3a0c855fd8ff870375a9"},
    +    {file = "django_debug_toolbar-3.2.4-py3-none-any.whl", hash = "sha256:6b633b6cfee24f232d73569870f19aa86c819d750e7f3e833f2344a9eb4b4409"},
    +]
    +
    +[[package]]
    +name = "django-extensions"
    +version = "3.1.5"
    +requires_python = ">=3.6"
    +summary = "Extensions for Django"
    +dependencies = [
    +    "Django>=2.2",
    +]
    +files = [
    +    {file = "django-extensions-3.1.5.tar.gz", hash = "sha256:28e1e1bf49f0e00307ba574d645b0af3564c981a6dfc87209d48cb98f77d0b1a"},
    +    {file = "django_extensions-3.1.5-py3-none-any.whl", hash = "sha256:9238b9e016bb0009d621e05cf56ea8ce5cce9b32e91ad2026996a7377ca28069"},
    +]
    +
    +[[package]]
    +name = "django-stubs"
    +version = "4.2.5"
    +requires_python = ">=3.8"
    +summary = "Mypy stubs for Django"
    +dependencies = [
    +    "django",
    +    "django-stubs-ext>=4.2.5",
    +    "mypy>=1.0.0",
    +    "tomli; python_version < \"3.11\"",
    +    "types-PyYAML",
    +    "types-pytz",
    +    "typing-extensions",
    +]
    +files = [
    +    {file = "django-stubs-4.2.5.tar.gz", hash = "sha256:5a23cf622f1426a0b0c48bd6e2ef709a66275d72073baf6fdf5ac36fc4cce736"},
    +    {file = "django_stubs-4.2.5-py3-none-any.whl", hash = "sha256:706b2456bd0e56c468dfd8f27b0e7dde001c5c7cd3010d67fcbda9d95467e050"},
    +]
    +
    +[[package]]
    +name = "django-stubs-ext"
    +version = "4.2.5"
    +requires_python = ">=3.8"
    +summary = "Monkey-patching and extensions for django-stubs"
    +dependencies = [
    +    "django",
    +    "typing-extensions",
    +]
    +files = [
    +    {file = "django-stubs-ext-4.2.5.tar.gz", hash = "sha256:8c4d1fb5f68419b3b2474c659681a189803e27d6a5e5abf5aa0da57601b58633"},
    +    {file = "django_stubs_ext-4.2.5-py3-none-any.whl", hash = "sha256:921cd7ae4614e74c234bc0fe86ee75537d163addfe1fc6f134bf03e29d86c01e"},
    +]
    +
    +[[package]]
    +name = "djdt-flamegraph"
    +version = "0.2.13"
    +summary = "Flamegraphs for Django Debug Toolbar"
    +files = [
    +    {file = "djdt_flamegraph-0.2.13-py2.py3-none-any.whl", hash = "sha256:b3252b8cc9b586829166cc158b26952626cd6f41a3ffa92dceef2f5dbe5b99a0"},
    +    {file = "djdt_flamegraph-0.2.13.tar.gz", hash = "sha256:c07a71be58484636e021d4c49b129fd819f24c9128849cb59558e5141192dbf3"},
    +]
    +
    +[[package]]
    +name = "docutils"
    +version = "0.18.1"
    +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
    +summary = "Docutils -- Python Documentation Utilities"
    +files = [
    +    {file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"},
    +    {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"},
    +]
    +
    +[[package]]
    +name = "exceptiongroup"
    +version = "1.1.3"
    +requires_python = ">=3.7"
    +summary = "Backport of PEP 654 (exception groups)"
    +files = [
    +    {file = "exceptiongroup-1.1.3-py3-none-any.whl", hash = "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3"},
    +    {file = "exceptiongroup-1.1.3.tar.gz", hash = "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9"},
    +]
    +
    +[[package]]
    +name = "executing"
    +version = "2.0.0"
    +summary = "Get the currently executing AST node of a frame, and other information"
    +files = [
    +    {file = "executing-2.0.0-py2.py3-none-any.whl", hash = "sha256:06df6183df67389625f4e763921c6cf978944721abf3e714000200aab95b0657"},
    +    {file = "executing-2.0.0.tar.gz", hash = "sha256:0ff053696fdeef426cda5bd18eacd94f82c91f49823a2e9090124212ceea9b08"},
    +]
    +
    +[[package]]
    +name = "filelock"
    +version = "3.12.4"
    +requires_python = ">=3.8"
    +summary = "A platform independent file lock."
    +files = [
    +    {file = "filelock-3.12.4-py3-none-any.whl", hash = "sha256:08c21d87ded6e2b9da6728c3dff51baf1dcecf973b768ef35bcbc3447edb9ad4"},
    +    {file = "filelock-3.12.4.tar.gz", hash = "sha256:2e6f249f1f3654291606e046b09f1fd5eac39b360664c27f5aad072012f8bcbd"},
    +]
    +
    +[[package]]
    +name = "findpython"
    +version = "0.4.0"
    +requires_python = ">=3.7"
    +summary = "A utility to find python versions on your system"
    +dependencies = [
    +    "packaging>=20",
    +]
    +files = [
    +    {file = "findpython-0.4.0-py3-none-any.whl", hash = "sha256:087148ac5935f9be458f36a05f3fa479efdf2c629f5d386c73ea481cfecff15e"},
    +    {file = "findpython-0.4.0.tar.gz", hash = "sha256:18b14d115678da18ae92ee22d7001cc30915ea531053f77010ee05a39680f438"},
    +]
    +
    +[[package]]
    +name = "flake8"
    +version = "6.1.0"
    +requires_python = ">=3.8.1"
    +summary = "the modular source code checker: pep8 pyflakes and co"
    +dependencies = [
    +    "mccabe<0.8.0,>=0.7.0",
    +    "pycodestyle<2.12.0,>=2.11.0",
    +    "pyflakes<3.2.0,>=3.1.0",
    +]
    +files = [
    +    {file = "flake8-6.1.0-py2.py3-none-any.whl", hash = "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"},
    +    {file = "flake8-6.1.0.tar.gz", hash = "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23"},
    +]
    +
    +[[package]]
    +name = "greenlet"
    +version = "3.0.0"
    +requires_python = ">=3.7"
    +summary = "Lightweight in-process concurrent programming"
    +files = [
    +    {file = "greenlet-3.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e09dea87cc91aea5500262993cbd484b41edf8af74f976719dd83fe724644cd6"},
    +    {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f47932c434a3c8d3c86d865443fadc1fbf574e9b11d6650b656e602b1797908a"},
    +    {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bdfaeecf8cc705d35d8e6de324bf58427d7eafb55f67050d8f28053a3d57118c"},
    +    {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a68d670c8f89ff65c82b936275369e532772eebc027c3be68c6b87ad05ca695"},
    +    {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38ad562a104cd41e9d4644f46ea37167b93190c6d5e4048fcc4b80d34ecb278f"},
    +    {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02a807b2a58d5cdebb07050efe3d7deaf915468d112dfcf5e426d0564aa3aa4a"},
    +    {file = "greenlet-3.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b1660a15a446206c8545edc292ab5c48b91ff732f91b3d3b30d9a915d5ec4779"},
    +    {file = "greenlet-3.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:813720bd57e193391dfe26f4871186cf460848b83df7e23e6bef698a7624b4c9"},
    +    {file = "greenlet-3.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:aa15a2ec737cb609ed48902b45c5e4ff6044feb5dcdfcf6fa8482379190330d7"},
    +    {file = "greenlet-3.0.0-cp310-universal2-macosx_11_0_x86_64.whl", hash = "sha256:7709fd7bb02b31908dc8fd35bfd0a29fc24681d5cc9ac1d64ad07f8d2b7db62f"},
    +    {file = "greenlet-3.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:211ef8d174601b80e01436f4e6905aca341b15a566f35a10dd8d1e93f5dbb3b7"},
    +    {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6512592cc49b2c6d9b19fbaa0312124cd4c4c8a90d28473f86f92685cc5fef8e"},
    +    {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:871b0a8835f9e9d461b7fdaa1b57e3492dd45398e87324c047469ce2fc9f516c"},
    +    {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b505fcfc26f4148551826a96f7317e02c400665fa0883fe505d4fcaab1dabfdd"},
    +    {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:123910c58234a8d40eaab595bc56a5ae49bdd90122dde5bdc012c20595a94c14"},
    +    {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:96d9ea57292f636ec851a9bb961a5cc0f9976900e16e5d5647f19aa36ba6366b"},
    +    {file = "greenlet-3.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0b72b802496cccbd9b31acea72b6f87e7771ccfd7f7927437d592e5c92ed703c"},
    +    {file = "greenlet-3.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:527cd90ba3d8d7ae7dceb06fda619895768a46a1b4e423bdb24c1969823b8362"},
    +    {file = "greenlet-3.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:37f60b3a42d8b5499be910d1267b24355c495064f271cfe74bf28b17b099133c"},
    +    {file = "greenlet-3.0.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1482fba7fbed96ea7842b5a7fc11d61727e8be75a077e603e8ab49d24e234383"},
    +    {file = "greenlet-3.0.0-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:be557119bf467d37a8099d91fbf11b2de5eb1fd5fc5b91598407574848dc910f"},
    +    {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:73b2f1922a39d5d59cc0e597987300df3396b148a9bd10b76a058a2f2772fc04"},
    +    {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1e22c22f7826096ad503e9bb681b05b8c1f5a8138469b255eb91f26a76634f2"},
    +    {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d363666acc21d2c204dd8705c0e0457d7b2ee7a76cb16ffc099d6799744ac99"},
    +    {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:334ef6ed8337bd0b58bb0ae4f7f2dcc84c9f116e474bb4ec250a8bb9bd797a66"},
    +    {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6672fdde0fd1a60b44fb1751a7779c6db487e42b0cc65e7caa6aa686874e79fb"},
    +    {file = "greenlet-3.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:952256c2bc5b4ee8df8dfc54fc4de330970bf5d79253c863fb5e6761f00dda35"},
    +    {file = "greenlet-3.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:269d06fa0f9624455ce08ae0179430eea61085e3cf6457f05982b37fd2cefe17"},
    +    {file = "greenlet-3.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:9adbd8ecf097e34ada8efde9b6fec4dd2a903b1e98037adf72d12993a1c80b51"},
    +    {file = "greenlet-3.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4cd83fb8d8e17633ad534d9ac93719ef8937568d730ef07ac3a98cb520fd93e4"},
    +    {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a5b2d4cdaf1c71057ff823a19d850ed5c6c2d3686cb71f73ae4d6382aaa7a06"},
    +    {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e7dcdfad252f2ca83c685b0fa9fba00e4d8f243b73839229d56ee3d9d219314"},
    +    {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c94e4e924d09b5a3e37b853fe5924a95eac058cb6f6fb437ebb588b7eda79870"},
    +    {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad6fb737e46b8bd63156b8f59ba6cdef46fe2b7db0c5804388a2d0519b8ddb99"},
    +    {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d55db1db455c59b46f794346efce896e754b8942817f46a1bada2d29446e305a"},
    +    {file = "greenlet-3.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:56867a3b3cf26dc8a0beecdb4459c59f4c47cdd5424618c08515f682e1d46692"},
    +    {file = "greenlet-3.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a812224a5fb17a538207e8cf8e86f517df2080c8ee0f8c1ed2bdaccd18f38f4"},
    +    {file = "greenlet-3.0.0-cp39-cp39-win32.whl", hash = "sha256:0d3f83ffb18dc57243e0151331e3c383b05e5b6c5029ac29f754745c800f8ed9"},
    +    {file = "greenlet-3.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:831d6f35037cf18ca5e80a737a27d822d87cd922521d18ed3dbc8a6967be50ce"},
    +    {file = "greenlet-3.0.0-cp39-universal2-macosx_11_0_x86_64.whl", hash = "sha256:a048293392d4e058298710a54dfaefcefdf49d287cd33fb1f7d63d55426e4355"},
    +    {file = "greenlet-3.0.0.tar.gz", hash = "sha256:19834e3f91f485442adc1ee440171ec5d9a4840a1f7bd5ed97833544719ce10b"},
    +]
    +
    +[[package]]
    +name = "idna"
    +version = "3.4"
    +requires_python = ">=3.5"
    +summary = "Internationalized Domain Names in Applications (IDNA)"
    +files = [
    +    {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
    +    {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
    +]
    +
    +[[package]]
    +name = "imagesize"
    +version = "1.4.1"
    +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
    +summary = "Getting image size from png/jpeg/jpeg2000/gif file"
    +files = [
    +    {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"},
    +    {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"},
    +]
    +
    +[[package]]
    +name = "importlib-metadata"
    +version = "6.8.0"
    +requires_python = ">=3.8"
    +summary = "Read metadata from Python packages"
    +dependencies = [
    +    "zipp>=0.5",
    +]
    +files = [
    +    {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"},
    +    {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"},
    +]
    +
    +[[package]]
    +name = "iniconfig"
    +version = "2.0.0"
    +requires_python = ">=3.7"
    +summary = "brain-dead simple config-ini parsing"
    +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 = "installer"
    +version = "0.7.0"
    +requires_python = ">=3.7"
    +summary = "A library for installing Python wheels."
    +files = [
    +    {file = "installer-0.7.0-py3-none-any.whl", hash = "sha256:05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53"},
    +    {file = "installer-0.7.0.tar.gz", hash = "sha256:a26d3e3116289bb08216e0d0f7d925fcef0b0194eedfa0c944bcaaa106c4b631"},
    +]
    +
    +[[package]]
    +name = "ipdb"
    +version = "0.13.13"
    +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
    +summary = "IPython-enabled pdb"
    +dependencies = [
    +    "decorator; python_version > \"3.6\" and python_version < \"3.11\"",
    +    "decorator; python_version >= \"3.11\"",
    +    "ipython>=7.31.1; python_version > \"3.6\" and python_version < \"3.11\"",
    +    "ipython>=7.31.1; python_version >= \"3.11\"",
    +    "tomli; python_version > \"3.6\" and python_version < \"3.11\"",
    +]
    +files = [
    +    {file = "ipdb-0.13.13-py3-none-any.whl", hash = "sha256:45529994741c4ab6d2388bfa5d7b725c2cf7fe9deffabdb8a6113aa5ed449ed4"},
    +    {file = "ipdb-0.13.13.tar.gz", hash = "sha256:e3ac6018ef05126d442af680aad863006ec19d02290561ac88b8b1c0b0cfc726"},
    +]
    +
    +[[package]]
    +name = "ipython"
    +version = "8.16.1"
    +requires_python = ">=3.9"
    +summary = "IPython: Productive Interactive Computing"
    +dependencies = [
    +    "appnope; sys_platform == \"darwin\"",
    +    "backcall",
    +    "colorama; sys_platform == \"win32\"",
    +    "decorator",
    +    "exceptiongroup; python_version < \"3.11\"",
    +    "jedi>=0.16",
    +    "matplotlib-inline",
    +    "pexpect>4.3; sys_platform != \"win32\"",
    +    "pickleshare",
    +    "prompt-toolkit!=3.0.37,<3.1.0,>=3.0.30",
    +    "pygments>=2.4.0",
    +    "stack-data",
    +    "traitlets>=5",
    +    "typing-extensions; python_version < \"3.10\"",
    +]
    +files = [
    +    {file = "ipython-8.16.1-py3-none-any.whl", hash = "sha256:0852469d4d579d9cd613c220af7bf0c9cc251813e12be647cb9d463939db9b1e"},
    +    {file = "ipython-8.16.1.tar.gz", hash = "sha256:ad52f58fca8f9f848e256c629eff888efc0528c12fe0f8ec14f33205f23ef938"},
    +]
    +
    +[[package]]
    +name = "jaraco-classes"
    +version = "3.3.0"
    +requires_python = ">=3.8"
    +summary = "Utility functions for Python class constructs"
    +dependencies = [
    +    "more-itertools",
    +]
    +files = [
    +    {file = "jaraco.classes-3.3.0-py3-none-any.whl", hash = "sha256:10afa92b6743f25c0cf5f37c6bb6e18e2c5bb84a16527ccfc0040ea377e7aaeb"},
    +    {file = "jaraco.classes-3.3.0.tar.gz", hash = "sha256:c063dd08e89217cee02c8d5e5ec560f2c8ce6cdc2fcdc2e68f7b2e5547ed3621"},
    +]
    +
    +[[package]]
    +name = "jedi"
    +version = "0.19.1"
    +requires_python = ">=3.6"
    +summary = "An autocompletion tool for Python that can be used for text editors."
    +dependencies = [
    +    "parso<0.9.0,>=0.8.3",
    +]
    +files = [
    +    {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"},
    +    {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"},
    +]
    +
    +[[package]]
    +name = "jeepney"
    +version = "0.8.0"
    +requires_python = ">=3.7"
    +summary = "Low-level, pure Python DBus protocol wrapper."
    +files = [
    +    {file = "jeepney-0.8.0-py3-none-any.whl", hash = "sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755"},
    +    {file = "jeepney-0.8.0.tar.gz", hash = "sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806"},
    +]
    +
    +[[package]]
    +name = "jinja2"
    +version = "3.1.2"
    +requires_python = ">=3.7"
    +summary = "A very fast and expressive template engine."
    +dependencies = [
    +    "MarkupSafe>=2.0",
    +]
    +files = [
    +    {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
    +    {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
    +]
    +
    +[[package]]
    +name = "keyring"
    +version = "24.2.0"
    +requires_python = ">=3.8"
    +summary = "Store and access your passwords safely."
    +dependencies = [
    +    "SecretStorage>=3.2; sys_platform == \"linux\"",
    +    "importlib-metadata>=4.11.4; python_version < \"3.12\"",
    +    "jaraco-classes",
    +    "jeepney>=0.4.2; sys_platform == \"linux\"",
    +    "pywin32-ctypes>=0.2.0; sys_platform == \"win32\"",
    +]
    +files = [
    +    {file = "keyring-24.2.0-py3-none-any.whl", hash = "sha256:4901caaf597bfd3bbd78c9a0c7c4c29fcd8310dab2cffefe749e916b6527acd6"},
    +    {file = "keyring-24.2.0.tar.gz", hash = "sha256:ca0746a19ec421219f4d713f848fa297a661a8a8c1504867e55bfb5e09091509"},
    +]
    +
    +[[package]]
    +name = "markdown-it-py"
    +version = "3.0.0"
    +requires_python = ">=3.8"
    +summary = "Python port of markdown-it. Markdown parsing, done right!"
    +dependencies = [
    +    "mdurl~=0.1",
    +]
    +files = [
    +    {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"},
    +    {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"},
    +]
    +
    +[[package]]
    +name = "markupsafe"
    +version = "2.1.3"
    +requires_python = ">=3.7"
    +summary = "Safely add untrusted strings to HTML/XML markup."
    +files = [
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"},
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"},
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"},
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"},
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"},
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"},
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"},
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"},
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"},
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"},
    +    {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"},
    +]
    +
    +[[package]]
    +name = "matplotlib-inline"
    +version = "0.1.6"
    +requires_python = ">=3.5"
    +summary = "Inline Matplotlib backend for Jupyter"
    +dependencies = [
    +    "traitlets",
    +]
    +files = [
    +    {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"},
    +    {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"},
    +]
    +
    +[[package]]
    +name = "mccabe"
    +version = "0.7.0"
    +requires_python = ">=3.6"
    +summary = "McCabe checker, plugin for flake8"
    +files = [
    +    {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
    +    {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
    +]
    +
    +[[package]]
    +name = "mdurl"
    +version = "0.1.2"
    +requires_python = ">=3.7"
    +summary = "Markdown URL utilities"
    +files = [
    +    {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"},
    +    {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
    +]
    +
    +[[package]]
    +name = "more-itertools"
    +version = "10.1.0"
    +requires_python = ">=3.8"
    +summary = "More routines for operating on iterables, beyond itertools"
    +files = [
    +    {file = "more-itertools-10.1.0.tar.gz", hash = "sha256:626c369fa0eb37bac0291bce8259b332fd59ac792fa5497b59837309cd5b114a"},
    +    {file = "more_itertools-10.1.0-py3-none-any.whl", hash = "sha256:64e0735fcfdc6f3464ea133afe8ea4483b1c5fe3a3d69852e6503b43a0b222e6"},
    +]
    +
    +[[package]]
    +name = "msgpack"
    +version = "1.0.7"
    +requires_python = ">=3.8"
    +summary = "MessagePack serializer"
    +files = [
    +    {file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:04ad6069c86e531682f9e1e71b71c1c3937d6014a7c3e9edd2aa81ad58842862"},
    +    {file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cca1b62fe70d761a282496b96a5e51c44c213e410a964bdffe0928e611368329"},
    +    {file = "msgpack-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e50ebce52f41370707f1e21a59514e3375e3edd6e1832f5e5235237db933c98b"},
    +    {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b4f35de6a304b5533c238bee86b670b75b03d31b7797929caa7a624b5dda6"},
    +    {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28efb066cde83c479dfe5a48141a53bc7e5f13f785b92ddde336c716663039ee"},
    +    {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cb14ce54d9b857be9591ac364cb08dc2d6a5c4318c1182cb1d02274029d590d"},
    +    {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b573a43ef7c368ba4ea06050a957c2a7550f729c31f11dd616d2ac4aba99888d"},
    +    {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ccf9a39706b604d884d2cb1e27fe973bc55f2890c52f38df742bc1d79ab9f5e1"},
    +    {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cb70766519500281815dfd7a87d3a178acf7ce95390544b8c90587d76b227681"},
    +    {file = "msgpack-1.0.7-cp310-cp310-win32.whl", hash = "sha256:b610ff0f24e9f11c9ae653c67ff8cc03c075131401b3e5ef4b82570d1728f8a9"},
    +    {file = "msgpack-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:a40821a89dc373d6427e2b44b572efc36a2778d3f543299e2f24eb1a5de65415"},
    +    {file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:576eb384292b139821c41995523654ad82d1916da6a60cff129c715a6223ea84"},
    +    {file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:730076207cb816138cf1af7f7237b208340a2c5e749707457d70705715c93b93"},
    +    {file = "msgpack-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:85765fdf4b27eb5086f05ac0491090fc76f4f2b28e09d9350c31aac25a5aaff8"},
    +    {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3476fae43db72bd11f29a5147ae2f3cb22e2f1a91d575ef130d2bf49afd21c46"},
    +    {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d4c80667de2e36970ebf74f42d1088cc9ee7ef5f4e8c35eee1b40eafd33ca5b"},
    +    {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b0bf0effb196ed76b7ad883848143427a73c355ae8e569fa538365064188b8e"},
    +    {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f9a7c509542db4eceed3dcf21ee5267ab565a83555c9b88a8109dcecc4709002"},
    +    {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:84b0daf226913133f899ea9b30618722d45feffa67e4fe867b0b5ae83a34060c"},
    +    {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ec79ff6159dffcc30853b2ad612ed572af86c92b5168aa3fc01a67b0fa40665e"},
    +    {file = "msgpack-1.0.7-cp311-cp311-win32.whl", hash = "sha256:3e7bf4442b310ff154b7bb9d81eb2c016b7d597e364f97d72b1acc3817a0fdc1"},
    +    {file = "msgpack-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:3f0c8c6dfa6605ab8ff0611995ee30d4f9fcff89966cf562733b4008a3d60d82"},
    +    {file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f0936e08e0003f66bfd97e74ee530427707297b0d0361247e9b4f59ab78ddc8b"},
    +    {file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:98bbd754a422a0b123c66a4c341de0474cad4a5c10c164ceed6ea090f3563db4"},
    +    {file = "msgpack-1.0.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b291f0ee7961a597cbbcc77709374087fa2a9afe7bdb6a40dbbd9b127e79afee"},
    +    {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebbbba226f0a108a7366bf4b59bf0f30a12fd5e75100c630267d94d7f0ad20e5"},
    +    {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e2d69948e4132813b8d1131f29f9101bc2c915f26089a6d632001a5c1349672"},
    +    {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdf38ba2d393c7911ae989c3bbba510ebbcdf4ecbdbfec36272abe350c454075"},
    +    {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:993584fc821c58d5993521bfdcd31a4adf025c7d745bbd4d12ccfecf695af5ba"},
    +    {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:52700dc63a4676669b341ba33520f4d6e43d3ca58d422e22ba66d1736b0a6e4c"},
    +    {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e45ae4927759289c30ccba8d9fdce62bb414977ba158286b5ddaf8df2cddb5c5"},
    +    {file = "msgpack-1.0.7-cp312-cp312-win32.whl", hash = "sha256:27dcd6f46a21c18fa5e5deed92a43d4554e3df8d8ca5a47bf0615d6a5f39dbc9"},
    +    {file = "msgpack-1.0.7-cp312-cp312-win_amd64.whl", hash = "sha256:7687e22a31e976a0e7fc99c2f4d11ca45eff652a81eb8c8085e9609298916dcf"},
    +    {file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfef2bb6ef068827bbd021017a107194956918ab43ce4d6dc945ffa13efbc25f"},
    +    {file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:484ae3240666ad34cfa31eea7b8c6cd2f1fdaae21d73ce2974211df099a95d81"},
    +    {file = "msgpack-1.0.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3967e4ad1aa9da62fd53e346ed17d7b2e922cba5ab93bdd46febcac39be636fc"},
    +    {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd178c4c80706546702c59529ffc005681bd6dc2ea234c450661b205445a34d"},
    +    {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ffbc252eb0d229aeb2f9ad051200668fc3a9aaa8994e49f0cb2ffe2b7867e7"},
    +    {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:822ea70dc4018c7e6223f13affd1c5c30c0f5c12ac1f96cd8e9949acddb48a61"},
    +    {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:384d779f0d6f1b110eae74cb0659d9aa6ff35aaf547b3955abf2ab4c901c4819"},
    +    {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f64e376cd20d3f030190e8c32e1c64582eba56ac6dc7d5b0b49a9d44021b52fd"},
    +    {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ed82f5a7af3697b1c4786053736f24a0efd0a1b8a130d4c7bfee4b9ded0f08f"},
    +    {file = "msgpack-1.0.7-cp39-cp39-win32.whl", hash = "sha256:f26a07a6e877c76a88e3cecac8531908d980d3d5067ff69213653649ec0f60ad"},
    +    {file = "msgpack-1.0.7-cp39-cp39-win_amd64.whl", hash = "sha256:1dc93e8e4653bdb5910aed79f11e165c85732067614f180f70534f056da97db3"},
    +    {file = "msgpack-1.0.7.tar.gz", hash = "sha256:572efc93db7a4d27e404501975ca6d2d9775705c2d922390d878fcf768d92c87"},
    +]
    +
    +[[package]]
    +name = "mutagen"
    +version = "1.47.0"
    +requires_python = ">=3.7"
    +summary = "read and write audio tags for many formats"
    +files = [
    +    {file = "mutagen-1.47.0-py3-none-any.whl", hash = "sha256:edd96f50c5907a9539d8e5bba7245f62c9f520aef333d13392a79a4f70aca719"},
    +    {file = "mutagen-1.47.0.tar.gz", hash = "sha256:719fadef0a978c31b4cf3c956261b3c58b6948b32023078a2117b1de09f0fc99"},
    +]
    +
    +[[package]]
    +name = "mypy"
    +version = "1.6.1"
    +requires_python = ">=3.8"
    +summary = "Optional static typing for Python"
    +dependencies = [
    +    "mypy-extensions>=1.0.0",
    +    "tomli>=1.1.0; python_version < \"3.11\"",
    +    "typing-extensions>=4.1.0",
    +]
    +files = [
    +    {file = "mypy-1.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e5012e5cc2ac628177eaac0e83d622b2dd499e28253d4107a08ecc59ede3fc2c"},
    +    {file = "mypy-1.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d8fbb68711905f8912e5af474ca8b78d077447d8f3918997fecbf26943ff3cbb"},
    +    {file = "mypy-1.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a1ad938fee7d2d96ca666c77b7c494c3c5bd88dff792220e1afbebb2925b5e"},
    +    {file = "mypy-1.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b96ae2c1279d1065413965c607712006205a9ac541895004a1e0d4f281f2ff9f"},
    +    {file = "mypy-1.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:40b1844d2e8b232ed92e50a4bd11c48d2daa351f9deee6c194b83bf03e418b0c"},
    +    {file = "mypy-1.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:81af8adaa5e3099469e7623436881eff6b3b06db5ef75e6f5b6d4871263547e5"},
    +    {file = "mypy-1.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8c223fa57cb154c7eab5156856c231c3f5eace1e0bed9b32a24696b7ba3c3245"},
    +    {file = "mypy-1.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8032e00ce71c3ceb93eeba63963b864bf635a18f6c0c12da6c13c450eedb183"},
    +    {file = "mypy-1.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4c46b51de523817a0045b150ed11b56f9fff55f12b9edd0f3ed35b15a2809de0"},
    +    {file = "mypy-1.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:19f905bcfd9e167159b3d63ecd8cb5e696151c3e59a1742e79bc3bcb540c42c7"},
    +    {file = "mypy-1.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:82e469518d3e9a321912955cc702d418773a2fd1e91c651280a1bda10622f02f"},
    +    {file = "mypy-1.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d4473c22cc296425bbbce7e9429588e76e05bc7342da359d6520b6427bf76660"},
    +    {file = "mypy-1.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59a0d7d24dfb26729e0a068639a6ce3500e31d6655df8557156c51c1cb874ce7"},
    +    {file = "mypy-1.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cfd13d47b29ed3bbaafaff7d8b21e90d827631afda134836962011acb5904b71"},
    +    {file = "mypy-1.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:eb4f18589d196a4cbe5290b435d135dee96567e07c2b2d43b5c4621b6501531a"},
    +    {file = "mypy-1.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:49ae115da099dcc0922a7a895c1eec82c1518109ea5c162ed50e3b3594c71208"},
    +    {file = "mypy-1.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8b27958f8c76bed8edaa63da0739d76e4e9ad4ed325c814f9b3851425582a3cd"},
    +    {file = "mypy-1.6.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:925cd6a3b7b55dfba252b7c4561892311c5358c6b5a601847015a1ad4eb7d332"},
    +    {file = "mypy-1.6.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8f57e6b6927a49550da3d122f0cb983d400f843a8a82e65b3b380d3d7259468f"},
    +    {file = "mypy-1.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:a43ef1c8ddfdb9575691720b6352761f3f53d85f1b57d7745701041053deff30"},
    +    {file = "mypy-1.6.1-py3-none-any.whl", hash = "sha256:4cbe68ef919c28ea561165206a2dcb68591c50f3bcf777932323bc208d949cf1"},
    +    {file = "mypy-1.6.1.tar.gz", hash = "sha256:4d01c00d09a0be62a4ca3f933e315455bde83f37f892ba4b08ce92f3cf44bcc1"},
    +]
    +
    +[[package]]
    +name = "mypy-extensions"
    +version = "1.0.0"
    +requires_python = ">=3.5"
    +summary = "Type system extensions for programs checked with the mypy type checker."
    +files = [
    +    {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
    +    {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
    +]
    +
    +[[package]]
    +name = "nh3"
    +version = "0.2.14"
    +summary = "Ammonia HTML sanitizer Python binding"
    +files = [
    +    {file = "nh3-0.2.14-cp37-abi3-macosx_10_7_x86_64.whl", hash = "sha256:9be2f68fb9a40d8440cbf34cbf40758aa7f6093160bfc7fb018cce8e424f0c3a"},
    +    {file = "nh3-0.2.14-cp37-abi3-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:f99212a81c62b5f22f9e7c3e347aa00491114a5647e1f13bbebd79c3e5f08d75"},
    +    {file = "nh3-0.2.14-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7771d43222b639a4cd9e341f870cee336b9d886de1ad9bec8dddab22fe1de450"},
    +    {file = "nh3-0.2.14-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:525846c56c2bcd376f5eaee76063ebf33cf1e620c1498b2a40107f60cfc6054e"},
    +    {file = "nh3-0.2.14-cp37-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e8986f1dd3221d1e741fda0a12eaa4a273f1d80a35e31a1ffe579e7c621d069e"},
    +    {file = "nh3-0.2.14-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:18415df36db9b001f71a42a3a5395db79cf23d556996090d293764436e98e8ad"},
    +    {file = "nh3-0.2.14-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:377aaf6a9e7c63962f367158d808c6a1344e2b4f83d071c43fbd631b75c4f0b2"},
    +    {file = "nh3-0.2.14-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b0be5c792bd43d0abef8ca39dd8acb3c0611052ce466d0401d51ea0d9aa7525"},
    +    {file = "nh3-0.2.14-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:93a943cfd3e33bd03f77b97baa11990148687877b74193bf777956b67054dcc6"},
    +    {file = "nh3-0.2.14-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ac8056e937f264995a82bf0053ca898a1cb1c9efc7cd68fa07fe0060734df7e4"},
    +    {file = "nh3-0.2.14-cp37-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:203cac86e313cf6486704d0ec620a992c8bc164c86d3a4fd3d761dd552d839b5"},
    +    {file = "nh3-0.2.14-cp37-abi3-musllinux_1_2_i686.whl", hash = "sha256:5529a3bf99402c34056576d80ae5547123f1078da76aa99e8ed79e44fa67282d"},
    +    {file = "nh3-0.2.14-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:aed56a86daa43966dd790ba86d4b810b219f75b4bb737461b6886ce2bde38fd6"},
    +    {file = "nh3-0.2.14-cp37-abi3-win32.whl", hash = "sha256:116c9515937f94f0057ef50ebcbcc10600860065953ba56f14473ff706371873"},
    +    {file = "nh3-0.2.14-cp37-abi3-win_amd64.whl", hash = "sha256:88c753efbcdfc2644a5012938c6b9753f1c64a5723a67f0301ca43e7b85dcf0e"},
    +    {file = "nh3-0.2.14.tar.gz", hash = "sha256:a0c509894fd4dccdff557068e5074999ae3b75f4c5a2d6fb5415e782e25679c4"},
    +]
    +
    +[[package]]
    +name = "packaging"
    +version = "23.2"
    +requires_python = ">=3.7"
    +summary = "Core utilities for Python packages"
    +files = [
    +    {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
    +    {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
    +]
    +
    +[[package]]
    +name = "parso"
    +version = "0.8.3"
    +requires_python = ">=3.6"
    +summary = "A Python Parser"
    +files = [
    +    {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"},
    +    {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"},
    +]
    +
    +[[package]]
    +name = "pdm"
    +version = "2.9.3"
    +requires_python = ">=3.7"
    +summary = "A modern Python package and dependency manager supporting the latest PEP standards"
    +dependencies = [
    +    "blinker",
    +    "cachecontrol[filecache]>=0.13.0",
    +    "certifi",
    +    "findpython<1.0.0a0,>=0.4.0",
    +    "importlib-metadata>=3.6; python_version < \"3.10\"",
    +    "installer<0.8,>=0.7",
    +    "packaging!=22.0,>=20.9",
    +    "platformdirs",
    +    "pyproject-hooks",
    +    "python-dotenv>=0.15",
    +    "requests-toolbelt",
    +    "resolvelib>=1.0.1",
    +    "rich>=12.3.0",
    +    "shellingham>=1.3.2",
    +    "tomli>=1.1.0; python_version < \"3.11\"",
    +    "tomlkit<1,>=0.11.1",
    +    "truststore; python_version >= \"3.10\"",
    +    "unearth>=0.10.0",
    +    "virtualenv>=20",
    +]
    +files = [
    +    {file = "pdm-2.9.3-py3-none-any.whl", hash = "sha256:0b55fcaa61ed70b9dacd03c4a937f15e908c8c031b621523890de9cdf04325fd"},
    +    {file = "pdm-2.9.3.tar.gz", hash = "sha256:0b1195b51e9630b5a0b063f27dfcb0120cb6ea284f1a4cd975a3a26f0856d253"},
    +]
    +
    +[[package]]
    +name = "pexpect"
    +version = "4.8.0"
    +summary = "Pexpect allows easy control of interactive console applications."
    +dependencies = [
    +    "ptyprocess>=0.5",
    +]
    +files = [
    +    {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"},
    +    {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"},
    +]
    +
    +[[package]]
    +name = "pickleshare"
    +version = "0.7.5"
    +summary = "Tiny 'shelve'-like database with concurrency support"
    +files = [
    +    {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"},
    +    {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"},
    +]
    +
    +[[package]]
    +name = "pkginfo"
    +version = "1.9.6"
    +requires_python = ">=3.6"
    +summary = "Query metadata from sdists / bdists / installed packages."
    +files = [
    +    {file = "pkginfo-1.9.6-py3-none-any.whl", hash = "sha256:4b7a555a6d5a22169fcc9cf7bfd78d296b0361adad412a346c1226849af5e546"},
    +    {file = "pkginfo-1.9.6.tar.gz", hash = "sha256:8fd5896e8718a4372f0ea9cc9d96f6417c9b986e23a4d116dda26b62cc29d046"},
    +]
    +
    +[[package]]
    +name = "platformdirs"
    +version = "3.11.0"
    +requires_python = ">=3.7"
    +summary = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
    +files = [
    +    {file = "platformdirs-3.11.0-py3-none-any.whl", hash = "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"},
    +    {file = "platformdirs-3.11.0.tar.gz", hash = "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3"},
    +]
    +
    +[[package]]
    +name = "playwright"
    +version = "1.39.0"
    +requires_python = ">=3.8"
    +summary = "A high-level API to automate web browsers"
    +dependencies = [
    +    "greenlet==3.0.0",
    +    "pyee==11.0.1",
    +]
    +files = [
    +    {file = "playwright-1.39.0-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:384e195a6d09343f319031cf552e9cd601ede78fe9c082b9fa197537c5cbfe7a"},
    +    {file = "playwright-1.39.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d2c3634411828d9273196ed6f69f2fa7645c89732b3c982dcf09ab03ed4c5d2b"},
    +    {file = "playwright-1.39.0-py3-none-macosx_11_0_universal2.whl", hash = "sha256:d2fd90f370599cf9a2c6a041bd79a5eeec62baf0e943c7c5c2079b29be476d2a"},
    +    {file = "playwright-1.39.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:699a8e707ca5f3567aa28223ee1be7e42d2bf25eda7d3d86babda71e36e5f16f"},
    +    {file = "playwright-1.39.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:654bb3ae0dc3c69ffddc0c38c127c3b8e93032d8cf3928e2c4f21890cb39514b"},
    +    {file = "playwright-1.39.0-py3-none-win32.whl", hash = "sha256:40ed7f2546c64f1bb3d22b2295b4d43ed5a2f0b7ea7599d93a72f723a1883e1e"},
    +    {file = "playwright-1.39.0-py3-none-win_amd64.whl", hash = "sha256:a420d814e21b05e1156747e2a9fae6c3cca2b46bb4a0226fb26ee65538ce09c9"},
    +]
    +
    +[[package]]
    +name = "pluggy"
    +version = "1.3.0"
    +requires_python = ">=3.8"
    +summary = "plugin and hook calling mechanisms for python"
    +files = [
    +    {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"},
    +    {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"},
    +]
    +
    +[[package]]
    +name = "prompt-toolkit"
    +version = "3.0.39"
    +requires_python = ">=3.7.0"
    +summary = "Library for building powerful interactive command lines in Python"
    +dependencies = [
    +    "wcwidth",
    +]
    +files = [
    +    {file = "prompt_toolkit-3.0.39-py3-none-any.whl", hash = "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88"},
    +    {file = "prompt_toolkit-3.0.39.tar.gz", hash = "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac"},
    +]
    +
    +[[package]]
    +name = "ptyprocess"
    +version = "0.7.0"
    +summary = "Run a subprocess in a pseudo terminal"
    +files = [
    +    {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"},
    +    {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"},
    +]
    +
    +[[package]]
    +name = "pure-eval"
    +version = "0.2.2"
    +summary = "Safely evaluate AST nodes without side effects"
    +files = [
    +    {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"},
    +    {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"},
    +]
    +
    +[[package]]
    +name = "pyasn1"
    +version = "0.5.0"
    +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
    +summary = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)"
    +files = [
    +    {file = "pyasn1-0.5.0-py2.py3-none-any.whl", hash = "sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57"},
    +    {file = "pyasn1-0.5.0.tar.gz", hash = "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde"},
    +]
    +
    +[[package]]
    +name = "pyasn1-modules"
    +version = "0.3.0"
    +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
    +summary = "A collection of ASN.1-based protocols modules"
    +dependencies = [
    +    "pyasn1<0.6.0,>=0.4.6",
    +]
    +files = [
    +    {file = "pyasn1_modules-0.3.0-py2.py3-none-any.whl", hash = "sha256:d3ccd6ed470d9ffbc716be08bd90efbd44d0734bc9303818f7336070984a162d"},
    +    {file = "pyasn1_modules-0.3.0.tar.gz", hash = "sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c"},
    +]
    +
    +[[package]]
    +name = "pycodestyle"
    +version = "2.11.1"
    +requires_python = ">=3.8"
    +summary = "Python style guide checker"
    +files = [
    +    {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"},
    +    {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"},
    +]
    +
    +[[package]]
    +name = "pycparser"
    +version = "2.21"
    +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
    +summary = "C parser in Python"
    +files = [
    +    {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"},
    +    {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
    +]
    +
    +[[package]]
    +name = "pycryptodomex"
    +version = "3.19.0"
    +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
    +summary = "Cryptographic library for Python"
    +files = [
    +    {file = "pycryptodomex-3.19.0-cp35-abi3-macosx_10_9_universal2.whl", hash = "sha256:a77b79852175064c822b047fee7cf5a1f434f06ad075cc9986aa1c19a0c53eb0"},
    +    {file = "pycryptodomex-3.19.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:5b883e1439ab63af976656446fb4839d566bb096f15fc3c06b5a99cde4927188"},
    +    {file = "pycryptodomex-3.19.0-cp35-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3866d68e2fc345162b1b9b83ef80686acfe5cec0d134337f3b03950a0a8bf56"},
    +    {file = "pycryptodomex-3.19.0-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c74eb1f73f788facece7979ce91594dc177e1a9b5d5e3e64697dd58299e5cb4d"},
    +    {file = "pycryptodomex-3.19.0-cp35-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7cb51096a6a8d400724104db8a7e4f2206041a1f23e58924aa3d8d96bcb48338"},
    +    {file = "pycryptodomex-3.19.0-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a588a1cb7781da9d5e1c84affd98c32aff9c89771eac8eaa659d2760666f7139"},
    +    {file = "pycryptodomex-3.19.0-cp35-abi3-musllinux_1_1_i686.whl", hash = "sha256:d4dd3b381ff5a5907a3eb98f5f6d32c64d319a840278ceea1dcfcc65063856f3"},
    +    {file = "pycryptodomex-3.19.0-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:263de9a96d2fcbc9f5bd3a279f14ea0d5f072adb68ebd324987576ec25da084d"},
    +    {file = "pycryptodomex-3.19.0-cp35-abi3-win32.whl", hash = "sha256:67c8eb79ab33d0fbcb56842992298ddb56eb6505a72369c20f60bc1d2b6fb002"},
    +    {file = "pycryptodomex-3.19.0-cp35-abi3-win_amd64.whl", hash = "sha256:09c9401dc06fb3d94cb1ec23b4ea067a25d1f4c6b7b118ff5631d0b5daaab3cc"},
    +    {file = "pycryptodomex-3.19.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:edbe083c299835de7e02c8aa0885cb904a75087d35e7bab75ebe5ed336e8c3e2"},
    +    {file = "pycryptodomex-3.19.0-pp27-pypy_73-win32.whl", hash = "sha256:136b284e9246b4ccf4f752d435c80f2c44fc2321c198505de1d43a95a3453b3c"},
    +    {file = "pycryptodomex-3.19.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5d73e9fa3fe830e7b6b42afc49d8329b07a049a47d12e0ef9225f2fd220f19b2"},
    +    {file = "pycryptodomex-3.19.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b2f1982c5bc311f0aab8c293524b861b485d76f7c9ab2c3ac9a25b6f7655975"},
    +    {file = "pycryptodomex-3.19.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfb040b5dda1dff1e197d2ef71927bd6b8bfcb9793bc4dfe0bb6df1e691eaacb"},
    +    {file = "pycryptodomex-3.19.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:800a2b05cfb83654df80266692f7092eeefe2a314fa7901dcefab255934faeec"},
    +    {file = "pycryptodomex-3.19.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c01678aee8ac0c1a461cbc38ad496f953f9efcb1fa19f5637cbeba7544792a53"},
    +    {file = "pycryptodomex-3.19.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2126bc54beccbede6eade00e647106b4f4c21e5201d2b0a73e9e816a01c50905"},
    +    {file = "pycryptodomex-3.19.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b801216c48c0886742abf286a9a6b117e248ca144d8ceec1f931ce2dd0c9cb40"},
    +    {file = "pycryptodomex-3.19.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:50cb18d4dd87571006fd2447ccec85e6cec0136632a550aa29226ba075c80644"},
    +    {file = "pycryptodomex-3.19.0.tar.gz", hash = "sha256:af83a554b3f077564229865c45af0791be008ac6469ef0098152139e6bd4b5b6"},
    +]
    +
    +[[package]]
    +name = "pyee"
    +version = "11.0.1"
    +requires_python = ">=3.8"
    +summary = "A rough port of Node.js's EventEmitter to Python with a few tricks of its own"
    +dependencies = [
    +    "typing-extensions",
    +]
    +files = [
    +    {file = "pyee-11.0.1-py3-none-any.whl", hash = "sha256:9bcc9647822234f42c228d88de63d0f9ffa881e87a87f9d36ddf5211f6ac977d"},
    +    {file = "pyee-11.0.1.tar.gz", hash = "sha256:a642c51e3885a33ead087286e35212783a4e9b8d6514a10a5db4e57ac57b2b29"},
    +]
    +
    +[[package]]
    +name = "pyflakes"
    +version = "3.1.0"
    +requires_python = ">=3.8"
    +summary = "passive checker of Python programs"
    +files = [
    +    {file = "pyflakes-3.1.0-py2.py3-none-any.whl", hash = "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774"},
    +    {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"},
    +]
    +
    +[[package]]
    +name = "pygments"
    +version = "2.16.1"
    +requires_python = ">=3.7"
    +summary = "Pygments is a syntax highlighting package written in Python."
    +files = [
    +    {file = "Pygments-2.16.1-py3-none-any.whl", hash = "sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692"},
    +    {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"},
    +]
    +
    +[[package]]
    +name = "pyproject-hooks"
    +version = "1.0.0"
    +requires_python = ">=3.7"
    +summary = "Wrappers to call pyproject.toml-based build backend hooks."
    +dependencies = [
    +    "tomli>=1.1.0; python_version < \"3.11\"",
    +]
    +files = [
    +    {file = "pyproject_hooks-1.0.0-py3-none-any.whl", hash = "sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8"},
    +    {file = "pyproject_hooks-1.0.0.tar.gz", hash = "sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5"},
    +]
    +
    +[[package]]
    +name = "pytest"
    +version = "7.4.2"
    +requires_python = ">=3.7"
    +summary = "pytest: simple powerful testing with Python"
    +dependencies = [
    +    "colorama; sys_platform == \"win32\"",
    +    "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"",
    +    "iniconfig",
    +    "packaging",
    +    "pluggy<2.0,>=0.12",
    +    "tomli>=1.0.0; python_version < \"3.11\"",
    +]
    +files = [
    +    {file = "pytest-7.4.2-py3-none-any.whl", hash = "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002"},
    +    {file = "pytest-7.4.2.tar.gz", hash = "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069"},
    +]
    +
    +[[package]]
    +name = "python-crontab"
    +version = "3.0.0"
    +summary = "Python Crontab API"
    +dependencies = [
    +    "python-dateutil",
    +]
    +files = [
    +    {file = "python-crontab-3.0.0.tar.gz", hash = "sha256:79fb7465039ddfd4fb93d072d6ee0d45c1ac8bf1597f0686ea14fd4361dba379"},
    +    {file = "python_crontab-3.0.0-py3-none-any.whl", hash = "sha256:6d5ba3c190ec76e4d252989a1644fcb233dbf53fbc8fceeb9febe1657b9fb1d4"},
    +]
    +
    +[[package]]
    +name = "python-dateutil"
    +version = "2.8.2"
    +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
    +summary = "Extensions to the standard Python datetime module"
    +dependencies = [
    +    "six>=1.5",
    +]
    +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]]
    +name = "python-dotenv"
    +version = "1.0.0"
    +requires_python = ">=3.8"
    +summary = "Read key-value pairs from a .env file and set them as environment variables"
    +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]]
    +name = "python-ldap"
    +version = "3.4.3"
    +requires_python = ">=3.6"
    +summary = "Python modules for implementing LDAP clients"
    +dependencies = [
    +    "pyasn1-modules>=0.1.5",
    +    "pyasn1>=0.3.7",
    +]
    +files = [
    +    {file = "python-ldap-3.4.3.tar.gz", hash = "sha256:ab26c519a0ef2a443a2a10391fa3c5cb52d7871323399db949ebfaa9f25ee2a0"},
    +]
    +
    +[[package]]
    +name = "pytz"
    +version = "2023.3.post1"
    +summary = "World timezone definitions, modern and historical"
    +files = [
    +    {file = "pytz-2023.3.post1-py2.py3-none-any.whl", hash = "sha256:ce42d816b81b68506614c11e8937d3aa9e41007ceb50bfdcb0749b921bf646c7"},
    +    {file = "pytz-2023.3.post1.tar.gz", hash = "sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b"},
    +]
    +
    +[[package]]
    +name = "pywin32-ctypes"
    +version = "0.2.2"
    +requires_python = ">=3.6"
    +summary = "A (partial) reimplementation of pywin32 using ctypes/cffi"
    +files = [
    +    {file = "pywin32-ctypes-0.2.2.tar.gz", hash = "sha256:3426e063bdd5fd4df74a14fa3cf80a0b42845a87e1d1e81f6549f9daec593a60"},
    +    {file = "pywin32_ctypes-0.2.2-py3-none-any.whl", hash = "sha256:bf490a1a709baf35d688fe0ecf980ed4de11d2b3e37b51e5442587a75d9957e7"},
    +]
    +
    +[[package]]
    +name = "readme-renderer"
    +version = "42.0"
    +requires_python = ">=3.8"
    +summary = "readme_renderer is a library for rendering readme descriptions for Warehouse"
    +dependencies = [
    +    "Pygments>=2.5.1",
    +    "docutils>=0.13.1",
    +    "nh3>=0.2.14",
    +]
    +files = [
    +    {file = "readme_renderer-42.0-py3-none-any.whl", hash = "sha256:13d039515c1f24de668e2c93f2e877b9dbe6c6c32328b90a40a49d8b2b85f36d"},
    +    {file = "readme_renderer-42.0.tar.gz", hash = "sha256:2d55489f83be4992fe4454939d1a051c33edbab778e82761d060c9fc6b308cd1"},
    +]
    +
    +[[package]]
    +name = "recommonmark"
    +version = "0.7.1"
    +summary = "A docutils-compatibility bridge to CommonMark, enabling you to write CommonMark inside of Docutils & Sphinx projects."
    +dependencies = [
    +    "commonmark>=0.8.1",
    +    "docutils>=0.11",
    +    "sphinx>=1.3.1",
    +]
    +files = [
    +    {file = "recommonmark-0.7.1-py2.py3-none-any.whl", hash = "sha256:1b1db69af0231efce3fa21b94ff627ea33dee7079a01dd0a7f8482c3da148b3f"},
    +    {file = "recommonmark-0.7.1.tar.gz", hash = "sha256:bdb4db649f2222dcd8d2d844f0006b958d627f732415d399791ee436a3686d67"},
    +]
    +
    +[[package]]
    +name = "regex"
    +version = "2023.10.3"
    +requires_python = ">=3.7"
    +summary = "Alternative regular expression module, to replace re."
    +files = [
    +    {file = "regex-2023.10.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4c34d4f73ea738223a094d8e0ffd6d2c1a1b4c175da34d6b0de3d8d69bee6bcc"},
    +    {file = "regex-2023.10.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8f4e49fc3ce020f65411432183e6775f24e02dff617281094ba6ab079ef0915"},
    +    {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cd1bccf99d3ef1ab6ba835308ad85be040e6a11b0977ef7ea8c8005f01a3c29"},
    +    {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:81dce2ddc9f6e8f543d94b05d56e70d03a0774d32f6cca53e978dc01e4fc75b8"},
    +    {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c6b4d23c04831e3ab61717a707a5d763b300213db49ca680edf8bf13ab5d91b"},
    +    {file = "regex-2023.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c15ad0aee158a15e17e0495e1e18741573d04eb6da06d8b84af726cfc1ed02ee"},
    +    {file = "regex-2023.10.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6239d4e2e0b52c8bd38c51b760cd870069f0bdf99700a62cd509d7a031749a55"},
    +    {file = "regex-2023.10.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4a8bf76e3182797c6b1afa5b822d1d5802ff30284abe4599e1247be4fd6b03be"},
    +    {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9c727bbcf0065cbb20f39d2b4f932f8fa1631c3e01fcedc979bd4f51fe051c5"},
    +    {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3ccf2716add72f80714b9a63899b67fa711b654be3fcdd34fa391d2d274ce767"},
    +    {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:107ac60d1bfdc3edb53be75e2a52aff7481b92817cfdddd9b4519ccf0e54a6ff"},
    +    {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:00ba3c9818e33f1fa974693fb55d24cdc8ebafcb2e4207680669d8f8d7cca79a"},
    +    {file = "regex-2023.10.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f0a47efb1dbef13af9c9a54a94a0b814902e547b7f21acb29434504d18f36e3a"},
    +    {file = "regex-2023.10.3-cp310-cp310-win32.whl", hash = "sha256:36362386b813fa6c9146da6149a001b7bd063dabc4d49522a1f7aa65b725c7ec"},
    +    {file = "regex-2023.10.3-cp310-cp310-win_amd64.whl", hash = "sha256:c65a3b5330b54103e7d21cac3f6bf3900d46f6d50138d73343d9e5b2900b2353"},
    +    {file = "regex-2023.10.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:90a79bce019c442604662d17bf69df99090e24cdc6ad95b18b6725c2988a490e"},
    +    {file = "regex-2023.10.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c7964c2183c3e6cce3f497e3a9f49d182e969f2dc3aeeadfa18945ff7bdd7051"},
    +    {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4ef80829117a8061f974b2fda8ec799717242353bff55f8a29411794d635d964"},
    +    {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5addc9d0209a9afca5fc070f93b726bf7003bd63a427f65ef797a931782e7edc"},
    +    {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c148bec483cc4b421562b4bcedb8e28a3b84fcc8f0aa4418e10898f3c2c0eb9b"},
    +    {file = "regex-2023.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d1f21af4c1539051049796a0f50aa342f9a27cde57318f2fc41ed50b0dbc4ac"},
    +    {file = "regex-2023.10.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b9ac09853b2a3e0d0082104036579809679e7715671cfbf89d83c1cb2a30f58"},
    +    {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ebedc192abbc7fd13c5ee800e83a6df252bec691eb2c4bedc9f8b2e2903f5e2a"},
    +    {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d8a993c0a0ffd5f2d3bda23d0cd75e7086736f8f8268de8a82fbc4bd0ac6791e"},
    +    {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:be6b7b8d42d3090b6c80793524fa66c57ad7ee3fe9722b258aec6d0672543fd0"},
    +    {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4023e2efc35a30e66e938de5aef42b520c20e7eda7bb5fb12c35e5d09a4c43f6"},
    +    {file = "regex-2023.10.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0d47840dc05e0ba04fe2e26f15126de7c755496d5a8aae4a08bda4dd8d646c54"},
    +    {file = "regex-2023.10.3-cp311-cp311-win32.whl", hash = "sha256:9145f092b5d1977ec8c0ab46e7b3381b2fd069957b9862a43bd383e5c01d18c2"},
    +    {file = "regex-2023.10.3-cp311-cp311-win_amd64.whl", hash = "sha256:b6104f9a46bd8743e4f738afef69b153c4b8b592d35ae46db07fc28ae3d5fb7c"},
    +    {file = "regex-2023.10.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:bff507ae210371d4b1fe316d03433ac099f184d570a1a611e541923f78f05037"},
    +    {file = "regex-2023.10.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:be5e22bbb67924dea15039c3282fa4cc6cdfbe0cbbd1c0515f9223186fc2ec5f"},
    +    {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a992f702c9be9c72fa46f01ca6e18d131906a7180950958f766c2aa294d4b41"},
    +    {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7434a61b158be563c1362d9071358f8ab91b8d928728cd2882af060481244c9e"},
    +    {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c2169b2dcabf4e608416f7f9468737583ce5f0a6e8677c4efbf795ce81109d7c"},
    +    {file = "regex-2023.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9e908ef5889cda4de038892b9accc36d33d72fb3e12c747e2799a0e806ec841"},
    +    {file = "regex-2023.10.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12bd4bc2c632742c7ce20db48e0d99afdc05e03f0b4c1af90542e05b809a03d9"},
    +    {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bc72c231f5449d86d6c7d9cc7cd819b6eb30134bb770b8cfdc0765e48ef9c420"},
    +    {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bce8814b076f0ce5766dc87d5a056b0e9437b8e0cd351b9a6c4e1134a7dfbda9"},
    +    {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:ba7cd6dc4d585ea544c1412019921570ebd8a597fabf475acc4528210d7c4a6f"},
    +    {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b0c7d2f698e83f15228ba41c135501cfe7d5740181d5903e250e47f617eb4292"},
    +    {file = "regex-2023.10.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5a8f91c64f390ecee09ff793319f30a0f32492e99f5dc1c72bc361f23ccd0a9a"},
    +    {file = "regex-2023.10.3-cp312-cp312-win32.whl", hash = "sha256:ad08a69728ff3c79866d729b095872afe1e0557251da4abb2c5faff15a91d19a"},
    +    {file = "regex-2023.10.3-cp312-cp312-win_amd64.whl", hash = "sha256:39cdf8d141d6d44e8d5a12a8569d5a227f645c87df4f92179bd06e2e2705e76b"},
    +    {file = "regex-2023.10.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2c54e23836650bdf2c18222c87f6f840d4943944146ca479858404fedeb9f9af"},
    +    {file = "regex-2023.10.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:69c0771ca5653c7d4b65203cbfc5e66db9375f1078689459fe196fe08b7b4930"},
    +    {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ac965a998e1388e6ff2e9781f499ad1eaa41e962a40d11c7823c9952c77123e"},
    +    {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c0e8fae5b27caa34177bdfa5a960c46ff2f78ee2d45c6db15ae3f64ecadde14"},
    +    {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6c56c3d47da04f921b73ff9415fbaa939f684d47293f071aa9cbb13c94afc17d"},
    +    {file = "regex-2023.10.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ef1e014eed78ab650bef9a6a9cbe50b052c0aebe553fb2881e0453717573f52"},
    +    {file = "regex-2023.10.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d29338556a59423d9ff7b6eb0cb89ead2b0875e08fe522f3e068b955c3e7b59b"},
    +    {file = "regex-2023.10.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9c6d0ced3c06d0f183b73d3c5920727268d2201aa0fe6d55c60d68c792ff3588"},
    +    {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:994645a46c6a740ee8ce8df7911d4aee458d9b1bc5639bc968226763d07f00fa"},
    +    {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:66e2fe786ef28da2b28e222c89502b2af984858091675044d93cb50e6f46d7af"},
    +    {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:11175910f62b2b8c055f2b089e0fedd694fe2be3941b3e2633653bc51064c528"},
    +    {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:06e9abc0e4c9ab4779c74ad99c3fc10d3967d03114449acc2c2762ad4472b8ca"},
    +    {file = "regex-2023.10.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:fb02e4257376ae25c6dd95a5aec377f9b18c09be6ebdefa7ad209b9137b73d48"},
    +    {file = "regex-2023.10.3-cp39-cp39-win32.whl", hash = "sha256:3b2c3502603fab52d7619b882c25a6850b766ebd1b18de3df23b2f939360e1bd"},
    +    {file = "regex-2023.10.3-cp39-cp39-win_amd64.whl", hash = "sha256:adbccd17dcaff65704c856bd29951c58a1bd4b2b0f8ad6b826dbd543fe740988"},
    +    {file = "regex-2023.10.3.tar.gz", hash = "sha256:3fef4f844d2290ee0ba57addcec17eec9e3df73f10a2748485dfd6a3a188cc0f"},
    +]
    +
    +[[package]]
    +name = "requests"
    +version = "2.31.0"
    +requires_python = ">=3.7"
    +summary = "Python HTTP for Humans."
    +dependencies = [
    +    "certifi>=2017.4.17",
    +    "charset-normalizer<4,>=2",
    +    "idna<4,>=2.5",
    +    "urllib3<3,>=1.21.1",
    +]
    +files = [
    +    {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"},
    +    {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
    +]
    +
    +[[package]]
    +name = "requests-toolbelt"
    +version = "1.0.0"
    +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
    +summary = "A utility belt for advanced users of python-requests"
    +dependencies = [
    +    "requests<3.0.0,>=2.0.1",
    +]
    +files = [
    +    {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"},
    +    {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"},
    +]
    +
    +[[package]]
    +name = "resolvelib"
    +version = "1.0.1"
    +summary = "Resolve abstract dependencies into concrete ones"
    +files = [
    +    {file = "resolvelib-1.0.1-py2.py3-none-any.whl", hash = "sha256:d2da45d1a8dfee81bdd591647783e340ef3bcb104b54c383f70d422ef5cc7dbf"},
    +    {file = "resolvelib-1.0.1.tar.gz", hash = "sha256:04ce76cbd63fded2078ce224785da6ecd42b9564b1390793f64ddecbe997b309"},
    +]
    +
    +[[package]]
    +name = "rfc3986"
    +version = "2.0.0"
    +requires_python = ">=3.7"
    +summary = "Validating URI References per RFC 3986"
    +files = [
    +    {file = "rfc3986-2.0.0-py2.py3-none-any.whl", hash = "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd"},
    +    {file = "rfc3986-2.0.0.tar.gz", hash = "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c"},
    +]
    +
    +[[package]]
    +name = "rich"
    +version = "13.6.0"
    +requires_python = ">=3.7.0"
    +summary = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
    +dependencies = [
    +    "markdown-it-py>=2.2.0",
    +    "pygments<3.0.0,>=2.13.0",
    +]
    +files = [
    +    {file = "rich-13.6.0-py3-none-any.whl", hash = "sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245"},
    +    {file = "rich-13.6.0.tar.gz", hash = "sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef"},
    +]
    +
    +[[package]]
    +name = "secretstorage"
    +version = "3.3.3"
    +requires_python = ">=3.6"
    +summary = "Python bindings to FreeDesktop.org Secret Service API"
    +dependencies = [
    +    "cryptography>=2.0",
    +    "jeepney>=0.6",
    +]
    +files = [
    +    {file = "SecretStorage-3.3.3-py3-none-any.whl", hash = "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99"},
    +    {file = "SecretStorage-3.3.3.tar.gz", hash = "sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77"},
    +]
    +
    +[[package]]
    +name = "setuptools"
    +version = "68.2.2"
    +requires_python = ">=3.8"
    +summary = "Easily download, build, install, upgrade, and uninstall Python packages"
    +files = [
    +    {file = "setuptools-68.2.2-py3-none-any.whl", hash = "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"},
    +    {file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"},
    +]
    +
    +[[package]]
    +name = "shellingham"
    +version = "1.5.3"
    +requires_python = ">=3.7"
    +summary = "Tool to Detect Surrounding Shell"
    +files = [
    +    {file = "shellingham-1.5.3-py2.py3-none-any.whl", hash = "sha256:419c6a164770c9c7cfcaeddfacb3d31ac7a8db0b0f3e9c1287679359734107e9"},
    +    {file = "shellingham-1.5.3.tar.gz", hash = "sha256:cb4a6fec583535bc6da17b647dd2330cf7ef30239e05d547d99ae3705fd0f7f8"},
    +]
    +
    +[[package]]
    +name = "six"
    +version = "1.16.0"
    +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
    +summary = "Python 2 and 3 compatibility utilities"
    +files = [
    +    {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
    +    {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
    +]
    +
    +[[package]]
    +name = "snowballstemmer"
    +version = "2.2.0"
    +summary = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
    +files = [
    +    {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
    +    {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
    +]
    +
    +[[package]]
    +name = "sonic-client"
    +version = "1.0.0"
    +summary = "python client for sonic search backend"
    +files = [
    +    {file = "sonic-client-1.0.0.tar.gz", hash = "sha256:fe324c7354670488ed84847f6a6727d3cb5fb3675cb9b61396dcf5720e5aca66"},
    +    {file = "sonic_client-1.0.0-py3-none-any.whl", hash = "sha256:291bf292861e97a2dd765ff0c8754ea9631383680d31a63ec3da6f5aa5f4beda"},
    +]
    +
    +[[package]]
    +name = "sphinx"
    +version = "7.2.6"
    +requires_python = ">=3.9"
    +summary = "Python documentation generator"
    +dependencies = [
    +    "Jinja2>=3.0",
    +    "Pygments>=2.14",
    +    "alabaster<0.8,>=0.7",
    +    "babel>=2.9",
    +    "colorama>=0.4.5; sys_platform == \"win32\"",
    +    "docutils<0.21,>=0.18.1",
    +    "imagesize>=1.3",
    +    "importlib-metadata>=4.8; python_version < \"3.10\"",
    +    "packaging>=21.0",
    +    "requests>=2.25.0",
    +    "snowballstemmer>=2.0",
    +    "sphinxcontrib-applehelp",
    +    "sphinxcontrib-devhelp",
    +    "sphinxcontrib-htmlhelp>=2.0.0",
    +    "sphinxcontrib-jsmath",
    +    "sphinxcontrib-qthelp",
    +    "sphinxcontrib-serializinghtml>=1.1.9",
    +]
    +files = [
    +    {file = "sphinx-7.2.6-py3-none-any.whl", hash = "sha256:1e09160a40b956dc623c910118fa636da93bd3ca0b9876a7b3df90f07d691560"},
    +    {file = "sphinx-7.2.6.tar.gz", hash = "sha256:9a5160e1ea90688d5963ba09a2dcd8bdd526620edbb65c328728f1b2228d5ab5"},
    +]
    +
    +[[package]]
    +name = "sphinx-rtd-theme"
    +version = "1.3.0"
    +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
    +summary = "Read the Docs theme for Sphinx"
    +dependencies = [
    +    "docutils<0.19",
    +    "sphinx<8,>=1.6",
    +    "sphinxcontrib-jquery<5,>=4",
    +]
    +files = [
    +    {file = "sphinx_rtd_theme-1.3.0-py2.py3-none-any.whl", hash = "sha256:46ddef89cc2416a81ecfbeaceab1881948c014b1b6e4450b815311a89fb977b0"},
    +    {file = "sphinx_rtd_theme-1.3.0.tar.gz", hash = "sha256:590b030c7abb9cf038ec053b95e5380b5c70d61591eb0b552063fbe7c41f0931"},
    +]
    +
    +[[package]]
    +name = "sphinxcontrib-applehelp"
    +version = "1.0.7"
    +requires_python = ">=3.9"
    +summary = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books"
    +dependencies = [
    +    "Sphinx>=5",
    +]
    +files = [
    +    {file = "sphinxcontrib_applehelp-1.0.7-py3-none-any.whl", hash = "sha256:094c4d56209d1734e7d252f6e0b3ccc090bd52ee56807a5d9315b19c122ab15d"},
    +    {file = "sphinxcontrib_applehelp-1.0.7.tar.gz", hash = "sha256:39fdc8d762d33b01a7d8f026a3b7d71563ea3b72787d5f00ad8465bd9d6dfbfa"},
    +]
    +
    +[[package]]
    +name = "sphinxcontrib-devhelp"
    +version = "1.0.5"
    +requires_python = ">=3.9"
    +summary = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents"
    +dependencies = [
    +    "Sphinx>=5",
    +]
    +files = [
    +    {file = "sphinxcontrib_devhelp-1.0.5-py3-none-any.whl", hash = "sha256:fe8009aed765188f08fcaadbb3ea0d90ce8ae2d76710b7e29ea7d047177dae2f"},
    +    {file = "sphinxcontrib_devhelp-1.0.5.tar.gz", hash = "sha256:63b41e0d38207ca40ebbeabcf4d8e51f76c03e78cd61abe118cf4435c73d4212"},
    +]
    +
    +[[package]]
    +name = "sphinxcontrib-htmlhelp"
    +version = "2.0.4"
    +requires_python = ">=3.9"
    +summary = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
    +dependencies = [
    +    "Sphinx>=5",
    +]
    +files = [
    +    {file = "sphinxcontrib_htmlhelp-2.0.4-py3-none-any.whl", hash = "sha256:8001661c077a73c29beaf4a79968d0726103c5605e27db92b9ebed8bab1359e9"},
    +    {file = "sphinxcontrib_htmlhelp-2.0.4.tar.gz", hash = "sha256:6c26a118a05b76000738429b724a0568dbde5b72391a688577da08f11891092a"},
    +]
    +
    +[[package]]
    +name = "sphinxcontrib-jquery"
    +version = "4.1"
    +requires_python = ">=2.7"
    +summary = "Extension to include jQuery on newer Sphinx releases"
    +dependencies = [
    +    "Sphinx>=1.8",
    +]
    +files = [
    +    {file = "sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a"},
    +    {file = "sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae"},
    +]
    +
    +[[package]]
    +name = "sphinxcontrib-jsmath"
    +version = "1.0.1"
    +requires_python = ">=3.5"
    +summary = "A sphinx extension which renders display math in HTML via JavaScript"
    +files = [
    +    {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"},
    +    {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"},
    +]
    +
    +[[package]]
    +name = "sphinxcontrib-qthelp"
    +version = "1.0.6"
    +requires_python = ">=3.9"
    +summary = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents"
    +dependencies = [
    +    "Sphinx>=5",
    +]
    +files = [
    +    {file = "sphinxcontrib_qthelp-1.0.6-py3-none-any.whl", hash = "sha256:bf76886ee7470b934e363da7a954ea2825650013d367728588732c7350f49ea4"},
    +    {file = "sphinxcontrib_qthelp-1.0.6.tar.gz", hash = "sha256:62b9d1a186ab7f5ee3356d906f648cacb7a6bdb94d201ee7adf26db55092982d"},
    +]
    +
    +[[package]]
    +name = "sphinxcontrib-serializinghtml"
    +version = "1.1.9"
    +requires_python = ">=3.9"
    +summary = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)"
    +dependencies = [
    +    "Sphinx>=5",
    +]
    +files = [
    +    {file = "sphinxcontrib_serializinghtml-1.1.9-py3-none-any.whl", hash = "sha256:9b36e503703ff04f20e9675771df105e58aa029cfcbc23b8ed716019b7416ae1"},
    +    {file = "sphinxcontrib_serializinghtml-1.1.9.tar.gz", hash = "sha256:0c64ff898339e1fac29abd2bf5f11078f3ec413cfe9c046d3120d7ca65530b54"},
    +]
    +
    +[[package]]
    +name = "sqlparse"
    +version = "0.4.4"
    +requires_python = ">=3.5"
    +summary = "A non-validating SQL parser."
    +files = [
    +    {file = "sqlparse-0.4.4-py3-none-any.whl", hash = "sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3"},
    +    {file = "sqlparse-0.4.4.tar.gz", hash = "sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c"},
    +]
    +
    +[[package]]
    +name = "stack-data"
    +version = "0.6.3"
    +summary = "Extract data from python stack frames and tracebacks for informative displays"
    +dependencies = [
    +    "asttokens>=2.1.0",
    +    "executing>=1.2.0",
    +    "pure-eval",
    +]
    +files = [
    +    {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"},
    +    {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"},
    +]
    +
    +[[package]]
    +name = "stdeb"
    +version = "0.10.0"
    +summary = "Python to Debian source package conversion utility"
    +files = [
    +    {file = "stdeb-0.10.0.tar.gz", hash = "sha256:08c22c9c03b28a140fe3ec5064b53a5288279f22e596ca06b0be698d50c93cf2"},
    +]
    +
    +[[package]]
    +name = "tomli"
    +version = "2.0.1"
    +requires_python = ">=3.7"
    +summary = "A lil' TOML parser"
    +files = [
    +    {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
    +    {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
    +]
    +
    +[[package]]
    +name = "tomlkit"
    +version = "0.12.1"
    +requires_python = ">=3.7"
    +summary = "Style preserving TOML library"
    +files = [
    +    {file = "tomlkit-0.12.1-py3-none-any.whl", hash = "sha256:712cbd236609acc6a3e2e97253dfc52d4c2082982a88f61b640ecf0817eab899"},
    +    {file = "tomlkit-0.12.1.tar.gz", hash = "sha256:38e1ff8edb991273ec9f6181244a6a391ac30e9f5098e7535640ea6be97a7c86"},
    +]
    +
    +[[package]]
    +name = "traitlets"
    +version = "5.11.2"
    +requires_python = ">=3.8"
    +summary = "Traitlets Python configuration system"
    +files = [
    +    {file = "traitlets-5.11.2-py3-none-any.whl", hash = "sha256:98277f247f18b2c5cabaf4af369187754f4fb0e85911d473f72329db8a7f4fae"},
    +    {file = "traitlets-5.11.2.tar.gz", hash = "sha256:7564b5bf8d38c40fa45498072bf4dc5e8346eb087bbf1e2ae2d8774f6a0f078e"},
    +]
    +
    +[[package]]
    +name = "truststore"
    +version = "0.8.0"
    +requires_python = ">= 3.10"
    +summary = "Verify certificates using native system trust stores"
    +files = [
    +    {file = "truststore-0.8.0-py3-none-any.whl", hash = "sha256:e37a5642ae9fc48caa8f120b6283d77225d600d224965a672c9e8ef49ce4bb4c"},
    +    {file = "truststore-0.8.0.tar.gz", hash = "sha256:dc70da89634944a579bfeec70a7a4523c53ffdb3cf52d1bb4a431fda278ddb96"},
    +]
    +
    +[[package]]
    +name = "twine"
    +version = "4.0.2"
    +requires_python = ">=3.7"
    +summary = "Collection of utilities for publishing packages on PyPI"
    +dependencies = [
    +    "importlib-metadata>=3.6",
    +    "keyring>=15.1",
    +    "pkginfo>=1.8.1",
    +    "readme-renderer>=35.0",
    +    "requests-toolbelt!=0.9.0,>=0.8.0",
    +    "requests>=2.20",
    +    "rfc3986>=1.4.0",
    +    "rich>=12.0.0",
    +    "urllib3>=1.26.0",
    +]
    +files = [
    +    {file = "twine-4.0.2-py3-none-any.whl", hash = "sha256:929bc3c280033347a00f847236564d1c52a3e61b1ac2516c97c48f3ceab756d8"},
    +    {file = "twine-4.0.2.tar.gz", hash = "sha256:9e102ef5fdd5a20661eb88fad46338806c3bd32cf1db729603fe3697b1bc83c8"},
    +]
    +
    +[[package]]
    +name = "types-pytz"
    +version = "2023.3.1.1"
    +summary = "Typing stubs for pytz"
    +files = [
    +    {file = "types-pytz-2023.3.1.1.tar.gz", hash = "sha256:cc23d0192cd49c8f6bba44ee0c81e4586a8f30204970fc0894d209a6b08dab9a"},
    +    {file = "types_pytz-2023.3.1.1-py3-none-any.whl", hash = "sha256:1999a123a3dc0e39a2ef6d19f3f8584211de9e6a77fe7a0259f04a524e90a5cf"},
    +]
    +
    +[[package]]
    +name = "types-pyyaml"
    +version = "6.0.12.12"
    +summary = "Typing stubs for PyYAML"
    +files = [
    +    {file = "types-PyYAML-6.0.12.12.tar.gz", hash = "sha256:334373d392fde0fdf95af5c3f1661885fa10c52167b14593eb856289e1855062"},
    +    {file = "types_PyYAML-6.0.12.12-py3-none-any.whl", hash = "sha256:c05bc6c158facb0676674b7f11fe3960db4f389718e19e62bd2b84d6205cfd24"},
    +]
    +
    +[[package]]
    +name = "typing-extensions"
    +version = "4.8.0"
    +requires_python = ">=3.8"
    +summary = "Backported and Experimental Type Hints for Python 3.8+"
    +files = [
    +    {file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"},
    +    {file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"},
    +]
    +
    +[[package]]
    +name = "tzdata"
    +version = "2023.3"
    +requires_python = ">=2"
    +summary = "Provider of IANA time zone data"
    +files = [
    +    {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"},
    +    {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"},
    +]
    +
    +[[package]]
    +name = "tzlocal"
    +version = "5.1"
    +requires_python = ">=3.7"
    +summary = "tzinfo object for the local timezone"
    +dependencies = [
    +    "tzdata; platform_system == \"Windows\"",
    +]
    +files = [
    +    {file = "tzlocal-5.1-py3-none-any.whl", hash = "sha256:2938498395d5f6a898ab8009555cb37a4d360913ad375d4747ef16826b03ef23"},
    +    {file = "tzlocal-5.1.tar.gz", hash = "sha256:a5ccb2365b295ed964e0a98ad076fe10c495591e75505d34f154d60a7f1ed722"},
    +]
    +
    +[[package]]
    +name = "unearth"
    +version = "0.11.2"
    +requires_python = ">=3.7"
    +summary = "A utility to fetch and download python packages"
    +dependencies = [
    +    "packaging>=20",
    +    "requests>=2.25",
    +]
    +files = [
    +    {file = "unearth-0.11.2-py3-none-any.whl", hash = "sha256:046a996466de40a16e257fc883ae08157e7ab78a85bcec00313f3fdf9131bd37"},
    +    {file = "unearth-0.11.2.tar.gz", hash = "sha256:0eb5a8800fda0610e095fef768b48d47c858c9b8417a785af647046c2df5ed2b"},
    +]
    +
    +[[package]]
    +name = "urllib3"
    +version = "2.0.7"
    +requires_python = ">=3.7"
    +summary = "HTTP library with thread-safe connection pooling, file post, and more."
    +files = [
    +    {file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"},
    +    {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"},
    +]
    +
    +[[package]]
    +name = "virtualenv"
    +version = "20.24.5"
    +requires_python = ">=3.7"
    +summary = "Virtual Python Environment builder"
    +dependencies = [
    +    "distlib<1,>=0.3.7",
    +    "filelock<4,>=3.12.2",
    +    "platformdirs<4,>=3.9.1",
    +]
    +files = [
    +    {file = "virtualenv-20.24.5-py3-none-any.whl", hash = "sha256:b80039f280f4919c77b30f1c23294ae357c4c8701042086e3fc005963e4e537b"},
    +    {file = "virtualenv-20.24.5.tar.gz", hash = "sha256:e8361967f6da6fbdf1426483bfe9fca8287c242ac0bc30429905721cefbff752"},
    +]
    +
    +[[package]]
    +name = "w3lib"
    +version = "2.1.2"
    +requires_python = ">=3.7"
    +summary = "Library of web-related functions"
    +files = [
    +    {file = "w3lib-2.1.2-py3-none-any.whl", hash = "sha256:c4432926e739caa8e3f49f5de783f336df563d9490416aebd5d39fb896d264e7"},
    +    {file = "w3lib-2.1.2.tar.gz", hash = "sha256:ed5b74e997eea2abe3c1321f916e344144ee8e9072a6f33463ee8e57f858a4b1"},
    +]
    +
    +[[package]]
    +name = "wcwidth"
    +version = "0.2.8"
    +summary = "Measures the displayed width of unicode strings in a terminal"
    +files = [
    +    {file = "wcwidth-0.2.8-py2.py3-none-any.whl", hash = "sha256:77f719e01648ed600dfa5402c347481c0992263b81a027344f3e1ba25493a704"},
    +    {file = "wcwidth-0.2.8.tar.gz", hash = "sha256:8705c569999ffbb4f6a87c6d1b80f324bd6db952f5eb0b95bc07517f4c1813d4"},
    +]
    +
    +[[package]]
    +name = "websockets"
    +version = "11.0.3"
    +requires_python = ">=3.7"
    +summary = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
    +files = [
    +    {file = "websockets-11.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3ccc8a0c387629aec40f2fc9fdcb4b9d5431954f934da3eaf16cdc94f67dbfac"},
    +    {file = "websockets-11.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d67ac60a307f760c6e65dad586f556dde58e683fab03323221a4e530ead6f74d"},
    +    {file = "websockets-11.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84d27a4832cc1a0ee07cdcf2b0629a8a72db73f4cf6de6f0904f6661227f256f"},
    +    {file = "websockets-11.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffd7dcaf744f25f82190856bc26ed81721508fc5cbf2a330751e135ff1283564"},
    +    {file = "websockets-11.0.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7622a89d696fc87af8e8d280d9b421db5133ef5b29d3f7a1ce9f1a7bf7fcfa11"},
    +    {file = "websockets-11.0.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bceab846bac555aff6427d060f2fcfff71042dba6f5fca7dc4f75cac815e57ca"},
    +    {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:54c6e5b3d3a8936a4ab6870d46bdd6ec500ad62bde9e44462c32d18f1e9a8e54"},
    +    {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:41f696ba95cd92dc047e46b41b26dd24518384749ed0d99bea0a941ca87404c4"},
    +    {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:86d2a77fd490ae3ff6fae1c6ceaecad063d3cc2320b44377efdde79880e11526"},
    +    {file = "websockets-11.0.3-cp310-cp310-win32.whl", hash = "sha256:2d903ad4419f5b472de90cd2d40384573b25da71e33519a67797de17ef849b69"},
    +    {file = "websockets-11.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:1d2256283fa4b7f4c7d7d3e84dc2ece74d341bce57d5b9bf385df109c2a1a82f"},
    +    {file = "websockets-11.0.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e848f46a58b9fcf3d06061d17be388caf70ea5b8cc3466251963c8345e13f7eb"},
    +    {file = "websockets-11.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:aa5003845cdd21ac0dc6c9bf661c5beddd01116f6eb9eb3c8e272353d45b3288"},
    +    {file = "websockets-11.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b58cbf0697721120866820b89f93659abc31c1e876bf20d0b3d03cef14faf84d"},
    +    {file = "websockets-11.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:660e2d9068d2bedc0912af508f30bbeb505bbbf9774d98def45f68278cea20d3"},
    +    {file = "websockets-11.0.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c1f0524f203e3bd35149f12157438f406eff2e4fb30f71221c8a5eceb3617b6b"},
    +    {file = "websockets-11.0.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:def07915168ac8f7853812cc593c71185a16216e9e4fa886358a17ed0fd9fcf6"},
    +    {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b30c6590146e53149f04e85a6e4fcae068df4289e31e4aee1fdf56a0dead8f97"},
    +    {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:619d9f06372b3a42bc29d0cd0354c9bb9fb39c2cbc1a9c5025b4538738dbffaf"},
    +    {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:01f5567d9cf6f502d655151645d4e8b72b453413d3819d2b6f1185abc23e82dd"},
    +    {file = "websockets-11.0.3-cp311-cp311-win32.whl", hash = "sha256:e1459677e5d12be8bbc7584c35b992eea142911a6236a3278b9b5ce3326f282c"},
    +    {file = "websockets-11.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:e7837cb169eca3b3ae94cc5787c4fed99eef74c0ab9506756eea335e0d6f3ed8"},
    +    {file = "websockets-11.0.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:777354ee16f02f643a4c7f2b3eff8027a33c9861edc691a2003531f5da4f6bc8"},
    +    {file = "websockets-11.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8c82f11964f010053e13daafdc7154ce7385ecc538989a354ccc7067fd7028fd"},
    +    {file = "websockets-11.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3580dd9c1ad0701169e4d6fc41e878ffe05e6bdcaf3c412f9d559389d0c9e016"},
    +    {file = "websockets-11.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f1a3f10f836fab6ca6efa97bb952300b20ae56b409414ca85bff2ad241d2a61"},
    +    {file = "websockets-11.0.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df41b9bc27c2c25b486bae7cf42fccdc52ff181c8c387bfd026624a491c2671b"},
    +    {file = "websockets-11.0.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:279e5de4671e79a9ac877427f4ac4ce93751b8823f276b681d04b2156713b9dd"},
    +    {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1fdf26fa8a6a592f8f9235285b8affa72748dc12e964a5518c6c5e8f916716f7"},
    +    {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:69269f3a0b472e91125b503d3c0b3566bda26da0a3261c49f0027eb6075086d1"},
    +    {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:97b52894d948d2f6ea480171a27122d77af14ced35f62e5c892ca2fae9344311"},
    +    {file = "websockets-11.0.3-cp39-cp39-win32.whl", hash = "sha256:c7f3cb904cce8e1be667c7e6fef4516b98d1a6a0635a58a57528d577ac18a128"},
    +    {file = "websockets-11.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c792ea4eabc0159535608fc5658a74d1a81020eb35195dd63214dcf07556f67e"},
    +    {file = "websockets-11.0.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f2e58f2c36cc52d41f2659e4c0cbf7353e28c8c9e63e30d8c6d3494dc9fdedcf"},
    +    {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de36fe9c02995c7e6ae6efe2e205816f5f00c22fd1fbf343d4d18c3d5ceac2f5"},
    +    {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0ac56b661e60edd453585f4bd68eb6a29ae25b5184fd5ba51e97652580458998"},
    +    {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e052b8467dd07d4943936009f46ae5ce7b908ddcac3fda581656b1b19c083d9b"},
    +    {file = "websockets-11.0.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:42cc5452a54a8e46a032521d7365da775823e21bfba2895fb7b77633cce031bb"},
    +    {file = "websockets-11.0.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e6316827e3e79b7b8e7d8e3b08f4e331af91a48e794d5d8b099928b6f0b85f20"},
    +    {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8531fdcad636d82c517b26a448dcfe62f720e1922b33c81ce695d0edb91eb931"},
    +    {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c114e8da9b475739dde229fd3bc6b05a6537a88a578358bc8eb29b4030fac9c9"},
    +    {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e063b1865974611313a3849d43f2c3f5368093691349cf3c7c8f8f75ad7cb280"},
    +    {file = "websockets-11.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:92b2065d642bf8c0a82d59e59053dd2fdde64d4ed44efe4870fa816c1232647b"},
    +    {file = "websockets-11.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0ee68fe502f9031f19d495dae2c268830df2760c0524cbac5d759921ba8c8e82"},
    +    {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcacf2c7a6c3a84e720d1bb2b543c675bf6c40e460300b628bab1b1efc7c034c"},
    +    {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b67c6f5e5a401fc56394f191f00f9b3811fe843ee93f4a70df3c389d1adf857d"},
    +    {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d5023a4b6a5b183dc838808087033ec5df77580485fc533e7dab2567851b0a4"},
    +    {file = "websockets-11.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ed058398f55163a79bb9f06a90ef9ccc063b204bb346c4de78efc5d15abfe602"},
    +    {file = "websockets-11.0.3-py3-none-any.whl", hash = "sha256:6681ba9e7f8f3b19440921e99efbb40fc89f26cd71bf539e45d8c8a25c976dc6"},
    +    {file = "websockets-11.0.3.tar.gz", hash = "sha256:88fc51d9a26b10fc331be344f1781224a375b78488fc343620184e95a4b27016"},
    +]
    +
    +[[package]]
    +name = "wheel"
    +version = "0.41.2"
    +requires_python = ">=3.7"
    +summary = "A built-package format for Python"
    +files = [
    +    {file = "wheel-0.41.2-py3-none-any.whl", hash = "sha256:75909db2664838d015e3d9139004ee16711748a52c8f336b52882266540215d8"},
    +    {file = "wheel-0.41.2.tar.gz", hash = "sha256:0c5ac5ff2afb79ac23ab82bab027a0be7b5dbcf2e54dc50efe4bf507de1f7985"},
    +]
    +
    +[[package]]
    +name = "youtube-dl"
    +version = "2021.12.17"
    +summary = "YouTube video downloader"
    +files = [
    +    {file = "youtube_dl-2021.12.17-py2.py3-none-any.whl", hash = "sha256:f1336d5de68647e0364a47b3c0712578e59ec76f02048ff5c50ef1c69d79cd55"},
    +    {file = "youtube_dl-2021.12.17.tar.gz", hash = "sha256:bc59e86c5d15d887ac590454511f08ce2c47698d5a82c27bfe27b5d814bbaed2"},
    +]
    +
    +[[package]]
    +name = "yt-dlp"
    +version = "2023.10.13"
    +requires_python = ">=3.7"
    +summary = "A youtube-dl fork with additional features and patches"
    +dependencies = [
    +    "brotli; platform_python_implementation == \"CPython\"",
    +    "brotlicffi; platform_python_implementation != \"CPython\"",
    +    "certifi",
    +    "mutagen",
    +    "pycryptodomex",
    +    "websockets",
    +]
    +files = [
    +    {file = "yt-dlp-2023.10.13.tar.gz", hash = "sha256:e026ea1c435ff36eef1215bc4c5bb8c479938b90054997ba99f63a4541fe63b4"},
    +    {file = "yt_dlp-2023.10.13-py2.py3-none-any.whl", hash = "sha256:2b069f22675532eebacdfd6372b1825651a751fef848de9ae6efe6491b2dc38a"},
    +]
    +
    +[[package]]
    +name = "zipp"
    +version = "3.17.0"
    +requires_python = ">=3.8"
    +summary = "Backport of pathlib-compatible object wrapper for zip files"
    +files = [
    +    {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"},
    +    {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"},
    +]
    diff --git a/pyproject.toml b/pyproject.toml
    new file mode 100644
    index 00000000..458809af
    --- /dev/null
    +++ b/pyproject.toml
    @@ -0,0 +1,118 @@
    +[project]
    +name = "archivebox"
    +version = "0.7.0"
    +description = "Self-hosted internet archiving solution."
    +authors = [
    +    {name = "Nick Sweeting", email = "setup.py@archivebox.io"},
    +]
    +dependencies = [
    +    "setuptools>=68.2.2",
    +    "croniter>=0.3.34",
    +    "dateparser>=1.0.0",
    +    "django-extensions>=3.0.3",
    +    "django>=3.1.3,<3.2",
    +    "ipython>5.0.0",
    +    "mypy-extensions>=0.4.3",
    +    "python-crontab>=2.5.1",
    +    "requests>=2.24.0",
    +    "w3lib>=1.22.0",
    +    "youtube-dl>=2021.04.17",
    +    "yt-dlp>=2021.4.11",
    +    "playwright>=1.39.0",
    +]
    +requires-python = ">=3.9"
    +readme = "README.md"
    +license = {text = "MIT"}
    +classifiers = [
    +    "Development Status :: 4 - Beta",
    +    "Environment :: Console",
    +    "Environment :: Web Environment",
    +    "Framework :: Django",
    +    "Intended Audience :: Developers",
    +    "Intended Audience :: Education",
    +    "Intended Audience :: End Users/Desktop",
    +    "Intended Audience :: Information Technology",
    +    "Intended Audience :: Legal Industry",
    +    "Intended Audience :: System Administrators",
    +    "License :: OSI Approved :: MIT License",
    +    "Natural Language :: English",
    +    "Operating System :: OS Independent",
    +    "Programming Language :: Python :: 3",
    +    "Programming Language :: Python :: 3.7",
    +    "Programming Language :: Python :: 3.8",
    +    "Programming Language :: Python :: 3.9",
    +    "Topic :: Internet :: WWW/HTTP",
    +    "Topic :: Internet :: WWW/HTTP :: Indexing/Search",
    +    "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
    +    "Topic :: Sociology :: History",
    +    "Topic :: Software Development :: Libraries :: Python Modules",
    +    "Topic :: System :: Archiving",
    +    "Topic :: System :: Archiving :: Backup",
    +    "Topic :: System :: Recovery Tools",
    +    "Topic :: Utilities",
    +    "Typing :: Typed",
    +]
    +
    +# pdm lock -G:all
    +# pdm install -G:all
    +[tool.pdm.dev-dependencies]
    +build = [
    +    "pdm",
    +    "bottle",
    +    "setuptools",
    +    "stdeb",
    +    "twine",
    +    "wheel",
    +]
    +lint = [
    +    "flake8",
    +    "mypy",
    +    "django-stubs",
    +]
    +test = [
    +    "pytest",
    +]
    +debug = [
    +    "django-debug-toolbar",
    +    "djdt_flamegraph",
    +    "ipdb",
    +]
    +doc = [
    +    "recommonmark",
    +    "sphinx",
    +    "sphinx-rtd-theme",
    +]
    +
    +[project.optional-dependencies]
    +sonic = [
    +    "sonic-client>=0.0.5",
    +]
    +ldap = [
    +    "django-auth-ldap>=4.1.0",
    +]
    +
    +[project.scripts]
    +archivebox = "archivebox.cli:main"
    +
    +[tool.pdm.scripts]
    +lint = "./bin/lint.sh"
    +test = "./bin/test.sh"
    +# all = {composite = ["lint mypackage/", "test -v tests/"]}
    +
    +[build-system]
    +requires = ["pdm-backend"]
    +build-backend = "pdm.backend"
    +
    +
    +[project.urls]
    +Homepage = "https://github.com/ArchiveBox/ArchiveBox"
    +Source = "https://github.com/ArchiveBox/ArchiveBox"
    +Documentation = "https://github.com/ArchiveBox/ArchiveBox/wiki"
    +"Bug Tracker" = "https://github.com/ArchiveBox/ArchiveBox/issues"
    +Changelog = "https://github.com/ArchiveBox/ArchiveBox/releases"
    +Roadmap = "https://github.com/ArchiveBox/ArchiveBox/wiki/Roadmap"
    +Community = "https://github.com/ArchiveBox/ArchiveBox/wiki/Web-Archiving-Community"
    +Demo = "https://demo.archivebox.io"
    +Donate = "https://github.com/ArchiveBox/ArchiveBox/wiki/Donations"
    +
    +
    diff --git a/setup.py b/setup.py
    index 218aec47..330d89fe 100755
    --- a/setup.py
    +++ b/setup.py
    @@ -1,149 +1,150 @@
    -import json
    -import setuptools
    -from setuptools.command.test import test
    +#####################################################################################
    +# THIS FILE IS DEPRECATED AND WILL BE REMOVED EVENTUALLU
    +# ALL FUTURE CHANGES SHOULD HAPPEN IN pyproject.toml with pdm
    +#####################################################################################
     
    -from pathlib import Path
    +# import json
    +# import setuptools
    +# from setuptools.command.test import test
    +
    +# from pathlib import Path
     
     
    -PKG_NAME = "archivebox"
    -DESCRIPTION = "Self-hosted internet archiving solution."
    -LICENSE = "MIT"
    -AUTHOR = "Nick Sweeting"
    -AUTHOR_EMAIL="git@nicksweeting.com"
    -REPO_URL = "https://github.com/ArchiveBox/ArchiveBox"
    -PROJECT_URLS = {
    -    "Source":           f"{REPO_URL}",
    -    "Documentation":    f"{REPO_URL}/wiki",
    -    "Bug Tracker":      f"{REPO_URL}/issues",
    -    "Changelog":        f"{REPO_URL}/releases",
    -    "Roadmap":          f"{REPO_URL}/wiki/Roadmap",
    -    "Community":        f"{REPO_URL}/wiki/Web-Archiving-Community",
    -    "Demo":             f"https://demo.archivebox.io",
    -    "Donate":           f"{REPO_URL}/wiki/Donations",
    -}
    +# PKG_NAME = "archivebox"
    +# DESCRIPTION = "Self-hosted internet archiving solution."
    +# LICENSE = "MIT"
    +# AUTHOR = "Nick Sweeting"
    +# AUTHOR_EMAIL="setup.py@archivebox.io"
    +# REPO_URL = "https://github.com/ArchiveBox/ArchiveBox"
    +# PROJECT_URLS = {
    +#     "Source":           f"{REPO_URL}",
    +#     "Documentation":    f"{REPO_URL}/wiki",
    +#     "Bug Tracker":      f"{REPO_URL}/issues",
    +#     "Changelog":        f"{REPO_URL}/releases",
    +#     "Roadmap":          f"{REPO_URL}/wiki/Roadmap",
    +#     "Community":        f"{REPO_URL}/wiki/Web-Archiving-Community",
    +#     "Demo":             f"https://demo.archivebox.io",
    +#     "Donate":           f"{REPO_URL}/wiki/Donations",
    +# }
     
    -ROOT_DIR = Path(__file__).parent.resolve()
    -PACKAGE_DIR = ROOT_DIR / PKG_NAME
    +# ROOT_DIR = Path(__file__).parent.resolve()
    +# PACKAGE_DIR = ROOT_DIR / PKG_NAME
     
    -README = (PACKAGE_DIR / "README.md").read_text(encoding='utf-8', errors='ignore')
    -VERSION = json.loads((PACKAGE_DIR / "package.json").read_text().strip())['version']
    +# README = (PACKAGE_DIR / "README.md").read_text(encoding='utf-8', errors='ignore')
    +# VERSION = json.loads((PACKAGE_DIR / "package.json").read_text().strip())['version']
     
    -PYTHON_REQUIRES = ">=3.9"
    -SETUP_REQUIRES = ["wheel"]
    -INSTALL_REQUIRES = [
    -    # only add things here that have corresponding apt python3-packages available
    -    # anything added here also needs to be added to our package dependencies in
    -    # stdeb.cfg (apt), archivebox.rb (brew), Dockerfile, etc.
    -    # if there is no apt python3-package equivalent, then vendor it instead in
    -    # ./archivebox/vendor/
    -    "requests>=2.24.0",
    -    "mypy-extensions>=0.4.3",
    -    "django>=3.1.3,<3.2",
    -    "django-extensions>=3.0.3",
    -    "dateparser>=1.0.0",
    -    "youtube-dl>=2021.04.17",
    -    "yt-dlp>=2021.4.11",
    -    "python-crontab>=2.5.1",
    -    "croniter>=0.3.34",
    -    "w3lib>=1.22.0",
    -    "ipython>5.0.0",
    -]
    -EXTRAS_REQUIRE = {
    -    'sonic': [
    -        "sonic-client>=0.0.5",
    -    ],
    -    'ldap': [
    -        "django-auth-ldap>=4.1.0",
    -    ],
    -    'dev': [
    -        "build",
    -        "setuptools",
    -        "twine",
    -        "wheel",
    -        "flake8",
    -        "ipdb",
    -        "mypy",
    -        "django-stubs",
    -        "sphinx",
    -        "sphinx-rtd-theme",
    -        "recommonmark",
    -        "pytest",
    -        "bottle",
    -        "stdeb",
    -        "django-debug-toolbar",
    -        "djdt_flamegraph",
    -    ],
    -}
    +# class DisabledTestCommand(test):
    +#     def run(self):
    +#         # setup.py test is deprecated, disable it here by force so stdeb doesnt run it
    +#         print('\n[X] Running tests via setup.py test is deprecated.')
    +#         print('    Hint: Use the ./bin/test.sh script or pytest instead')
     
     # To see when setup.py gets called (uncomment for debugging):
     # import sys
     # print(PACKAGE_DIR, f"     (v{VERSION})")
     # print('>', sys.executable, *sys.argv)
     
    +# PYTHON_REQUIRES = ">=3.9"
    +# SETUP_REQUIRES = ["wheel"]
    +# INSTALL_REQUIRES = [
    +#     # only add things here that have corresponding apt python3-packages available
    +#     # anything added here also needs to be added to our package dependencies in
    +#     # stdeb.cfg (apt), archivebox.rb (brew), Dockerfile, etc.
    +#     # if there is no apt python3-package equivalent, then vendor it instead in
    +#     # ./archivebox/vendor/
    +#     "requests>=2.24.0",
    +#     "mypy-extensions>=0.4.3",
    +#     "django>=3.1.3,<3.2",
    +#     "django-extensions>=3.0.3",
    +#     "dateparser>=1.0.0",
    +#     "youtube-dl>=2021.04.17",
    +#     "yt-dlp>=2021.4.11",
    +#     "python-crontab>=2.5.1",
    +#     "croniter>=0.3.34",
    +#     "w3lib>=1.22.0",
    +#     "ipython>5.0.0",
    +# ]
    +# EXTRAS_REQUIRE = {
    +#     'sonic': [
    +#         "sonic-client>=0.0.5",
    +#     ],
    +#     'ldap': [
    +#         "django-auth-ldap>=4.1.0",
    +#     ],
    +#     'dev': [
    +#         "setuptools",
    +#         "twine",
    +#         "wheel",
    +#         "flake8",
    +#         "ipdb",
    +#         "mypy",
    +#         "django-stubs",
    +#         "sphinx",
    +#         "sphinx-rtd-theme",
    +#         "recommonmark",
    +#         "pytest",
    +#         "bottle",
    +#         "stdeb",
    +#         "django-debug-toolbar",
    +#         "djdt_flamegraph",
    +#     ],
    +# }
    +#
    +# setuptools.setup(
    +#     name=PKG_NAME,
    +#     version=VERSION,
    +#     license=LICENSE,
    +#     author=AUTHOR,
    +#     author_email=AUTHOR_EMAIL,
    +#     description=DESCRIPTION,
    +#     long_description=README,
    +#     long_description_content_type="text/markdown",
    +#     url=REPO_URL,
    +#     project_urls=PROJECT_URLS,
    +#     python_requires=PYTHON_REQUIRES,
    +#     setup_requires=SETUP_REQUIRES,
    +#     install_requires=INSTALL_REQUIRES,
    +#     extras_require=EXTRAS_REQUIRE,
    +#     packages=[PKG_NAME],
    +#     include_package_data=True,   # see MANIFEST.in
    +#     entry_points={
    +#         "console_scripts": [
    +#             f"{PKG_NAME} = {PKG_NAME}.cli:main",
    +#         ],
    +#     },
    +#     classifiers=[
    +#         "License :: OSI Approved :: MIT License",
    +#         "Natural Language :: English",
    +#         "Operating System :: OS Independent",
    +#         "Development Status :: 4 - Beta",
     
    -class DisabledTestCommand(test):
    -    def run(self):
    -        # setup.py test is deprecated, disable it here by force so stdeb doesnt run it
    -        print()
    -        print('[X] Running tests via setup.py test is deprecated.')
    -        print('    Hint: Use the ./bin/test.sh script or pytest instead')
    +#         "Topic :: Utilities",
    +#         "Topic :: System :: Archiving",
    +#         "Topic :: System :: Archiving :: Backup",
    +#         "Topic :: System :: Recovery Tools",
    +#         "Topic :: Sociology :: History",
    +#         "Topic :: Internet :: WWW/HTTP",
    +#         "Topic :: Internet :: WWW/HTTP :: Indexing/Search",
    +#         "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
    +#         "Topic :: Software Development :: Libraries :: Python Modules",
     
    -
    -setuptools.setup(
    -    name=PKG_NAME,
    -    version=VERSION,
    -    license=LICENSE,
    -    author=AUTHOR,
    -    author_email=AUTHOR_EMAIL,
    -    description=DESCRIPTION,
    -    long_description=README,
    -    long_description_content_type="text/markdown",
    -    url=REPO_URL,
    -    project_urls=PROJECT_URLS,
    -    python_requires=PYTHON_REQUIRES,
    -    setup_requires=SETUP_REQUIRES,
    -    install_requires=INSTALL_REQUIRES,
    -    extras_require=EXTRAS_REQUIRE,
    -    packages=[PKG_NAME],
    -    include_package_data=True,   # see MANIFEST.in
    -    entry_points={
    -        "console_scripts": [
    -            f"{PKG_NAME} = {PKG_NAME}.cli:main",
    -        ],
    -    },
    -    classifiers=[
    -        "License :: OSI Approved :: MIT License",
    -        "Natural Language :: English",
    -        "Operating System :: OS Independent",
    -        "Development Status :: 4 - Beta",
    -
    -        "Topic :: Utilities",
    -        "Topic :: System :: Archiving",
    -        "Topic :: System :: Archiving :: Backup",
    -        "Topic :: System :: Recovery Tools",
    -        "Topic :: Sociology :: History",
    -        "Topic :: Internet :: WWW/HTTP",
    -        "Topic :: Internet :: WWW/HTTP :: Indexing/Search",
    -        "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
    -        "Topic :: Software Development :: Libraries :: Python Modules",
    -
    -        "Intended Audience :: Developers",
    -        "Intended Audience :: Education",
    -        "Intended Audience :: End Users/Desktop",
    -        "Intended Audience :: Information Technology",
    -        "Intended Audience :: Legal Industry",
    -        "Intended Audience :: System Administrators",
    +#         "Intended Audience :: Developers",
    +#         "Intended Audience :: Education",
    +#         "Intended Audience :: End Users/Desktop",
    +#         "Intended Audience :: Information Technology",
    +#         "Intended Audience :: Legal Industry",
    +#         "Intended Audience :: System Administrators",
             
    -        "Environment :: Console",
    -        "Environment :: Web Environment",
    -        "Programming Language :: Python :: 3",
    -        "Programming Language :: Python :: 3.7",
    -        "Programming Language :: Python :: 3.8",
    -        "Programming Language :: Python :: 3.9",
    -        "Framework :: Django",
    -        "Typing :: Typed",
    -    ],
    -    cmdclass={
    -        "test": DisabledTestCommand,
    -    },
    -)
    +#         "Environment :: Console",
    +#         "Environment :: Web Environment",
    +#         "Programming Language :: Python :: 3",
    +#         "Programming Language :: Python :: 3.7",
    +#         "Programming Language :: Python :: 3.8",
    +#         "Programming Language :: Python :: 3.9",
    +#         "Framework :: Django",
    +#         "Typing :: Typed",
    +#     ],
    +#     cmdclass={
    +#         "test": DisabledTestCommand,
    +#     },
    +# )
    
    From 85f8583d62a341b0d5ffafe7d781eea33d1476db Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Thu, 19 Oct 2023 18:05:59 -0700
    Subject: [PATCH 32/89] catch ldap configuration and packaging errors and make
     them non fatal
    
    ---
     archivebox/core/settings.py | 56 ++++++++++++++++++++-----------------
     1 file changed, 31 insertions(+), 25 deletions(-)
    
    diff --git a/archivebox/core/settings.py b/archivebox/core/settings.py
    index de002f82..222b13e9 100644
    --- a/archivebox/core/settings.py
    +++ b/archivebox/core/settings.py
    @@ -6,9 +6,6 @@ import re
     import logging
     import tempfile
     
    -import ldap
    -from django_auth_ldap.config import LDAPSearch
    -
     from pathlib import Path
     from django.utils.crypto import get_random_string
     
    @@ -97,33 +94,42 @@ AUTHENTICATION_BACKENDS = [
     ]
     
     if LDAP:
    -    global AUTH_LDAP_SERVER_URI
    -    AUTH_LDAP_SERVER_URI = LDAP_SERVER_URI
    +    try:
    +        import ldap
    +        from django_auth_ldap.config import LDAPSearch
     
    -    global AUTH_LDAP_BIND_DN
    -    AUTH_LDAP_BIND_DN = LDAP_BIND_DN
    +        global AUTH_LDAP_SERVER_URI
    +        AUTH_LDAP_SERVER_URI = LDAP_SERVER_URI
     
    -    global AUTH_LDAP_BIND_PASSWORD
    -    AUTH_LDAP_BIND_PASSWORD = LDAP_BIND_PASSWORD
    +        global AUTH_LDAP_BIND_DN
    +        AUTH_LDAP_BIND_DN = LDAP_BIND_DN
     
    -    global AUTH_LDAP_USER_SEARCH
    -    AUTH_LDAP_USER_SEARCH = LDAPSearch(
    -        LDAP_USER_BASE,
    -        ldap.SCOPE_SUBTREE,
    -        '(&(' + LDAP_USERNAME_ATTR + '=%(user)s)' + LDAP_USER_FILTER + ')',
    -    )
    +        global AUTH_LDAP_BIND_PASSWORD
    +        AUTH_LDAP_BIND_PASSWORD = LDAP_BIND_PASSWORD
     
    -    global AUTH_LDAP_USER_ATTR_MAP
    -    AUTH_LDAP_USER_ATTR_MAP = {
    -        'username': LDAP_USERNAME_ATTR,
    -        'first_name': LDAP_FIRSTNAME_ATTR,
    -        'last_name': LDAP_LASTNAME_ATTR,
    -        'email': LDAP_EMAIL_ATTR,
    -    }
    +        global AUTH_LDAP_USER_SEARCH
    +        AUTH_LDAP_USER_SEARCH = LDAPSearch(
    +            LDAP_USER_BASE,
    +            ldap.SCOPE_SUBTREE,
    +            '(&(' + LDAP_USERNAME_ATTR + '=%(user)s)' + LDAP_USER_FILTER + ')',
    +        )
    +
    +        global AUTH_LDAP_USER_ATTR_MAP
    +        AUTH_LDAP_USER_ATTR_MAP = {
    +            'username': LDAP_USERNAME_ATTR,
    +            'first_name': LDAP_FIRSTNAME_ATTR,
    +            'last_name': LDAP_LASTNAME_ATTR,
    +            'email': LDAP_EMAIL_ATTR,
    +        }
    +
    +        AUTHENTICATION_BACKENDS = [
    +            'django_auth_ldap.backend.LDAPBackend',
    +        ]
    +    except ModuleNotFoundError:
    +        sys.stderr.write('[X] Error: Found LDAP=True config but LDAP packages not installed. You may need to run: pip install archivebox[ldap]\n\n')
    +        # dont hard exit here. in case the user is just running "archivebox version" or "archivebox help", we still want those to work despite broken ldap
    +        # sys.exit(1)
     
    -    AUTHENTICATION_BACKENDS = [
    -        'django_auth_ldap.backend.LDAPBackend',
    -    ]
     
     ################################################################################
     ### Debug Settings
    
    From 22bcffe5eef17b5d7525a106f45a79dc31eb257a Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Thu, 19 Oct 2023 18:24:05 -0700
    Subject: [PATCH 33/89] remove accidental duplicate template code
    
    ---
     archivebox/templates/admin/private_index.html | 59 -------------------
     1 file changed, 59 deletions(-)
    
    diff --git a/archivebox/templates/admin/private_index.html b/archivebox/templates/admin/private_index.html
    index 7afb62c3..b60f3a3e 100644
    --- a/archivebox/templates/admin/private_index.html
    +++ b/archivebox/templates/admin/private_index.html
    @@ -1,62 +1,3 @@
    -{% extends "base.html" %}
    -{% load static %}
    -
    -{% block body %}
    -    <div id="toolbar">
    -        <form id="changelist-search" action="{% url 'public-index' %}" method="get">
    -            <div>
    -                <label for="searchbar"><img src="/static/admin/img/search.svg" alt="Search"></label>
    -                <input type="text" size="40" name="q" value="" id="searchbar" autofocus placeholder="Title, URL, tags, timestamp, or content...".>
    -                <input type="submit" value="Search" style="height: 36px; padding-top: 6px; margin: 8px"/>
    -                <input type="button"
    -                       value="♺"
    -                       title="Refresh..."
    -                       onclick="location.href='{% url 'public-index' %}'"
    -                       style="background-color: rgba(121, 174, 200, 0.8); height: 30px; font-size: 0.8em; margin-top: 12px; padding-top: 6px; float:right">
    -                </input>
    -            </div>
    -        </form>
    -    </div>
    -    <table id="table-bookmarks">
    -        <thead>
    -            <tr>
    -                <th style="width: 100px;">Bookmarked</th>
    -                <th style="width: 26vw;">Snapshot ({{object_list|length}})</th>
    -                <th style="width: 140px">Files</th>
    -                <th style="width: 16vw;whitespace:nowrap;overflow-x:hidden;">Original URL</th>
    -            </tr>
    -        </thead>
    -            <tbody>
    -                {% for link in object_list %}
    -                    {% include 'main_index_row.html' with link=link  %}
    -                {% endfor %}
    -            </tbody>
    -        </table>
    -        <center>
    -            <span class="step-links">
    -                {% if page_obj.has_previous %}
    -                    <a href="{% url 'public-index' %}?page=1">« first</a>
    -                    <a href="{% url 'public-index' %}?page={{ page_obj.previous_page_number }}">previous</a>
    -                {% endif %}
    -        
    -                <span class="current">
    -                    Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
    -                </span>
    -        
    -                {% if page_obj.has_next %}
    -                    <a href="{% url 'public-index' %}?page={{ page_obj.next_page_number }}">next </a>
    -                    <a href="{% url 'public-index' %}?page={{ page_obj.paginator.num_pages }}">last »</a>
    -                {% endif %}
    -            </span>
    -    
    -            {% if page_obj.has_next %}
    -                <a href="{% url 'public-index' %}?page={{ page_obj.next_page_number }}">next </a>
    -                <a href="{% url 'public-index' %}?page={{ page_obj.paginator.num_pages }}">last »</a>
    -            {% endif %}
    -        </span>
    -        <br>
    -    </center>
    -{% endblock %}
     {% extends "admin/base_site.html" %}
     {% load i18n admin_urls static admin_list %}
     {% load core_tags %}
    
    From 63c276a93d89091e7e122a464efbf6ed9001a4d8 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Thu, 19 Oct 2023 18:24:19 -0700
    Subject: [PATCH 34/89] redirect add page back to snapshots list automatically
    
    ---
     archivebox/templates/core/add.html | 11 +++++++----
     1 file changed, 7 insertions(+), 4 deletions(-)
    
    diff --git a/archivebox/templates/core/add.html b/archivebox/templates/core/add.html
    index 7d6efc6c..b26a57e6 100644
    --- a/archivebox/templates/core/add.html
    +++ b/archivebox/templates/core/add.html
    @@ -33,7 +33,7 @@
                         <br/>
                         <div class="loader"></div>
                         <br/>
    -                    Check the server log or the <a href="/admin/core/archiveresult/?o=-1">Log</a> page for progress...
    +                    Check the server log or the <a href="/admin/core/archiveresult/?o=-1">Log</a> page for detailed progress...
                     </center>
                 </div>
                 <form id="add-form" method="POST" class="p-form">{% csrf_token %}
    @@ -46,19 +46,22 @@
                 </form>
                 <br/><br/><br/>
                 <center id="delay-warning" style="display: none">
    -                <small>(it's safe to leave this page, adding will continue in the background)</small>
    +                <small>(you will be redirected to your <a href="/">Snapshot list</a> momentarily, its safe to close this page at any time)</small>
                 </center>
                 {% if absolute_add_path %}
    -            <center id="bookmarklet">
    +            <!-- <center id="bookmarklet">
                   <p>Bookmark this link to quickly add to your archive:
                     <a href="javascript:void(window.open('{{ absolute_add_path }}?url='+encodeURIComponent(document.location.href)));">Add to ArchiveBox</a></p>
    -            </center>
    +            </center> -->
                 {% endif %}
                 <script>
                     document.getElementById('add-form').addEventListener('submit', function(event) {
                         document.getElementById('in-progress').style.display = 'block'
                         document.getElementById('add-form').style.display = 'none'
                         document.getElementById('delay-warning').style.display = 'block'
    +                    setTimeout(function() {
    +                        window.location = '/'
    +                    }, 2000)
                         return true
                     })
                 </script>
    
    From 3b3bdab97dd1f9205d3f9eaf41f86b41091e6355 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Fri, 20 Oct 2023 02:45:20 -0700
    Subject: [PATCH 35/89] update ignore files
    
    ---
     .dockerignore | 9 +++++++--
     .gitignore    | 1 +
     2 files changed, 8 insertions(+), 2 deletions(-)
    
    diff --git a/.dockerignore b/.dockerignore
    index 8cebf35e..28505e39 100644
    --- a/.dockerignore
    +++ b/.dockerignore
    @@ -5,16 +5,21 @@ __pycache__/
     .mypy_cache/
     .pytest_cache/
     .github/
    +.git/
    +.pdm-build/
    +.pdm-python/
    +.eggs/
     
     venv/
     .venv/
     .docker-venv/
    +node_modules/
     
     build/
     dist/
    -pip_dist/
    -!pip_dist/archivebox.egg-info/requires.txt
     brew_dist/
    +deb_dist/
    +pip_dist/
     assets/
     
     data/
    diff --git a/.gitignore b/.gitignore
    index a615433e..22cad1c0 100644
    --- a/.gitignore
    +++ b/.gitignore
    @@ -14,6 +14,7 @@ node_modules/
     
     # Packaging artifacts
     .pdm-python
    +.pdm-build
     archivebox.egg-info
     archivebox-*.tar.gz
     build/
    
    From e0e34e6377d0887c289a753c85ba1151ce573990 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Fri, 20 Oct 2023 02:45:37 -0700
    Subject: [PATCH 36/89] update package.json and npm lockfile
    
    ---
     package-lock.json | 3339 +++++++++++++++------------------------------
     package.json      |    4 +-
     2 files changed, 1092 insertions(+), 2251 deletions(-)
    
    diff --git a/package-lock.json b/package-lock.json
    index 64cfe6ba..ffc60ff5 100644
    --- a/package-lock.json
    +++ b/package-lock.json
    @@ -1,27 +1,25 @@
     {
       "name": "archivebox",
    -  "version": "0.6.3",
    +  "version": "0.7.0",
       "lockfileVersion": 3,
       "requires": true,
       "packages": {
         "": {
           "name": "archivebox",
    -      "version": "0.6.3",
    +      "version": "0.7.0",
           "license": "MIT",
           "dependencies": {
    -        "@postlight/mercury-parser": "git+https://github.com/postlight/mercury-parser.git",
    -        "playwright": "^1.37.1",
    +        "@postlight/parser": "^2.2.3",
             "readability-extractor": "git+https://github.com/ArchiveBox/readability-extractor.git",
    -        "single-file-cli": "^1.0.63"
    +        "single-file-cli": "^1.1.12"
           }
         },
         "node_modules/@babel/runtime-corejs2": {
    -      "version": "7.22.6",
    -      "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.22.6.tgz",
    -      "integrity": "sha512-GTJVRjzQIHUBwRzuWxPII87XoWxXzILBJrQh5gqIV6q6m231Y0BBA9NKta5FV5Lbl8z5gS3+m6YSoKJp0KQJ4g==",
    +      "version": "7.23.2",
    +      "license": "MIT",
           "dependencies": {
             "core-js": "^2.6.12",
    -        "regenerator-runtime": "^0.13.11"
    +        "regenerator-runtime": "^0.14.0"
           },
           "engines": {
             "node": ">=6.9.0"
    @@ -29,16 +27,14 @@
         },
         "node_modules/@mozilla/readability": {
           "version": "0.4.4",
    -      "resolved": "https://registry.npmjs.org/@mozilla/readability/-/readability-0.4.4.tgz",
    -      "integrity": "sha512-MCgZyANpJ6msfvVMi6+A0UAsvZj//4OHREYUB9f2087uXHVoU+H+SWhuihvb1beKpM323bReQPRio0WNk2+V6g==",
    +      "license": "Apache-2.0",
           "engines": {
             "node": ">=14.0.0"
           }
         },
         "node_modules/@postlight/ci-failed-test-reporter": {
           "version": "1.0.26",
    -      "resolved": "https://registry.npmjs.org/@postlight/ci-failed-test-reporter/-/ci-failed-test-reporter-1.0.26.tgz",
    -      "integrity": "sha512-xfXzxyOiKhco7Gx2OLTe9b66b0dFJw0elg94KGHoQXf5F8JqqFvdo35J8wayGOor64CSMvn+4Bjlu2NKV+yTGA==",
    +      "license": "MIT",
           "dependencies": {
             "dotenv": "^6.2.0",
             "node-fetch": "^2.3.0"
    @@ -47,10 +43,8 @@
             "ciftr": "cli.js"
           }
         },
    -    "node_modules/@postlight/mercury-parser": {
    -      "version": "2.2.1",
    -      "resolved": "git+ssh://git@github.com/postlight/mercury-parser.git#9cd9662bcbfea00b773fad691a4f6e53394ff543",
    -      "integrity": "sha512-nTyjg98Zpe2anZVjl16QzC3b9nThISzhzw59aoRMCW7gqjDb8VFU1bXrFlt9dEkxxey1ysuJ109hdCJI17TVVg==",
    +    "node_modules/@postlight/parser": {
    +      "version": "2.2.3",
           "bundleDependencies": [
             "jquery",
             "moment-timezone",
    @@ -65,27 +59,26 @@
             "difflib": "github:postlight/difflib.js",
             "ellipsize": "0.1.0",
             "iconv-lite": "0.5.0",
    -        "jquery": "^3.4.1",
    +        "jquery": "^3.5.0",
             "moment": "^2.23.0",
             "moment-parseformat": "3.0.0",
    -        "moment-timezone": "0.5.26",
    -        "postman-request": "^2.88.1-postman.7.1",
    -        "request-promise": "^4.2.2",
    +        "moment-timezone": "0.5.37",
    +        "postman-request": "^2.88.1-postman.31",
             "string-direction": "^0.1.2",
    -        "turndown": "^5.0.3",
    -        "url": "^0.11.0",
    +        "turndown": "^7.1.1",
             "valid-url": "^1.0.9",
             "wuzzy": "^0.1.4",
             "yargs-parser": "^15.0.1"
           },
           "bin": {
    -        "mercury-parser": "cli.js"
    +        "mercury-parser": "cli.js",
    +        "postlight-parser": "cli.js"
           },
           "engines": {
             "node": ">=10"
           }
         },
    -    "node_modules/@postlight/mercury-parser/node_modules/browser-request": {
    +    "node_modules/@postlight/parser/node_modules/browser-request": {
           "version": "0.3.2",
           "engines": [
             "node"
    @@ -95,7 +88,7 @@
             "http-headers": "^3.0.1"
           }
         },
    -    "node_modules/@postlight/mercury-parser/node_modules/http-headers": {
    +    "node_modules/@postlight/parser/node_modules/http-headers": {
           "version": "3.0.2",
           "inBundle": true,
           "license": "MIT",
    @@ -103,21 +96,21 @@
             "next-line": "^1.1.0"
           }
         },
    -    "node_modules/@postlight/mercury-parser/node_modules/jquery": {
    -      "version": "3.5.0",
    +    "node_modules/@postlight/parser/node_modules/jquery": {
    +      "version": "3.6.0",
           "inBundle": true,
           "license": "MIT"
         },
    -    "node_modules/@postlight/mercury-parser/node_modules/moment": {
    -      "version": "2.29.2",
    +    "node_modules/@postlight/parser/node_modules/moment": {
    +      "version": "2.29.4",
           "inBundle": true,
           "license": "MIT",
           "engines": {
             "node": "*"
           }
         },
    -    "node_modules/@postlight/mercury-parser/node_modules/moment-timezone": {
    -      "version": "0.5.26",
    +    "node_modules/@postlight/parser/node_modules/moment-timezone": {
    +      "version": "0.5.37",
           "inBundle": true,
           "license": "MIT",
           "dependencies": {
    @@ -127,15 +120,14 @@
             "node": "*"
           }
         },
    -    "node_modules/@postlight/mercury-parser/node_modules/next-line": {
    +    "node_modules/@postlight/parser/node_modules/next-line": {
           "version": "1.1.0",
           "inBundle": true,
           "license": "MIT"
         },
         "node_modules/@postman/form-data": {
           "version": "3.1.1",
    -      "resolved": "https://registry.npmjs.org/@postman/form-data/-/form-data-3.1.1.tgz",
    -      "integrity": "sha512-vjh8Q2a8S6UCm/KKs31XFJqEEgmbjBmpPNVV2eVav6905wyFAwaUOBGA1NPBI4ERH9MMZc6w0umFgM6WbEPMdg==",
    +      "license": "MIT",
           "dependencies": {
             "asynckit": "^0.4.0",
             "combined-stream": "^1.0.8",
    @@ -147,8 +139,7 @@
         },
         "node_modules/@postman/tough-cookie": {
           "version": "4.1.3-postman.1",
    -      "resolved": "https://registry.npmjs.org/@postman/tough-cookie/-/tough-cookie-4.1.3-postman.1.tgz",
    -      "integrity": "sha512-txpgUqZOnWYnUHZpHjkfb0IwVH4qJmyq77pPnJLlfhMtdCLMFTEeQHlzQiK906aaNCe4NEB5fGJHo9uzGbFMeA==",
    +      "license": "BSD-3-Clause",
           "dependencies": {
             "psl": "^1.1.33",
             "punycode": "^2.1.1",
    @@ -161,8 +152,7 @@
         },
         "node_modules/@postman/tunnel-agent": {
           "version": "0.6.3",
    -      "resolved": "https://registry.npmjs.org/@postman/tunnel-agent/-/tunnel-agent-0.6.3.tgz",
    -      "integrity": "sha512-k57fzmAZ2PJGxfOA4SGR05ejorHbVAa/84Hxh/2nAztjNXc4ZjOm9NUIk6/Z6LCrBvJZqjRZbN8e/nROVUPVdg==",
    +      "license": "Apache-2.0",
           "dependencies": {
             "safe-buffer": "^5.0.1"
           },
    @@ -171,14 +161,13 @@
           }
         },
         "node_modules/@puppeteer/browsers": {
    -      "version": "1.7.0",
    -      "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.7.0.tgz",
    -      "integrity": "sha512-sl7zI0IkbQGak/+IE3VEEZab5SSOlI5F6558WvzWGC1n3+C722rfewC1ZIkcF9dsoGSsxhsONoseVlNQG4wWvQ==",
    +      "version": "1.7.1",
    +      "license": "Apache-2.0",
           "dependencies": {
             "debug": "4.3.4",
             "extract-zip": "2.0.1",
             "progress": "2.0.3",
    -        "proxy-agent": "6.3.0",
    +        "proxy-agent": "6.3.1",
             "tar-fs": "3.0.4",
             "unbzip2-stream": "1.4.3",
             "yargs": "17.7.1"
    @@ -190,43 +179,9 @@
             "node": ">=16.3.0"
           }
         },
    -    "node_modules/@puppeteer/browsers/node_modules/cliui": {
    -      "version": "8.0.1",
    -      "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
    -      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
    -      "dependencies": {
    -        "string-width": "^4.2.0",
    -        "strip-ansi": "^6.0.1",
    -        "wrap-ansi": "^7.0.0"
    -      },
    -      "engines": {
    -        "node": ">=12"
    -      }
    -    },
    -    "node_modules/@puppeteer/browsers/node_modules/tar-fs": {
    -      "version": "3.0.4",
    -      "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz",
    -      "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==",
    -      "dependencies": {
    -        "mkdirp-classic": "^0.5.2",
    -        "pump": "^3.0.0",
    -        "tar-stream": "^3.1.5"
    -      }
    -    },
    -    "node_modules/@puppeteer/browsers/node_modules/tar-stream": {
    -      "version": "3.1.6",
    -      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz",
    -      "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==",
    -      "dependencies": {
    -        "b4a": "^1.6.4",
    -        "fast-fifo": "^1.2.0",
    -        "streamx": "^2.15.0"
    -      }
    -    },
         "node_modules/@puppeteer/browsers/node_modules/yargs": {
           "version": "17.7.1",
    -      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz",
    -      "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==",
    +      "license": "MIT",
           "dependencies": {
             "cliui": "^8.0.1",
             "escalade": "^3.1.1",
    @@ -242,35 +197,33 @@
         },
         "node_modules/@puppeteer/browsers/node_modules/yargs-parser": {
           "version": "21.1.1",
    -      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
    -      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
    +      "license": "ISC",
           "engines": {
             "node": ">=12"
           }
         },
         "node_modules/@tootallnate/once": {
    -      "version": "1.1.2",
    -      "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
    -      "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
    +      "version": "2.0.0",
    +      "license": "MIT",
           "engines": {
    -        "node": ">= 6"
    +        "node": ">= 10"
           }
         },
         "node_modules/@tootallnate/quickjs-emscripten": {
           "version": "0.23.0",
    -      "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",
    -      "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="
    +      "license": "MIT"
         },
         "node_modules/@types/node": {
    -      "version": "20.4.2",
    -      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.4.2.tgz",
    -      "integrity": "sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw==",
    -      "optional": true
    +      "version": "20.8.7",
    +      "license": "MIT",
    +      "optional": true,
    +      "dependencies": {
    +        "undici-types": "~5.25.1"
    +      }
         },
         "node_modules/@types/yauzl": {
    -      "version": "2.10.0",
    -      "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz",
    -      "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==",
    +      "version": "2.10.2",
    +      "license": "MIT",
           "optional": true,
           "dependencies": {
             "@types/node": "*"
    @@ -278,52 +231,11 @@
         },
         "node_modules/abab": {
           "version": "2.0.6",
    -      "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
    -      "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA=="
    -    },
    -    "node_modules/acorn": {
    -      "version": "5.7.4",
    -      "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.4.tgz",
    -      "integrity": "sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==",
    -      "bin": {
    -        "acorn": "bin/acorn"
    -      },
    -      "engines": {
    -        "node": ">=0.4.0"
    -      }
    -    },
    -    "node_modules/acorn-globals": {
    -      "version": "4.3.4",
    -      "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz",
    -      "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==",
    -      "dependencies": {
    -        "acorn": "^6.0.1",
    -        "acorn-walk": "^6.0.1"
    -      }
    -    },
    -    "node_modules/acorn-globals/node_modules/acorn": {
    -      "version": "6.4.2",
    -      "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz",
    -      "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==",
    -      "bin": {
    -        "acorn": "bin/acorn"
    -      },
    -      "engines": {
    -        "node": ">=0.4.0"
    -      }
    -    },
    -    "node_modules/acorn-walk": {
    -      "version": "6.2.0",
    -      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz",
    -      "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==",
    -      "engines": {
    -        "node": ">=0.4.0"
    -      }
    +      "license": "BSD-3-Clause"
         },
         "node_modules/agent-base": {
           "version": "6.0.2",
    -      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
    -      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
    +      "license": "MIT",
           "dependencies": {
             "debug": "4"
           },
    @@ -333,8 +245,7 @@
         },
         "node_modules/ajv": {
           "version": "6.12.6",
    -      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
    -      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
    +      "license": "MIT",
           "dependencies": {
             "fast-deep-equal": "^3.1.1",
             "fast-json-stable-stringify": "^2.0.0",
    @@ -348,16 +259,14 @@
         },
         "node_modules/ansi-regex": {
           "version": "5.0.1",
    -      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
    -      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
    +      "license": "MIT",
           "engines": {
             "node": ">=8"
           }
         },
         "node_modules/ansi-styles": {
           "version": "4.3.0",
    -      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
    -      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
    +      "license": "MIT",
           "dependencies": {
             "color-convert": "^2.0.1"
           },
    @@ -368,31 +277,23 @@
             "url": "https://github.com/chalk/ansi-styles?sponsor=1"
           }
         },
    -    "node_modules/array-equal": {
    -      "version": "1.0.0",
    -      "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
    -      "integrity": "sha512-H3LU5RLiSsGXPhN+Nipar0iR0IofH+8r89G2y1tBKxQ/agagKyAjhkAFDRBfodP2caPrNKHpAWNIM/c9yeL7uA=="
    -    },
         "node_modules/asn1": {
           "version": "0.2.6",
    -      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
    -      "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
    +      "license": "MIT",
           "dependencies": {
             "safer-buffer": "~2.1.0"
           }
         },
         "node_modules/assert-plus": {
           "version": "1.0.0",
    -      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
    -      "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
    +      "license": "MIT",
           "engines": {
             "node": ">=0.8"
           }
         },
         "node_modules/ast-types": {
           "version": "0.13.4",
    -      "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz",
    -      "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==",
    +      "license": "MIT",
           "dependencies": {
             "tslib": "^2.0.1"
           },
    @@ -400,110 +301,31 @@
             "node": ">=4"
           }
         },
    -    "node_modules/async-limiter": {
    -      "version": "1.0.1",
    -      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz",
    -      "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
    -    },
         "node_modules/asynckit": {
           "version": "0.4.0",
    -      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
    -      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
    +      "license": "MIT"
         },
         "node_modules/aws-sign2": {
           "version": "0.7.0",
    -      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
    -      "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==",
    +      "license": "Apache-2.0",
           "engines": {
             "node": "*"
           }
         },
         "node_modules/aws4": {
           "version": "1.12.0",
    -      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz",
    -      "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg=="
    +      "license": "MIT"
         },
         "node_modules/b4a": {
           "version": "1.6.4",
    -      "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz",
    -      "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw=="
    +      "license": "ISC"
         },
         "node_modules/balanced-match": {
           "version": "1.0.2",
    -      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
    -      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
    +      "license": "MIT"
         },
         "node_modules/base64-js": {
           "version": "1.5.1",
    -      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
    -      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
    -      "funding": [
    -        {
    -          "type": "github",
    -          "url": "https://github.com/sponsors/feross"
    -        },
    -        {
    -          "type": "patreon",
    -          "url": "https://www.patreon.com/feross"
    -        },
    -        {
    -          "type": "consulting",
    -          "url": "https://feross.org/support"
    -        }
    -      ]
    -    },
    -    "node_modules/basic-ftp": {
    -      "version": "5.0.3",
    -      "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.3.tgz",
    -      "integrity": "sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==",
    -      "engines": {
    -        "node": ">=10.0.0"
    -      }
    -    },
    -    "node_modules/bcrypt-pbkdf": {
    -      "version": "1.0.2",
    -      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
    -      "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
    -      "dependencies": {
    -        "tweetnacl": "^0.14.3"
    -      }
    -    },
    -    "node_modules/bluebird": {
    -      "version": "2.11.0",
    -      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
    -      "integrity": "sha512-UfFSr22dmHPQqPP9XWHRhq+gWnHCYguQGkXQlbyPtW5qTnhFWA8/iXg765tH0cAjy7l/zPJ1aBTO0g5XgA7kvQ=="
    -    },
    -    "node_modules/boolbase": {
    -      "version": "1.0.0",
    -      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
    -      "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
    -    },
    -    "node_modules/brace-expansion": {
    -      "version": "1.1.11",
    -      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
    -      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
    -      "dependencies": {
    -        "balanced-match": "^1.0.0",
    -        "concat-map": "0.0.1"
    -      }
    -    },
    -    "node_modules/brotli": {
    -      "version": "1.3.3",
    -      "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz",
    -      "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==",
    -      "dependencies": {
    -        "base64-js": "^1.1.2"
    -      }
    -    },
    -    "node_modules/browser-process-hrtime": {
    -      "version": "1.0.0",
    -      "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
    -      "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow=="
    -    },
    -    "node_modules/buffer": {
    -      "version": "5.7.1",
    -      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
    -      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
           "funding": [
             {
               "type": "github",
    @@ -518,6 +340,62 @@
               "url": "https://feross.org/support"
             }
           ],
    +      "license": "MIT"
    +    },
    +    "node_modules/basic-ftp": {
    +      "version": "5.0.3",
    +      "license": "MIT",
    +      "engines": {
    +        "node": ">=10.0.0"
    +      }
    +    },
    +    "node_modules/bcrypt-pbkdf": {
    +      "version": "1.0.2",
    +      "license": "BSD-3-Clause",
    +      "dependencies": {
    +        "tweetnacl": "^0.14.3"
    +      }
    +    },
    +    "node_modules/bluebird": {
    +      "version": "2.11.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/boolbase": {
    +      "version": "1.0.0",
    +      "license": "ISC"
    +    },
    +    "node_modules/brace-expansion": {
    +      "version": "1.1.11",
    +      "license": "MIT",
    +      "dependencies": {
    +        "balanced-match": "^1.0.0",
    +        "concat-map": "0.0.1"
    +      }
    +    },
    +    "node_modules/brotli": {
    +      "version": "1.3.3",
    +      "license": "MIT",
    +      "dependencies": {
    +        "base64-js": "^1.1.2"
    +      }
    +    },
    +    "node_modules/buffer": {
    +      "version": "5.7.1",
    +      "funding": [
    +        {
    +          "type": "github",
    +          "url": "https://github.com/sponsors/feross"
    +        },
    +        {
    +          "type": "patreon",
    +          "url": "https://www.patreon.com/feross"
    +        },
    +        {
    +          "type": "consulting",
    +          "url": "https://feross.org/support"
    +        }
    +      ],
    +      "license": "MIT",
           "dependencies": {
             "base64-js": "^1.3.1",
             "ieee754": "^1.1.13"
    @@ -525,41 +403,25 @@
         },
         "node_modules/buffer-crc32": {
           "version": "0.2.13",
    -      "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
    -      "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
    +      "license": "MIT",
           "engines": {
             "node": "*"
           }
         },
    -    "node_modules/call-bind": {
    -      "version": "1.0.2",
    -      "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
    -      "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
    -      "dependencies": {
    -        "function-bind": "^1.1.1",
    -        "get-intrinsic": "^1.0.2"
    -      },
    -      "funding": {
    -        "url": "https://github.com/sponsors/ljharb"
    -      }
    -    },
         "node_modules/camelcase": {
           "version": "5.3.1",
    -      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
    -      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
    +      "license": "MIT",
           "engines": {
             "node": ">=6"
           }
         },
         "node_modules/caseless": {
           "version": "0.12.0",
    -      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
    -      "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
    +      "license": "Apache-2.0"
         },
         "node_modules/cheerio": {
           "version": "0.22.0",
    -      "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz",
    -      "integrity": "sha512-8/MzidM6G/TgRelkzDG13y3Y9LxBjCb+8yOEZ9+wwq5gVF2w2pV0wmHvjfT0RvuxGyR7UEuK36r+yYMbT4uKgA==",
    +      "license": "MIT",
           "dependencies": {
             "css-select": "~1.2.0",
             "dom-serializer": "~0.1.0",
    @@ -583,9 +445,8 @@
           }
         },
         "node_modules/chromium-bidi": {
    -      "version": "0.4.20",
    -      "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.20.tgz",
    -      "integrity": "sha512-ruHgVZFEv00mAQMz1tQjfjdG63jiPWrQPF6HLlX2ucqLqVTJoWngeBEKHaJ6n1swV/HSvgnBNbtTRIlcVyW3Fw==",
    +      "version": "0.4.26",
    +      "license": "Apache-2.0",
           "dependencies": {
             "mitt": "3.0.1"
           },
    @@ -593,10 +454,21 @@
             "devtools-protocol": "*"
           }
         },
    +    "node_modules/cliui": {
    +      "version": "8.0.1",
    +      "license": "ISC",
    +      "dependencies": {
    +        "string-width": "^4.2.0",
    +        "strip-ansi": "^6.0.1",
    +        "wrap-ansi": "^7.0.0"
    +      },
    +      "engines": {
    +        "node": ">=12"
    +      }
    +    },
         "node_modules/color-convert": {
           "version": "2.0.1",
    -      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
    -      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
    +      "license": "MIT",
           "dependencies": {
             "color-name": "~1.1.4"
           },
    @@ -606,13 +478,11 @@
         },
         "node_modules/color-name": {
           "version": "1.1.4",
    -      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
    -      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
    +      "license": "MIT"
         },
         "node_modules/combined-stream": {
           "version": "1.0.8",
    -      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
    -      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
    +      "license": "MIT",
           "dependencies": {
             "delayed-stream": "~1.0.0"
           },
    @@ -622,33 +492,27 @@
         },
         "node_modules/concat-map": {
           "version": "0.0.1",
    -      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
    -      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
    +      "license": "MIT"
         },
         "node_modules/core-js": {
           "version": "2.6.12",
    -      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
    -      "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
    -      "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.",
    -      "hasInstallScript": true
    +      "hasInstallScript": true,
    +      "license": "MIT"
         },
         "node_modules/core-util-is": {
           "version": "1.0.2",
    -      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
    -      "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="
    +      "license": "MIT"
         },
         "node_modules/cross-fetch": {
           "version": "4.0.0",
    -      "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz",
    -      "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==",
    +      "license": "MIT",
           "dependencies": {
             "node-fetch": "^2.6.12"
           }
         },
         "node_modules/css-select": {
           "version": "1.2.0",
    -      "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
    -      "integrity": "sha512-dUQOBoqdR7QwV90WysXPLXG5LO7nhYBgiWVfxF80DKPF8zx1t/pUd2FYy73emg3zrjtM6dzmYgbHKfV2rxiHQA==",
    +      "license": "BSD-like",
           "dependencies": {
             "boolbase": "~1.0.0",
             "css-what": "2.1",
    @@ -658,29 +522,24 @@
         },
         "node_modules/css-what": {
           "version": "2.1.3",
    -      "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
    -      "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==",
    +      "license": "BSD-2-Clause",
           "engines": {
             "node": "*"
           }
         },
    -    "node_modules/cssom": {
    -      "version": "0.3.8",
    -      "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
    -      "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="
    -    },
         "node_modules/cssstyle": {
    -      "version": "1.4.0",
    -      "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz",
    -      "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==",
    +      "version": "3.0.0",
    +      "license": "MIT",
           "dependencies": {
    -        "cssom": "0.3.x"
    +        "rrweb-cssom": "^0.6.0"
    +      },
    +      "engines": {
    +        "node": ">=14"
           }
         },
         "node_modules/dashdash": {
           "version": "1.14.1",
    -      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
    -      "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
    +      "license": "MIT",
           "dependencies": {
             "assert-plus": "^1.0.0"
           },
    @@ -689,50 +548,48 @@
           }
         },
         "node_modules/data-uri-to-buffer": {
    -      "version": "5.0.1",
    -      "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-5.0.1.tgz",
    -      "integrity": "sha512-a9l6T1qqDogvvnw0nKlfZzqsyikEBZBClF39V3TFoKhDtGBqHu2HkuomJc02j5zft8zrUaXEuoicLeW54RkzPg==",
    +      "version": "6.0.1",
    +      "license": "MIT",
           "engines": {
             "node": ">= 14"
           }
         },
         "node_modules/data-urls": {
    -      "version": "1.1.0",
    -      "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz",
    -      "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==",
    +      "version": "4.0.0",
    +      "license": "MIT",
           "dependencies": {
    -        "abab": "^2.0.0",
    -        "whatwg-mimetype": "^2.2.0",
    -        "whatwg-url": "^7.0.0"
    +        "abab": "^2.0.6",
    +        "whatwg-mimetype": "^3.0.0",
    +        "whatwg-url": "^12.0.0"
    +      },
    +      "engines": {
    +        "node": ">=14"
           }
         },
         "node_modules/data-urls/node_modules/tr46": {
    -      "version": "1.0.1",
    -      "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
    -      "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==",
    +      "version": "4.1.1",
    +      "license": "MIT",
           "dependencies": {
    -        "punycode": "^2.1.0"
    +        "punycode": "^2.3.0"
    +      },
    +      "engines": {
    +        "node": ">=14"
           }
         },
    -    "node_modules/data-urls/node_modules/webidl-conversions": {
    -      "version": "4.0.2",
    -      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
    -      "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="
    -    },
         "node_modules/data-urls/node_modules/whatwg-url": {
    -      "version": "7.1.0",
    -      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.1.0.tgz",
    -      "integrity": "sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==",
    +      "version": "12.0.1",
    +      "license": "MIT",
           "dependencies": {
    -        "lodash.sortby": "^4.7.0",
    -        "tr46": "^1.0.1",
    -        "webidl-conversions": "^4.0.2"
    +        "tr46": "^4.1.1",
    +        "webidl-conversions": "^7.0.0"
    +      },
    +      "engines": {
    +        "node": ">=14"
           }
         },
         "node_modules/debug": {
           "version": "4.3.4",
    -      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
    -      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
    +      "license": "MIT",
           "dependencies": {
             "ms": "2.1.2"
           },
    @@ -747,26 +604,18 @@
         },
         "node_modules/decamelize": {
           "version": "1.2.0",
    -      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
    -      "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
    +      "license": "MIT",
           "engines": {
             "node": ">=0.10.0"
           }
         },
         "node_modules/decimal.js": {
           "version": "10.4.3",
    -      "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
    -      "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA=="
    -    },
    -    "node_modules/deep-is": {
    -      "version": "0.1.4",
    -      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
    -      "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
    +      "license": "MIT"
         },
         "node_modules/degenerator": {
           "version": "5.0.1",
    -      "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",
    -      "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==",
    +      "license": "MIT",
           "dependencies": {
             "ast-types": "^0.13.4",
             "escodegen": "^2.1.0",
    @@ -776,10 +625,113 @@
             "node": ">= 14"
           }
         },
    -    "node_modules/degenerator/node_modules/escodegen": {
    +    "node_modules/delayed-stream": {
    +      "version": "1.0.0",
    +      "license": "MIT",
    +      "engines": {
    +        "node": ">=0.4.0"
    +      }
    +    },
    +    "node_modules/devtools-protocol": {
    +      "version": "0.0.1159816",
    +      "license": "BSD-3-Clause"
    +    },
    +    "node_modules/difflib": {
    +      "version": "0.2.6",
    +      "resolved": "git+ssh://git@github.com/postlight/difflib.js.git#32e8e38c7fcd935241b9baab71bb432fd9b166ed",
    +      "dependencies": {
    +        "heap": ">= 0.2.0"
    +      }
    +    },
    +    "node_modules/dom-serializer": {
    +      "version": "0.1.1",
    +      "license": "MIT",
    +      "dependencies": {
    +        "domelementtype": "^1.3.0",
    +        "entities": "^1.1.1"
    +      }
    +    },
    +    "node_modules/domelementtype": {
    +      "version": "1.3.1",
    +      "license": "BSD-2-Clause"
    +    },
    +    "node_modules/domexception": {
    +      "version": "4.0.0",
    +      "license": "MIT",
    +      "dependencies": {
    +        "webidl-conversions": "^7.0.0"
    +      },
    +      "engines": {
    +        "node": ">=12"
    +      }
    +    },
    +    "node_modules/domhandler": {
    +      "version": "2.4.2",
    +      "license": "BSD-2-Clause",
    +      "dependencies": {
    +        "domelementtype": "1"
    +      }
    +    },
    +    "node_modules/domino": {
    +      "version": "2.1.6",
    +      "license": "BSD-2-Clause"
    +    },
    +    "node_modules/dompurify": {
    +      "version": "3.0.6",
    +      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.6.tgz",
    +      "integrity": "sha512-ilkD8YEnnGh1zJ240uJsW7AzE+2qpbOUYjacomn3AvJ6J4JhKGSZ2nh4wUIXPZrEPppaCLx5jFe8T89Rk8tQ7w=="
    +    },
    +    "node_modules/domutils": {
    +      "version": "1.5.1",
    +      "dependencies": {
    +        "dom-serializer": "0",
    +        "domelementtype": "1"
    +      }
    +    },
    +    "node_modules/dotenv": {
    +      "version": "6.2.0",
    +      "license": "BSD-2-Clause",
    +      "engines": {
    +        "node": ">=6"
    +      }
    +    },
    +    "node_modules/ecc-jsbn": {
    +      "version": "0.1.2",
    +      "license": "MIT",
    +      "dependencies": {
    +        "jsbn": "~0.1.0",
    +        "safer-buffer": "^2.1.0"
    +      }
    +    },
    +    "node_modules/ellipsize": {
    +      "version": "0.1.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/emoji-regex": {
    +      "version": "8.0.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/end-of-stream": {
    +      "version": "1.4.4",
    +      "license": "MIT",
    +      "dependencies": {
    +        "once": "^1.4.0"
    +      }
    +    },
    +    "node_modules/entities": {
    +      "version": "1.1.2",
    +      "license": "BSD-2-Clause"
    +    },
    +    "node_modules/escalade": {
    +      "version": "3.1.1",
    +      "license": "MIT",
    +      "engines": {
    +        "node": ">=6"
    +      }
    +    },
    +    "node_modules/escodegen": {
           "version": "2.1.0",
    -      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
    -      "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
    +      "license": "BSD-2-Clause",
           "dependencies": {
             "esprima": "^4.0.1",
             "estraverse": "^5.2.0",
    @@ -796,158 +748,9 @@
             "source-map": "~0.6.1"
           }
         },
    -    "node_modules/degenerator/node_modules/estraverse": {
    -      "version": "5.3.0",
    -      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
    -      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
    -      "engines": {
    -        "node": ">=4.0"
    -      }
    -    },
    -    "node_modules/delayed-stream": {
    -      "version": "1.0.0",
    -      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
    -      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
    -      "engines": {
    -        "node": ">=0.4.0"
    -      }
    -    },
    -    "node_modules/devtools-protocol": {
    -      "version": "0.0.818844",
    -      "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.818844.tgz",
    -      "integrity": "sha512-AD1hi7iVJ8OD0aMLQU5VK0XH9LDlA1+BcPIgrAxPfaibx2DbWucuyOhc4oyQCbnvDDO68nN6/LcKfqTP343Jjg==",
    -      "peer": true
    -    },
    -    "node_modules/difflib": {
    -      "version": "0.2.6",
    -      "resolved": "git+ssh://git@github.com/postlight/difflib.js.git#32e8e38c7fcd935241b9baab71bb432fd9b166ed",
    -      "integrity": "sha512-uFNs7czGYLWdMP22WQhD/vlFen/CuKzC+KiajNCj+ik2Ah/I9i2AFyMWkBjFgbVFGhv95kBHOtx7tgF6IVngqA==",
    -      "dependencies": {
    -        "heap": ">= 0.2.0"
    -      }
    -    },
    -    "node_modules/dom-serializer": {
    -      "version": "0.1.1",
    -      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
    -      "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
    -      "dependencies": {
    -        "domelementtype": "^1.3.0",
    -        "entities": "^1.1.1"
    -      }
    -    },
    -    "node_modules/domelementtype": {
    -      "version": "1.3.1",
    -      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
    -      "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
    -    },
    -    "node_modules/domexception": {
    -      "version": "1.0.1",
    -      "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
    -      "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
    -      "dependencies": {
    -        "webidl-conversions": "^4.0.2"
    -      }
    -    },
    -    "node_modules/domexception/node_modules/webidl-conversions": {
    -      "version": "4.0.2",
    -      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
    -      "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="
    -    },
    -    "node_modules/domhandler": {
    -      "version": "2.4.2",
    -      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
    -      "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
    -      "dependencies": {
    -        "domelementtype": "1"
    -      }
    -    },
    -    "node_modules/dompurify": {
    -      "version": "2.4.7",
    -      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.7.tgz",
    -      "integrity": "sha512-kxxKlPEDa6Nc5WJi+qRgPbOAbgTpSULL+vI3NUXsZMlkJxTqYI9wg5ZTay2sFrdZRWHPWNi+EdAhcJf81WtoMQ=="
    -    },
    -    "node_modules/domutils": {
    -      "version": "1.5.1",
    -      "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
    -      "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==",
    -      "dependencies": {
    -        "dom-serializer": "0",
    -        "domelementtype": "1"
    -      }
    -    },
    -    "node_modules/dotenv": {
    -      "version": "6.2.0",
    -      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz",
    -      "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==",
    -      "engines": {
    -        "node": ">=6"
    -      }
    -    },
    -    "node_modules/ecc-jsbn": {
    -      "version": "0.1.2",
    -      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
    -      "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
    -      "dependencies": {
    -        "jsbn": "~0.1.0",
    -        "safer-buffer": "^2.1.0"
    -      }
    -    },
    -    "node_modules/ellipsize": {
    -      "version": "0.1.0",
    -      "resolved": "https://registry.npmjs.org/ellipsize/-/ellipsize-0.1.0.tgz",
    -      "integrity": "sha512-5gxbEjcb/Z2n6TTmXZx9wVi3N/DOzE7RXY3Xg9dakDuhX/izwumB9rGjeWUV6dTA0D0+juvo+JonZgNR9sgA5A=="
    -    },
    -    "node_modules/emoji-regex": {
    -      "version": "8.0.0",
    -      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
    -      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
    -    },
    -    "node_modules/end-of-stream": {
    -      "version": "1.4.4",
    -      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
    -      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
    -      "dependencies": {
    -        "once": "^1.4.0"
    -      }
    -    },
    -    "node_modules/entities": {
    -      "version": "1.1.2",
    -      "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
    -      "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
    -    },
    -    "node_modules/escalade": {
    -      "version": "3.1.1",
    -      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
    -      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
    -      "engines": {
    -        "node": ">=6"
    -      }
    -    },
    -    "node_modules/escodegen": {
    -      "version": "1.14.3",
    -      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz",
    -      "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==",
    -      "dependencies": {
    -        "esprima": "^4.0.1",
    -        "estraverse": "^4.2.0",
    -        "esutils": "^2.0.2",
    -        "optionator": "^0.8.1"
    -      },
    -      "bin": {
    -        "escodegen": "bin/escodegen.js",
    -        "esgenerate": "bin/esgenerate.js"
    -      },
    -      "engines": {
    -        "node": ">=4.0"
    -      },
    -      "optionalDependencies": {
    -        "source-map": "~0.6.1"
    -      }
    -    },
         "node_modules/esprima": {
           "version": "4.0.1",
    -      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
    -      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
    +      "license": "BSD-2-Clause",
           "bin": {
             "esparse": "bin/esparse.js",
             "esvalidate": "bin/esvalidate.js"
    @@ -957,30 +760,26 @@
           }
         },
         "node_modules/estraverse": {
    -      "version": "4.3.0",
    -      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
    -      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
    +      "version": "5.3.0",
    +      "license": "BSD-2-Clause",
           "engines": {
             "node": ">=4.0"
           }
         },
         "node_modules/esutils": {
           "version": "2.0.3",
    -      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
    -      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
    +      "license": "BSD-2-Clause",
           "engines": {
             "node": ">=0.10.0"
           }
         },
         "node_modules/extend": {
           "version": "3.0.2",
    -      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
    -      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
    +      "license": "MIT"
         },
         "node_modules/extract-zip": {
           "version": "2.0.1",
    -      "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
    -      "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
    +      "license": "BSD-2-Clause",
           "dependencies": {
             "debug": "^4.1.1",
             "get-stream": "^5.1.0",
    @@ -998,73 +797,59 @@
         },
         "node_modules/extsprintf": {
           "version": "1.3.0",
    -      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
    -      "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==",
           "engines": [
             "node >=0.6.0"
    -      ]
    +      ],
    +      "license": "MIT"
         },
         "node_modules/fast-deep-equal": {
           "version": "3.1.3",
    -      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
    -      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
    +      "license": "MIT"
         },
         "node_modules/fast-fifo": {
           "version": "1.3.2",
    -      "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
    -      "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="
    +      "license": "MIT"
         },
         "node_modules/fast-json-stable-stringify": {
           "version": "2.1.0",
    -      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
    -      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
    -    },
    -    "node_modules/fast-levenshtein": {
    -      "version": "2.0.6",
    -      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
    -      "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
    +      "license": "MIT"
         },
         "node_modules/fd-slicer": {
           "version": "1.1.0",
    -      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
    -      "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
    +      "license": "MIT",
           "dependencies": {
             "pend": "~1.2.0"
           }
         },
         "node_modules/file-url": {
           "version": "3.0.0",
    -      "resolved": "https://registry.npmjs.org/file-url/-/file-url-3.0.0.tgz",
    -      "integrity": "sha512-g872QGsHexznxkIAdK8UiZRe7SkE6kvylShU4Nsj8NvfvZag7S0QuQ4IgvPDkk75HxgjIVDwycFTDAgIiO4nDA==",
    +      "license": "MIT",
           "engines": {
             "node": ">=8"
           }
         },
         "node_modules/forever-agent": {
           "version": "0.6.1",
    -      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
    -      "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==",
    +      "license": "Apache-2.0",
           "engines": {
             "node": "*"
           }
         },
         "node_modules/form-data": {
    -      "version": "2.3.3",
    -      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
    -      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
    +      "version": "4.0.0",
    +      "license": "MIT",
           "dependencies": {
             "asynckit": "^0.4.0",
    -        "combined-stream": "^1.0.6",
    +        "combined-stream": "^1.0.8",
             "mime-types": "^2.1.12"
           },
           "engines": {
    -        "node": ">= 0.12"
    +        "node": ">= 6"
           }
         },
         "node_modules/fs-extra": {
           "version": "8.1.0",
    -      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
    -      "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
    +      "license": "MIT",
           "dependencies": {
             "graceful-fs": "^4.2.0",
             "jsonfile": "^4.0.0",
    @@ -1076,48 +861,25 @@
         },
         "node_modules/fs-extra/node_modules/universalify": {
           "version": "0.1.2",
    -      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
    -      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
    +      "license": "MIT",
           "engines": {
             "node": ">= 4.0.0"
           }
         },
         "node_modules/fs.realpath": {
           "version": "1.0.0",
    -      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
    -      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
    -    },
    -    "node_modules/function-bind": {
    -      "version": "1.1.1",
    -      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
    -      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
    +      "license": "ISC"
         },
         "node_modules/get-caller-file": {
           "version": "2.0.5",
    -      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
    -      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
    +      "license": "ISC",
           "engines": {
             "node": "6.* || 8.* || >= 10.*"
           }
         },
    -    "node_modules/get-intrinsic": {
    -      "version": "1.2.1",
    -      "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
    -      "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
    -      "dependencies": {
    -        "function-bind": "^1.1.1",
    -        "has": "^1.0.3",
    -        "has-proto": "^1.0.1",
    -        "has-symbols": "^1.0.3"
    -      },
    -      "funding": {
    -        "url": "https://github.com/sponsors/ljharb"
    -      }
    -    },
         "node_modules/get-stream": {
           "version": "5.2.0",
    -      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
    -      "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
    +      "license": "MIT",
           "dependencies": {
             "pump": "^3.0.0"
           },
    @@ -1129,12 +891,11 @@
           }
         },
         "node_modules/get-uri": {
    -      "version": "6.0.1",
    -      "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.1.tgz",
    -      "integrity": "sha512-7ZqONUVqaabogsYNWlYj0t3YZaL6dhuEueZXGF+/YVmf6dHmaFg8/6psJKqhx9QykIDKzpGcy2cn4oV4YC7V/Q==",
    +      "version": "6.0.2",
    +      "license": "MIT",
           "dependencies": {
             "basic-ftp": "^5.0.2",
    -        "data-uri-to-buffer": "^5.0.1",
    +        "data-uri-to-buffer": "^6.0.0",
             "debug": "^4.3.4",
             "fs-extra": "^8.1.0"
           },
    @@ -1144,16 +905,14 @@
         },
         "node_modules/getpass": {
           "version": "0.1.7",
    -      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
    -      "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
    +      "license": "MIT",
           "dependencies": {
             "assert-plus": "^1.0.0"
           }
         },
         "node_modules/glob": {
           "version": "7.2.3",
    -      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
    -      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
    +      "license": "ISC",
           "dependencies": {
             "fs.realpath": "^1.0.0",
             "inflight": "^1.0.4",
    @@ -1171,22 +930,18 @@
         },
         "node_modules/graceful-fs": {
           "version": "4.2.11",
    -      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
    -      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
    +      "license": "ISC"
         },
         "node_modules/har-schema": {
           "version": "2.0.0",
    -      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
    -      "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==",
    +      "license": "ISC",
           "engines": {
             "node": ">=4"
           }
         },
         "node_modules/har-validator": {
           "version": "5.1.5",
    -      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
    -      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
    -      "deprecated": "this library is no longer supported",
    +      "license": "MIT",
           "dependencies": {
             "ajv": "^6.12.3",
             "har-schema": "^2.0.0"
    @@ -1195,56 +950,23 @@
             "node": ">=6"
           }
         },
    -    "node_modules/has": {
    -      "version": "1.0.3",
    -      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
    -      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
    -      "dependencies": {
    -        "function-bind": "^1.1.1"
    -      },
    -      "engines": {
    -        "node": ">= 0.4.0"
    -      }
    -    },
    -    "node_modules/has-proto": {
    -      "version": "1.0.1",
    -      "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
    -      "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
    -      "engines": {
    -        "node": ">= 0.4"
    -      },
    -      "funding": {
    -        "url": "https://github.com/sponsors/ljharb"
    -      }
    -    },
    -    "node_modules/has-symbols": {
    -      "version": "1.0.3",
    -      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
    -      "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
    -      "engines": {
    -        "node": ">= 0.4"
    -      },
    -      "funding": {
    -        "url": "https://github.com/sponsors/ljharb"
    -      }
    -    },
         "node_modules/heap": {
           "version": "0.2.7",
    -      "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz",
    -      "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg=="
    +      "license": "MIT"
         },
         "node_modules/html-encoding-sniffer": {
    -      "version": "1.0.2",
    -      "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
    -      "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
    +      "version": "3.0.0",
    +      "license": "MIT",
           "dependencies": {
    -        "whatwg-encoding": "^1.0.1"
    +        "whatwg-encoding": "^2.0.0"
    +      },
    +      "engines": {
    +        "node": ">=12"
           }
         },
         "node_modules/htmlparser2": {
           "version": "3.10.1",
    -      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
    -      "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
    +      "license": "MIT",
           "dependencies": {
             "domelementtype": "^1.3.1",
             "domhandler": "^2.3.0",
    @@ -1255,11 +977,10 @@
           }
         },
         "node_modules/http-proxy-agent": {
    -      "version": "4.0.1",
    -      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
    -      "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
    +      "version": "5.0.0",
    +      "license": "MIT",
           "dependencies": {
    -        "@tootallnate/once": "1",
    +        "@tootallnate/once": "2",
             "agent-base": "6",
             "debug": "4"
           },
    @@ -1269,8 +990,7 @@
         },
         "node_modules/http-signature": {
           "version": "1.3.6",
    -      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz",
    -      "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==",
    +      "license": "MIT",
           "dependencies": {
             "assert-plus": "^1.0.0",
             "jsprim": "^2.0.2",
    @@ -1282,8 +1002,7 @@
         },
         "node_modules/https-proxy-agent": {
           "version": "5.0.1",
    -      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
    -      "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
    +      "license": "MIT",
           "dependencies": {
             "agent-base": "6",
             "debug": "4"
    @@ -1294,8 +1013,7 @@
         },
         "node_modules/iconv-lite": {
           "version": "0.5.0",
    -      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.0.tgz",
    -      "integrity": "sha512-NnEhI9hIEKHOzJ4f697DMz9IQEXr/MMJ5w64vN2/4Ai+wRnvV7SBrL0KLoRlwaKVghOc7LQ5YkPLuX146b6Ydw==",
    +      "license": "MIT",
           "dependencies": {
             "safer-buffer": ">= 2.1.2 < 3"
           },
    @@ -1305,8 +1023,6 @@
         },
         "node_modules/ieee754": {
           "version": "1.2.1",
    -      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
    -      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
           "funding": [
             {
               "type": "github",
    @@ -1320,17 +1036,16 @@
               "type": "consulting",
               "url": "https://feross.org/support"
             }
    -      ]
    +      ],
    +      "license": "BSD-3-Clause"
         },
         "node_modules/immediate": {
           "version": "3.0.6",
    -      "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
    -      "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
    +      "license": "MIT"
         },
         "node_modules/inflight": {
           "version": "1.0.6",
    -      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
    -      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
    +      "license": "ISC",
           "dependencies": {
             "once": "^1.3.0",
             "wrappy": "1"
    @@ -1338,1331 +1053,40 @@
         },
         "node_modules/inherits": {
           "version": "2.0.4",
    -      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
    -      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
    +      "license": "ISC"
         },
         "node_modules/ip": {
           "version": "1.1.8",
    -      "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
    -      "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg=="
    +      "license": "MIT"
         },
         "node_modules/is-fullwidth-code-point": {
           "version": "3.0.0",
    -      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
    -      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
    +      "license": "MIT",
           "engines": {
             "node": ">=8"
           }
         },
         "node_modules/is-potential-custom-element-name": {
           "version": "1.0.1",
    -      "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
    -      "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="
    +      "license": "MIT"
         },
         "node_modules/is-typedarray": {
           "version": "1.0.0",
    -      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
    -      "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
    +      "license": "MIT"
         },
         "node_modules/isarray": {
           "version": "1.0.0",
    -      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
    -      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
    +      "license": "MIT"
         },
         "node_modules/isstream": {
           "version": "0.1.2",
    -      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
    -      "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
    +      "license": "MIT"
         },
         "node_modules/jsbn": {
           "version": "0.1.1",
    -      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
    -      "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg=="
    +      "license": "MIT"
         },
         "node_modules/jsdom": {
    -      "version": "11.12.0",
    -      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz",
    -      "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==",
    -      "dependencies": {
    -        "abab": "^2.0.0",
    -        "acorn": "^5.5.3",
    -        "acorn-globals": "^4.1.0",
    -        "array-equal": "^1.0.0",
    -        "cssom": ">= 0.3.2 < 0.4.0",
    -        "cssstyle": "^1.0.0",
    -        "data-urls": "^1.0.0",
    -        "domexception": "^1.0.1",
    -        "escodegen": "^1.9.1",
    -        "html-encoding-sniffer": "^1.0.2",
    -        "left-pad": "^1.3.0",
    -        "nwsapi": "^2.0.7",
    -        "parse5": "4.0.0",
    -        "pn": "^1.1.0",
    -        "request": "^2.87.0",
    -        "request-promise-native": "^1.0.5",
    -        "sax": "^1.2.4",
    -        "symbol-tree": "^3.2.2",
    -        "tough-cookie": "^2.3.4",
    -        "w3c-hr-time": "^1.0.1",
    -        "webidl-conversions": "^4.0.2",
    -        "whatwg-encoding": "^1.0.3",
    -        "whatwg-mimetype": "^2.1.0",
    -        "whatwg-url": "^6.4.1",
    -        "ws": "^5.2.0",
    -        "xml-name-validator": "^3.0.0"
    -      }
    -    },
    -    "node_modules/jsdom/node_modules/tr46": {
    -      "version": "1.0.1",
    -      "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
    -      "integrity": "sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==",
    -      "dependencies": {
    -        "punycode": "^2.1.0"
    -      }
    -    },
    -    "node_modules/jsdom/node_modules/webidl-conversions": {
    -      "version": "4.0.2",
    -      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
    -      "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="
    -    },
    -    "node_modules/jsdom/node_modules/whatwg-url": {
    -      "version": "6.5.0",
    -      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz",
    -      "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==",
    -      "dependencies": {
    -        "lodash.sortby": "^4.7.0",
    -        "tr46": "^1.0.1",
    -        "webidl-conversions": "^4.0.2"
    -      }
    -    },
    -    "node_modules/json-schema": {
    -      "version": "0.4.0",
    -      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
    -      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
    -    },
    -    "node_modules/json-schema-traverse": {
    -      "version": "0.4.1",
    -      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
    -      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
    -    },
    -    "node_modules/json-stringify-safe": {
    -      "version": "5.0.1",
    -      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
    -      "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
    -    },
    -    "node_modules/jsonfile": {
    -      "version": "4.0.0",
    -      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
    -      "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
    -      "optionalDependencies": {
    -        "graceful-fs": "^4.1.6"
    -      }
    -    },
    -    "node_modules/jsprim": {
    -      "version": "2.0.2",
    -      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz",
    -      "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==",
    -      "engines": [
    -        "node >=0.6.0"
    -      ],
    -      "dependencies": {
    -        "assert-plus": "1.0.0",
    -        "extsprintf": "1.3.0",
    -        "json-schema": "0.4.0",
    -        "verror": "1.10.0"
    -      }
    -    },
    -    "node_modules/jszip": {
    -      "version": "3.10.1",
    -      "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
    -      "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
    -      "dependencies": {
    -        "lie": "~3.3.0",
    -        "pako": "~1.0.2",
    -        "readable-stream": "~2.3.6",
    -        "setimmediate": "^1.0.5"
    -      }
    -    },
    -    "node_modules/jszip/node_modules/readable-stream": {
    -      "version": "2.3.8",
    -      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
    -      "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
    -      "dependencies": {
    -        "core-util-is": "~1.0.0",
    -        "inherits": "~2.0.3",
    -        "isarray": "~1.0.0",
    -        "process-nextick-args": "~2.0.0",
    -        "safe-buffer": "~5.1.1",
    -        "string_decoder": "~1.1.1",
    -        "util-deprecate": "~1.0.1"
    -      }
    -    },
    -    "node_modules/jszip/node_modules/safe-buffer": {
    -      "version": "5.1.2",
    -      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
    -      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
    -    },
    -    "node_modules/jszip/node_modules/string_decoder": {
    -      "version": "1.1.1",
    -      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
    -      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
    -      "dependencies": {
    -        "safe-buffer": "~5.1.0"
    -      }
    -    },
    -    "node_modules/left-pad": {
    -      "version": "1.3.0",
    -      "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz",
    -      "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==",
    -      "deprecated": "use String.prototype.padStart()"
    -    },
    -    "node_modules/levn": {
    -      "version": "0.3.0",
    -      "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
    -      "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==",
    -      "dependencies": {
    -        "prelude-ls": "~1.1.2",
    -        "type-check": "~0.3.2"
    -      },
    -      "engines": {
    -        "node": ">= 0.8.0"
    -      }
    -    },
    -    "node_modules/lie": {
    -      "version": "3.3.0",
    -      "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
    -      "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
    -      "dependencies": {
    -        "immediate": "~3.0.5"
    -      }
    -    },
    -    "node_modules/lodash": {
    -      "version": "4.17.21",
    -      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
    -      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
    -    },
    -    "node_modules/lodash.assignin": {
    -      "version": "4.2.0",
    -      "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz",
    -      "integrity": "sha512-yX/rx6d/UTVh7sSVWVSIMjfnz95evAgDFdb1ZozC35I9mSFCkmzptOzevxjgbQUsc78NR44LVHWjsoMQXy9FDg=="
    -    },
    -    "node_modules/lodash.bind": {
    -      "version": "4.2.1",
    -      "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz",
    -      "integrity": "sha512-lxdsn7xxlCymgLYo1gGvVrfHmkjDiyqVv62FAeF2i5ta72BipE1SLxw8hPEPLhD4/247Ijw07UQH7Hq/chT5LA=="
    -    },
    -    "node_modules/lodash.defaults": {
    -      "version": "4.2.0",
    -      "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
    -      "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ=="
    -    },
    -    "node_modules/lodash.filter": {
    -      "version": "4.6.0",
    -      "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz",
    -      "integrity": "sha512-pXYUy7PR8BCLwX5mgJ/aNtyOvuJTdZAo9EQFUvMIYugqmJxnrYaANvTbgndOzHSCSR0wnlBBfRXJL5SbWxo3FQ=="
    -    },
    -    "node_modules/lodash.flatten": {
    -      "version": "4.4.0",
    -      "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
    -      "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g=="
    -    },
    -    "node_modules/lodash.foreach": {
    -      "version": "4.5.0",
    -      "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz",
    -      "integrity": "sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ=="
    -    },
    -    "node_modules/lodash.map": {
    -      "version": "4.6.0",
    -      "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz",
    -      "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q=="
    -    },
    -    "node_modules/lodash.merge": {
    -      "version": "4.6.2",
    -      "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
    -      "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
    -    },
    -    "node_modules/lodash.pick": {
    -      "version": "4.4.0",
    -      "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz",
    -      "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q=="
    -    },
    -    "node_modules/lodash.reduce": {
    -      "version": "4.6.0",
    -      "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz",
    -      "integrity": "sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw=="
    -    },
    -    "node_modules/lodash.reject": {
    -      "version": "4.6.0",
    -      "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz",
    -      "integrity": "sha512-qkTuvgEzYdyhiJBx42YPzPo71R1aEr0z79kAv7Ixg8wPFEjgRgJdUsGMG3Hf3OYSF/kHI79XhNlt+5Ar6OzwxQ=="
    -    },
    -    "node_modules/lodash.some": {
    -      "version": "4.6.0",
    -      "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz",
    -      "integrity": "sha512-j7MJE+TuT51q9ggt4fSgVqro163BEFjAt3u97IqU+JA2DkWl80nFTrowzLpZ/BnpN7rrl0JA/593NAdd8p/scQ=="
    -    },
    -    "node_modules/lodash.sortby": {
    -      "version": "4.7.0",
    -      "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
    -      "integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA=="
    -    },
    -    "node_modules/lru-cache": {
    -      "version": "7.18.3",
    -      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
    -      "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
    -      "engines": {
    -        "node": ">=12"
    -      }
    -    },
    -    "node_modules/mime-db": {
    -      "version": "1.52.0",
    -      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
    -      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
    -      "engines": {
    -        "node": ">= 0.6"
    -      }
    -    },
    -    "node_modules/mime-types": {
    -      "version": "2.1.35",
    -      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
    -      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
    -      "dependencies": {
    -        "mime-db": "1.52.0"
    -      },
    -      "engines": {
    -        "node": ">= 0.6"
    -      }
    -    },
    -    "node_modules/minimatch": {
    -      "version": "3.1.2",
    -      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
    -      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
    -      "dependencies": {
    -        "brace-expansion": "^1.1.7"
    -      },
    -      "engines": {
    -        "node": "*"
    -      }
    -    },
    -    "node_modules/mitt": {
    -      "version": "3.0.1",
    -      "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
    -      "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="
    -    },
    -    "node_modules/mkdirp-classic": {
    -      "version": "0.5.3",
    -      "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
    -      "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
    -    },
    -    "node_modules/moment-parseformat": {
    -      "version": "3.0.0",
    -      "resolved": "https://registry.npmjs.org/moment-parseformat/-/moment-parseformat-3.0.0.tgz",
    -      "integrity": "sha512-dVgXe6b6DLnv4CHG7a1zUe5mSXaIZ3c6lSHm/EKeVeQI2/4pwe0VRde8OyoCE1Ro2lKT5P6uT9JElF7KDLV+jw=="
    -    },
    -    "node_modules/ms": {
    -      "version": "2.1.2",
    -      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
    -      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
    -    },
    -    "node_modules/netmask": {
    -      "version": "2.0.2",
    -      "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz",
    -      "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==",
    -      "engines": {
    -        "node": ">= 0.4.0"
    -      }
    -    },
    -    "node_modules/node-fetch": {
    -      "version": "2.6.12",
    -      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz",
    -      "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==",
    -      "dependencies": {
    -        "whatwg-url": "^5.0.0"
    -      },
    -      "engines": {
    -        "node": "4.x || >=6.0.0"
    -      },
    -      "peerDependencies": {
    -        "encoding": "^0.1.0"
    -      },
    -      "peerDependenciesMeta": {
    -        "encoding": {
    -          "optional": true
    -        }
    -      }
    -    },
    -    "node_modules/nth-check": {
    -      "version": "1.0.2",
    -      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
    -      "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
    -      "dependencies": {
    -        "boolbase": "~1.0.0"
    -      }
    -    },
    -    "node_modules/nwsapi": {
    -      "version": "2.2.7",
    -      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz",
    -      "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ=="
    -    },
    -    "node_modules/oauth-sign": {
    -      "version": "0.9.0",
    -      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
    -      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
    -      "engines": {
    -        "node": "*"
    -      }
    -    },
    -    "node_modules/object-inspect": {
    -      "version": "1.12.3",
    -      "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
    -      "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
    -      "funding": {
    -        "url": "https://github.com/sponsors/ljharb"
    -      }
    -    },
    -    "node_modules/once": {
    -      "version": "1.4.0",
    -      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
    -      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
    -      "dependencies": {
    -        "wrappy": "1"
    -      }
    -    },
    -    "node_modules/optionator": {
    -      "version": "0.8.3",
    -      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
    -      "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
    -      "dependencies": {
    -        "deep-is": "~0.1.3",
    -        "fast-levenshtein": "~2.0.6",
    -        "levn": "~0.3.0",
    -        "prelude-ls": "~1.1.2",
    -        "type-check": "~0.3.2",
    -        "word-wrap": "~1.2.3"
    -      },
    -      "engines": {
    -        "node": ">= 0.8.0"
    -      }
    -    },
    -    "node_modules/pac-proxy-agent": {
    -      "version": "7.0.0",
    -      "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.0.tgz",
    -      "integrity": "sha512-t4tRAMx0uphnZrio0S0Jw9zg3oDbz1zVhQ/Vy18FjLfP1XOLNUEjaVxYCYRI6NS+BsMBXKIzV6cTLOkO9AtywA==",
    -      "dependencies": {
    -        "@tootallnate/quickjs-emscripten": "^0.23.0",
    -        "agent-base": "^7.0.2",
    -        "debug": "^4.3.4",
    -        "get-uri": "^6.0.1",
    -        "http-proxy-agent": "^7.0.0",
    -        "https-proxy-agent": "^7.0.0",
    -        "pac-resolver": "^7.0.0",
    -        "socks-proxy-agent": "^8.0.1"
    -      },
    -      "engines": {
    -        "node": ">= 14"
    -      }
    -    },
    -    "node_modules/pac-proxy-agent/node_modules/agent-base": {
    -      "version": "7.1.0",
    -      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz",
    -      "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==",
    -      "dependencies": {
    -        "debug": "^4.3.4"
    -      },
    -      "engines": {
    -        "node": ">= 14"
    -      }
    -    },
    -    "node_modules/pac-proxy-agent/node_modules/http-proxy-agent": {
    -      "version": "7.0.0",
    -      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz",
    -      "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==",
    -      "dependencies": {
    -        "agent-base": "^7.1.0",
    -        "debug": "^4.3.4"
    -      },
    -      "engines": {
    -        "node": ">= 14"
    -      }
    -    },
    -    "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": {
    -      "version": "7.0.1",
    -      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.1.tgz",
    -      "integrity": "sha512-Eun8zV0kcYS1g19r78osiQLEFIRspRUDd9tIfBCTBPBeMieF/EsJNL8VI3xOIdYRDEkjQnqOYPsZ2DsWsVsFwQ==",
    -      "dependencies": {
    -        "agent-base": "^7.0.2",
    -        "debug": "4"
    -      },
    -      "engines": {
    -        "node": ">= 14"
    -      }
    -    },
    -    "node_modules/pac-resolver": {
    -      "version": "7.0.0",
    -      "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz",
    -      "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==",
    -      "dependencies": {
    -        "degenerator": "^5.0.0",
    -        "ip": "^1.1.8",
    -        "netmask": "^2.0.2"
    -      },
    -      "engines": {
    -        "node": ">= 14"
    -      }
    -    },
    -    "node_modules/pako": {
    -      "version": "1.0.11",
    -      "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
    -      "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
    -    },
    -    "node_modules/parse5": {
    -      "version": "4.0.0",
    -      "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
    -      "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA=="
    -    },
    -    "node_modules/path-is-absolute": {
    -      "version": "1.0.1",
    -      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
    -      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
    -      "engines": {
    -        "node": ">=0.10.0"
    -      }
    -    },
    -    "node_modules/pend": {
    -      "version": "1.2.0",
    -      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
    -      "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="
    -    },
    -    "node_modules/performance-now": {
    -      "version": "2.1.0",
    -      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
    -      "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
    -    },
    -    "node_modules/playwright": {
    -      "version": "1.37.1",
    -      "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.37.1.tgz",
    -      "integrity": "sha512-bgUXRrQKhT48zHdxDYQTpf//0xDfDd5hLeEhjuSw8rXEGoT9YeElpfvs/izonTNY21IQZ7d3s22jLxYaAnubbQ==",
    -      "hasInstallScript": true,
    -      "dependencies": {
    -        "playwright-core": "1.37.1"
    -      },
    -      "bin": {
    -        "playwright": "cli.js"
    -      },
    -      "engines": {
    -        "node": ">=16"
    -      }
    -    },
    -    "node_modules/playwright-core": {
    -      "version": "1.37.1",
    -      "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.37.1.tgz",
    -      "integrity": "sha512-17EuQxlSIYCmEMwzMqusJ2ztDgJePjrbttaefgdsiqeLWidjYz9BxXaTaZWxH1J95SHGk6tjE+dwgWILJoUZfA==",
    -      "bin": {
    -        "playwright-core": "cli.js"
    -      },
    -      "engines": {
    -        "node": ">=16"
    -      }
    -    },
    -    "node_modules/pn": {
    -      "version": "1.1.0",
    -      "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
    -      "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA=="
    -    },
    -    "node_modules/postman-request": {
    -      "version": "2.88.1-postman.33",
    -      "resolved": "https://registry.npmjs.org/postman-request/-/postman-request-2.88.1-postman.33.tgz",
    -      "integrity": "sha512-uL9sCML4gPH6Z4hreDWbeinKU0p0Ke261nU7OvII95NU22HN6Dk7T/SaVPaj6T4TsQqGKIFw6/woLZnH7ugFNA==",
    -      "dependencies": {
    -        "@postman/form-data": "~3.1.1",
    -        "@postman/tough-cookie": "~4.1.3-postman.1",
    -        "@postman/tunnel-agent": "^0.6.3",
    -        "aws-sign2": "~0.7.0",
    -        "aws4": "^1.12.0",
    -        "brotli": "^1.3.3",
    -        "caseless": "~0.12.0",
    -        "combined-stream": "~1.0.6",
    -        "extend": "~3.0.2",
    -        "forever-agent": "~0.6.1",
    -        "har-validator": "~5.1.3",
    -        "http-signature": "~1.3.1",
    -        "is-typedarray": "~1.0.0",
    -        "isstream": "~0.1.2",
    -        "json-stringify-safe": "~5.0.1",
    -        "mime-types": "^2.1.35",
    -        "oauth-sign": "~0.9.0",
    -        "performance-now": "^2.1.0",
    -        "qs": "~6.5.3",
    -        "safe-buffer": "^5.1.2",
    -        "stream-length": "^1.0.2",
    -        "uuid": "^8.3.2"
    -      },
    -      "engines": {
    -        "node": ">= 6"
    -      }
    -    },
    -    "node_modules/prelude-ls": {
    -      "version": "1.1.2",
    -      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
    -      "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==",
    -      "engines": {
    -        "node": ">= 0.8.0"
    -      }
    -    },
    -    "node_modules/process-nextick-args": {
    -      "version": "2.0.1",
    -      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
    -      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
    -    },
    -    "node_modules/progress": {
    -      "version": "2.0.3",
    -      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
    -      "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
    -      "engines": {
    -        "node": ">=0.4.0"
    -      }
    -    },
    -    "node_modules/proxy-agent": {
    -      "version": "6.3.0",
    -      "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.0.tgz",
    -      "integrity": "sha512-0LdR757eTj/JfuU7TL2YCuAZnxWXu3tkJbg4Oq3geW/qFNT/32T0sp2HnZ9O0lMR4q3vwAt0+xCA8SR0WAD0og==",
    -      "dependencies": {
    -        "agent-base": "^7.0.2",
    -        "debug": "^4.3.4",
    -        "http-proxy-agent": "^7.0.0",
    -        "https-proxy-agent": "^7.0.0",
    -        "lru-cache": "^7.14.1",
    -        "pac-proxy-agent": "^7.0.0",
    -        "proxy-from-env": "^1.1.0",
    -        "socks-proxy-agent": "^8.0.1"
    -      },
    -      "engines": {
    -        "node": ">= 14"
    -      }
    -    },
    -    "node_modules/proxy-agent/node_modules/agent-base": {
    -      "version": "7.1.0",
    -      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz",
    -      "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==",
    -      "dependencies": {
    -        "debug": "^4.3.4"
    -      },
    -      "engines": {
    -        "node": ">= 14"
    -      }
    -    },
    -    "node_modules/proxy-agent/node_modules/http-proxy-agent": {
    -      "version": "7.0.0",
    -      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz",
    -      "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==",
    -      "dependencies": {
    -        "agent-base": "^7.1.0",
    -        "debug": "^4.3.4"
    -      },
    -      "engines": {
    -        "node": ">= 14"
    -      }
    -    },
    -    "node_modules/proxy-agent/node_modules/https-proxy-agent": {
    -      "version": "7.0.1",
    -      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.1.tgz",
    -      "integrity": "sha512-Eun8zV0kcYS1g19r78osiQLEFIRspRUDd9tIfBCTBPBeMieF/EsJNL8VI3xOIdYRDEkjQnqOYPsZ2DsWsVsFwQ==",
    -      "dependencies": {
    -        "agent-base": "^7.0.2",
    -        "debug": "4"
    -      },
    -      "engines": {
    -        "node": ">= 14"
    -      }
    -    },
    -    "node_modules/proxy-from-env": {
    -      "version": "1.1.0",
    -      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
    -      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
    -    },
    -    "node_modules/psl": {
    -      "version": "1.9.0",
    -      "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
    -      "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag=="
    -    },
    -    "node_modules/pump": {
    -      "version": "3.0.0",
    -      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
    -      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
    -      "dependencies": {
    -        "end-of-stream": "^1.1.0",
    -        "once": "^1.3.1"
    -      }
    -    },
    -    "node_modules/punycode": {
    -      "version": "2.3.0",
    -      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
    -      "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
    -      "engines": {
    -        "node": ">=6"
    -      }
    -    },
    -    "node_modules/qs": {
    -      "version": "6.5.3",
    -      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
    -      "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
    -      "engines": {
    -        "node": ">=0.6"
    -      }
    -    },
    -    "node_modules/querystringify": {
    -      "version": "2.2.0",
    -      "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
    -      "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
    -    },
    -    "node_modules/queue-tick": {
    -      "version": "1.0.1",
    -      "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
    -      "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag=="
    -    },
    -    "node_modules/readability-extractor": {
    -      "version": "0.0.2",
    -      "resolved": "git+ssh://git@github.com/ArchiveBox/readability-extractor.git#42b243843c724a5d7a6b364d23985ff6acaeb55a",
    -      "integrity": "sha512-B+oZuG4FwPYg5hxEafuhrwNOS8uiv/gYKlLKbIaeXXHlyznARYOqHpkHumiLMU6vkbZ3VAC7WucnWwh5jVOaBQ==",
    -      "license": "MIT",
    -      "dependencies": {
    -        "@mozilla/readability": "^0.4.1",
    -        "dompurify": "^2.2.7",
    -        "jsdom": "^16.5.2"
    -      },
    -      "bin": {
    -        "readability-extractor": "readability-extractor"
    -      }
    -    },
    -    "node_modules/readability-extractor/node_modules/acorn": {
    -      "version": "8.10.0",
    -      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
    -      "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
    -      "bin": {
    -        "acorn": "bin/acorn"
    -      },
    -      "engines": {
    -        "node": ">=0.4.0"
    -      }
    -    },
    -    "node_modules/readability-extractor/node_modules/acorn-globals": {
    -      "version": "6.0.0",
    -      "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz",
    -      "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==",
    -      "dependencies": {
    -        "acorn": "^7.1.1",
    -        "acorn-walk": "^7.1.1"
    -      }
    -    },
    -    "node_modules/readability-extractor/node_modules/acorn-globals/node_modules/acorn": {
    -      "version": "7.4.1",
    -      "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
    -      "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
    -      "bin": {
    -        "acorn": "bin/acorn"
    -      },
    -      "engines": {
    -        "node": ">=0.4.0"
    -      }
    -    },
    -    "node_modules/readability-extractor/node_modules/acorn-walk": {
    -      "version": "7.2.0",
    -      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
    -      "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==",
    -      "engines": {
    -        "node": ">=0.4.0"
    -      }
    -    },
    -    "node_modules/readability-extractor/node_modules/cssom": {
    -      "version": "0.4.4",
    -      "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
    -      "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw=="
    -    },
    -    "node_modules/readability-extractor/node_modules/cssstyle": {
    -      "version": "2.3.0",
    -      "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
    -      "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
    -      "dependencies": {
    -        "cssom": "~0.3.6"
    -      },
    -      "engines": {
    -        "node": ">=8"
    -      }
    -    },
    -    "node_modules/readability-extractor/node_modules/cssstyle/node_modules/cssom": {
    -      "version": "0.3.8",
    -      "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
    -      "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="
    -    },
    -    "node_modules/readability-extractor/node_modules/data-urls": {
    -      "version": "2.0.0",
    -      "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz",
    -      "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==",
    -      "dependencies": {
    -        "abab": "^2.0.3",
    -        "whatwg-mimetype": "^2.3.0",
    -        "whatwg-url": "^8.0.0"
    -      },
    -      "engines": {
    -        "node": ">=10"
    -      }
    -    },
    -    "node_modules/readability-extractor/node_modules/domexception": {
    -      "version": "2.0.1",
    -      "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz",
    -      "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==",
    -      "dependencies": {
    -        "webidl-conversions": "^5.0.0"
    -      },
    -      "engines": {
    -        "node": ">=8"
    -      }
    -    },
    -    "node_modules/readability-extractor/node_modules/domexception/node_modules/webidl-conversions": {
    -      "version": "5.0.0",
    -      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz",
    -      "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==",
    -      "engines": {
    -        "node": ">=8"
    -      }
    -    },
    -    "node_modules/readability-extractor/node_modules/escodegen": {
    -      "version": "2.1.0",
    -      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
    -      "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
    -      "dependencies": {
    -        "esprima": "^4.0.1",
    -        "estraverse": "^5.2.0",
    -        "esutils": "^2.0.2"
    -      },
    -      "bin": {
    -        "escodegen": "bin/escodegen.js",
    -        "esgenerate": "bin/esgenerate.js"
    -      },
    -      "engines": {
    -        "node": ">=6.0"
    -      },
    -      "optionalDependencies": {
    -        "source-map": "~0.6.1"
    -      }
    -    },
    -    "node_modules/readability-extractor/node_modules/estraverse": {
    -      "version": "5.3.0",
    -      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
    -      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
    -      "engines": {
    -        "node": ">=4.0"
    -      }
    -    },
    -    "node_modules/readability-extractor/node_modules/form-data": {
    -      "version": "3.0.1",
    -      "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz",
    -      "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==",
    -      "dependencies": {
    -        "asynckit": "^0.4.0",
    -        "combined-stream": "^1.0.8",
    -        "mime-types": "^2.1.12"
    -      },
    -      "engines": {
    -        "node": ">= 6"
    -      }
    -    },
    -    "node_modules/readability-extractor/node_modules/html-encoding-sniffer": {
    -      "version": "2.0.1",
    -      "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz",
    -      "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==",
    -      "dependencies": {
    -        "whatwg-encoding": "^1.0.5"
    -      },
    -      "engines": {
    -        "node": ">=10"
    -      }
    -    },
    -    "node_modules/readability-extractor/node_modules/jsdom": {
    -      "version": "16.7.0",
    -      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz",
    -      "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==",
    -      "dependencies": {
    -        "abab": "^2.0.5",
    -        "acorn": "^8.2.4",
    -        "acorn-globals": "^6.0.0",
    -        "cssom": "^0.4.4",
    -        "cssstyle": "^2.3.0",
    -        "data-urls": "^2.0.0",
    -        "decimal.js": "^10.2.1",
    -        "domexception": "^2.0.1",
    -        "escodegen": "^2.0.0",
    -        "form-data": "^3.0.0",
    -        "html-encoding-sniffer": "^2.0.1",
    -        "http-proxy-agent": "^4.0.1",
    -        "https-proxy-agent": "^5.0.0",
    -        "is-potential-custom-element-name": "^1.0.1",
    -        "nwsapi": "^2.2.0",
    -        "parse5": "6.0.1",
    -        "saxes": "^5.0.1",
    -        "symbol-tree": "^3.2.4",
    -        "tough-cookie": "^4.0.0",
    -        "w3c-hr-time": "^1.0.2",
    -        "w3c-xmlserializer": "^2.0.0",
    -        "webidl-conversions": "^6.1.0",
    -        "whatwg-encoding": "^1.0.5",
    -        "whatwg-mimetype": "^2.3.0",
    -        "whatwg-url": "^8.5.0",
    -        "ws": "^7.4.6",
    -        "xml-name-validator": "^3.0.0"
    -      },
    -      "engines": {
    -        "node": ">=10"
    -      },
    -      "peerDependencies": {
    -        "canvas": "^2.5.0"
    -      },
    -      "peerDependenciesMeta": {
    -        "canvas": {
    -          "optional": true
    -        }
    -      }
    -    },
    -    "node_modules/readability-extractor/node_modules/parse5": {
    -      "version": "6.0.1",
    -      "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
    -      "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
    -    },
    -    "node_modules/readability-extractor/node_modules/tough-cookie": {
    -      "version": "4.1.3",
    -      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
    -      "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
    -      "dependencies": {
    -        "psl": "^1.1.33",
    -        "punycode": "^2.1.1",
    -        "universalify": "^0.2.0",
    -        "url-parse": "^1.5.3"
    -      },
    -      "engines": {
    -        "node": ">=6"
    -      }
    -    },
    -    "node_modules/readability-extractor/node_modules/tr46": {
    -      "version": "2.1.0",
    -      "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz",
    -      "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==",
    -      "dependencies": {
    -        "punycode": "^2.1.1"
    -      },
    -      "engines": {
    -        "node": ">=8"
    -      }
    -    },
    -    "node_modules/readability-extractor/node_modules/webidl-conversions": {
    -      "version": "6.1.0",
    -      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",
    -      "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==",
    -      "engines": {
    -        "node": ">=10.4"
    -      }
    -    },
    -    "node_modules/readability-extractor/node_modules/whatwg-url": {
    -      "version": "8.7.0",
    -      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz",
    -      "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==",
    -      "dependencies": {
    -        "lodash": "^4.7.0",
    -        "tr46": "^2.1.0",
    -        "webidl-conversions": "^6.1.0"
    -      },
    -      "engines": {
    -        "node": ">=10"
    -      }
    -    },
    -    "node_modules/readability-extractor/node_modules/ws": {
    -      "version": "7.5.9",
    -      "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
    -      "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
    -      "engines": {
    -        "node": ">=8.3.0"
    -      },
    -      "peerDependencies": {
    -        "bufferutil": "^4.0.1",
    -        "utf-8-validate": "^5.0.2"
    -      },
    -      "peerDependenciesMeta": {
    -        "bufferutil": {
    -          "optional": true
    -        },
    -        "utf-8-validate": {
    -          "optional": true
    -        }
    -      }
    -    },
    -    "node_modules/readable-stream": {
    -      "version": "3.6.2",
    -      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
    -      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
    -      "dependencies": {
    -        "inherits": "^2.0.3",
    -        "string_decoder": "^1.1.1",
    -        "util-deprecate": "^1.0.1"
    -      },
    -      "engines": {
    -        "node": ">= 6"
    -      }
    -    },
    -    "node_modules/regenerator-runtime": {
    -      "version": "0.13.11",
    -      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
    -      "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
    -    },
    -    "node_modules/request": {
    -      "version": "2.88.2",
    -      "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
    -      "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
    -      "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
    -      "dependencies": {
    -        "aws-sign2": "~0.7.0",
    -        "aws4": "^1.8.0",
    -        "caseless": "~0.12.0",
    -        "combined-stream": "~1.0.6",
    -        "extend": "~3.0.2",
    -        "forever-agent": "~0.6.1",
    -        "form-data": "~2.3.2",
    -        "har-validator": "~5.1.3",
    -        "http-signature": "~1.2.0",
    -        "is-typedarray": "~1.0.0",
    -        "isstream": "~0.1.2",
    -        "json-stringify-safe": "~5.0.1",
    -        "mime-types": "~2.1.19",
    -        "oauth-sign": "~0.9.0",
    -        "performance-now": "^2.1.0",
    -        "qs": "~6.5.2",
    -        "safe-buffer": "^5.1.2",
    -        "tough-cookie": "~2.5.0",
    -        "tunnel-agent": "^0.6.0",
    -        "uuid": "^3.3.2"
    -      },
    -      "engines": {
    -        "node": ">= 6"
    -      }
    -    },
    -    "node_modules/request-promise": {
    -      "version": "4.2.6",
    -      "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.6.tgz",
    -      "integrity": "sha512-HCHI3DJJUakkOr8fNoCc73E5nU5bqITjOYFMDrKHYOXWXrgD/SBaC7LjwuPymUprRyuF06UK7hd/lMHkmUXglQ==",
    -      "deprecated": "request-promise has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142",
    -      "dependencies": {
    -        "bluebird": "^3.5.0",
    -        "request-promise-core": "1.1.4",
    -        "stealthy-require": "^1.1.1",
    -        "tough-cookie": "^2.3.3"
    -      },
    -      "engines": {
    -        "node": ">=0.10.0"
    -      },
    -      "peerDependencies": {
    -        "request": "^2.34"
    -      }
    -    },
    -    "node_modules/request-promise-core": {
    -      "version": "1.1.4",
    -      "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.4.tgz",
    -      "integrity": "sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw==",
    -      "dependencies": {
    -        "lodash": "^4.17.19"
    -      },
    -      "engines": {
    -        "node": ">=0.10.0"
    -      },
    -      "peerDependencies": {
    -        "request": "^2.34"
    -      }
    -    },
    -    "node_modules/request-promise-native": {
    -      "version": "1.0.9",
    -      "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.9.tgz",
    -      "integrity": "sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g==",
    -      "deprecated": "request-promise-native has been deprecated because it extends the now deprecated request package, see https://github.com/request/request/issues/3142",
    -      "dependencies": {
    -        "request-promise-core": "1.1.4",
    -        "stealthy-require": "^1.1.1",
    -        "tough-cookie": "^2.3.3"
    -      },
    -      "engines": {
    -        "node": ">=0.12.0"
    -      },
    -      "peerDependencies": {
    -        "request": "^2.34"
    -      }
    -    },
    -    "node_modules/request-promise/node_modules/bluebird": {
    -      "version": "3.7.2",
    -      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
    -      "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
    -    },
    -    "node_modules/request/node_modules/http-signature": {
    -      "version": "1.2.0",
    -      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
    -      "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==",
    -      "dependencies": {
    -        "assert-plus": "^1.0.0",
    -        "jsprim": "^1.2.2",
    -        "sshpk": "^1.7.0"
    -      },
    -      "engines": {
    -        "node": ">=0.8",
    -        "npm": ">=1.3.7"
    -      }
    -    },
    -    "node_modules/request/node_modules/jsprim": {
    -      "version": "1.4.2",
    -      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
    -      "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
    -      "dependencies": {
    -        "assert-plus": "1.0.0",
    -        "extsprintf": "1.3.0",
    -        "json-schema": "0.4.0",
    -        "verror": "1.10.0"
    -      },
    -      "engines": {
    -        "node": ">=0.6.0"
    -      }
    -    },
    -    "node_modules/request/node_modules/uuid": {
    -      "version": "3.4.0",
    -      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
    -      "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
    -      "deprecated": "Please upgrade  to version 7 or higher.  Older versions may use Math.random() in certain circumstances, which is known to be problematic.  See https://v8.dev/blog/math-random for details.",
    -      "bin": {
    -        "uuid": "bin/uuid"
    -      }
    -    },
    -    "node_modules/require-directory": {
    -      "version": "2.1.1",
    -      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
    -      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
    -      "engines": {
    -        "node": ">=0.10.0"
    -      }
    -    },
    -    "node_modules/requires-port": {
    -      "version": "1.0.0",
    -      "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
    -      "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
    -    },
    -    "node_modules/rimraf": {
    -      "version": "3.0.2",
    -      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
    -      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
    -      "dependencies": {
    -        "glob": "^7.1.3"
    -      },
    -      "bin": {
    -        "rimraf": "bin.js"
    -      },
    -      "funding": {
    -        "url": "https://github.com/sponsors/isaacs"
    -      }
    -    },
    -    "node_modules/rrweb-cssom": {
    -      "version": "0.6.0",
    -      "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz",
    -      "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw=="
    -    },
    -    "node_modules/safe-buffer": {
    -      "version": "5.2.1",
    -      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
    -      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
    -      "funding": [
    -        {
    -          "type": "github",
    -          "url": "https://github.com/sponsors/feross"
    -        },
    -        {
    -          "type": "patreon",
    -          "url": "https://www.patreon.com/feross"
    -        },
    -        {
    -          "type": "consulting",
    -          "url": "https://feross.org/support"
    -        }
    -      ]
    -    },
    -    "node_modules/safer-buffer": {
    -      "version": "2.1.2",
    -      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
    -      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
    -    },
    -    "node_modules/sax": {
    -      "version": "1.2.4",
    -      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
    -      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
    -    },
    -    "node_modules/saxes": {
    -      "version": "5.0.1",
    -      "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
    -      "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==",
    -      "dependencies": {
    -        "xmlchars": "^2.2.0"
    -      },
    -      "engines": {
    -        "node": ">=10"
    -      }
    -    },
    -    "node_modules/setimmediate": {
    -      "version": "1.0.5",
    -      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
    -      "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
    -    },
    -    "node_modules/side-channel": {
    -      "version": "1.0.4",
    -      "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz",
    -      "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==",
    -      "dependencies": {
    -        "call-bind": "^1.0.0",
    -        "get-intrinsic": "^1.0.2",
    -        "object-inspect": "^1.9.0"
    -      },
    -      "funding": {
    -        "url": "https://github.com/sponsors/ljharb"
    -      }
    -    },
    -    "node_modules/single-file-cli": {
    -      "version": "1.0.63",
    -      "resolved": "https://registry.npmjs.org/single-file-cli/-/single-file-cli-1.0.63.tgz",
    -      "integrity": "sha512-lxfYl/H+zHJoidTk4MtGz+uFy6xsiprRLpZEqFppJwBr/iz0QNMYt+eJnlVF5q0xnyXVyLqU1EznfX528Z0WRg==",
    -      "dependencies": {
    -        "file-url": "3.0.0",
    -        "iconv-lite": "0.6.3",
    -        "jsdom": "22.1.0",
    -        "puppeteer-core": "21.1.0",
    -        "selenium-webdriver": "4.11.1",
    -        "single-file-core": "1.0.72",
    -        "strong-data-uri": "1.0.6",
    -        "yargs": "17.7.2"
    -      },
    -      "bin": {
    -        "single-file": "single-file"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/@tootallnate/once": {
    -      "version": "2.0.0",
    -      "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
    -      "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
    -      "engines": {
    -        "node": ">= 10"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/cliui": {
    -      "version": "8.0.1",
    -      "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
    -      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
    -      "dependencies": {
    -        "string-width": "^4.2.0",
    -        "strip-ansi": "^6.0.1",
    -        "wrap-ansi": "^7.0.0"
    -      },
    -      "engines": {
    -        "node": ">=12"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/cssstyle": {
    -      "version": "3.0.0",
    -      "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz",
    -      "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==",
    -      "dependencies": {
    -        "rrweb-cssom": "^0.6.0"
    -      },
    -      "engines": {
    -        "node": ">=14"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/data-urls": {
    -      "version": "4.0.0",
    -      "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz",
    -      "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==",
    -      "dependencies": {
    -        "abab": "^2.0.6",
    -        "whatwg-mimetype": "^3.0.0",
    -        "whatwg-url": "^12.0.0"
    -      },
    -      "engines": {
    -        "node": ">=14"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/devtools-protocol": {
    -      "version": "0.0.1159816",
    -      "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1159816.tgz",
    -      "integrity": "sha512-2cZlHxC5IlgkIWe2pSDmCrDiTzbSJWywjbDDnupOImEBcG31CQgBLV8wWE+5t+C4rimcjHsbzy7CBzf9oFjboA=="
    -    },
    -    "node_modules/single-file-cli/node_modules/domexception": {
    -      "version": "4.0.0",
    -      "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz",
    -      "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==",
    -      "dependencies": {
    -        "webidl-conversions": "^7.0.0"
    -      },
    -      "engines": {
    -        "node": ">=12"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/entities": {
    -      "version": "4.5.0",
    -      "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
    -      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
    -      "engines": {
    -        "node": ">=0.12"
    -      },
    -      "funding": {
    -        "url": "https://github.com/fb55/entities?sponsor=1"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/form-data": {
    -      "version": "4.0.0",
    -      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
    -      "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
    -      "dependencies": {
    -        "asynckit": "^0.4.0",
    -        "combined-stream": "^1.0.8",
    -        "mime-types": "^2.1.12"
    -      },
    -      "engines": {
    -        "node": ">= 6"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/html-encoding-sniffer": {
    -      "version": "3.0.0",
    -      "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
    -      "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
    -      "dependencies": {
    -        "whatwg-encoding": "^2.0.0"
    -      },
    -      "engines": {
    -        "node": ">=12"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/http-proxy-agent": {
    -      "version": "5.0.0",
    -      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
    -      "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
    -      "dependencies": {
    -        "@tootallnate/once": "2",
    -        "agent-base": "6",
    -        "debug": "4"
    -      },
    -      "engines": {
    -        "node": ">= 6"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/iconv-lite": {
    -      "version": "0.6.3",
    -      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
    -      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
    -      "dependencies": {
    -        "safer-buffer": ">= 2.1.2 < 3.0.0"
    -      },
    -      "engines": {
    -        "node": ">=0.10.0"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/jsdom": {
           "version": "22.1.0",
           "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz",
           "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==",
    @@ -2703,83 +1127,7 @@
             }
           }
         },
    -    "node_modules/single-file-cli/node_modules/parse5": {
    -      "version": "7.1.2",
    -      "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
    -      "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
    -      "dependencies": {
    -        "entities": "^4.4.0"
    -      },
    -      "funding": {
    -        "url": "https://github.com/inikulin/parse5?sponsor=1"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/puppeteer-core": {
    -      "version": "21.1.0",
    -      "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-21.1.0.tgz",
    -      "integrity": "sha512-ggfTj09jo81Y6M4DyNj80GrY6Pip+AtDUgGljqoSzP6FG5nz5Aju6Cs/X147fLgkJ4UKTb736U6cDp0ssLzN5Q==",
    -      "dependencies": {
    -        "@puppeteer/browsers": "1.7.0",
    -        "chromium-bidi": "0.4.20",
    -        "cross-fetch": "4.0.0",
    -        "debug": "4.3.4",
    -        "devtools-protocol": "0.0.1159816",
    -        "ws": "8.13.0"
    -      },
    -      "engines": {
    -        "node": ">=16.3.0"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/saxes": {
    -      "version": "6.0.0",
    -      "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
    -      "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
    -      "dependencies": {
    -        "xmlchars": "^2.2.0"
    -      },
    -      "engines": {
    -        "node": ">=v12.22.7"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/selenium-webdriver": {
    -      "version": "4.11.1",
    -      "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.11.1.tgz",
    -      "integrity": "sha512-bvrnr3UZlLScErOmn8gV6cqc+1PYDHn0575CxUR2U14fMWt7OKxSy0lAThhZq4sq4d1HqP8ebz11oiHSlAQ2WA==",
    -      "dependencies": {
    -        "jszip": "^3.10.1",
    -        "tmp": "^0.2.1",
    -        "ws": ">=8.13.0"
    -      },
    -      "engines": {
    -        "node": ">= 14.20.0"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/tmp": {
    -      "version": "0.2.1",
    -      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
    -      "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
    -      "dependencies": {
    -        "rimraf": "^3.0.0"
    -      },
    -      "engines": {
    -        "node": ">=8.17.0"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/tough-cookie": {
    -      "version": "4.1.3",
    -      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
    -      "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
    -      "dependencies": {
    -        "psl": "^1.1.33",
    -        "punycode": "^2.1.1",
    -        "universalify": "^0.2.0",
    -        "url-parse": "^1.5.3"
    -      },
    -      "engines": {
    -        "node": ">=6"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/tr46": {
    +    "node_modules/jsdom/node_modules/tr46": {
           "version": "4.1.1",
           "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz",
           "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==",
    @@ -2790,45 +1138,7 @@
             "node": ">=14"
           }
         },
    -    "node_modules/single-file-cli/node_modules/w3c-xmlserializer": {
    -      "version": "4.0.0",
    -      "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
    -      "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==",
    -      "dependencies": {
    -        "xml-name-validator": "^4.0.0"
    -      },
    -      "engines": {
    -        "node": ">=14"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/webidl-conversions": {
    -      "version": "7.0.0",
    -      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
    -      "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
    -      "engines": {
    -        "node": ">=12"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/whatwg-encoding": {
    -      "version": "2.0.0",
    -      "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
    -      "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
    -      "dependencies": {
    -        "iconv-lite": "0.6.3"
    -      },
    -      "engines": {
    -        "node": ">=12"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/whatwg-mimetype": {
    -      "version": "3.0.0",
    -      "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz",
    -      "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==",
    -      "engines": {
    -        "node": ">=12"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/whatwg-url": {
    +    "node_modules/jsdom/node_modules/whatwg-url": {
           "version": "12.0.1",
           "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz",
           "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==",
    @@ -2840,10 +1150,463 @@
             "node": ">=14"
           }
         },
    -    "node_modules/single-file-cli/node_modules/ws": {
    -      "version": "8.13.0",
    -      "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz",
    -      "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==",
    +    "node_modules/json-schema": {
    +      "version": "0.4.0",
    +      "license": "(AFL-2.1 OR BSD-3-Clause)"
    +    },
    +    "node_modules/json-schema-traverse": {
    +      "version": "0.4.1",
    +      "license": "MIT"
    +    },
    +    "node_modules/json-stringify-safe": {
    +      "version": "5.0.1",
    +      "license": "ISC"
    +    },
    +    "node_modules/jsonfile": {
    +      "version": "4.0.0",
    +      "license": "MIT",
    +      "optionalDependencies": {
    +        "graceful-fs": "^4.1.6"
    +      }
    +    },
    +    "node_modules/jsprim": {
    +      "version": "2.0.2",
    +      "engines": [
    +        "node >=0.6.0"
    +      ],
    +      "license": "MIT",
    +      "dependencies": {
    +        "assert-plus": "1.0.0",
    +        "extsprintf": "1.3.0",
    +        "json-schema": "0.4.0",
    +        "verror": "1.10.0"
    +      }
    +    },
    +    "node_modules/jszip": {
    +      "version": "3.10.1",
    +      "license": "(MIT OR GPL-3.0-or-later)",
    +      "dependencies": {
    +        "lie": "~3.3.0",
    +        "pako": "~1.0.2",
    +        "readable-stream": "~2.3.6",
    +        "setimmediate": "^1.0.5"
    +      }
    +    },
    +    "node_modules/jszip/node_modules/readable-stream": {
    +      "version": "2.3.8",
    +      "license": "MIT",
    +      "dependencies": {
    +        "core-util-is": "~1.0.0",
    +        "inherits": "~2.0.3",
    +        "isarray": "~1.0.0",
    +        "process-nextick-args": "~2.0.0",
    +        "safe-buffer": "~5.1.1",
    +        "string_decoder": "~1.1.1",
    +        "util-deprecate": "~1.0.1"
    +      }
    +    },
    +    "node_modules/jszip/node_modules/safe-buffer": {
    +      "version": "5.1.2",
    +      "license": "MIT"
    +    },
    +    "node_modules/jszip/node_modules/string_decoder": {
    +      "version": "1.1.1",
    +      "license": "MIT",
    +      "dependencies": {
    +        "safe-buffer": "~5.1.0"
    +      }
    +    },
    +    "node_modules/lie": {
    +      "version": "3.3.0",
    +      "license": "MIT",
    +      "dependencies": {
    +        "immediate": "~3.0.5"
    +      }
    +    },
    +    "node_modules/lodash": {
    +      "version": "4.17.21",
    +      "license": "MIT"
    +    },
    +    "node_modules/lodash.assignin": {
    +      "version": "4.2.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/lodash.bind": {
    +      "version": "4.2.1",
    +      "license": "MIT"
    +    },
    +    "node_modules/lodash.defaults": {
    +      "version": "4.2.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/lodash.filter": {
    +      "version": "4.6.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/lodash.flatten": {
    +      "version": "4.4.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/lodash.foreach": {
    +      "version": "4.5.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/lodash.map": {
    +      "version": "4.6.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/lodash.merge": {
    +      "version": "4.6.2",
    +      "license": "MIT"
    +    },
    +    "node_modules/lodash.pick": {
    +      "version": "4.4.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/lodash.reduce": {
    +      "version": "4.6.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/lodash.reject": {
    +      "version": "4.6.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/lodash.some": {
    +      "version": "4.6.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/lru-cache": {
    +      "version": "7.18.3",
    +      "license": "ISC",
    +      "engines": {
    +        "node": ">=12"
    +      }
    +    },
    +    "node_modules/mime-db": {
    +      "version": "1.52.0",
    +      "license": "MIT",
    +      "engines": {
    +        "node": ">= 0.6"
    +      }
    +    },
    +    "node_modules/mime-types": {
    +      "version": "2.1.35",
    +      "license": "MIT",
    +      "dependencies": {
    +        "mime-db": "1.52.0"
    +      },
    +      "engines": {
    +        "node": ">= 0.6"
    +      }
    +    },
    +    "node_modules/minimatch": {
    +      "version": "3.1.2",
    +      "license": "ISC",
    +      "dependencies": {
    +        "brace-expansion": "^1.1.7"
    +      },
    +      "engines": {
    +        "node": "*"
    +      }
    +    },
    +    "node_modules/mitt": {
    +      "version": "3.0.1",
    +      "license": "MIT"
    +    },
    +    "node_modules/mkdirp-classic": {
    +      "version": "0.5.3",
    +      "license": "MIT"
    +    },
    +    "node_modules/moment-parseformat": {
    +      "version": "3.0.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/ms": {
    +      "version": "2.1.2",
    +      "license": "MIT"
    +    },
    +    "node_modules/netmask": {
    +      "version": "2.0.2",
    +      "license": "MIT",
    +      "engines": {
    +        "node": ">= 0.4.0"
    +      }
    +    },
    +    "node_modules/node-fetch": {
    +      "version": "2.7.0",
    +      "license": "MIT",
    +      "dependencies": {
    +        "whatwg-url": "^5.0.0"
    +      },
    +      "engines": {
    +        "node": "4.x || >=6.0.0"
    +      },
    +      "peerDependencies": {
    +        "encoding": "^0.1.0"
    +      },
    +      "peerDependenciesMeta": {
    +        "encoding": {
    +          "optional": true
    +        }
    +      }
    +    },
    +    "node_modules/nth-check": {
    +      "version": "1.0.2",
    +      "license": "BSD-2-Clause",
    +      "dependencies": {
    +        "boolbase": "~1.0.0"
    +      }
    +    },
    +    "node_modules/nwsapi": {
    +      "version": "2.2.7",
    +      "license": "MIT"
    +    },
    +    "node_modules/oauth-sign": {
    +      "version": "0.9.0",
    +      "license": "Apache-2.0",
    +      "engines": {
    +        "node": "*"
    +      }
    +    },
    +    "node_modules/once": {
    +      "version": "1.4.0",
    +      "license": "ISC",
    +      "dependencies": {
    +        "wrappy": "1"
    +      }
    +    },
    +    "node_modules/pac-proxy-agent": {
    +      "version": "7.0.1",
    +      "license": "MIT",
    +      "dependencies": {
    +        "@tootallnate/quickjs-emscripten": "^0.23.0",
    +        "agent-base": "^7.0.2",
    +        "debug": "^4.3.4",
    +        "get-uri": "^6.0.1",
    +        "http-proxy-agent": "^7.0.0",
    +        "https-proxy-agent": "^7.0.2",
    +        "pac-resolver": "^7.0.0",
    +        "socks-proxy-agent": "^8.0.2"
    +      },
    +      "engines": {
    +        "node": ">= 14"
    +      }
    +    },
    +    "node_modules/pac-proxy-agent/node_modules/agent-base": {
    +      "version": "7.1.0",
    +      "license": "MIT",
    +      "dependencies": {
    +        "debug": "^4.3.4"
    +      },
    +      "engines": {
    +        "node": ">= 14"
    +      }
    +    },
    +    "node_modules/pac-proxy-agent/node_modules/http-proxy-agent": {
    +      "version": "7.0.0",
    +      "license": "MIT",
    +      "dependencies": {
    +        "agent-base": "^7.1.0",
    +        "debug": "^4.3.4"
    +      },
    +      "engines": {
    +        "node": ">= 14"
    +      }
    +    },
    +    "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": {
    +      "version": "7.0.2",
    +      "license": "MIT",
    +      "dependencies": {
    +        "agent-base": "^7.0.2",
    +        "debug": "4"
    +      },
    +      "engines": {
    +        "node": ">= 14"
    +      }
    +    },
    +    "node_modules/pac-resolver": {
    +      "version": "7.0.0",
    +      "license": "MIT",
    +      "dependencies": {
    +        "degenerator": "^5.0.0",
    +        "ip": "^1.1.8",
    +        "netmask": "^2.0.2"
    +      },
    +      "engines": {
    +        "node": ">= 14"
    +      }
    +    },
    +    "node_modules/pako": {
    +      "version": "1.0.11",
    +      "license": "(MIT AND Zlib)"
    +    },
    +    "node_modules/parse5": {
    +      "version": "7.1.2",
    +      "license": "MIT",
    +      "dependencies": {
    +        "entities": "^4.4.0"
    +      },
    +      "funding": {
    +        "url": "https://github.com/inikulin/parse5?sponsor=1"
    +      }
    +    },
    +    "node_modules/parse5/node_modules/entities": {
    +      "version": "4.5.0",
    +      "license": "BSD-2-Clause",
    +      "engines": {
    +        "node": ">=0.12"
    +      },
    +      "funding": {
    +        "url": "https://github.com/fb55/entities?sponsor=1"
    +      }
    +    },
    +    "node_modules/path-is-absolute": {
    +      "version": "1.0.1",
    +      "license": "MIT",
    +      "engines": {
    +        "node": ">=0.10.0"
    +      }
    +    },
    +    "node_modules/pend": {
    +      "version": "1.2.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/performance-now": {
    +      "version": "2.1.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/postman-request": {
    +      "version": "2.88.1-postman.33",
    +      "license": "Apache-2.0",
    +      "dependencies": {
    +        "@postman/form-data": "~3.1.1",
    +        "@postman/tough-cookie": "~4.1.3-postman.1",
    +        "@postman/tunnel-agent": "^0.6.3",
    +        "aws-sign2": "~0.7.0",
    +        "aws4": "^1.12.0",
    +        "brotli": "^1.3.3",
    +        "caseless": "~0.12.0",
    +        "combined-stream": "~1.0.6",
    +        "extend": "~3.0.2",
    +        "forever-agent": "~0.6.1",
    +        "har-validator": "~5.1.3",
    +        "http-signature": "~1.3.1",
    +        "is-typedarray": "~1.0.0",
    +        "isstream": "~0.1.2",
    +        "json-stringify-safe": "~5.0.1",
    +        "mime-types": "^2.1.35",
    +        "oauth-sign": "~0.9.0",
    +        "performance-now": "^2.1.0",
    +        "qs": "~6.5.3",
    +        "safe-buffer": "^5.1.2",
    +        "stream-length": "^1.0.2",
    +        "uuid": "^8.3.2"
    +      },
    +      "engines": {
    +        "node": ">= 6"
    +      }
    +    },
    +    "node_modules/process-nextick-args": {
    +      "version": "2.0.1",
    +      "license": "MIT"
    +    },
    +    "node_modules/progress": {
    +      "version": "2.0.3",
    +      "license": "MIT",
    +      "engines": {
    +        "node": ">=0.4.0"
    +      }
    +    },
    +    "node_modules/proxy-agent": {
    +      "version": "6.3.1",
    +      "license": "MIT",
    +      "dependencies": {
    +        "agent-base": "^7.0.2",
    +        "debug": "^4.3.4",
    +        "http-proxy-agent": "^7.0.0",
    +        "https-proxy-agent": "^7.0.2",
    +        "lru-cache": "^7.14.1",
    +        "pac-proxy-agent": "^7.0.1",
    +        "proxy-from-env": "^1.1.0",
    +        "socks-proxy-agent": "^8.0.2"
    +      },
    +      "engines": {
    +        "node": ">= 14"
    +      }
    +    },
    +    "node_modules/proxy-agent/node_modules/agent-base": {
    +      "version": "7.1.0",
    +      "license": "MIT",
    +      "dependencies": {
    +        "debug": "^4.3.4"
    +      },
    +      "engines": {
    +        "node": ">= 14"
    +      }
    +    },
    +    "node_modules/proxy-agent/node_modules/http-proxy-agent": {
    +      "version": "7.0.0",
    +      "license": "MIT",
    +      "dependencies": {
    +        "agent-base": "^7.1.0",
    +        "debug": "^4.3.4"
    +      },
    +      "engines": {
    +        "node": ">= 14"
    +      }
    +    },
    +    "node_modules/proxy-agent/node_modules/https-proxy-agent": {
    +      "version": "7.0.2",
    +      "license": "MIT",
    +      "dependencies": {
    +        "agent-base": "^7.0.2",
    +        "debug": "4"
    +      },
    +      "engines": {
    +        "node": ">= 14"
    +      }
    +    },
    +    "node_modules/proxy-from-env": {
    +      "version": "1.1.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/psl": {
    +      "version": "1.9.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/pump": {
    +      "version": "3.0.0",
    +      "license": "MIT",
    +      "dependencies": {
    +        "end-of-stream": "^1.1.0",
    +        "once": "^1.3.1"
    +      }
    +    },
    +    "node_modules/punycode": {
    +      "version": "2.3.0",
    +      "license": "MIT",
    +      "engines": {
    +        "node": ">=6"
    +      }
    +    },
    +    "node_modules/puppeteer-core": {
    +      "version": "21.2.1",
    +      "license": "Apache-2.0",
    +      "dependencies": {
    +        "@puppeteer/browsers": "1.7.1",
    +        "chromium-bidi": "0.4.26",
    +        "cross-fetch": "4.0.0",
    +        "debug": "4.3.4",
    +        "devtools-protocol": "0.0.1159816",
    +        "ws": "8.14.1"
    +      },
    +      "engines": {
    +        "node": ">=16.3.0"
    +      }
    +    },
    +    "node_modules/puppeteer-core/node_modules/ws": {
    +      "version": "8.14.1",
    +      "license": "MIT",
           "engines": {
             "node": ">=10.0.0"
           },
    @@ -2860,48 +1623,160 @@
             }
           }
         },
    -    "node_modules/single-file-cli/node_modules/xml-name-validator": {
    -      "version": "4.0.0",
    -      "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
    -      "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
    +    "node_modules/qs": {
    +      "version": "6.5.3",
    +      "license": "BSD-3-Clause",
           "engines": {
    -        "node": ">=12"
    +        "node": ">=0.6"
           }
         },
    -    "node_modules/single-file-cli/node_modules/yargs": {
    -      "version": "17.7.2",
    -      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
    -      "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
    +    "node_modules/querystringify": {
    +      "version": "2.2.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/queue-tick": {
    +      "version": "1.0.1",
    +      "license": "MIT"
    +    },
    +    "node_modules/readability-extractor": {
    +      "version": "0.0.7",
    +      "resolved": "git+ssh://git@github.com/ArchiveBox/readability-extractor.git#4e298e47a780095697473afb04266943164b8364",
    +      "license": "MIT",
           "dependencies": {
    -        "cliui": "^8.0.1",
    -        "escalade": "^3.1.1",
    -        "get-caller-file": "^2.0.5",
    -        "require-directory": "^2.1.1",
    -        "string-width": "^4.2.3",
    -        "y18n": "^5.0.5",
    -        "yargs-parser": "^21.1.1"
    +        "@mozilla/readability": "^0.4.4",
    +        "dompurify": "^3.0.6",
    +        "jsdom": "^22.1.0"
    +      },
    +      "bin": {
    +        "readability-extractor": "readability-extractor"
    +      }
    +    },
    +    "node_modules/readable-stream": {
    +      "version": "3.6.2",
    +      "license": "MIT",
    +      "dependencies": {
    +        "inherits": "^2.0.3",
    +        "string_decoder": "^1.1.1",
    +        "util-deprecate": "^1.0.1"
           },
           "engines": {
    -        "node": ">=12"
    +        "node": ">= 6"
           }
         },
    -    "node_modules/single-file-cli/node_modules/yargs-parser": {
    -      "version": "21.1.1",
    -      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
    -      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
    +    "node_modules/regenerator-runtime": {
    +      "version": "0.14.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/require-directory": {
    +      "version": "2.1.1",
    +      "license": "MIT",
           "engines": {
    -        "node": ">=12"
    +        "node": ">=0.10.0"
    +      }
    +    },
    +    "node_modules/requires-port": {
    +      "version": "1.0.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/rimraf": {
    +      "version": "3.0.2",
    +      "license": "ISC",
    +      "dependencies": {
    +        "glob": "^7.1.3"
    +      },
    +      "bin": {
    +        "rimraf": "bin.js"
    +      },
    +      "funding": {
    +        "url": "https://github.com/sponsors/isaacs"
    +      }
    +    },
    +    "node_modules/rrweb-cssom": {
    +      "version": "0.6.0",
    +      "license": "MIT"
    +    },
    +    "node_modules/safe-buffer": {
    +      "version": "5.2.1",
    +      "funding": [
    +        {
    +          "type": "github",
    +          "url": "https://github.com/sponsors/feross"
    +        },
    +        {
    +          "type": "patreon",
    +          "url": "https://www.patreon.com/feross"
    +        },
    +        {
    +          "type": "consulting",
    +          "url": "https://feross.org/support"
    +        }
    +      ],
    +      "license": "MIT"
    +    },
    +    "node_modules/safer-buffer": {
    +      "version": "2.1.2",
    +      "license": "MIT"
    +    },
    +    "node_modules/saxes": {
    +      "version": "6.0.0",
    +      "license": "ISC",
    +      "dependencies": {
    +        "xmlchars": "^2.2.0"
    +      },
    +      "engines": {
    +        "node": ">=v12.22.7"
    +      }
    +    },
    +    "node_modules/selenium-webdriver": {
    +      "version": "4.12.0",
    +      "license": "Apache-2.0",
    +      "dependencies": {
    +        "jszip": "^3.10.1",
    +        "tmp": "^0.2.1",
    +        "ws": ">=8.13.0"
    +      },
    +      "engines": {
    +        "node": ">= 14.20.0"
    +      }
    +    },
    +    "node_modules/setimmediate": {
    +      "version": "1.0.5",
    +      "license": "MIT"
    +    },
    +    "node_modules/single-file-cli": {
    +      "version": "1.1.12",
    +      "license": "AGPL-3.0-or-later",
    +      "dependencies": {
    +        "file-url": "3.0.0",
    +        "iconv-lite": "0.6.3",
    +        "jsdom": "22.1.0",
    +        "puppeteer-core": "21.2.1",
    +        "selenium-webdriver": "4.12.0",
    +        "single-file-core": "1.2.13",
    +        "strong-data-uri": "1.0.6",
    +        "yargs": "17.7.2"
    +      },
    +      "bin": {
    +        "single-file": "single-file"
    +      }
    +    },
    +    "node_modules/single-file-cli/node_modules/iconv-lite": {
    +      "version": "0.6.3",
    +      "license": "MIT",
    +      "dependencies": {
    +        "safer-buffer": ">= 2.1.2 < 3.0.0"
    +      },
    +      "engines": {
    +        "node": ">=0.10.0"
           }
         },
         "node_modules/single-file-core": {
    -      "version": "1.0.72",
    -      "resolved": "https://registry.npmjs.org/single-file-core/-/single-file-core-1.0.72.tgz",
    -      "integrity": "sha512-7CiXd1Uw5mZpU1+BtwDd4wwj2LU+iYpptQcPQxz0WbhN5yQ7KwyNR+Zie4/tuum8GuIxY3YX4wdrEQSNzELVrw=="
    +      "version": "1.2.13",
    +      "license": "AGPL-3.0-or-later"
         },
         "node_modules/smart-buffer": {
           "version": "4.2.0",
    -      "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
    -      "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
    +      "license": "MIT",
           "engines": {
             "node": ">= 6.0.0",
             "npm": ">= 3.0.0"
    @@ -2909,8 +1784,7 @@
         },
         "node_modules/socks": {
           "version": "2.7.1",
    -      "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
    -      "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==",
    +      "license": "MIT",
           "dependencies": {
             "ip": "^2.0.0",
             "smart-buffer": "^4.2.0"
    @@ -2921,11 +1795,10 @@
           }
         },
         "node_modules/socks-proxy-agent": {
    -      "version": "8.0.1",
    -      "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.1.tgz",
    -      "integrity": "sha512-59EjPbbgg8U3x62hhKOFVAmySQUcfRQ4C7Q/D5sEHnZTQRrQlNKINks44DMR1gwXp0p4LaVIeccX2KHTTcHVqQ==",
    +      "version": "8.0.2",
    +      "license": "MIT",
           "dependencies": {
    -        "agent-base": "^7.0.1",
    +        "agent-base": "^7.0.2",
             "debug": "^4.3.4",
             "socks": "^2.7.1"
           },
    @@ -2935,8 +1808,7 @@
         },
         "node_modules/socks-proxy-agent/node_modules/agent-base": {
           "version": "7.1.0",
    -      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz",
    -      "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==",
    +      "license": "MIT",
           "dependencies": {
             "debug": "^4.3.4"
           },
    @@ -2946,22 +1818,19 @@
         },
         "node_modules/socks/node_modules/ip": {
           "version": "2.0.0",
    -      "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
    -      "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ=="
    +      "license": "MIT"
         },
         "node_modules/source-map": {
           "version": "0.6.1",
    -      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
    -      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
    +      "license": "BSD-3-Clause",
           "optional": true,
           "engines": {
             "node": ">=0.10.0"
           }
         },
         "node_modules/sshpk": {
    -      "version": "1.17.0",
    -      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
    -      "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
    +      "version": "1.18.0",
    +      "license": "MIT",
           "dependencies": {
             "asn1": "~0.2.3",
             "assert-plus": "^1.0.0",
    @@ -2982,26 +1851,16 @@
             "node": ">=0.10.0"
           }
         },
    -    "node_modules/stealthy-require": {
    -      "version": "1.1.1",
    -      "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
    -      "integrity": "sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==",
    -      "engines": {
    -        "node": ">=0.10.0"
    -      }
    -    },
         "node_modules/stream-length": {
           "version": "1.0.2",
    -      "resolved": "https://registry.npmjs.org/stream-length/-/stream-length-1.0.2.tgz",
    -      "integrity": "sha512-aI+qKFiwoDV4rsXiS7WRoCt+v2RX1nUj17+KJC5r2gfh5xoSJIfP6Y3Do/HtvesFcTSWthIuJ3l1cvKQY/+nZg==",
    +      "license": "WTFPL",
           "dependencies": {
             "bluebird": "^2.6.2"
           }
         },
         "node_modules/streamx": {
           "version": "2.15.1",
    -      "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.1.tgz",
    -      "integrity": "sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==",
    +      "license": "MIT",
           "dependencies": {
             "fast-fifo": "^1.1.0",
             "queue-tick": "^1.0.1"
    @@ -3009,21 +1868,18 @@
         },
         "node_modules/string_decoder": {
           "version": "1.3.0",
    -      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
    -      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
    +      "license": "MIT",
           "dependencies": {
             "safe-buffer": "~5.2.0"
           }
         },
         "node_modules/string-direction": {
           "version": "0.1.2",
    -      "resolved": "https://registry.npmjs.org/string-direction/-/string-direction-0.1.2.tgz",
    -      "integrity": "sha512-NJHQRg6GlOEMLA6jEAlSy21KaXvJDNoAid/v6fBAJbqdvOEIiPpCrIPTHnl4636wUF/IGyktX5A9eddmETb1Cw=="
    +      "license": "MIT"
         },
         "node_modules/string-width": {
           "version": "4.2.3",
    -      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
    -      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
    +      "license": "MIT",
           "dependencies": {
             "emoji-regex": "^8.0.0",
             "is-fullwidth-code-point": "^3.0.0",
    @@ -3035,8 +1891,7 @@
         },
         "node_modules/strip-ansi": {
           "version": "6.0.1",
    -      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
    -      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
    +      "license": "MIT",
           "dependencies": {
             "ansi-regex": "^5.0.1"
           },
    @@ -3046,8 +1901,7 @@
         },
         "node_modules/strong-data-uri": {
           "version": "1.0.6",
    -      "resolved": "https://registry.npmjs.org/strong-data-uri/-/strong-data-uri-1.0.6.tgz",
    -      "integrity": "sha512-zhzBZev0uhT2IrFUerenXhfaE0vFUYwAZsnG0gIKGpfM/Gi6jOUQ3cmcvyTsXeDLIPiTubHESeO7EbD6FoPmzw==",
    +      "license": "Artistic-2.0",
           "dependencies": {
             "truncate": "^2.0.1"
           },
    @@ -3057,242 +1911,199 @@
         },
         "node_modules/symbol-tree": {
           "version": "3.2.4",
    -      "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
    -      "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="
    +      "license": "MIT"
    +    },
    +    "node_modules/tar-fs": {
    +      "version": "3.0.4",
    +      "license": "MIT",
    +      "dependencies": {
    +        "mkdirp-classic": "^0.5.2",
    +        "pump": "^3.0.0",
    +        "tar-stream": "^3.1.5"
    +      }
    +    },
    +    "node_modules/tar-stream": {
    +      "version": "3.1.6",
    +      "license": "MIT",
    +      "dependencies": {
    +        "b4a": "^1.6.4",
    +        "fast-fifo": "^1.2.0",
    +        "streamx": "^2.15.0"
    +      }
         },
         "node_modules/through": {
           "version": "2.3.8",
    -      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
    -      "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
    +      "license": "MIT"
         },
    -    "node_modules/tough-cookie": {
    -      "version": "2.5.0",
    -      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
    -      "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
    +    "node_modules/tmp": {
    +      "version": "0.2.1",
    +      "license": "MIT",
           "dependencies": {
    -        "psl": "^1.1.28",
    -        "punycode": "^2.1.1"
    +        "rimraf": "^3.0.0"
           },
           "engines": {
    -        "node": ">=0.8"
    +        "node": ">=8.17.0"
    +      }
    +    },
    +    "node_modules/tough-cookie": {
    +      "version": "4.1.3",
    +      "license": "BSD-3-Clause",
    +      "dependencies": {
    +        "psl": "^1.1.33",
    +        "punycode": "^2.1.1",
    +        "universalify": "^0.2.0",
    +        "url-parse": "^1.5.3"
    +      },
    +      "engines": {
    +        "node": ">=6"
           }
         },
         "node_modules/tr46": {
           "version": "0.0.3",
    -      "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
    -      "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
    +      "license": "MIT"
         },
         "node_modules/truncate": {
           "version": "2.1.0",
    -      "resolved": "https://registry.npmjs.org/truncate/-/truncate-2.1.0.tgz",
    -      "integrity": "sha512-em3E3SUDONOjTBcZ36DTm3RvDded3IRU9rX32oHwwXNt3rJD5MVaFlJTQvs8tJoHRoeYP36OuQ1eL/Q7bNEWIQ==",
    +      "license": "MIT",
           "engines": {
             "node": "*"
           }
         },
         "node_modules/tslib": {
           "version": "2.6.2",
    -      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
    -      "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
    -    },
    -    "node_modules/tunnel-agent": {
    -      "version": "0.6.0",
    -      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
    -      "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
    -      "dependencies": {
    -        "safe-buffer": "^5.0.1"
    -      },
    -      "engines": {
    -        "node": "*"
    -      }
    +      "license": "0BSD"
         },
         "node_modules/turndown": {
    -      "version": "5.0.3",
    -      "resolved": "https://registry.npmjs.org/turndown/-/turndown-5.0.3.tgz",
    -      "integrity": "sha512-popfGXEiedpq6F5saRIAThKxq/bbEPVFnsDnUdjaDGIre9f3/OL9Yi/yPbPcZ7RYUDpekghr666bBfZPrwNnhQ==",
    +      "version": "7.1.2",
    +      "license": "MIT",
           "dependencies": {
    -        "jsdom": "^11.9.0"
    +        "domino": "^2.1.6"
           }
         },
         "node_modules/tweetnacl": {
           "version": "0.14.5",
    -      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
    -      "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
    -    },
    -    "node_modules/type-check": {
    -      "version": "0.3.2",
    -      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
    -      "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==",
    -      "dependencies": {
    -        "prelude-ls": "~1.1.2"
    -      },
    -      "engines": {
    -        "node": ">= 0.8.0"
    -      }
    +      "license": "Unlicense"
         },
         "node_modules/unbzip2-stream": {
           "version": "1.4.3",
    -      "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
    -      "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
    +      "license": "MIT",
           "dependencies": {
             "buffer": "^5.2.1",
             "through": "^2.3.8"
           }
         },
    +    "node_modules/undici-types": {
    +      "version": "5.25.3",
    +      "license": "MIT",
    +      "optional": true
    +    },
         "node_modules/universalify": {
           "version": "0.2.0",
    -      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
    -      "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
    +      "license": "MIT",
           "engines": {
             "node": ">= 4.0.0"
           }
         },
         "node_modules/uri-js": {
           "version": "4.4.1",
    -      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
    -      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
    +      "license": "BSD-2-Clause",
           "dependencies": {
             "punycode": "^2.1.0"
           }
         },
    -    "node_modules/url": {
    -      "version": "0.11.1",
    -      "resolved": "https://registry.npmjs.org/url/-/url-0.11.1.tgz",
    -      "integrity": "sha512-rWS3H04/+mzzJkv0eZ7vEDGiQbgquI1fGfOad6zKvgYQi1SzMmhl7c/DdRGxhaWrVH6z0qWITo8rpnxK/RfEhA==",
    -      "dependencies": {
    -        "punycode": "^1.4.1",
    -        "qs": "^6.11.0"
    -      }
    -    },
         "node_modules/url-parse": {
           "version": "1.5.10",
    -      "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
    -      "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
    +      "license": "MIT",
           "dependencies": {
             "querystringify": "^2.1.1",
             "requires-port": "^1.0.0"
           }
         },
    -    "node_modules/url/node_modules/punycode": {
    -      "version": "1.4.1",
    -      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
    -      "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="
    -    },
    -    "node_modules/url/node_modules/qs": {
    -      "version": "6.11.2",
    -      "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz",
    -      "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==",
    -      "dependencies": {
    -        "side-channel": "^1.0.4"
    -      },
    -      "engines": {
    -        "node": ">=0.6"
    -      },
    -      "funding": {
    -        "url": "https://github.com/sponsors/ljharb"
    -      }
    -    },
         "node_modules/util-deprecate": {
           "version": "1.0.2",
    -      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
    -      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
    +      "license": "MIT"
         },
         "node_modules/uuid": {
           "version": "8.3.2",
    -      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
    -      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
    +      "license": "MIT",
           "bin": {
             "uuid": "dist/bin/uuid"
           }
         },
         "node_modules/valid-url": {
    -      "version": "1.0.9",
    -      "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz",
    -      "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA=="
    +      "version": "1.0.9"
         },
         "node_modules/verror": {
           "version": "1.10.0",
    -      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
    -      "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
           "engines": [
             "node >=0.6.0"
           ],
    +      "license": "MIT",
           "dependencies": {
             "assert-plus": "^1.0.0",
             "core-util-is": "1.0.2",
             "extsprintf": "^1.2.0"
           }
         },
    -    "node_modules/w3c-hr-time": {
    -      "version": "1.0.2",
    -      "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
    -      "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==",
    -      "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.",
    -      "dependencies": {
    -        "browser-process-hrtime": "^1.0.0"
    -      }
    -    },
         "node_modules/w3c-xmlserializer": {
    -      "version": "2.0.0",
    -      "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz",
    -      "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==",
    +      "version": "4.0.0",
    +      "license": "MIT",
           "dependencies": {
    -        "xml-name-validator": "^3.0.0"
    +        "xml-name-validator": "^4.0.0"
           },
           "engines": {
    -        "node": ">=10"
    +        "node": ">=14"
           }
         },
         "node_modules/webidl-conversions": {
    -      "version": "3.0.1",
    -      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
    -      "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
    +      "version": "7.0.0",
    +      "license": "BSD-2-Clause",
    +      "engines": {
    +        "node": ">=12"
    +      }
         },
         "node_modules/whatwg-encoding": {
    -      "version": "1.0.5",
    -      "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
    -      "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
    +      "version": "2.0.0",
    +      "license": "MIT",
           "dependencies": {
    -        "iconv-lite": "0.4.24"
    +        "iconv-lite": "0.6.3"
    +      },
    +      "engines": {
    +        "node": ">=12"
           }
         },
         "node_modules/whatwg-encoding/node_modules/iconv-lite": {
    -      "version": "0.4.24",
    -      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
    -      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
    +      "version": "0.6.3",
    +      "license": "MIT",
           "dependencies": {
    -        "safer-buffer": ">= 2.1.2 < 3"
    +        "safer-buffer": ">= 2.1.2 < 3.0.0"
           },
           "engines": {
             "node": ">=0.10.0"
           }
         },
         "node_modules/whatwg-mimetype": {
    -      "version": "2.3.0",
    -      "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
    -      "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g=="
    +      "version": "3.0.0",
    +      "license": "MIT",
    +      "engines": {
    +        "node": ">=12"
    +      }
         },
         "node_modules/whatwg-url": {
           "version": "5.0.0",
    -      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
    -      "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
    +      "license": "MIT",
           "dependencies": {
             "tr46": "~0.0.3",
             "webidl-conversions": "^3.0.0"
           }
         },
    -    "node_modules/word-wrap": {
    -      "version": "1.2.4",
    -      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
    -      "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
    -      "engines": {
    -        "node": ">=0.10.0"
    -      }
    +    "node_modules/whatwg-url/node_modules/webidl-conversions": {
    +      "version": "3.0.1",
    +      "license": "BSD-2-Clause"
         },
         "node_modules/wrap-ansi": {
           "version": "7.0.0",
    -      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
    -      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
    +      "license": "MIT",
           "dependencies": {
             "ansi-styles": "^4.0.0",
             "string-width": "^4.1.0",
    @@ -3307,56 +2118,86 @@
         },
         "node_modules/wrappy": {
           "version": "1.0.2",
    -      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
    -      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
    +      "license": "ISC"
         },
         "node_modules/ws": {
    -      "version": "5.2.3",
    -      "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.3.tgz",
    -      "integrity": "sha512-jZArVERrMsKUatIdnLzqvcfydI85dvd/Fp1u/VOpfdDWQ4c9qWXe+VIeAbQ5FrDwciAkr+lzofXLz3Kuf26AOA==",
    -      "dependencies": {
    -        "async-limiter": "~1.0.0"
    +      "version": "8.14.2",
    +      "license": "MIT",
    +      "engines": {
    +        "node": ">=10.0.0"
    +      },
    +      "peerDependencies": {
    +        "bufferutil": "^4.0.1",
    +        "utf-8-validate": ">=5.0.2"
    +      },
    +      "peerDependenciesMeta": {
    +        "bufferutil": {
    +          "optional": true
    +        },
    +        "utf-8-validate": {
    +          "optional": true
    +        }
           }
         },
         "node_modules/wuzzy": {
           "version": "0.1.8",
    -      "resolved": "https://registry.npmjs.org/wuzzy/-/wuzzy-0.1.8.tgz",
    -      "integrity": "sha512-FUzKQepFSTnANsDYwxpIzGJ/dIJaqxuMre6tzzbvWwFAiUHPsI1nVQVCLK4Xqr67KO7oYAK0kaCcI/+WYj/7JA==",
    +      "license": "MIT",
           "dependencies": {
             "lodash": "^4.17.15"
           }
         },
         "node_modules/xml-name-validator": {
    -      "version": "3.0.0",
    -      "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
    -      "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw=="
    +      "version": "4.0.0",
    +      "license": "Apache-2.0",
    +      "engines": {
    +        "node": ">=12"
    +      }
         },
         "node_modules/xmlchars": {
           "version": "2.2.0",
    -      "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
    -      "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="
    +      "license": "MIT"
         },
         "node_modules/y18n": {
           "version": "5.0.8",
    -      "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
    -      "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
    +      "license": "ISC",
           "engines": {
             "node": ">=10"
           }
         },
    +    "node_modules/yargs": {
    +      "version": "17.7.2",
    +      "license": "MIT",
    +      "dependencies": {
    +        "cliui": "^8.0.1",
    +        "escalade": "^3.1.1",
    +        "get-caller-file": "^2.0.5",
    +        "require-directory": "^2.1.1",
    +        "string-width": "^4.2.3",
    +        "y18n": "^5.0.5",
    +        "yargs-parser": "^21.1.1"
    +      },
    +      "engines": {
    +        "node": ">=12"
    +      }
    +    },
         "node_modules/yargs-parser": {
           "version": "15.0.3",
    -      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.3.tgz",
    -      "integrity": "sha512-/MVEVjTXy/cGAjdtQf8dW3V9b97bPN7rNn8ETj6BmAQL7ibC7O1Q9SPJbGjgh3SlwoBNXMzj/ZGIj8mBgl12YA==",
    +      "license": "ISC",
           "dependencies": {
             "camelcase": "^5.0.0",
             "decamelize": "^1.2.0"
           }
         },
    +    "node_modules/yargs/node_modules/yargs-parser": {
    +      "version": "21.1.1",
    +      "license": "ISC",
    +      "engines": {
    +        "node": ">=12"
    +      }
    +    },
         "node_modules/yauzl": {
           "version": "2.10.0",
    -      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
    -      "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
    +      "license": "MIT",
           "dependencies": {
             "buffer-crc32": "~0.2.3",
             "fd-slicer": "~1.1.0"
    diff --git a/package.json b/package.json
    index 4eb06c3d..f3d5b736 100644
    --- a/package.json
    +++ b/package.json
    @@ -6,8 +6,8 @@
       "repository": "github:ArchiveBox/ArchiveBox",
       "license": "MIT",
       "dependencies": {
    -    "@postlight/mercury-parser": "git+https://github.com/postlight/mercury-parser.git",
    +    "@postlight/parser": "^2.2.3",
         "readability-extractor": "git+https://github.com/ArchiveBox/readability-extractor.git",
    -    "single-file-cli": "^1.0.63"
    +    "single-file-cli": "^1.1.12"
       }
     }
    
    From 16796a63fd7a814dd7acaad08f6317f68d2e6f1a Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Fri, 20 Oct 2023 02:45:54 -0700
    Subject: [PATCH 37/89] share PUID and PGID with child procs from entrypoint
    
    ---
     bin/docker_entrypoint.sh | 5 ++---
     1 file changed, 2 insertions(+), 3 deletions(-)
    
    diff --git a/bin/docker_entrypoint.sh b/bin/docker_entrypoint.sh
    index 71abc2bc..b245968f 100755
    --- a/bin/docker_entrypoint.sh
    +++ b/bin/docker_entrypoint.sh
    @@ -12,8 +12,8 @@ if [[ -n "$PGID" && "$PGID" != 0 ]]; then
         groupmod -g "$PGID" "$ARCHIVEBOX_USER" > /dev/null 2>&1
     fi
     
    -PUID="$(id -u archivebox)"
    -PGID="$(id -g archivebox)"
    +export PUID="$(id -u archivebox)"
    +export PGID="$(id -g archivebox)"
     
     # Check the permissions of the data dir (or create if it doesn't exist)
     if [[ -d "$DATA_DIR/archive" ]]; then
    @@ -33,7 +33,6 @@ else
     fi
     chown $ARCHIVEBOX_USER:$ARCHIVEBOX_USER "$DATA_DIR" "$DATA_DIR"/*
     
    -
     # Drop permissions to run commands as the archivebox user
     if [[ "$1" == /* || "$1" == "echo" || "$1" == "archivebox" ]]; then
         # arg 1 is a binary, execute it verbatim
    
    From 75eeb12ebefd537e296d4fe6c04f2a8c16f62f8b Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Fri, 20 Oct 2023 02:46:09 -0700
    Subject: [PATCH 38/89] dont install youtubedl anymore
    
    ---
     pyproject.toml | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/pyproject.toml b/pyproject.toml
    index 458809af..4f3135b4 100644
    --- a/pyproject.toml
    +++ b/pyproject.toml
    @@ -16,7 +16,7 @@ dependencies = [
         "python-crontab>=2.5.1",
         "requests>=2.24.0",
         "w3lib>=1.22.0",
    -    "youtube-dl>=2021.04.17",
    +    # "youtube-dl>=2021.04.17",
         "yt-dlp>=2021.4.11",
         "playwright>=1.39.0",
     ]
    
    From d4ca2d1154aa21eef8688dd80cfb457fe46bbc50 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Fri, 20 Oct 2023 02:46:41 -0700
    Subject: [PATCH 39/89] update mercury bin path to postlight parser
    
    ---
     archivebox/config.py | 9 ++++-----
     1 file changed, 4 insertions(+), 5 deletions(-)
    
    diff --git a/archivebox/config.py b/archivebox/config.py
    index 64d3d0a2..8f094ea3 100644
    --- a/archivebox/config.py
    +++ b/archivebox/config.py
    @@ -231,12 +231,11 @@ CONFIG_SCHEMA: Dict[str, ConfigDefaultDict] = {
     
             'CURL_BINARY':              {'type': str,   'default': 'curl'},
             'GIT_BINARY':               {'type': str,   'default': 'git'},
    -        'WGET_BINARY':              {'type': str,   'default': 'wget'},
    +        'WGET_BINARY':              {'type': str,   'default': 'wget'},     # also can accept wget2
             'SINGLEFILE_BINARY':        {'type': str,   'default': lambda c: bin_path('single-file')},
             'READABILITY_BINARY':       {'type': str,   'default': lambda c: bin_path('readability-extractor')},
    -        'MERCURY_BINARY':           {'type': str,   'default': lambda c: bin_path('mercury-parser')},
    -        #'YOUTUBEDL_BINARY':         {'type': str,   'default': 'youtube-dl'},
    -        'YOUTUBEDL_BINARY':         {'type': str,   'default': 'yt-dlp'},
    +        'MERCURY_BINARY':           {'type': str,   'default': lambda c: bin_path('postlight-parser')},
    +        'YOUTUBEDL_BINARY':         {'type': str,   'default': 'yt-dlp'},   # also can accept youtube-dl
             'NODE_BINARY':              {'type': str,   'default': 'node'},
             'RIPGREP_BINARY':           {'type': str,   'default': 'rg'},
             'CHROME_BINARY':            {'type': str,   'default': None},
    @@ -435,7 +434,7 @@ DYNAMIC_CONFIG_SCHEMA: ConfigDefaultDict = {
         'READABILITY_VERSION':      {'default': lambda c: bin_version(c['READABILITY_BINARY']) if c['USE_READABILITY'] else None},
     
         'USE_MERCURY':              {'default': lambda c: c['USE_MERCURY'] and c['SAVE_MERCURY']},
    -    'MERCURY_VERSION':          {'default': lambda c: '1.0.0' if shutil.which(str(bin_path(c['MERCURY_BINARY']))) else None},  # mercury is unversioned
    +    'MERCURY_VERSION':          {'default': lambda c: '1.0.0' if shutil.which(str(bin_path(c['MERCURY_BINARY']))) else None},  # mercury doesnt expose version info until this is merged https://github.com/postlight/parser/pull/750
     
         'USE_GIT':                  {'default': lambda c: c['USE_GIT'] and c['SAVE_GIT']},
         'GIT_VERSION':              {'default': lambda c: bin_version(c['GIT_BINARY']) if c['USE_GIT'] else None},
    
    From 7910a5b34b71b7fa8a90e74b2e7a2f394c20f793 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Fri, 20 Oct 2023 02:47:03 -0700
    Subject: [PATCH 40/89] fix pretty_path printing logic
    
    ---
     archivebox/logging_util.py | 37 +++++++++++++++++++++++--------------
     1 file changed, 23 insertions(+), 14 deletions(-)
    
    diff --git a/archivebox/logging_util.py b/archivebox/logging_util.py
    index 70998dbd..a52cf82a 100644
    --- a/archivebox/logging_util.py
    +++ b/archivebox/logging_util.py
    @@ -533,11 +533,27 @@ def log_shell_welcome_msg():
     ### Helpers
     
     @enforce_types
    -def pretty_path(path: Union[Path, str]) -> str:
    +def pretty_path(path: Union[Path, str], pwd: Union[Path, str]=OUTPUT_DIR) -> str:
         """convert paths like .../ArchiveBox/archivebox/../output/abc into output/abc"""
    -    pwd = Path('.').resolve()
    -    # parent = os.path.abspath(os.path.join(pwd, os.path.pardir))
    -    return str(path).replace(str(pwd) + '/', './')
    +    pwd = str(Path(pwd))  # .resolve()
    +    path = str(path)
    +
    +    if not path:
    +        return path
    +
    +    # replace long absolute paths with ./ relative ones to save on terminal output width
    +    if path.startswith(pwd) and (pwd != '/'):
    +        path = path.replace(pwd, '.', 1)
    +    
    +    # quote paths containing spaces
    +    if ' ' in path:
    +        path = f'"{path}"'
    +
    +    # if path is just a plain dot, replace it back with the absolute path for clarity
    +    if path == '.':
    +        path = pwd
    +
    +    return path
     
     
     @enforce_types
    @@ -578,6 +594,7 @@ def printable_folder_status(name: str, folder: Dict) -> str:
         else:
             color, symbol, note, num_files = 'lightyellow', '-', 'disabled', '-'
     
    +
         if folder['path']:
             if Path(folder['path']).exists():
                 num_files = (
    @@ -592,13 +609,7 @@ def printable_folder_status(name: str, folder: Dict) -> str:
             # add symbol @ next to filecount if path is a remote filesystem mount
             num_files = f'{num_files} @' if num_files else '@'
     
    -    path = str(folder['path']).replace(str(OUTPUT_DIR), '.') if folder['path'] else ''
    -    if path and ' ' in path:
    -        path = f'"{path}"'
    -
    -    # if path is just a plain dot, replace it back with the full path for clarity
    -    if path == '.':
    -        path = str(OUTPUT_DIR)
    +    path = pretty_path(folder['path'])
     
         return ' '.join((
             ANSI[color],
    @@ -629,9 +640,7 @@ def printable_dependency_version(name: str, dependency: Dict) -> str:
         else:
             color, symbol, note, version = 'lightyellow', '-', 'disabled', '-'
     
    -    path = str(dependency["path"]).replace(str(OUTPUT_DIR), '.') if dependency["path"] else ''
    -    if path and ' ' in path:
    -        path = f'"{path}"'
    +    path = pretty_path(dependency['path'])
     
         return ' '.join((
             ANSI[color],
    
    From 86c662421b922dc398f124efcadc3c1c682f5a3e Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Fri, 20 Oct 2023 02:47:23 -0700
    Subject: [PATCH 41/89] show FS_USER in version output debug string
    
    ---
     archivebox/main.py | 17 +++++++++--------
     1 file changed, 9 insertions(+), 8 deletions(-)
    
    diff --git a/archivebox/main.py b/archivebox/main.py
    index 5268691b..e56479f6 100755
    --- a/archivebox/main.py
    +++ b/archivebox/main.py
    @@ -218,7 +218,7 @@ def version(quiet: bool=False,
         if not quiet:
             # 0.6.3
             # ArchiveBox v0.6.3 Cpython Linux Linux-4.19.121-linuxkit-x86_64-with-glibc2.28 x86_64 (in Docker) (in TTY)
    -        # DEBUG=False IN_DOCKER=True IS_TTY=True TZ=UTC FS_ATOMIC=True FS_REMOTE=False FS_PERMS=644 501:20 SEARCH_BACKEND=ripgrep
    +        # DEBUG=False IN_DOCKER=True IS_TTY=True TZ=UTC FS_ATOMIC=True FS_REMOTE=False FS_PERMS=644 FS_USER=501:20 SEARCH_BACKEND=ripgrep
             
             p = platform.uname()
             print(
    @@ -238,7 +238,8 @@ def version(quiet: bool=False,
                 #f'DB=django.db.backends.sqlite3 (({CONFIG["SQLITE_JOURNAL_MODE"]})',  # add this if we have more useful info to show eventually
                 f'FS_ATOMIC={ENFORCE_ATOMIC_WRITES}',
                 f'FS_REMOTE={OUTPUT_IS_REMOTE_FS}',
    -            f'FS_PERMS={OUTPUT_PERMISSIONS} {PUID}:{PGID}',
    +            f'FS_USER={PUID}:{PGID}',
    +            f'FS_PERMS={OUTPUT_PERMISSIONS}',
                 f'SEARCH_BACKEND={SEARCH_BACKEND_ENGINE}',
             )
             print()
    @@ -253,19 +254,19 @@ def version(quiet: bool=False,
             
             print()
             print('{white}[i] Source-code locations:{reset}'.format(**ANSI))
    -        for name, folder in CODE_LOCATIONS.items():
    -            print(printable_folder_status(name, folder))
    +        for name, path in CODE_LOCATIONS.items():
    +            print(printable_folder_status(name, path))
     
             print()
             print('{white}[i] Secrets locations:{reset}'.format(**ANSI))
    -        for name, folder in EXTERNAL_LOCATIONS.items():
    -            print(printable_folder_status(name, folder))
    +        for name, path in EXTERNAL_LOCATIONS.items():
    +            print(printable_folder_status(name, path))
     
             print()
             if DATA_LOCATIONS['OUTPUT_DIR']['is_valid']:
                 print('{white}[i] Data locations:{reset}'.format(**ANSI))
    -            for name, folder in DATA_LOCATIONS.items():
    -                print(printable_folder_status(name, folder))
    +            for name, path in DATA_LOCATIONS.items():
    +                print(printable_folder_status(name, path))
             else:
                 print()
                 print('{white}[i] Data locations:{reset}'.format(**ANSI))
    
    From 6736e63ef0f0ff976e4922618fe28c08cf180ef1 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Fri, 20 Oct 2023 02:47:34 -0700
    Subject: [PATCH 42/89] new Dockerfile layout with better layering
    
    ---
     Dockerfile | 171 ++++++++++++++++++++++++++++++++---------------------
     1 file changed, 103 insertions(+), 68 deletions(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index de02208e..adcbc36f 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -16,15 +16,17 @@
     # Archivebox](https://github.com/ArchiveBox/ArchiveBox#archivebox-development).
     
     
    -FROM python:3.11-slim-bullseye
    +FROM debian:bookworm-backports
     
     LABEL name="archivebox" \
    -    maintainer="Nick Sweeting <archivebox-docker@sweeting.me>" \
    +    maintainer="Nick Sweeting <dockerfile@archivebox.io>" \
         description="All-in-one personal internet archiving container" \
         homepage="https://github.com/ArchiveBox/ArchiveBox" \
         documentation="https://github.com/ArchiveBox/ArchiveBox/wiki/Docker#docker"
     
    -# System-level base config
    +######### Base System Setup ####################################
    +
    +# Global system-level config
     ENV TZ=UTC \
         LANGUAGE=en_US:en \
         LC_ALL=C.UTF-8 \
    @@ -32,103 +34,136 @@ ENV TZ=UTC \
         PYTHONIOENCODING=UTF-8 \
         PYTHONUNBUFFERED=1 \
         DEBIAN_FRONTEND=noninteractive \
    -    APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1
    +    APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 \
    +    npm_config_loglevel=error
     
    -# Application-level base config
    +# Application-level config
     ENV CODE_DIR=/app \
    -    VENV_PATH=/venv \
         DATA_DIR=/data \
    -    NODE_DIR=/node \
    +    GLOBAL_VENV=/venv \
    +    APP_VENV=/app/.venv \
    +    NODE_MODULES=/app/node_modules \
         ARCHIVEBOX_USER="archivebox"
     
    +ENV PATH="$PATH:$GLOBAL_VENV/bin:$APP_VENV/bin:$NODE_MODULES/.bin"
    +
    +
     # Create non-privileged user for archivebox and chrome
     RUN groupadd --system $ARCHIVEBOX_USER \
    -    && useradd --system --create-home --gid $ARCHIVEBOX_USER --groups audio,video $ARCHIVEBOX_USER
    +    && useradd --system --create-home --gid $ARCHIVEBOX_USER --groups audio,video $ARCHIVEBOX_USER \
    +    && mkdir -p /etc/apt/keyrings
     
    -# Install system dependencies
    -RUN apt-get update -qq \
    -    && apt-get install -qq -y --no-install-recommends \
    -        apt-transport-https ca-certificates gnupg2 zlib1g-dev \
    -        dumb-init gosu cron unzip curl \
    +# Install system apt dependencies (adding backports to access more recent apt updates)
    +RUN echo 'deb https://deb.debian.org/debian bullseye-backports main contrib non-free' >> /etc/apt/sources.list.d/backports.list \
    +    && apt-get update -qq \
    +    && apt-get install -qq -y \
    +        apt-transport-https ca-certificates gnupg2 curl wget \
    +        zlib1g-dev dumb-init gosu cron unzip \
    +        nano iputils-ping dnsutils \
    +        # 1. packaging dependencies
    +        # 2. docker and init system dependencies
    +        # 3. frivolous CLI helpers to make debugging failed archiving easier
    +    && mkdir -p /etc/apt/keyrings \
         && rm -rf /var/lib/apt/lists/*
     
    +
    +######### Language Environments ####################################
    +
    +# Install Node environment
    +RUN echo 'deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main' >> /etc/apt/sources.list.d/nodejs.list \
    +    && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
    +    && apt-get update -qq \
    +    && apt-get install -qq -y nodejs \
    +    && npm i -g npm \
    +    && node --version \
    +    && npm --version
    +
    +# Install Python environment
    +RUN apt-get update -qq \
    +    && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    +        python3 python3-pip python3-venv python3-setuptools python3-wheel python-dev-is-python3 \
    +    && rm /usr/lib/python3*/EXTERNALLY-MANAGED \
    +    && python3 -m venv $GLOBAL_VENV \
    +    && $GLOBAL_VENV/bin/pip install --upgrade pip pdm setuptools wheel \
    +    && rm -rf /var/lib/apt/lists/*
    +
    +######### Extractor Dependencies ##################################
    +
     # Install apt dependencies
     RUN apt-get update -qq \
    -    && apt-get install -qq -y --no-install-recommends \
    -        wget curl chromium git ffmpeg youtube-dl ripgrep \
    -        fontconfig fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-symbola fonts-noto fonts-freefont-ttf \
    -    && ln -s /usr/bin/chromium /usr/bin/chromium-browser \
    +    && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    +        curl wget git yt-dlp ffmpeg ripgrep \
    +        # Packages we have also needed in the past:
    +        # youtube-dl wget2 aria2 python3-pyxattr rtmpdump libfribidi-bin mpv \
    +        # fontconfig fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-symbola fonts-noto fonts-freefont-ttf \
         && rm -rf /var/lib/apt/lists/*
     
    -# Install Node environment
    -RUN curl -s https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \
    -    && echo 'deb https://deb.nodesource.com/node_18.x buster main' >> /etc/apt/sources.list \
    -    && apt-get update -qq \
    -    && apt-get install -qq -y --no-install-recommends \
    -        nodejs \
    -    # && npm install -g npm \
    -    && rm -rf /var/lib/apt/lists/*
    +# Install chromium browser using playwright
    +ENV PLAYWRIGHT_BROWSERS_PATH=/browsers
    +RUN apt-get update -qq \
    +    && $GLOBAL_VENV/bin/pip install playwright \
    +    && $GLOBAL_VENV/bin/playwright install --with-deps chromium \
    +    && CHROME_BINARY="$($GLOBAL_VENV/bin/python -c 'from playwright.sync_api import sync_playwright; print(sync_playwright().start().chromium.executable_path)')" \
    +    && ln -s "$CHROME_BINARY" /usr/bin/chromium-browser \
    +    && mkdir -p "/home/${ARCHIVEBOX_USER}/.config/chromium/Crash Reports/pending/" \
    +    && chown -R $ARCHIVEBOX_USER "/home/${ARCHIVEBOX_USER}/.config"
     
     # Install Node dependencies
    -WORKDIR "$NODE_DIR"
    -ENV PATH="${PATH}:$NODE_DIR/node_modules/.bin" \
    -    npm_config_loglevel=error
    -ADD ./package.json ./package.json
    -ADD ./package-lock.json ./package-lock.json
    -RUN npm ci
    -
    -# Install Python dependencies
     WORKDIR "$CODE_DIR"
    -ENV PATH="${PATH}:$VENV_PATH/bin"
    -RUN python -m venv --clear --symlinks "$VENV_PATH" \
    -    && pip install --upgrade --quiet pip setuptools \
    -    && mkdir -p "$CODE_DIR/archivebox"
    -ADD "./setup.py" "$CODE_DIR/"
    -ADD "./package.json" "$CODE_DIR/archivebox/"
    +ADD "package.json" "package-lock.json" "$CODE_DIR/"
    +RUN npm ci --prefer-offline --no-audit
    +RUN "$NODE_MODULES/.bin/readability-extractor" --version
    +
    +######### Build Dependencies ####################################
    +
    +WORKDIR "$CODE_DIR"
    +COPY --chown=root:root . "$CODE_DIR/"
    +
    +# Install Python Build dependencies & build ArchiveBox package
    +# RUN apt-get update -qq \
    +#     && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    +#         build-essential libssl-dev libldap2-dev libsasl2-dev \
    +#     && pdm venv create \
    +#     && pdm install --fail-fast --no-lock --group :all \
    +#     && pdm build \
    +#     && apt-get purge -y \
    +#         build-essential libssl-dev libldap2-dev libsasl2-dev \
    +#         # these are only needed to build CPython libs, we discard after build phase to shrink layer size
    +#     && apt-get autoremove -y \
    +#     && rm -rf /var/lib/apt/lists/*
    +
    +
    +# Install ArchiveBox Python package from source
     RUN apt-get update -qq \
    -    && apt-get install -qq -y --no-install-recommends \
    -        build-essential python-dev python3-dev libldap2-dev libsasl2-dev \
    -    && echo 'empty placeholder for setup.py to use' > "$CODE_DIR/archivebox/README.md" \
    -    && python3 -c 'from distutils.core import run_setup; result = run_setup("./setup.py", stop_after="init"); print("\n".join(result.install_requires + result.extras_require["sonic"]))' > /tmp/requirements.txt \
    -    && pip install -r /tmp/requirements.txt \
    -    && pip install --upgrade youtube-dl yt-dlp \
    -    && apt-get purge -y build-essential python-dev python3-dev libldap2-dev libsasl2-dev \
    -    && apt-get autoremove -y \
    -    && rm -rf /var/lib/apt/lists/*
    +    && $GLOBAL_VENV/bin/pip install -e "$CODE_DIR"[sonic,ldap]
     
    -# Install apt development dependencies
    -# RUN apt-get install -qq \
    -#     && apt-get install -qq -y --no-install-recommends \
    -#         python3 python3-dev python3-pip python3-venv python3-all \
    -#         dh-python debhelper devscripts dput software-properties-common \
    -#         python3-distutils python3-setuptools python3-wheel python3-stdeb
    -# RUN python3 -c 'from distutils.core import run_setup; result = run_setup("./setup.py", stop_after="init"); print("\n".join(result.extras_require["dev"]))' > /tmp/dev_requirements.txt \
    -    # && pip install --quiet -r /tmp/dev_requirements.txt
    -
    -# Install ArchiveBox Python package and its dependencies
    -WORKDIR "$CODE_DIR"
    -ADD . "$CODE_DIR"
    -RUN chown -R root:root . && chmod a+rX -R . && pip install -e .
    +####################################################
     
     # Setup ArchiveBox runtime config
    -WORKDIR "$DATA_DIR"
     ENV IN_DOCKER=True \
    +    WGET_BINARY="wget" \
    +    YOUTUBEDL_BINARY="yt-dlp" \
         CHROME_SANDBOX=False \
         CHROME_BINARY="/usr/bin/chromium-browser" \
         USE_SINGLEFILE=True \
    -    SINGLEFILE_BINARY="$NODE_DIR/node_modules/.bin/single-file" \
    +    SINGLEFILE_BINARY="$NODE_MODULES/.bin/single-file" \
         USE_READABILITY=True \
    -    READABILITY_BINARY="$NODE_DIR/node_modules/.bin/readability-extractor" \
    +    READABILITY_BINARY="$NODE_MODULES/.bin/readability-extractor" \
         USE_MERCURY=True \
    -    MERCURY_BINARY="$NODE_DIR/node_modules/.bin/mercury-parser" \
    -    YOUTUBEDL_BINARY="yt-dlp"
    +    MERCURY_BINARY="$NODE_MODULES/.bin/postlight-parser"
     
     # Print version for nice docker finish summary
     # RUN archivebox version
    -RUN /app/bin/docker_entrypoint.sh archivebox version
    +RUN echo "[√] Finished Docker build succesfully. Saving build summary in: /version_info.txt" \
    +    && uname -a | tee -a /version_info.txt \
    +    && env --chdir="$NODE_DIR" npm version | tee -a /version_info.txt \
    +    && env --chdir="$CODE_DIR" pdm info | tee -a /version_info.txt \
    +    && "$CODE_DIR/bin/docker_entrypoint.sh" archivebox version 2>&1 | tee -a /version_info.txt
    +
    +####################################################
     
     # Open up the interfaces to the outside world
    -VOLUME "$DATA_DIR"
    +VOLUME "/data"
     EXPOSE 8000
     
     # Optional:
    
    From 76f9b91ed3138613b16006f69d78e5c1c296e37f Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Fri, 20 Oct 2023 04:08:38 -0700
    Subject: [PATCH 43/89] dockerfile fixes
    
    ---
     Dockerfile                  | 54 ++++++++++++++++++++++---------------
     archivebox/core/settings.py | 13 ++++-----
     bin/build_docker.sh         |  3 ++-
     pyproject.toml              |  3 +++
     4 files changed, 44 insertions(+), 29 deletions(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index adcbc36f..db9986b7 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -49,17 +49,19 @@ ENV PATH="$PATH:$GLOBAL_VENV/bin:$APP_VENV/bin:$NODE_MODULES/.bin"
     
     
     # Create non-privileged user for archivebox and chrome
    -RUN groupadd --system $ARCHIVEBOX_USER \
    +RUN echo "[*] Setting up system environment..." \
    +    && groupadd --system $ARCHIVEBOX_USER \
         && useradd --system --create-home --gid $ARCHIVEBOX_USER --groups audio,video $ARCHIVEBOX_USER \
         && mkdir -p /etc/apt/keyrings
     
     # Install system apt dependencies (adding backports to access more recent apt updates)
    -RUN echo 'deb https://deb.debian.org/debian bullseye-backports main contrib non-free' >> /etc/apt/sources.list.d/backports.list \
    +RUN echo "[+] Installing system dependencies..." \
    +    && echo 'deb https://deb.debian.org/debian bullseye-backports main contrib non-free' >> /etc/apt/sources.list.d/backports.list \
         && apt-get update -qq \
         && apt-get install -qq -y \
             apt-transport-https ca-certificates gnupg2 curl wget \
             zlib1g-dev dumb-init gosu cron unzip \
    -        nano iputils-ping dnsutils \
    +        nano iputils-ping dnsutils htop procps \
             # 1. packaging dependencies
             # 2. docker and init system dependencies
             # 3. frivolous CLI helpers to make debugging failed archiving easier
    @@ -70,7 +72,8 @@ RUN echo 'deb https://deb.debian.org/debian bullseye-backports main contrib non-
     ######### Language Environments ####################################
     
     # Install Node environment
    -RUN echo 'deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main' >> /etc/apt/sources.list.d/nodejs.list \
    +RUN echo "[+] Installing Node environment..." \
    +    && echo 'deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main' >> /etc/apt/sources.list.d/nodejs.list \
         && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
         && apt-get update -qq \
         && apt-get install -qq -y nodejs \
    @@ -79,18 +82,21 @@ RUN echo 'deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesourc
         && npm --version
     
     # Install Python environment
    -RUN apt-get update -qq \
    +RUN echo "[+] Installing Python environment..." \
    +    && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
             python3 python3-pip python3-venv python3-setuptools python3-wheel python-dev-is-python3 \
    +        python3-ldap libldap2-dev libsasl2-dev libssl-dev \
         && rm /usr/lib/python3*/EXTERNALLY-MANAGED \
    -    && python3 -m venv $GLOBAL_VENV \
    -    && $GLOBAL_VENV/bin/pip install --upgrade pip pdm setuptools wheel \
    +    && python3 -m venv --system-site-packages --symlinks $GLOBAL_VENV \
    +    && $GLOBAL_VENV/bin/pip install --upgrade pip pdm setuptools wheel python-ldap \
         && rm -rf /var/lib/apt/lists/*
     
     ######### Extractor Dependencies ##################################
     
     # Install apt dependencies
    -RUN apt-get update -qq \
    +RUN echo "[+] Installing extractor APT dependencies..." \
    +    && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
             curl wget git yt-dlp ffmpeg ripgrep \
             # Packages we have also needed in the past:
    @@ -99,8 +105,9 @@ RUN apt-get update -qq \
         && rm -rf /var/lib/apt/lists/*
     
     # Install chromium browser using playwright
    -ENV PLAYWRIGHT_BROWSERS_PATH=/browsers
    -RUN apt-get update -qq \
    +ENV PLAYWRIGHT_BROWSERS_PATH="/browsers"
    +RUN echo "[+] Installing extractor Chromium dependency..." \
    +    && apt-get update -qq \
         && $GLOBAL_VENV/bin/pip install playwright \
         && $GLOBAL_VENV/bin/playwright install --with-deps chromium \
         && CHROME_BINARY="$($GLOBAL_VENV/bin/python -c 'from playwright.sync_api import sync_playwright; print(sync_playwright().start().chromium.executable_path)')" \
    @@ -110,21 +117,22 @@ RUN apt-get update -qq \
     
     # Install Node dependencies
     WORKDIR "$CODE_DIR"
    -ADD "package.json" "package-lock.json" "$CODE_DIR/"
    -RUN npm ci --prefer-offline --no-audit
    -RUN "$NODE_MODULES/.bin/readability-extractor" --version
    +COPY --chown=root:root --chmod=755 "package.json" "package-lock.json" "$CODE_DIR/"
    +RUN echo "[+] Installing extractor Node dependencies..." \
    +    && npm ci --prefer-offline --no-audit \
    +    && npm version
     
     ######### Build Dependencies ####################################
     
    -WORKDIR "$CODE_DIR"
    -COPY --chown=root:root . "$CODE_DIR/"
    -
    -# Install Python Build dependencies & build ArchiveBox package
    -# RUN apt-get update -qq \
    +# # Installing Python dependencies to build from source
    +# WORKDIR "$CODE_DIR"
    +# COPY --chown=root:root --chmod=755 "./pyproject.toml" "./pdm.lock" "$CODE_DIR/"
    +# RUN echo "[+] Installing project Python dependencies..." \
    +#     && apt-get update -qq \
     #     && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
     #         build-essential libssl-dev libldap2-dev libsasl2-dev \
    -#     && pdm venv create \
    -#     && pdm install --fail-fast --no-lock --group :all \
    +#     && pdm use -f $GLOBAL_VENV \
    +#     && pdm install --fail-fast --no-lock --group :all --no-self \
     #     && pdm build \
     #     && apt-get purge -y \
     #         build-essential libssl-dev libldap2-dev libsasl2-dev \
    @@ -132,14 +140,16 @@ COPY --chown=root:root . "$CODE_DIR/"
     #     && apt-get autoremove -y \
     #     && rm -rf /var/lib/apt/lists/*
     
    -
     # Install ArchiveBox Python package from source
    -RUN apt-get update -qq \
    +COPY --chown=root:root --chmod=755 "." "$CODE_DIR/"
    +RUN echo "[*] Installing ArchiveBox package from /app..." \
    +    && apt-get update -qq \
         && $GLOBAL_VENV/bin/pip install -e "$CODE_DIR"[sonic,ldap]
     
     ####################################################
     
     # Setup ArchiveBox runtime config
    +WORKDIR "$DATA_DIR"
     ENV IN_DOCKER=True \
         WGET_BINARY="wget" \
         YOUTUBEDL_BINARY="yt-dlp" \
    diff --git a/archivebox/core/settings.py b/archivebox/core/settings.py
    index 222b13e9..11fd649d 100644
    --- a/archivebox/core/settings.py
    +++ b/archivebox/core/settings.py
    @@ -99,22 +99,23 @@ if LDAP:
             from django_auth_ldap.config import LDAPSearch
     
             global AUTH_LDAP_SERVER_URI
    -        AUTH_LDAP_SERVER_URI = LDAP_SERVER_URI
    -
             global AUTH_LDAP_BIND_DN
    -        AUTH_LDAP_BIND_DN = LDAP_BIND_DN
    -
             global AUTH_LDAP_BIND_PASSWORD
    +        global AUTH_LDAP_USER_SEARCH
    +        global AUTH_LDAP_USER_ATTR_MAP
    +
    +        AUTH_LDAP_SERVER_URI = LDAP_SERVER_URI
    +        AUTH_LDAP_BIND_DN = LDAP_BIND_DN
             AUTH_LDAP_BIND_PASSWORD = LDAP_BIND_PASSWORD
     
    -        global AUTH_LDAP_USER_SEARCH
    +        assert AUTH_LDAP_SERVER_URI and LDAP_USERNAME_ATTR and LDAP_USER_FILTER, 'LDAP_* config options must all be set if LDAP=True'
    +
             AUTH_LDAP_USER_SEARCH = LDAPSearch(
                 LDAP_USER_BASE,
                 ldap.SCOPE_SUBTREE,
                 '(&(' + LDAP_USERNAME_ATTR + '=%(user)s)' + LDAP_USER_FILTER + ')',
             )
     
    -        global AUTH_LDAP_USER_ATTR_MAP
             AUTH_LDAP_USER_ATTR_MAP = {
                 'username': LDAP_USERNAME_ATTR,
                 'first_name': LDAP_FIRSTNAME_ATTR,
    diff --git a/bin/build_docker.sh b/bin/build_docker.sh
    index 1b9d32fc..65b55d0b 100755
    --- a/bin/build_docker.sh
    +++ b/bin/build_docker.sh
    @@ -65,7 +65,8 @@ check_platforms || (recreate_builder && check_platforms) || exit 1
     
     
     echo "[+] Building archivebox:$VERSION docker image..."
    -#docker build . \
    +# docker builder prune
    +# docker build . --no-cache -t archivebox-dev \
     docker buildx build --platform "$REQUIRED_PLATFORMS" --load . \
                    -t archivebox \
                    -t archivebox:$TAG_NAME \
    diff --git a/pyproject.toml b/pyproject.toml
    index 4f3135b4..aee8ac84 100644
    --- a/pyproject.toml
    +++ b/pyproject.toml
    @@ -85,9 +85,12 @@ doc = [
     
     [project.optional-dependencies]
     sonic = [
    +    # echo "deb [signed-by=/usr/share/keyrings/valeriansaliou_sonic.gpg] https://packagecloud.io/valeriansaliou/sonic/debian/ bookworm main" > /etc/apt/sources.list.d/valeriansaliou_sonic.list
    +    # curl -fsSL https://packagecloud.io/valeriansaliou/sonic/gpgkey | gpg --dearmor -o /usr/share/keyrings/valeriansaliou_sonic.gpg
         "sonic-client>=0.0.5",
     ]
     ldap = [
    +    # apt install libldap2-dev libsasl2-dev
         "django-auth-ldap>=4.1.0",
     ]
     
    
    From f3e81c1487b4609f763c269bb24d35851151312a Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Fri, 20 Oct 2023 04:09:03 -0700
    Subject: [PATCH 44/89] bump npm lockfile
    
    ---
     package-lock.json | 1951 ++++++++++++++++++++++++++-------------------
     1 file changed, 1149 insertions(+), 802 deletions(-)
    
    diff --git a/package-lock.json b/package-lock.json
    index ffc60ff5..484fc4e7 100644
    --- a/package-lock.json
    +++ b/package-lock.json
    @@ -16,7 +16,8 @@
         },
         "node_modules/@babel/runtime-corejs2": {
           "version": "7.23.2",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.23.2.tgz",
    +      "integrity": "sha512-lTwRWGcAUBANnxD0A4c5/wKQ0eLhgdAy9kdY2rzTmmliumBQ8u8awykMnaQAnZR3PC47jLRjGoj+hozZqy9Bww==",
           "dependencies": {
             "core-js": "^2.6.12",
             "regenerator-runtime": "^0.14.0"
    @@ -27,14 +28,16 @@
         },
         "node_modules/@mozilla/readability": {
           "version": "0.4.4",
    -      "license": "Apache-2.0",
    +      "resolved": "https://registry.npmjs.org/@mozilla/readability/-/readability-0.4.4.tgz",
    +      "integrity": "sha512-MCgZyANpJ6msfvVMi6+A0UAsvZj//4OHREYUB9f2087uXHVoU+H+SWhuihvb1beKpM323bReQPRio0WNk2+V6g==",
           "engines": {
             "node": ">=14.0.0"
           }
         },
         "node_modules/@postlight/ci-failed-test-reporter": {
           "version": "1.0.26",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/@postlight/ci-failed-test-reporter/-/ci-failed-test-reporter-1.0.26.tgz",
    +      "integrity": "sha512-xfXzxyOiKhco7Gx2OLTe9b66b0dFJw0elg94KGHoQXf5F8JqqFvdo35J8wayGOor64CSMvn+4Bjlu2NKV+yTGA==",
           "dependencies": {
             "dotenv": "^6.2.0",
             "node-fetch": "^2.3.0"
    @@ -45,24 +48,25 @@
         },
         "node_modules/@postlight/parser": {
           "version": "2.2.3",
    +      "resolved": "https://registry.npmjs.org/@postlight/parser/-/parser-2.2.3.tgz",
    +      "integrity": "sha512-4/syRvqJARgLN4yH8qtl634WO0+KINjkijU/SmhCJqqh8/aOfv5uQf+SquFpA+JwsAsbGzYQkIxSum29riOreg==",
           "bundleDependencies": [
             "jquery",
             "moment-timezone",
             "browser-request"
           ],
    -      "license": "MIT",
           "dependencies": {
             "@babel/runtime-corejs2": "^7.2.0",
             "@postlight/ci-failed-test-reporter": "^1.0",
    -        "browser-request": "github:postlight/browser-request#feat-add-headers-to-response",
    +        "browser-request": "*",
             "cheerio": "^0.22.0",
             "difflib": "github:postlight/difflib.js",
             "ellipsize": "0.1.0",
             "iconv-lite": "0.5.0",
    -        "jquery": "^3.5.0",
    +        "jquery": "*",
             "moment": "^2.23.0",
             "moment-parseformat": "3.0.0",
    -        "moment-timezone": "0.5.37",
    +        "moment-timezone": "*",
             "postman-request": "^2.88.1-postman.31",
             "string-direction": "^0.1.2",
             "turndown": "^7.1.1",
    @@ -127,7 +131,8 @@
         },
         "node_modules/@postman/form-data": {
           "version": "3.1.1",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/@postman/form-data/-/form-data-3.1.1.tgz",
    +      "integrity": "sha512-vjh8Q2a8S6UCm/KKs31XFJqEEgmbjBmpPNVV2eVav6905wyFAwaUOBGA1NPBI4ERH9MMZc6w0umFgM6WbEPMdg==",
           "dependencies": {
             "asynckit": "^0.4.0",
             "combined-stream": "^1.0.8",
    @@ -139,7 +144,8 @@
         },
         "node_modules/@postman/tough-cookie": {
           "version": "4.1.3-postman.1",
    -      "license": "BSD-3-Clause",
    +      "resolved": "https://registry.npmjs.org/@postman/tough-cookie/-/tough-cookie-4.1.3-postman.1.tgz",
    +      "integrity": "sha512-txpgUqZOnWYnUHZpHjkfb0IwVH4qJmyq77pPnJLlfhMtdCLMFTEeQHlzQiK906aaNCe4NEB5fGJHo9uzGbFMeA==",
           "dependencies": {
             "psl": "^1.1.33",
             "punycode": "^2.1.1",
    @@ -152,7 +158,8 @@
         },
         "node_modules/@postman/tunnel-agent": {
           "version": "0.6.3",
    -      "license": "Apache-2.0",
    +      "resolved": "https://registry.npmjs.org/@postman/tunnel-agent/-/tunnel-agent-0.6.3.tgz",
    +      "integrity": "sha512-k57fzmAZ2PJGxfOA4SGR05ejorHbVAa/84Hxh/2nAztjNXc4ZjOm9NUIk6/Z6LCrBvJZqjRZbN8e/nROVUPVdg==",
           "dependencies": {
             "safe-buffer": "^5.0.1"
           },
    @@ -162,7 +169,8 @@
         },
         "node_modules/@puppeteer/browsers": {
           "version": "1.7.1",
    -      "license": "Apache-2.0",
    +      "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-1.7.1.tgz",
    +      "integrity": "sha512-nIb8SOBgDEMFY2iS2MdnUZOg2ikcYchRrBoF+wtdjieRFKR2uGRipHY/oFLo+2N6anDualyClPzGywTHRGrLfw==",
           "dependencies": {
             "debug": "4.3.4",
             "extract-zip": "2.0.1",
    @@ -181,7 +189,8 @@
         },
         "node_modules/@puppeteer/browsers/node_modules/yargs": {
           "version": "17.7.1",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz",
    +      "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==",
           "dependencies": {
             "cliui": "^8.0.1",
             "escalade": "^3.1.1",
    @@ -197,25 +206,29 @@
         },
         "node_modules/@puppeteer/browsers/node_modules/yargs-parser": {
           "version": "21.1.1",
    -      "license": "ISC",
    +      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
    +      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
           "engines": {
             "node": ">=12"
           }
         },
         "node_modules/@tootallnate/once": {
           "version": "2.0.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
    +      "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
           "engines": {
             "node": ">= 10"
           }
         },
         "node_modules/@tootallnate/quickjs-emscripten": {
           "version": "0.23.0",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",
    +      "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="
         },
         "node_modules/@types/node": {
           "version": "20.8.7",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.7.tgz",
    +      "integrity": "sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==",
           "optional": true,
           "dependencies": {
             "undici-types": "~5.25.1"
    @@ -223,7 +236,8 @@
         },
         "node_modules/@types/yauzl": {
           "version": "2.10.2",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.2.tgz",
    +      "integrity": "sha512-Km7XAtUIduROw7QPgvcft0lIupeG8a8rdKL8RiSyKvlE7dYY31fEn41HVuQsRFDuROA8tA4K2UVL+WdfFmErBA==",
           "optional": true,
           "dependencies": {
             "@types/node": "*"
    @@ -231,11 +245,41 @@
         },
         "node_modules/abab": {
           "version": "2.0.6",
    -      "license": "BSD-3-Clause"
    +      "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz",
    +      "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA=="
    +    },
    +    "node_modules/acorn": {
    +      "version": "8.10.0",
    +      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
    +      "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
    +      "bin": {
    +        "acorn": "bin/acorn"
    +      },
    +      "engines": {
    +        "node": ">=0.4.0"
    +      }
    +    },
    +    "node_modules/acorn-globals": {
    +      "version": "7.0.1",
    +      "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz",
    +      "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==",
    +      "dependencies": {
    +        "acorn": "^8.1.0",
    +        "acorn-walk": "^8.0.2"
    +      }
    +    },
    +    "node_modules/acorn-walk": {
    +      "version": "8.2.0",
    +      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
    +      "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
    +      "engines": {
    +        "node": ">=0.4.0"
    +      }
         },
         "node_modules/agent-base": {
           "version": "6.0.2",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
    +      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
           "dependencies": {
             "debug": "4"
           },
    @@ -245,7 +289,8 @@
         },
         "node_modules/ajv": {
           "version": "6.12.6",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
    +      "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
           "dependencies": {
             "fast-deep-equal": "^3.1.1",
             "fast-json-stable-stringify": "^2.0.0",
    @@ -259,14 +304,16 @@
         },
         "node_modules/ansi-regex": {
           "version": "5.0.1",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
    +      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
           "engines": {
             "node": ">=8"
           }
         },
         "node_modules/ansi-styles": {
           "version": "4.3.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
    +      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
           "dependencies": {
             "color-convert": "^2.0.1"
           },
    @@ -279,21 +326,24 @@
         },
         "node_modules/asn1": {
           "version": "0.2.6",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
    +      "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
           "dependencies": {
             "safer-buffer": "~2.1.0"
           }
         },
         "node_modules/assert-plus": {
           "version": "1.0.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
    +      "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
           "engines": {
             "node": ">=0.8"
           }
         },
         "node_modules/ast-types": {
           "version": "0.13.4",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz",
    +      "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==",
           "dependencies": {
             "tslib": "^2.0.1"
           },
    @@ -303,29 +353,36 @@
         },
         "node_modules/asynckit": {
           "version": "0.4.0",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
    +      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
         },
         "node_modules/aws-sign2": {
           "version": "0.7.0",
    -      "license": "Apache-2.0",
    +      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
    +      "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==",
           "engines": {
             "node": "*"
           }
         },
         "node_modules/aws4": {
           "version": "1.12.0",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz",
    +      "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg=="
         },
         "node_modules/b4a": {
           "version": "1.6.4",
    -      "license": "ISC"
    +      "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz",
    +      "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw=="
         },
         "node_modules/balanced-match": {
           "version": "1.0.2",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
    +      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
         },
         "node_modules/base64-js": {
           "version": "1.5.1",
    +      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
    +      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
           "funding": [
             {
               "type": "github",
    @@ -339,34 +396,38 @@
               "type": "consulting",
               "url": "https://feross.org/support"
             }
    -      ],
    -      "license": "MIT"
    +      ]
         },
         "node_modules/basic-ftp": {
           "version": "5.0.3",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.3.tgz",
    +      "integrity": "sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==",
           "engines": {
             "node": ">=10.0.0"
           }
         },
         "node_modules/bcrypt-pbkdf": {
           "version": "1.0.2",
    -      "license": "BSD-3-Clause",
    +      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
    +      "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
           "dependencies": {
             "tweetnacl": "^0.14.3"
           }
         },
         "node_modules/bluebird": {
           "version": "2.11.0",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
    +      "integrity": "sha512-UfFSr22dmHPQqPP9XWHRhq+gWnHCYguQGkXQlbyPtW5qTnhFWA8/iXg765tH0cAjy7l/zPJ1aBTO0g5XgA7kvQ=="
         },
         "node_modules/boolbase": {
           "version": "1.0.0",
    -      "license": "ISC"
    +      "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
    +      "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
         },
         "node_modules/brace-expansion": {
           "version": "1.1.11",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
    +      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
           "dependencies": {
             "balanced-match": "^1.0.0",
             "concat-map": "0.0.1"
    @@ -374,13 +435,16 @@
         },
         "node_modules/brotli": {
           "version": "1.3.3",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/brotli/-/brotli-1.3.3.tgz",
    +      "integrity": "sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg==",
           "dependencies": {
             "base64-js": "^1.1.2"
           }
         },
         "node_modules/buffer": {
           "version": "5.7.1",
    +      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
    +      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
           "funding": [
             {
               "type": "github",
    @@ -395,7 +459,6 @@
               "url": "https://feross.org/support"
             }
           ],
    -      "license": "MIT",
           "dependencies": {
             "base64-js": "^1.3.1",
             "ieee754": "^1.1.13"
    @@ -403,25 +466,29 @@
         },
         "node_modules/buffer-crc32": {
           "version": "0.2.13",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
    +      "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
           "engines": {
             "node": "*"
           }
         },
         "node_modules/camelcase": {
           "version": "5.3.1",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
    +      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
           "engines": {
             "node": ">=6"
           }
         },
         "node_modules/caseless": {
           "version": "0.12.0",
    -      "license": "Apache-2.0"
    +      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
    +      "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
         },
         "node_modules/cheerio": {
           "version": "0.22.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz",
    +      "integrity": "sha512-8/MzidM6G/TgRelkzDG13y3Y9LxBjCb+8yOEZ9+wwq5gVF2w2pV0wmHvjfT0RvuxGyR7UEuK36r+yYMbT4uKgA==",
           "dependencies": {
             "css-select": "~1.2.0",
             "dom-serializer": "~0.1.0",
    @@ -446,7 +513,8 @@
         },
         "node_modules/chromium-bidi": {
           "version": "0.4.26",
    -      "license": "Apache-2.0",
    +      "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.26.tgz",
    +      "integrity": "sha512-lukBGfogAI4T0y3acc86RaacqgKQve47/8pV2c+Hr1PjcICj2K4OkL3qfX3qrqxxnd4ddurFC0WBA3VCQqYeUQ==",
           "dependencies": {
             "mitt": "3.0.1"
           },
    @@ -456,7 +524,8 @@
         },
         "node_modules/cliui": {
           "version": "8.0.1",
    -      "license": "ISC",
    +      "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
    +      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
           "dependencies": {
             "string-width": "^4.2.0",
             "strip-ansi": "^6.0.1",
    @@ -468,7 +537,8 @@
         },
         "node_modules/color-convert": {
           "version": "2.0.1",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
    +      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
           "dependencies": {
             "color-name": "~1.1.4"
           },
    @@ -478,11 +548,13 @@
         },
         "node_modules/color-name": {
           "version": "1.1.4",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
    +      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
         },
         "node_modules/combined-stream": {
           "version": "1.0.8",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
    +      "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
           "dependencies": {
             "delayed-stream": "~1.0.0"
           },
    @@ -492,27 +564,33 @@
         },
         "node_modules/concat-map": {
           "version": "0.0.1",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
    +      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
         },
         "node_modules/core-js": {
           "version": "2.6.12",
    -      "hasInstallScript": true,
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz",
    +      "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==",
    +      "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.",
    +      "hasInstallScript": true
         },
         "node_modules/core-util-is": {
           "version": "1.0.2",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
    +      "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="
         },
         "node_modules/cross-fetch": {
           "version": "4.0.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz",
    +      "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==",
           "dependencies": {
             "node-fetch": "^2.6.12"
           }
         },
         "node_modules/css-select": {
           "version": "1.2.0",
    -      "license": "BSD-like",
    +      "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
    +      "integrity": "sha512-dUQOBoqdR7QwV90WysXPLXG5LO7nhYBgiWVfxF80DKPF8zx1t/pUd2FYy73emg3zrjtM6dzmYgbHKfV2rxiHQA==",
           "dependencies": {
             "boolbase": "~1.0.0",
             "css-what": "2.1",
    @@ -522,14 +600,16 @@
         },
         "node_modules/css-what": {
           "version": "2.1.3",
    -      "license": "BSD-2-Clause",
    +      "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
    +      "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==",
           "engines": {
             "node": "*"
           }
         },
         "node_modules/cssstyle": {
           "version": "3.0.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-3.0.0.tgz",
    +      "integrity": "sha512-N4u2ABATi3Qplzf0hWbVCdjenim8F3ojEXpBDF5hBpjzW182MjNGLqfmQ0SkSPeQ+V86ZXgeH8aXj6kayd4jgg==",
           "dependencies": {
             "rrweb-cssom": "^0.6.0"
           },
    @@ -539,7 +619,8 @@
         },
         "node_modules/dashdash": {
           "version": "1.14.1",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
    +      "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
           "dependencies": {
             "assert-plus": "^1.0.0"
           },
    @@ -549,14 +630,16 @@
         },
         "node_modules/data-uri-to-buffer": {
           "version": "6.0.1",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.1.tgz",
    +      "integrity": "sha512-MZd3VlchQkp8rdend6vrx7MmVDJzSNTBvghvKjirLkD+WTChA3KUf0jkE68Q4UyctNqI11zZO9/x2Yx+ub5Cvg==",
           "engines": {
             "node": ">= 14"
           }
         },
         "node_modules/data-urls": {
           "version": "4.0.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-4.0.0.tgz",
    +      "integrity": "sha512-/mMTei/JXPqvFqQtfyTowxmJVwr2PVAeCcDxyFf6LhoOu/09TX2OX3kb2wzi4DMXcfj4OItwDOnhl5oziPnT6g==",
           "dependencies": {
             "abab": "^2.0.6",
             "whatwg-mimetype": "^3.0.0",
    @@ -568,7 +651,8 @@
         },
         "node_modules/data-urls/node_modules/tr46": {
           "version": "4.1.1",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz",
    +      "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==",
           "dependencies": {
             "punycode": "^2.3.0"
           },
    @@ -578,7 +662,8 @@
         },
         "node_modules/data-urls/node_modules/whatwg-url": {
           "version": "12.0.1",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz",
    +      "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==",
           "dependencies": {
             "tr46": "^4.1.1",
             "webidl-conversions": "^7.0.0"
    @@ -589,7 +674,8 @@
         },
         "node_modules/debug": {
           "version": "4.3.4",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
    +      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
           "dependencies": {
             "ms": "2.1.2"
           },
    @@ -604,18 +690,21 @@
         },
         "node_modules/decamelize": {
           "version": "1.2.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
    +      "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
           "engines": {
             "node": ">=0.10.0"
           }
         },
         "node_modules/decimal.js": {
           "version": "10.4.3",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz",
    +      "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA=="
         },
         "node_modules/degenerator": {
           "version": "5.0.1",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",
    +      "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==",
           "dependencies": {
             "ast-types": "^0.13.4",
             "escodegen": "^2.1.0",
    @@ -627,14 +716,16 @@
         },
         "node_modules/delayed-stream": {
           "version": "1.0.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
    +      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
           "engines": {
             "node": ">=0.4.0"
           }
         },
         "node_modules/devtools-protocol": {
           "version": "0.0.1159816",
    -      "license": "BSD-3-Clause"
    +      "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1159816.tgz",
    +      "integrity": "sha512-2cZlHxC5IlgkIWe2pSDmCrDiTzbSJWywjbDDnupOImEBcG31CQgBLV8wWE+5t+C4rimcjHsbzy7CBzf9oFjboA=="
         },
         "node_modules/difflib": {
           "version": "0.2.6",
    @@ -645,7 +736,8 @@
         },
         "node_modules/dom-serializer": {
           "version": "0.1.1",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
    +      "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
           "dependencies": {
             "domelementtype": "^1.3.0",
             "entities": "^1.1.1"
    @@ -653,11 +745,13 @@
         },
         "node_modules/domelementtype": {
           "version": "1.3.1",
    -      "license": "BSD-2-Clause"
    +      "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
    +      "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
         },
         "node_modules/domexception": {
           "version": "4.0.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz",
    +      "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==",
           "dependencies": {
             "webidl-conversions": "^7.0.0"
           },
    @@ -667,22 +761,26 @@
         },
         "node_modules/domhandler": {
           "version": "2.4.2",
    -      "license": "BSD-2-Clause",
    +      "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
    +      "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
           "dependencies": {
             "domelementtype": "1"
           }
         },
         "node_modules/domino": {
           "version": "2.1.6",
    -      "license": "BSD-2-Clause"
    +      "resolved": "https://registry.npmjs.org/domino/-/domino-2.1.6.tgz",
    +      "integrity": "sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ=="
         },
         "node_modules/dompurify": {
    -      "version": "3.0.6",
    -      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-3.0.6.tgz",
    -      "integrity": "sha512-ilkD8YEnnGh1zJ240uJsW7AzE+2qpbOUYjacomn3AvJ6J4JhKGSZ2nh4wUIXPZrEPppaCLx5jFe8T89Rk8tQ7w=="
    +      "version": "2.4.7",
    +      "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.7.tgz",
    +      "integrity": "sha512-kxxKlPEDa6Nc5WJi+qRgPbOAbgTpSULL+vI3NUXsZMlkJxTqYI9wg5ZTay2sFrdZRWHPWNi+EdAhcJf81WtoMQ=="
         },
         "node_modules/domutils": {
           "version": "1.5.1",
    +      "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
    +      "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==",
           "dependencies": {
             "dom-serializer": "0",
             "domelementtype": "1"
    @@ -690,14 +788,16 @@
         },
         "node_modules/dotenv": {
           "version": "6.2.0",
    -      "license": "BSD-2-Clause",
    +      "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz",
    +      "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==",
           "engines": {
             "node": ">=6"
           }
         },
         "node_modules/ecc-jsbn": {
           "version": "0.1.2",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
    +      "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
           "dependencies": {
             "jsbn": "~0.1.0",
             "safer-buffer": "^2.1.0"
    @@ -705,33 +805,39 @@
         },
         "node_modules/ellipsize": {
           "version": "0.1.0",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/ellipsize/-/ellipsize-0.1.0.tgz",
    +      "integrity": "sha512-5gxbEjcb/Z2n6TTmXZx9wVi3N/DOzE7RXY3Xg9dakDuhX/izwumB9rGjeWUV6dTA0D0+juvo+JonZgNR9sgA5A=="
         },
         "node_modules/emoji-regex": {
           "version": "8.0.0",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
    +      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
         },
         "node_modules/end-of-stream": {
           "version": "1.4.4",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
    +      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
           "dependencies": {
             "once": "^1.4.0"
           }
         },
         "node_modules/entities": {
           "version": "1.1.2",
    -      "license": "BSD-2-Clause"
    +      "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
    +      "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
         },
         "node_modules/escalade": {
           "version": "3.1.1",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
    +      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
           "engines": {
             "node": ">=6"
           }
         },
         "node_modules/escodegen": {
           "version": "2.1.0",
    -      "license": "BSD-2-Clause",
    +      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
    +      "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
           "dependencies": {
             "esprima": "^4.0.1",
             "estraverse": "^5.2.0",
    @@ -750,7 +856,8 @@
         },
         "node_modules/esprima": {
           "version": "4.0.1",
    -      "license": "BSD-2-Clause",
    +      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
    +      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
           "bin": {
             "esparse": "bin/esparse.js",
             "esvalidate": "bin/esvalidate.js"
    @@ -761,25 +868,29 @@
         },
         "node_modules/estraverse": {
           "version": "5.3.0",
    -      "license": "BSD-2-Clause",
    +      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
    +      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
           "engines": {
             "node": ">=4.0"
           }
         },
         "node_modules/esutils": {
           "version": "2.0.3",
    -      "license": "BSD-2-Clause",
    +      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
    +      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
           "engines": {
             "node": ">=0.10.0"
           }
         },
         "node_modules/extend": {
           "version": "3.0.2",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
    +      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
         },
         "node_modules/extract-zip": {
           "version": "2.0.1",
    -      "license": "BSD-2-Clause",
    +      "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz",
    +      "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==",
           "dependencies": {
             "debug": "^4.1.1",
             "get-stream": "^5.1.0",
    @@ -797,47 +908,55 @@
         },
         "node_modules/extsprintf": {
           "version": "1.3.0",
    +      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
    +      "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==",
           "engines": [
             "node >=0.6.0"
    -      ],
    -      "license": "MIT"
    +      ]
         },
         "node_modules/fast-deep-equal": {
           "version": "3.1.3",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
    +      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
         },
         "node_modules/fast-fifo": {
           "version": "1.3.2",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
    +      "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ=="
         },
         "node_modules/fast-json-stable-stringify": {
           "version": "2.1.0",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
    +      "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
         },
         "node_modules/fd-slicer": {
           "version": "1.1.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
    +      "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
           "dependencies": {
             "pend": "~1.2.0"
           }
         },
         "node_modules/file-url": {
           "version": "3.0.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/file-url/-/file-url-3.0.0.tgz",
    +      "integrity": "sha512-g872QGsHexznxkIAdK8UiZRe7SkE6kvylShU4Nsj8NvfvZag7S0QuQ4IgvPDkk75HxgjIVDwycFTDAgIiO4nDA==",
           "engines": {
             "node": ">=8"
           }
         },
         "node_modules/forever-agent": {
           "version": "0.6.1",
    -      "license": "Apache-2.0",
    +      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
    +      "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==",
           "engines": {
             "node": "*"
           }
         },
         "node_modules/form-data": {
           "version": "4.0.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
    +      "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
           "dependencies": {
             "asynckit": "^0.4.0",
             "combined-stream": "^1.0.8",
    @@ -849,7 +968,8 @@
         },
         "node_modules/fs-extra": {
           "version": "8.1.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
    +      "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
           "dependencies": {
             "graceful-fs": "^4.2.0",
             "jsonfile": "^4.0.0",
    @@ -861,25 +981,29 @@
         },
         "node_modules/fs-extra/node_modules/universalify": {
           "version": "0.1.2",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
    +      "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==",
           "engines": {
             "node": ">= 4.0.0"
           }
         },
         "node_modules/fs.realpath": {
           "version": "1.0.0",
    -      "license": "ISC"
    +      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
    +      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
         },
         "node_modules/get-caller-file": {
           "version": "2.0.5",
    -      "license": "ISC",
    +      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
    +      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
           "engines": {
             "node": "6.* || 8.* || >= 10.*"
           }
         },
         "node_modules/get-stream": {
           "version": "5.2.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
    +      "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
           "dependencies": {
             "pump": "^3.0.0"
           },
    @@ -892,7 +1016,8 @@
         },
         "node_modules/get-uri": {
           "version": "6.0.2",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.2.tgz",
    +      "integrity": "sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==",
           "dependencies": {
             "basic-ftp": "^5.0.2",
             "data-uri-to-buffer": "^6.0.0",
    @@ -905,14 +1030,16 @@
         },
         "node_modules/getpass": {
           "version": "0.1.7",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
    +      "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
           "dependencies": {
             "assert-plus": "^1.0.0"
           }
         },
         "node_modules/glob": {
           "version": "7.2.3",
    -      "license": "ISC",
    +      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
    +      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
           "dependencies": {
             "fs.realpath": "^1.0.0",
             "inflight": "^1.0.4",
    @@ -930,18 +1057,22 @@
         },
         "node_modules/graceful-fs": {
           "version": "4.2.11",
    -      "license": "ISC"
    +      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
    +      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
         },
         "node_modules/har-schema": {
           "version": "2.0.0",
    -      "license": "ISC",
    +      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
    +      "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==",
           "engines": {
             "node": ">=4"
           }
         },
         "node_modules/har-validator": {
           "version": "5.1.5",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
    +      "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
    +      "deprecated": "this library is no longer supported",
           "dependencies": {
             "ajv": "^6.12.3",
             "har-schema": "^2.0.0"
    @@ -952,11 +1083,13 @@
         },
         "node_modules/heap": {
           "version": "0.2.7",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz",
    +      "integrity": "sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg=="
         },
         "node_modules/html-encoding-sniffer": {
           "version": "3.0.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
    +      "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
           "dependencies": {
             "whatwg-encoding": "^2.0.0"
           },
    @@ -966,7 +1099,8 @@
         },
         "node_modules/htmlparser2": {
           "version": "3.10.1",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
    +      "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
           "dependencies": {
             "domelementtype": "^1.3.1",
             "domhandler": "^2.3.0",
    @@ -978,7 +1112,8 @@
         },
         "node_modules/http-proxy-agent": {
           "version": "5.0.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
    +      "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
           "dependencies": {
             "@tootallnate/once": "2",
             "agent-base": "6",
    @@ -990,7 +1125,8 @@
         },
         "node_modules/http-signature": {
           "version": "1.3.6",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz",
    +      "integrity": "sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==",
           "dependencies": {
             "assert-plus": "^1.0.0",
             "jsprim": "^2.0.2",
    @@ -1002,7 +1138,8 @@
         },
         "node_modules/https-proxy-agent": {
           "version": "5.0.1",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
    +      "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
           "dependencies": {
             "agent-base": "6",
             "debug": "4"
    @@ -1013,7 +1150,8 @@
         },
         "node_modules/iconv-lite": {
           "version": "0.5.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.0.tgz",
    +      "integrity": "sha512-NnEhI9hIEKHOzJ4f697DMz9IQEXr/MMJ5w64vN2/4Ai+wRnvV7SBrL0KLoRlwaKVghOc7LQ5YkPLuX146b6Ydw==",
           "dependencies": {
             "safer-buffer": ">= 2.1.2 < 3"
           },
    @@ -1023,6 +1161,8 @@
         },
         "node_modules/ieee754": {
           "version": "1.2.1",
    +      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
    +      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
           "funding": [
             {
               "type": "github",
    @@ -1036,16 +1176,17 @@
               "type": "consulting",
               "url": "https://feross.org/support"
             }
    -      ],
    -      "license": "BSD-3-Clause"
    +      ]
         },
         "node_modules/immediate": {
           "version": "3.0.6",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
    +      "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
         },
         "node_modules/inflight": {
           "version": "1.0.6",
    -      "license": "ISC",
    +      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
    +      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
           "dependencies": {
             "once": "^1.3.0",
             "wrappy": "1"
    @@ -1053,40 +1194,812 @@
         },
         "node_modules/inherits": {
           "version": "2.0.4",
    -      "license": "ISC"
    +      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
    +      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
         },
         "node_modules/ip": {
           "version": "1.1.8",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz",
    +      "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg=="
         },
         "node_modules/is-fullwidth-code-point": {
           "version": "3.0.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
    +      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
           "engines": {
             "node": ">=8"
           }
         },
         "node_modules/is-potential-custom-element-name": {
           "version": "1.0.1",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
    +      "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="
         },
         "node_modules/is-typedarray": {
           "version": "1.0.0",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
    +      "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
         },
         "node_modules/isarray": {
           "version": "1.0.0",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
    +      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
         },
         "node_modules/isstream": {
           "version": "0.1.2",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
    +      "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
         },
         "node_modules/jsbn": {
           "version": "0.1.1",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
    +      "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg=="
         },
         "node_modules/jsdom": {
    +      "version": "21.1.2",
    +      "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-21.1.2.tgz",
    +      "integrity": "sha512-sCpFmK2jv+1sjff4u7fzft+pUh2KSUbUrEHYHyfSIbGTIcmnjyp83qg6qLwdJ/I3LpTXx33ACxeRL7Lsyc6lGQ==",
    +      "dependencies": {
    +        "abab": "^2.0.6",
    +        "acorn": "^8.8.2",
    +        "acorn-globals": "^7.0.0",
    +        "cssstyle": "^3.0.0",
    +        "data-urls": "^4.0.0",
    +        "decimal.js": "^10.4.3",
    +        "domexception": "^4.0.0",
    +        "escodegen": "^2.0.0",
    +        "form-data": "^4.0.0",
    +        "html-encoding-sniffer": "^3.0.0",
    +        "http-proxy-agent": "^5.0.0",
    +        "https-proxy-agent": "^5.0.1",
    +        "is-potential-custom-element-name": "^1.0.1",
    +        "nwsapi": "^2.2.4",
    +        "parse5": "^7.1.2",
    +        "rrweb-cssom": "^0.6.0",
    +        "saxes": "^6.0.0",
    +        "symbol-tree": "^3.2.4",
    +        "tough-cookie": "^4.1.2",
    +        "w3c-xmlserializer": "^4.0.0",
    +        "webidl-conversions": "^7.0.0",
    +        "whatwg-encoding": "^2.0.0",
    +        "whatwg-mimetype": "^3.0.0",
    +        "whatwg-url": "^12.0.1",
    +        "ws": "^8.13.0",
    +        "xml-name-validator": "^4.0.0"
    +      },
    +      "engines": {
    +        "node": ">=14"
    +      },
    +      "peerDependencies": {
    +        "canvas": "^2.5.0"
    +      },
    +      "peerDependenciesMeta": {
    +        "canvas": {
    +          "optional": true
    +        }
    +      }
    +    },
    +    "node_modules/jsdom/node_modules/tr46": {
    +      "version": "4.1.1",
    +      "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz",
    +      "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==",
    +      "dependencies": {
    +        "punycode": "^2.3.0"
    +      },
    +      "engines": {
    +        "node": ">=14"
    +      }
    +    },
    +    "node_modules/jsdom/node_modules/whatwg-url": {
    +      "version": "12.0.1",
    +      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz",
    +      "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==",
    +      "dependencies": {
    +        "tr46": "^4.1.1",
    +        "webidl-conversions": "^7.0.0"
    +      },
    +      "engines": {
    +        "node": ">=14"
    +      }
    +    },
    +    "node_modules/json-schema": {
    +      "version": "0.4.0",
    +      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
    +      "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
    +    },
    +    "node_modules/json-schema-traverse": {
    +      "version": "0.4.1",
    +      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
    +      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
    +    },
    +    "node_modules/json-stringify-safe": {
    +      "version": "5.0.1",
    +      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
    +      "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
    +    },
    +    "node_modules/jsonfile": {
    +      "version": "4.0.0",
    +      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
    +      "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
    +      "optionalDependencies": {
    +        "graceful-fs": "^4.1.6"
    +      }
    +    },
    +    "node_modules/jsprim": {
    +      "version": "2.0.2",
    +      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz",
    +      "integrity": "sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==",
    +      "engines": [
    +        "node >=0.6.0"
    +      ],
    +      "dependencies": {
    +        "assert-plus": "1.0.0",
    +        "extsprintf": "1.3.0",
    +        "json-schema": "0.4.0",
    +        "verror": "1.10.0"
    +      }
    +    },
    +    "node_modules/jszip": {
    +      "version": "3.10.1",
    +      "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
    +      "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
    +      "dependencies": {
    +        "lie": "~3.3.0",
    +        "pako": "~1.0.2",
    +        "readable-stream": "~2.3.6",
    +        "setimmediate": "^1.0.5"
    +      }
    +    },
    +    "node_modules/jszip/node_modules/readable-stream": {
    +      "version": "2.3.8",
    +      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
    +      "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
    +      "dependencies": {
    +        "core-util-is": "~1.0.0",
    +        "inherits": "~2.0.3",
    +        "isarray": "~1.0.0",
    +        "process-nextick-args": "~2.0.0",
    +        "safe-buffer": "~5.1.1",
    +        "string_decoder": "~1.1.1",
    +        "util-deprecate": "~1.0.1"
    +      }
    +    },
    +    "node_modules/jszip/node_modules/safe-buffer": {
    +      "version": "5.1.2",
    +      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
    +      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
    +    },
    +    "node_modules/jszip/node_modules/string_decoder": {
    +      "version": "1.1.1",
    +      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
    +      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
    +      "dependencies": {
    +        "safe-buffer": "~5.1.0"
    +      }
    +    },
    +    "node_modules/lie": {
    +      "version": "3.3.0",
    +      "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
    +      "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
    +      "dependencies": {
    +        "immediate": "~3.0.5"
    +      }
    +    },
    +    "node_modules/lodash": {
    +      "version": "4.17.21",
    +      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
    +      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
    +    },
    +    "node_modules/lodash.assignin": {
    +      "version": "4.2.0",
    +      "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz",
    +      "integrity": "sha512-yX/rx6d/UTVh7sSVWVSIMjfnz95evAgDFdb1ZozC35I9mSFCkmzptOzevxjgbQUsc78NR44LVHWjsoMQXy9FDg=="
    +    },
    +    "node_modules/lodash.bind": {
    +      "version": "4.2.1",
    +      "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz",
    +      "integrity": "sha512-lxdsn7xxlCymgLYo1gGvVrfHmkjDiyqVv62FAeF2i5ta72BipE1SLxw8hPEPLhD4/247Ijw07UQH7Hq/chT5LA=="
    +    },
    +    "node_modules/lodash.defaults": {
    +      "version": "4.2.0",
    +      "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz",
    +      "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ=="
    +    },
    +    "node_modules/lodash.filter": {
    +      "version": "4.6.0",
    +      "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz",
    +      "integrity": "sha512-pXYUy7PR8BCLwX5mgJ/aNtyOvuJTdZAo9EQFUvMIYugqmJxnrYaANvTbgndOzHSCSR0wnlBBfRXJL5SbWxo3FQ=="
    +    },
    +    "node_modules/lodash.flatten": {
    +      "version": "4.4.0",
    +      "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
    +      "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g=="
    +    },
    +    "node_modules/lodash.foreach": {
    +      "version": "4.5.0",
    +      "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-4.5.0.tgz",
    +      "integrity": "sha512-aEXTF4d+m05rVOAUG3z4vZZ4xVexLKZGF0lIxuHZ1Hplpk/3B6Z1+/ICICYRLm7c41Z2xiejbkCkJoTlypoXhQ=="
    +    },
    +    "node_modules/lodash.map": {
    +      "version": "4.6.0",
    +      "resolved": "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz",
    +      "integrity": "sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q=="
    +    },
    +    "node_modules/lodash.merge": {
    +      "version": "4.6.2",
    +      "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
    +      "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
    +    },
    +    "node_modules/lodash.pick": {
    +      "version": "4.4.0",
    +      "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz",
    +      "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q=="
    +    },
    +    "node_modules/lodash.reduce": {
    +      "version": "4.6.0",
    +      "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz",
    +      "integrity": "sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw=="
    +    },
    +    "node_modules/lodash.reject": {
    +      "version": "4.6.0",
    +      "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz",
    +      "integrity": "sha512-qkTuvgEzYdyhiJBx42YPzPo71R1aEr0z79kAv7Ixg8wPFEjgRgJdUsGMG3Hf3OYSF/kHI79XhNlt+5Ar6OzwxQ=="
    +    },
    +    "node_modules/lodash.some": {
    +      "version": "4.6.0",
    +      "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz",
    +      "integrity": "sha512-j7MJE+TuT51q9ggt4fSgVqro163BEFjAt3u97IqU+JA2DkWl80nFTrowzLpZ/BnpN7rrl0JA/593NAdd8p/scQ=="
    +    },
    +    "node_modules/lru-cache": {
    +      "version": "7.18.3",
    +      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
    +      "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
    +      "engines": {
    +        "node": ">=12"
    +      }
    +    },
    +    "node_modules/mime-db": {
    +      "version": "1.52.0",
    +      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
    +      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
    +      "engines": {
    +        "node": ">= 0.6"
    +      }
    +    },
    +    "node_modules/mime-types": {
    +      "version": "2.1.35",
    +      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
    +      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
    +      "dependencies": {
    +        "mime-db": "1.52.0"
    +      },
    +      "engines": {
    +        "node": ">= 0.6"
    +      }
    +    },
    +    "node_modules/minimatch": {
    +      "version": "3.1.2",
    +      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
    +      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
    +      "dependencies": {
    +        "brace-expansion": "^1.1.7"
    +      },
    +      "engines": {
    +        "node": "*"
    +      }
    +    },
    +    "node_modules/mitt": {
    +      "version": "3.0.1",
    +      "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
    +      "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="
    +    },
    +    "node_modules/mkdirp-classic": {
    +      "version": "0.5.3",
    +      "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
    +      "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
    +    },
    +    "node_modules/moment-parseformat": {
    +      "version": "3.0.0",
    +      "resolved": "https://registry.npmjs.org/moment-parseformat/-/moment-parseformat-3.0.0.tgz",
    +      "integrity": "sha512-dVgXe6b6DLnv4CHG7a1zUe5mSXaIZ3c6lSHm/EKeVeQI2/4pwe0VRde8OyoCE1Ro2lKT5P6uT9JElF7KDLV+jw=="
    +    },
    +    "node_modules/ms": {
    +      "version": "2.1.2",
    +      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
    +      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
    +    },
    +    "node_modules/netmask": {
    +      "version": "2.0.2",
    +      "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz",
    +      "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==",
    +      "engines": {
    +        "node": ">= 0.4.0"
    +      }
    +    },
    +    "node_modules/node-fetch": {
    +      "version": "2.7.0",
    +      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
    +      "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
    +      "dependencies": {
    +        "whatwg-url": "^5.0.0"
    +      },
    +      "engines": {
    +        "node": "4.x || >=6.0.0"
    +      },
    +      "peerDependencies": {
    +        "encoding": "^0.1.0"
    +      },
    +      "peerDependenciesMeta": {
    +        "encoding": {
    +          "optional": true
    +        }
    +      }
    +    },
    +    "node_modules/nth-check": {
    +      "version": "1.0.2",
    +      "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
    +      "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
    +      "dependencies": {
    +        "boolbase": "~1.0.0"
    +      }
    +    },
    +    "node_modules/nwsapi": {
    +      "version": "2.2.7",
    +      "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.7.tgz",
    +      "integrity": "sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ=="
    +    },
    +    "node_modules/oauth-sign": {
    +      "version": "0.9.0",
    +      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
    +      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
    +      "engines": {
    +        "node": "*"
    +      }
    +    },
    +    "node_modules/once": {
    +      "version": "1.4.0",
    +      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
    +      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
    +      "dependencies": {
    +        "wrappy": "1"
    +      }
    +    },
    +    "node_modules/pac-proxy-agent": {
    +      "version": "7.0.1",
    +      "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz",
    +      "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==",
    +      "dependencies": {
    +        "@tootallnate/quickjs-emscripten": "^0.23.0",
    +        "agent-base": "^7.0.2",
    +        "debug": "^4.3.4",
    +        "get-uri": "^6.0.1",
    +        "http-proxy-agent": "^7.0.0",
    +        "https-proxy-agent": "^7.0.2",
    +        "pac-resolver": "^7.0.0",
    +        "socks-proxy-agent": "^8.0.2"
    +      },
    +      "engines": {
    +        "node": ">= 14"
    +      }
    +    },
    +    "node_modules/pac-proxy-agent/node_modules/agent-base": {
    +      "version": "7.1.0",
    +      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz",
    +      "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==",
    +      "dependencies": {
    +        "debug": "^4.3.4"
    +      },
    +      "engines": {
    +        "node": ">= 14"
    +      }
    +    },
    +    "node_modules/pac-proxy-agent/node_modules/http-proxy-agent": {
    +      "version": "7.0.0",
    +      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz",
    +      "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==",
    +      "dependencies": {
    +        "agent-base": "^7.1.0",
    +        "debug": "^4.3.4"
    +      },
    +      "engines": {
    +        "node": ">= 14"
    +      }
    +    },
    +    "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": {
    +      "version": "7.0.2",
    +      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz",
    +      "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==",
    +      "dependencies": {
    +        "agent-base": "^7.0.2",
    +        "debug": "4"
    +      },
    +      "engines": {
    +        "node": ">= 14"
    +      }
    +    },
    +    "node_modules/pac-resolver": {
    +      "version": "7.0.0",
    +      "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.0.tgz",
    +      "integrity": "sha512-Fd9lT9vJbHYRACT8OhCbZBbxr6KRSawSovFpy8nDGshaK99S/EBhVIHp9+crhxrsZOuvLpgL1n23iyPg6Rl2hg==",
    +      "dependencies": {
    +        "degenerator": "^5.0.0",
    +        "ip": "^1.1.8",
    +        "netmask": "^2.0.2"
    +      },
    +      "engines": {
    +        "node": ">= 14"
    +      }
    +    },
    +    "node_modules/pako": {
    +      "version": "1.0.11",
    +      "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
    +      "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
    +    },
    +    "node_modules/parse5": {
    +      "version": "7.1.2",
    +      "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
    +      "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
    +      "dependencies": {
    +        "entities": "^4.4.0"
    +      },
    +      "funding": {
    +        "url": "https://github.com/inikulin/parse5?sponsor=1"
    +      }
    +    },
    +    "node_modules/parse5/node_modules/entities": {
    +      "version": "4.5.0",
    +      "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
    +      "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
    +      "engines": {
    +        "node": ">=0.12"
    +      },
    +      "funding": {
    +        "url": "https://github.com/fb55/entities?sponsor=1"
    +      }
    +    },
    +    "node_modules/path-is-absolute": {
    +      "version": "1.0.1",
    +      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
    +      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
    +      "engines": {
    +        "node": ">=0.10.0"
    +      }
    +    },
    +    "node_modules/pend": {
    +      "version": "1.2.0",
    +      "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
    +      "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="
    +    },
    +    "node_modules/performance-now": {
    +      "version": "2.1.0",
    +      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
    +      "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
    +    },
    +    "node_modules/postman-request": {
    +      "version": "2.88.1-postman.33",
    +      "resolved": "https://registry.npmjs.org/postman-request/-/postman-request-2.88.1-postman.33.tgz",
    +      "integrity": "sha512-uL9sCML4gPH6Z4hreDWbeinKU0p0Ke261nU7OvII95NU22HN6Dk7T/SaVPaj6T4TsQqGKIFw6/woLZnH7ugFNA==",
    +      "dependencies": {
    +        "@postman/form-data": "~3.1.1",
    +        "@postman/tough-cookie": "~4.1.3-postman.1",
    +        "@postman/tunnel-agent": "^0.6.3",
    +        "aws-sign2": "~0.7.0",
    +        "aws4": "^1.12.0",
    +        "brotli": "^1.3.3",
    +        "caseless": "~0.12.0",
    +        "combined-stream": "~1.0.6",
    +        "extend": "~3.0.2",
    +        "forever-agent": "~0.6.1",
    +        "har-validator": "~5.1.3",
    +        "http-signature": "~1.3.1",
    +        "is-typedarray": "~1.0.0",
    +        "isstream": "~0.1.2",
    +        "json-stringify-safe": "~5.0.1",
    +        "mime-types": "^2.1.35",
    +        "oauth-sign": "~0.9.0",
    +        "performance-now": "^2.1.0",
    +        "qs": "~6.5.3",
    +        "safe-buffer": "^5.1.2",
    +        "stream-length": "^1.0.2",
    +        "uuid": "^8.3.2"
    +      },
    +      "engines": {
    +        "node": ">= 6"
    +      }
    +    },
    +    "node_modules/process-nextick-args": {
    +      "version": "2.0.1",
    +      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
    +      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
    +    },
    +    "node_modules/progress": {
    +      "version": "2.0.3",
    +      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
    +      "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
    +      "engines": {
    +        "node": ">=0.4.0"
    +      }
    +    },
    +    "node_modules/proxy-agent": {
    +      "version": "6.3.1",
    +      "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.1.tgz",
    +      "integrity": "sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==",
    +      "dependencies": {
    +        "agent-base": "^7.0.2",
    +        "debug": "^4.3.4",
    +        "http-proxy-agent": "^7.0.0",
    +        "https-proxy-agent": "^7.0.2",
    +        "lru-cache": "^7.14.1",
    +        "pac-proxy-agent": "^7.0.1",
    +        "proxy-from-env": "^1.1.0",
    +        "socks-proxy-agent": "^8.0.2"
    +      },
    +      "engines": {
    +        "node": ">= 14"
    +      }
    +    },
    +    "node_modules/proxy-agent/node_modules/agent-base": {
    +      "version": "7.1.0",
    +      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz",
    +      "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==",
    +      "dependencies": {
    +        "debug": "^4.3.4"
    +      },
    +      "engines": {
    +        "node": ">= 14"
    +      }
    +    },
    +    "node_modules/proxy-agent/node_modules/http-proxy-agent": {
    +      "version": "7.0.0",
    +      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz",
    +      "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==",
    +      "dependencies": {
    +        "agent-base": "^7.1.0",
    +        "debug": "^4.3.4"
    +      },
    +      "engines": {
    +        "node": ">= 14"
    +      }
    +    },
    +    "node_modules/proxy-agent/node_modules/https-proxy-agent": {
    +      "version": "7.0.2",
    +      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz",
    +      "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==",
    +      "dependencies": {
    +        "agent-base": "^7.0.2",
    +        "debug": "4"
    +      },
    +      "engines": {
    +        "node": ">= 14"
    +      }
    +    },
    +    "node_modules/proxy-from-env": {
    +      "version": "1.1.0",
    +      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
    +      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
    +    },
    +    "node_modules/psl": {
    +      "version": "1.9.0",
    +      "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
    +      "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag=="
    +    },
    +    "node_modules/pump": {
    +      "version": "3.0.0",
    +      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
    +      "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
    +      "dependencies": {
    +        "end-of-stream": "^1.1.0",
    +        "once": "^1.3.1"
    +      }
    +    },
    +    "node_modules/punycode": {
    +      "version": "2.3.0",
    +      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
    +      "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
    +      "engines": {
    +        "node": ">=6"
    +      }
    +    },
    +    "node_modules/puppeteer-core": {
    +      "version": "21.2.1",
    +      "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-21.2.1.tgz",
    +      "integrity": "sha512-+I8EjpWFeeFKScpQiTEnC4jGve2Wr4eA9qUMoa8S317DJPm9h7wzrT4YednZK2TQZMyPtPQ2Disb/Tg02+4Naw==",
    +      "dependencies": {
    +        "@puppeteer/browsers": "1.7.1",
    +        "chromium-bidi": "0.4.26",
    +        "cross-fetch": "4.0.0",
    +        "debug": "4.3.4",
    +        "devtools-protocol": "0.0.1159816",
    +        "ws": "8.14.1"
    +      },
    +      "engines": {
    +        "node": ">=16.3.0"
    +      }
    +    },
    +    "node_modules/puppeteer-core/node_modules/ws": {
    +      "version": "8.14.1",
    +      "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.1.tgz",
    +      "integrity": "sha512-4OOseMUq8AzRBI/7SLMUwO+FEDnguetSk7KMb1sHwvF2w2Wv5Hoj0nlifx8vtGsftE/jWHojPy8sMMzYLJ2G/A==",
    +      "engines": {
    +        "node": ">=10.0.0"
    +      },
    +      "peerDependencies": {
    +        "bufferutil": "^4.0.1",
    +        "utf-8-validate": ">=5.0.2"
    +      },
    +      "peerDependenciesMeta": {
    +        "bufferutil": {
    +          "optional": true
    +        },
    +        "utf-8-validate": {
    +          "optional": true
    +        }
    +      }
    +    },
    +    "node_modules/qs": {
    +      "version": "6.5.3",
    +      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
    +      "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
    +      "engines": {
    +        "node": ">=0.6"
    +      }
    +    },
    +    "node_modules/querystringify": {
    +      "version": "2.2.0",
    +      "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz",
    +      "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ=="
    +    },
    +    "node_modules/queue-tick": {
    +      "version": "1.0.1",
    +      "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz",
    +      "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag=="
    +    },
    +    "node_modules/readability-extractor": {
    +      "version": "0.0.8",
    +      "resolved": "git+ssh://git@github.com/ArchiveBox/readability-extractor.git#fd0c971ea15c69338aad38871b5246fc474f6152",
    +      "license": "MIT",
    +      "dependencies": {
    +        "@mozilla/readability": "^0.4.4",
    +        "dompurify": "^2.4.4",
    +        "jsdom": "^21.1.0"
    +      },
    +      "bin": {
    +        "readability-extractor": "readability-extractor"
    +      }
    +    },
    +    "node_modules/readable-stream": {
    +      "version": "3.6.2",
    +      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
    +      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
    +      "dependencies": {
    +        "inherits": "^2.0.3",
    +        "string_decoder": "^1.1.1",
    +        "util-deprecate": "^1.0.1"
    +      },
    +      "engines": {
    +        "node": ">= 6"
    +      }
    +    },
    +    "node_modules/regenerator-runtime": {
    +      "version": "0.14.0",
    +      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
    +      "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
    +    },
    +    "node_modules/require-directory": {
    +      "version": "2.1.1",
    +      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
    +      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
    +      "engines": {
    +        "node": ">=0.10.0"
    +      }
    +    },
    +    "node_modules/requires-port": {
    +      "version": "1.0.0",
    +      "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
    +      "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ=="
    +    },
    +    "node_modules/rimraf": {
    +      "version": "3.0.2",
    +      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
    +      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
    +      "dependencies": {
    +        "glob": "^7.1.3"
    +      },
    +      "bin": {
    +        "rimraf": "bin.js"
    +      },
    +      "funding": {
    +        "url": "https://github.com/sponsors/isaacs"
    +      }
    +    },
    +    "node_modules/rrweb-cssom": {
    +      "version": "0.6.0",
    +      "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz",
    +      "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw=="
    +    },
    +    "node_modules/safe-buffer": {
    +      "version": "5.2.1",
    +      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
    +      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
    +      "funding": [
    +        {
    +          "type": "github",
    +          "url": "https://github.com/sponsors/feross"
    +        },
    +        {
    +          "type": "patreon",
    +          "url": "https://www.patreon.com/feross"
    +        },
    +        {
    +          "type": "consulting",
    +          "url": "https://feross.org/support"
    +        }
    +      ]
    +    },
    +    "node_modules/safer-buffer": {
    +      "version": "2.1.2",
    +      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
    +      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
    +    },
    +    "node_modules/saxes": {
    +      "version": "6.0.0",
    +      "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz",
    +      "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==",
    +      "dependencies": {
    +        "xmlchars": "^2.2.0"
    +      },
    +      "engines": {
    +        "node": ">=v12.22.7"
    +      }
    +    },
    +    "node_modules/selenium-webdriver": {
    +      "version": "4.12.0",
    +      "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.12.0.tgz",
    +      "integrity": "sha512-zvPzmTsky6WfO6+BGMj2mCJsw7qKnfQONur2b+pGn8jeTiC+WAUOthZOnaK+HkX5wiU6L4uoMF+JIcOVstp25A==",
    +      "dependencies": {
    +        "jszip": "^3.10.1",
    +        "tmp": "^0.2.1",
    +        "ws": ">=8.13.0"
    +      },
    +      "engines": {
    +        "node": ">= 14.20.0"
    +      }
    +    },
    +    "node_modules/setimmediate": {
    +      "version": "1.0.5",
    +      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
    +      "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
    +    },
    +    "node_modules/single-file-cli": {
    +      "version": "1.1.12",
    +      "resolved": "https://registry.npmjs.org/single-file-cli/-/single-file-cli-1.1.12.tgz",
    +      "integrity": "sha512-CTMqoCnHgB/duMU10SwA6v9uqG511GItVghLDTv1lTVa4JRwJ4qpsiz7KWXYQh5QyefQJHFVVxzSNWDVpNJC4w==",
    +      "dependencies": {
    +        "file-url": "3.0.0",
    +        "iconv-lite": "0.6.3",
    +        "jsdom": "22.1.0",
    +        "puppeteer-core": "21.2.1",
    +        "selenium-webdriver": "4.12.0",
    +        "single-file-core": "1.2.13",
    +        "strong-data-uri": "1.0.6",
    +        "yargs": "17.7.2"
    +      },
    +      "bin": {
    +        "single-file": "single-file"
    +      }
    +    },
    +    "node_modules/single-file-cli/node_modules/iconv-lite": {
    +      "version": "0.6.3",
    +      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
    +      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
    +      "dependencies": {
    +        "safer-buffer": ">= 2.1.2 < 3.0.0"
    +      },
    +      "engines": {
    +        "node": ">=0.10.0"
    +      }
    +    },
    +    "node_modules/single-file-cli/node_modules/jsdom": {
           "version": "22.1.0",
           "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-22.1.0.tgz",
           "integrity": "sha512-/9AVW7xNbsBv6GfWho4TTNjEo9fe6Zhf9O7s0Fhhr3u+awPwAJMKwAMXnkk5vBxflqLW9hTHX/0cs+P3gW+cQw==",
    @@ -1127,7 +2040,7 @@
             }
           }
         },
    -    "node_modules/jsdom/node_modules/tr46": {
    +    "node_modules/single-file-cli/node_modules/tr46": {
           "version": "4.1.1",
           "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz",
           "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==",
    @@ -1138,7 +2051,7 @@
             "node": ">=14"
           }
         },
    -    "node_modules/jsdom/node_modules/whatwg-url": {
    +    "node_modules/single-file-cli/node_modules/whatwg-url": {
           "version": "12.0.1",
           "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz",
           "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==",
    @@ -1150,633 +2063,15 @@
             "node": ">=14"
           }
         },
    -    "node_modules/json-schema": {
    -      "version": "0.4.0",
    -      "license": "(AFL-2.1 OR BSD-3-Clause)"
    -    },
    -    "node_modules/json-schema-traverse": {
    -      "version": "0.4.1",
    -      "license": "MIT"
    -    },
    -    "node_modules/json-stringify-safe": {
    -      "version": "5.0.1",
    -      "license": "ISC"
    -    },
    -    "node_modules/jsonfile": {
    -      "version": "4.0.0",
    -      "license": "MIT",
    -      "optionalDependencies": {
    -        "graceful-fs": "^4.1.6"
    -      }
    -    },
    -    "node_modules/jsprim": {
    -      "version": "2.0.2",
    -      "engines": [
    -        "node >=0.6.0"
    -      ],
    -      "license": "MIT",
    -      "dependencies": {
    -        "assert-plus": "1.0.0",
    -        "extsprintf": "1.3.0",
    -        "json-schema": "0.4.0",
    -        "verror": "1.10.0"
    -      }
    -    },
    -    "node_modules/jszip": {
    -      "version": "3.10.1",
    -      "license": "(MIT OR GPL-3.0-or-later)",
    -      "dependencies": {
    -        "lie": "~3.3.0",
    -        "pako": "~1.0.2",
    -        "readable-stream": "~2.3.6",
    -        "setimmediate": "^1.0.5"
    -      }
    -    },
    -    "node_modules/jszip/node_modules/readable-stream": {
    -      "version": "2.3.8",
    -      "license": "MIT",
    -      "dependencies": {
    -        "core-util-is": "~1.0.0",
    -        "inherits": "~2.0.3",
    -        "isarray": "~1.0.0",
    -        "process-nextick-args": "~2.0.0",
    -        "safe-buffer": "~5.1.1",
    -        "string_decoder": "~1.1.1",
    -        "util-deprecate": "~1.0.1"
    -      }
    -    },
    -    "node_modules/jszip/node_modules/safe-buffer": {
    -      "version": "5.1.2",
    -      "license": "MIT"
    -    },
    -    "node_modules/jszip/node_modules/string_decoder": {
    -      "version": "1.1.1",
    -      "license": "MIT",
    -      "dependencies": {
    -        "safe-buffer": "~5.1.0"
    -      }
    -    },
    -    "node_modules/lie": {
    -      "version": "3.3.0",
    -      "license": "MIT",
    -      "dependencies": {
    -        "immediate": "~3.0.5"
    -      }
    -    },
    -    "node_modules/lodash": {
    -      "version": "4.17.21",
    -      "license": "MIT"
    -    },
    -    "node_modules/lodash.assignin": {
    -      "version": "4.2.0",
    -      "license": "MIT"
    -    },
    -    "node_modules/lodash.bind": {
    -      "version": "4.2.1",
    -      "license": "MIT"
    -    },
    -    "node_modules/lodash.defaults": {
    -      "version": "4.2.0",
    -      "license": "MIT"
    -    },
    -    "node_modules/lodash.filter": {
    -      "version": "4.6.0",
    -      "license": "MIT"
    -    },
    -    "node_modules/lodash.flatten": {
    -      "version": "4.4.0",
    -      "license": "MIT"
    -    },
    -    "node_modules/lodash.foreach": {
    -      "version": "4.5.0",
    -      "license": "MIT"
    -    },
    -    "node_modules/lodash.map": {
    -      "version": "4.6.0",
    -      "license": "MIT"
    -    },
    -    "node_modules/lodash.merge": {
    -      "version": "4.6.2",
    -      "license": "MIT"
    -    },
    -    "node_modules/lodash.pick": {
    -      "version": "4.4.0",
    -      "license": "MIT"
    -    },
    -    "node_modules/lodash.reduce": {
    -      "version": "4.6.0",
    -      "license": "MIT"
    -    },
    -    "node_modules/lodash.reject": {
    -      "version": "4.6.0",
    -      "license": "MIT"
    -    },
    -    "node_modules/lodash.some": {
    -      "version": "4.6.0",
    -      "license": "MIT"
    -    },
    -    "node_modules/lru-cache": {
    -      "version": "7.18.3",
    -      "license": "ISC",
    -      "engines": {
    -        "node": ">=12"
    -      }
    -    },
    -    "node_modules/mime-db": {
    -      "version": "1.52.0",
    -      "license": "MIT",
    -      "engines": {
    -        "node": ">= 0.6"
    -      }
    -    },
    -    "node_modules/mime-types": {
    -      "version": "2.1.35",
    -      "license": "MIT",
    -      "dependencies": {
    -        "mime-db": "1.52.0"
    -      },
    -      "engines": {
    -        "node": ">= 0.6"
    -      }
    -    },
    -    "node_modules/minimatch": {
    -      "version": "3.1.2",
    -      "license": "ISC",
    -      "dependencies": {
    -        "brace-expansion": "^1.1.7"
    -      },
    -      "engines": {
    -        "node": "*"
    -      }
    -    },
    -    "node_modules/mitt": {
    -      "version": "3.0.1",
    -      "license": "MIT"
    -    },
    -    "node_modules/mkdirp-classic": {
    -      "version": "0.5.3",
    -      "license": "MIT"
    -    },
    -    "node_modules/moment-parseformat": {
    -      "version": "3.0.0",
    -      "license": "MIT"
    -    },
    -    "node_modules/ms": {
    -      "version": "2.1.2",
    -      "license": "MIT"
    -    },
    -    "node_modules/netmask": {
    -      "version": "2.0.2",
    -      "license": "MIT",
    -      "engines": {
    -        "node": ">= 0.4.0"
    -      }
    -    },
    -    "node_modules/node-fetch": {
    -      "version": "2.7.0",
    -      "license": "MIT",
    -      "dependencies": {
    -        "whatwg-url": "^5.0.0"
    -      },
    -      "engines": {
    -        "node": "4.x || >=6.0.0"
    -      },
    -      "peerDependencies": {
    -        "encoding": "^0.1.0"
    -      },
    -      "peerDependenciesMeta": {
    -        "encoding": {
    -          "optional": true
    -        }
    -      }
    -    },
    -    "node_modules/nth-check": {
    -      "version": "1.0.2",
    -      "license": "BSD-2-Clause",
    -      "dependencies": {
    -        "boolbase": "~1.0.0"
    -      }
    -    },
    -    "node_modules/nwsapi": {
    -      "version": "2.2.7",
    -      "license": "MIT"
    -    },
    -    "node_modules/oauth-sign": {
    -      "version": "0.9.0",
    -      "license": "Apache-2.0",
    -      "engines": {
    -        "node": "*"
    -      }
    -    },
    -    "node_modules/once": {
    -      "version": "1.4.0",
    -      "license": "ISC",
    -      "dependencies": {
    -        "wrappy": "1"
    -      }
    -    },
    -    "node_modules/pac-proxy-agent": {
    -      "version": "7.0.1",
    -      "license": "MIT",
    -      "dependencies": {
    -        "@tootallnate/quickjs-emscripten": "^0.23.0",
    -        "agent-base": "^7.0.2",
    -        "debug": "^4.3.4",
    -        "get-uri": "^6.0.1",
    -        "http-proxy-agent": "^7.0.0",
    -        "https-proxy-agent": "^7.0.2",
    -        "pac-resolver": "^7.0.0",
    -        "socks-proxy-agent": "^8.0.2"
    -      },
    -      "engines": {
    -        "node": ">= 14"
    -      }
    -    },
    -    "node_modules/pac-proxy-agent/node_modules/agent-base": {
    -      "version": "7.1.0",
    -      "license": "MIT",
    -      "dependencies": {
    -        "debug": "^4.3.4"
    -      },
    -      "engines": {
    -        "node": ">= 14"
    -      }
    -    },
    -    "node_modules/pac-proxy-agent/node_modules/http-proxy-agent": {
    -      "version": "7.0.0",
    -      "license": "MIT",
    -      "dependencies": {
    -        "agent-base": "^7.1.0",
    -        "debug": "^4.3.4"
    -      },
    -      "engines": {
    -        "node": ">= 14"
    -      }
    -    },
    -    "node_modules/pac-proxy-agent/node_modules/https-proxy-agent": {
    -      "version": "7.0.2",
    -      "license": "MIT",
    -      "dependencies": {
    -        "agent-base": "^7.0.2",
    -        "debug": "4"
    -      },
    -      "engines": {
    -        "node": ">= 14"
    -      }
    -    },
    -    "node_modules/pac-resolver": {
    -      "version": "7.0.0",
    -      "license": "MIT",
    -      "dependencies": {
    -        "degenerator": "^5.0.0",
    -        "ip": "^1.1.8",
    -        "netmask": "^2.0.2"
    -      },
    -      "engines": {
    -        "node": ">= 14"
    -      }
    -    },
    -    "node_modules/pako": {
    -      "version": "1.0.11",
    -      "license": "(MIT AND Zlib)"
    -    },
    -    "node_modules/parse5": {
    -      "version": "7.1.2",
    -      "license": "MIT",
    -      "dependencies": {
    -        "entities": "^4.4.0"
    -      },
    -      "funding": {
    -        "url": "https://github.com/inikulin/parse5?sponsor=1"
    -      }
    -    },
    -    "node_modules/parse5/node_modules/entities": {
    -      "version": "4.5.0",
    -      "license": "BSD-2-Clause",
    -      "engines": {
    -        "node": ">=0.12"
    -      },
    -      "funding": {
    -        "url": "https://github.com/fb55/entities?sponsor=1"
    -      }
    -    },
    -    "node_modules/path-is-absolute": {
    -      "version": "1.0.1",
    -      "license": "MIT",
    -      "engines": {
    -        "node": ">=0.10.0"
    -      }
    -    },
    -    "node_modules/pend": {
    -      "version": "1.2.0",
    -      "license": "MIT"
    -    },
    -    "node_modules/performance-now": {
    -      "version": "2.1.0",
    -      "license": "MIT"
    -    },
    -    "node_modules/postman-request": {
    -      "version": "2.88.1-postman.33",
    -      "license": "Apache-2.0",
    -      "dependencies": {
    -        "@postman/form-data": "~3.1.1",
    -        "@postman/tough-cookie": "~4.1.3-postman.1",
    -        "@postman/tunnel-agent": "^0.6.3",
    -        "aws-sign2": "~0.7.0",
    -        "aws4": "^1.12.0",
    -        "brotli": "^1.3.3",
    -        "caseless": "~0.12.0",
    -        "combined-stream": "~1.0.6",
    -        "extend": "~3.0.2",
    -        "forever-agent": "~0.6.1",
    -        "har-validator": "~5.1.3",
    -        "http-signature": "~1.3.1",
    -        "is-typedarray": "~1.0.0",
    -        "isstream": "~0.1.2",
    -        "json-stringify-safe": "~5.0.1",
    -        "mime-types": "^2.1.35",
    -        "oauth-sign": "~0.9.0",
    -        "performance-now": "^2.1.0",
    -        "qs": "~6.5.3",
    -        "safe-buffer": "^5.1.2",
    -        "stream-length": "^1.0.2",
    -        "uuid": "^8.3.2"
    -      },
    -      "engines": {
    -        "node": ">= 6"
    -      }
    -    },
    -    "node_modules/process-nextick-args": {
    -      "version": "2.0.1",
    -      "license": "MIT"
    -    },
    -    "node_modules/progress": {
    -      "version": "2.0.3",
    -      "license": "MIT",
    -      "engines": {
    -        "node": ">=0.4.0"
    -      }
    -    },
    -    "node_modules/proxy-agent": {
    -      "version": "6.3.1",
    -      "license": "MIT",
    -      "dependencies": {
    -        "agent-base": "^7.0.2",
    -        "debug": "^4.3.4",
    -        "http-proxy-agent": "^7.0.0",
    -        "https-proxy-agent": "^7.0.2",
    -        "lru-cache": "^7.14.1",
    -        "pac-proxy-agent": "^7.0.1",
    -        "proxy-from-env": "^1.1.0",
    -        "socks-proxy-agent": "^8.0.2"
    -      },
    -      "engines": {
    -        "node": ">= 14"
    -      }
    -    },
    -    "node_modules/proxy-agent/node_modules/agent-base": {
    -      "version": "7.1.0",
    -      "license": "MIT",
    -      "dependencies": {
    -        "debug": "^4.3.4"
    -      },
    -      "engines": {
    -        "node": ">= 14"
    -      }
    -    },
    -    "node_modules/proxy-agent/node_modules/http-proxy-agent": {
    -      "version": "7.0.0",
    -      "license": "MIT",
    -      "dependencies": {
    -        "agent-base": "^7.1.0",
    -        "debug": "^4.3.4"
    -      },
    -      "engines": {
    -        "node": ">= 14"
    -      }
    -    },
    -    "node_modules/proxy-agent/node_modules/https-proxy-agent": {
    -      "version": "7.0.2",
    -      "license": "MIT",
    -      "dependencies": {
    -        "agent-base": "^7.0.2",
    -        "debug": "4"
    -      },
    -      "engines": {
    -        "node": ">= 14"
    -      }
    -    },
    -    "node_modules/proxy-from-env": {
    -      "version": "1.1.0",
    -      "license": "MIT"
    -    },
    -    "node_modules/psl": {
    -      "version": "1.9.0",
    -      "license": "MIT"
    -    },
    -    "node_modules/pump": {
    -      "version": "3.0.0",
    -      "license": "MIT",
    -      "dependencies": {
    -        "end-of-stream": "^1.1.0",
    -        "once": "^1.3.1"
    -      }
    -    },
    -    "node_modules/punycode": {
    -      "version": "2.3.0",
    -      "license": "MIT",
    -      "engines": {
    -        "node": ">=6"
    -      }
    -    },
    -    "node_modules/puppeteer-core": {
    -      "version": "21.2.1",
    -      "license": "Apache-2.0",
    -      "dependencies": {
    -        "@puppeteer/browsers": "1.7.1",
    -        "chromium-bidi": "0.4.26",
    -        "cross-fetch": "4.0.0",
    -        "debug": "4.3.4",
    -        "devtools-protocol": "0.0.1159816",
    -        "ws": "8.14.1"
    -      },
    -      "engines": {
    -        "node": ">=16.3.0"
    -      }
    -    },
    -    "node_modules/puppeteer-core/node_modules/ws": {
    -      "version": "8.14.1",
    -      "license": "MIT",
    -      "engines": {
    -        "node": ">=10.0.0"
    -      },
    -      "peerDependencies": {
    -        "bufferutil": "^4.0.1",
    -        "utf-8-validate": ">=5.0.2"
    -      },
    -      "peerDependenciesMeta": {
    -        "bufferutil": {
    -          "optional": true
    -        },
    -        "utf-8-validate": {
    -          "optional": true
    -        }
    -      }
    -    },
    -    "node_modules/qs": {
    -      "version": "6.5.3",
    -      "license": "BSD-3-Clause",
    -      "engines": {
    -        "node": ">=0.6"
    -      }
    -    },
    -    "node_modules/querystringify": {
    -      "version": "2.2.0",
    -      "license": "MIT"
    -    },
    -    "node_modules/queue-tick": {
    -      "version": "1.0.1",
    -      "license": "MIT"
    -    },
    -    "node_modules/readability-extractor": {
    -      "version": "0.0.7",
    -      "resolved": "git+ssh://git@github.com/ArchiveBox/readability-extractor.git#4e298e47a780095697473afb04266943164b8364",
    -      "license": "MIT",
    -      "dependencies": {
    -        "@mozilla/readability": "^0.4.4",
    -        "dompurify": "^3.0.6",
    -        "jsdom": "^22.1.0"
    -      },
    -      "bin": {
    -        "readability-extractor": "readability-extractor"
    -      }
    -    },
    -    "node_modules/readable-stream": {
    -      "version": "3.6.2",
    -      "license": "MIT",
    -      "dependencies": {
    -        "inherits": "^2.0.3",
    -        "string_decoder": "^1.1.1",
    -        "util-deprecate": "^1.0.1"
    -      },
    -      "engines": {
    -        "node": ">= 6"
    -      }
    -    },
    -    "node_modules/regenerator-runtime": {
    -      "version": "0.14.0",
    -      "license": "MIT"
    -    },
    -    "node_modules/require-directory": {
    -      "version": "2.1.1",
    -      "license": "MIT",
    -      "engines": {
    -        "node": ">=0.10.0"
    -      }
    -    },
    -    "node_modules/requires-port": {
    -      "version": "1.0.0",
    -      "license": "MIT"
    -    },
    -    "node_modules/rimraf": {
    -      "version": "3.0.2",
    -      "license": "ISC",
    -      "dependencies": {
    -        "glob": "^7.1.3"
    -      },
    -      "bin": {
    -        "rimraf": "bin.js"
    -      },
    -      "funding": {
    -        "url": "https://github.com/sponsors/isaacs"
    -      }
    -    },
    -    "node_modules/rrweb-cssom": {
    -      "version": "0.6.0",
    -      "license": "MIT"
    -    },
    -    "node_modules/safe-buffer": {
    -      "version": "5.2.1",
    -      "funding": [
    -        {
    -          "type": "github",
    -          "url": "https://github.com/sponsors/feross"
    -        },
    -        {
    -          "type": "patreon",
    -          "url": "https://www.patreon.com/feross"
    -        },
    -        {
    -          "type": "consulting",
    -          "url": "https://feross.org/support"
    -        }
    -      ],
    -      "license": "MIT"
    -    },
    -    "node_modules/safer-buffer": {
    -      "version": "2.1.2",
    -      "license": "MIT"
    -    },
    -    "node_modules/saxes": {
    -      "version": "6.0.0",
    -      "license": "ISC",
    -      "dependencies": {
    -        "xmlchars": "^2.2.0"
    -      },
    -      "engines": {
    -        "node": ">=v12.22.7"
    -      }
    -    },
    -    "node_modules/selenium-webdriver": {
    -      "version": "4.12.0",
    -      "license": "Apache-2.0",
    -      "dependencies": {
    -        "jszip": "^3.10.1",
    -        "tmp": "^0.2.1",
    -        "ws": ">=8.13.0"
    -      },
    -      "engines": {
    -        "node": ">= 14.20.0"
    -      }
    -    },
    -    "node_modules/setimmediate": {
    -      "version": "1.0.5",
    -      "license": "MIT"
    -    },
    -    "node_modules/single-file-cli": {
    -      "version": "1.1.12",
    -      "license": "AGPL-3.0-or-later",
    -      "dependencies": {
    -        "file-url": "3.0.0",
    -        "iconv-lite": "0.6.3",
    -        "jsdom": "22.1.0",
    -        "puppeteer-core": "21.2.1",
    -        "selenium-webdriver": "4.12.0",
    -        "single-file-core": "1.2.13",
    -        "strong-data-uri": "1.0.6",
    -        "yargs": "17.7.2"
    -      },
    -      "bin": {
    -        "single-file": "single-file"
    -      }
    -    },
    -    "node_modules/single-file-cli/node_modules/iconv-lite": {
    -      "version": "0.6.3",
    -      "license": "MIT",
    -      "dependencies": {
    -        "safer-buffer": ">= 2.1.2 < 3.0.0"
    -      },
    -      "engines": {
    -        "node": ">=0.10.0"
    -      }
    -    },
         "node_modules/single-file-core": {
           "version": "1.2.13",
    -      "license": "AGPL-3.0-or-later"
    +      "resolved": "https://registry.npmjs.org/single-file-core/-/single-file-core-1.2.13.tgz",
    +      "integrity": "sha512-QO9wfaajBii670m5mmjslrpCxmK9gkiGUg3XSTLtG4YN9k7t6EAhSORpjg5N/DwZk0seEZqXTorPp6aN9c6lYA=="
         },
         "node_modules/smart-buffer": {
           "version": "4.2.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
    +      "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
           "engines": {
             "node": ">= 6.0.0",
             "npm": ">= 3.0.0"
    @@ -1784,7 +2079,8 @@
         },
         "node_modules/socks": {
           "version": "2.7.1",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
    +      "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==",
           "dependencies": {
             "ip": "^2.0.0",
             "smart-buffer": "^4.2.0"
    @@ -1796,7 +2092,8 @@
         },
         "node_modules/socks-proxy-agent": {
           "version": "8.0.2",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz",
    +      "integrity": "sha512-8zuqoLv1aP/66PHF5TqwJ7Czm3Yv32urJQHrVyhD7mmA6d61Zv8cIXQYPTWwmg6qlupnPvs/QKDmfa4P/qct2g==",
           "dependencies": {
             "agent-base": "^7.0.2",
             "debug": "^4.3.4",
    @@ -1808,7 +2105,8 @@
         },
         "node_modules/socks-proxy-agent/node_modules/agent-base": {
           "version": "7.1.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz",
    +      "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==",
           "dependencies": {
             "debug": "^4.3.4"
           },
    @@ -1818,11 +2116,13 @@
         },
         "node_modules/socks/node_modules/ip": {
           "version": "2.0.0",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
    +      "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ=="
         },
         "node_modules/source-map": {
           "version": "0.6.1",
    -      "license": "BSD-3-Clause",
    +      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
    +      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
           "optional": true,
           "engines": {
             "node": ">=0.10.0"
    @@ -1830,7 +2130,8 @@
         },
         "node_modules/sshpk": {
           "version": "1.18.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz",
    +      "integrity": "sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==",
           "dependencies": {
             "asn1": "~0.2.3",
             "assert-plus": "^1.0.0",
    @@ -1853,14 +2154,16 @@
         },
         "node_modules/stream-length": {
           "version": "1.0.2",
    -      "license": "WTFPL",
    +      "resolved": "https://registry.npmjs.org/stream-length/-/stream-length-1.0.2.tgz",
    +      "integrity": "sha512-aI+qKFiwoDV4rsXiS7WRoCt+v2RX1nUj17+KJC5r2gfh5xoSJIfP6Y3Do/HtvesFcTSWthIuJ3l1cvKQY/+nZg==",
           "dependencies": {
             "bluebird": "^2.6.2"
           }
         },
         "node_modules/streamx": {
           "version": "2.15.1",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.1.tgz",
    +      "integrity": "sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==",
           "dependencies": {
             "fast-fifo": "^1.1.0",
             "queue-tick": "^1.0.1"
    @@ -1868,18 +2171,21 @@
         },
         "node_modules/string_decoder": {
           "version": "1.3.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
    +      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
           "dependencies": {
             "safe-buffer": "~5.2.0"
           }
         },
         "node_modules/string-direction": {
           "version": "0.1.2",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/string-direction/-/string-direction-0.1.2.tgz",
    +      "integrity": "sha512-NJHQRg6GlOEMLA6jEAlSy21KaXvJDNoAid/v6fBAJbqdvOEIiPpCrIPTHnl4636wUF/IGyktX5A9eddmETb1Cw=="
         },
         "node_modules/string-width": {
           "version": "4.2.3",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
    +      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
           "dependencies": {
             "emoji-regex": "^8.0.0",
             "is-fullwidth-code-point": "^3.0.0",
    @@ -1891,7 +2197,8 @@
         },
         "node_modules/strip-ansi": {
           "version": "6.0.1",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
    +      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
           "dependencies": {
             "ansi-regex": "^5.0.1"
           },
    @@ -1901,7 +2208,8 @@
         },
         "node_modules/strong-data-uri": {
           "version": "1.0.6",
    -      "license": "Artistic-2.0",
    +      "resolved": "https://registry.npmjs.org/strong-data-uri/-/strong-data-uri-1.0.6.tgz",
    +      "integrity": "sha512-zhzBZev0uhT2IrFUerenXhfaE0vFUYwAZsnG0gIKGpfM/Gi6jOUQ3cmcvyTsXeDLIPiTubHESeO7EbD6FoPmzw==",
           "dependencies": {
             "truncate": "^2.0.1"
           },
    @@ -1911,11 +2219,13 @@
         },
         "node_modules/symbol-tree": {
           "version": "3.2.4",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
    +      "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="
         },
         "node_modules/tar-fs": {
           "version": "3.0.4",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz",
    +      "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==",
           "dependencies": {
             "mkdirp-classic": "^0.5.2",
             "pump": "^3.0.0",
    @@ -1924,7 +2234,8 @@
         },
         "node_modules/tar-stream": {
           "version": "3.1.6",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz",
    +      "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==",
           "dependencies": {
             "b4a": "^1.6.4",
             "fast-fifo": "^1.2.0",
    @@ -1933,11 +2244,13 @@
         },
         "node_modules/through": {
           "version": "2.3.8",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
    +      "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
         },
         "node_modules/tmp": {
           "version": "0.2.1",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
    +      "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
           "dependencies": {
             "rimraf": "^3.0.0"
           },
    @@ -1947,7 +2260,8 @@
         },
         "node_modules/tough-cookie": {
           "version": "4.1.3",
    -      "license": "BSD-3-Clause",
    +      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz",
    +      "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==",
           "dependencies": {
             "psl": "^1.1.33",
             "punycode": "^2.1.1",
    @@ -1960,33 +2274,39 @@
         },
         "node_modules/tr46": {
           "version": "0.0.3",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
    +      "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
         },
         "node_modules/truncate": {
           "version": "2.1.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/truncate/-/truncate-2.1.0.tgz",
    +      "integrity": "sha512-em3E3SUDONOjTBcZ36DTm3RvDded3IRU9rX32oHwwXNt3rJD5MVaFlJTQvs8tJoHRoeYP36OuQ1eL/Q7bNEWIQ==",
           "engines": {
             "node": "*"
           }
         },
         "node_modules/tslib": {
           "version": "2.6.2",
    -      "license": "0BSD"
    +      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
    +      "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
         },
         "node_modules/turndown": {
           "version": "7.1.2",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/turndown/-/turndown-7.1.2.tgz",
    +      "integrity": "sha512-ntI9R7fcUKjqBP6QU8rBK2Ehyt8LAzt3UBT9JR9tgo6GtuKvyUzpayWmeMKJw1DPdXzktvtIT8m2mVXz+bL/Qg==",
           "dependencies": {
             "domino": "^2.1.6"
           }
         },
         "node_modules/tweetnacl": {
           "version": "0.14.5",
    -      "license": "Unlicense"
    +      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
    +      "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
         },
         "node_modules/unbzip2-stream": {
           "version": "1.4.3",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
    +      "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
           "dependencies": {
             "buffer": "^5.2.1",
             "through": "^2.3.8"
    @@ -1994,26 +2314,30 @@
         },
         "node_modules/undici-types": {
           "version": "5.25.3",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
    +      "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==",
           "optional": true
         },
         "node_modules/universalify": {
           "version": "0.2.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz",
    +      "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==",
           "engines": {
             "node": ">= 4.0.0"
           }
         },
         "node_modules/uri-js": {
           "version": "4.4.1",
    -      "license": "BSD-2-Clause",
    +      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
    +      "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
           "dependencies": {
             "punycode": "^2.1.0"
           }
         },
         "node_modules/url-parse": {
           "version": "1.5.10",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz",
    +      "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==",
           "dependencies": {
             "querystringify": "^2.1.1",
             "requires-port": "^1.0.0"
    @@ -2021,24 +2345,29 @@
         },
         "node_modules/util-deprecate": {
           "version": "1.0.2",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
    +      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
         },
         "node_modules/uuid": {
           "version": "8.3.2",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
    +      "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
           "bin": {
             "uuid": "dist/bin/uuid"
           }
         },
         "node_modules/valid-url": {
    -      "version": "1.0.9"
    +      "version": "1.0.9",
    +      "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz",
    +      "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA=="
         },
         "node_modules/verror": {
           "version": "1.10.0",
    +      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
    +      "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
           "engines": [
             "node >=0.6.0"
           ],
    -      "license": "MIT",
           "dependencies": {
             "assert-plus": "^1.0.0",
             "core-util-is": "1.0.2",
    @@ -2047,7 +2376,8 @@
         },
         "node_modules/w3c-xmlserializer": {
           "version": "4.0.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz",
    +      "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==",
           "dependencies": {
             "xml-name-validator": "^4.0.0"
           },
    @@ -2057,14 +2387,16 @@
         },
         "node_modules/webidl-conversions": {
           "version": "7.0.0",
    -      "license": "BSD-2-Clause",
    +      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
    +      "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==",
           "engines": {
             "node": ">=12"
           }
         },
         "node_modules/whatwg-encoding": {
           "version": "2.0.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
    +      "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
           "dependencies": {
             "iconv-lite": "0.6.3"
           },
    @@ -2074,7 +2406,8 @@
         },
         "node_modules/whatwg-encoding/node_modules/iconv-lite": {
           "version": "0.6.3",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
    +      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
           "dependencies": {
             "safer-buffer": ">= 2.1.2 < 3.0.0"
           },
    @@ -2084,14 +2417,16 @@
         },
         "node_modules/whatwg-mimetype": {
           "version": "3.0.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz",
    +      "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==",
           "engines": {
             "node": ">=12"
           }
         },
         "node_modules/whatwg-url": {
           "version": "5.0.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
    +      "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
           "dependencies": {
             "tr46": "~0.0.3",
             "webidl-conversions": "^3.0.0"
    @@ -2099,11 +2434,13 @@
         },
         "node_modules/whatwg-url/node_modules/webidl-conversions": {
           "version": "3.0.1",
    -      "license": "BSD-2-Clause"
    +      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
    +      "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
         },
         "node_modules/wrap-ansi": {
           "version": "7.0.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
    +      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
           "dependencies": {
             "ansi-styles": "^4.0.0",
             "string-width": "^4.1.0",
    @@ -2118,11 +2455,13 @@
         },
         "node_modules/wrappy": {
           "version": "1.0.2",
    -      "license": "ISC"
    +      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
    +      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
         },
         "node_modules/ws": {
           "version": "8.14.2",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz",
    +      "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==",
           "engines": {
             "node": ">=10.0.0"
           },
    @@ -2141,32 +2480,37 @@
         },
         "node_modules/wuzzy": {
           "version": "0.1.8",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/wuzzy/-/wuzzy-0.1.8.tgz",
    +      "integrity": "sha512-FUzKQepFSTnANsDYwxpIzGJ/dIJaqxuMre6tzzbvWwFAiUHPsI1nVQVCLK4Xqr67KO7oYAK0kaCcI/+WYj/7JA==",
           "dependencies": {
             "lodash": "^4.17.15"
           }
         },
         "node_modules/xml-name-validator": {
           "version": "4.0.0",
    -      "license": "Apache-2.0",
    +      "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
    +      "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==",
           "engines": {
             "node": ">=12"
           }
         },
         "node_modules/xmlchars": {
           "version": "2.2.0",
    -      "license": "MIT"
    +      "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
    +      "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="
         },
         "node_modules/y18n": {
           "version": "5.0.8",
    -      "license": "ISC",
    +      "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
    +      "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
           "engines": {
             "node": ">=10"
           }
         },
         "node_modules/yargs": {
           "version": "17.7.2",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
    +      "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
           "dependencies": {
             "cliui": "^8.0.1",
             "escalade": "^3.1.1",
    @@ -2182,7 +2526,8 @@
         },
         "node_modules/yargs-parser": {
           "version": "15.0.3",
    -      "license": "ISC",
    +      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-15.0.3.tgz",
    +      "integrity": "sha512-/MVEVjTXy/cGAjdtQf8dW3V9b97bPN7rNn8ETj6BmAQL7ibC7O1Q9SPJbGjgh3SlwoBNXMzj/ZGIj8mBgl12YA==",
           "dependencies": {
             "camelcase": "^5.0.0",
             "decamelize": "^1.2.0"
    @@ -2190,14 +2535,16 @@
         },
         "node_modules/yargs/node_modules/yargs-parser": {
           "version": "21.1.1",
    -      "license": "ISC",
    +      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
    +      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
           "engines": {
             "node": ">=12"
           }
         },
         "node_modules/yauzl": {
           "version": "2.10.0",
    -      "license": "MIT",
    +      "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
    +      "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
           "dependencies": {
             "buffer-crc32": "~0.2.3",
             "fd-slicer": "~1.1.0"
    
    From 82d8662c74c598a403fdabc9a6fd0bd4ceda0508 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Fri, 20 Oct 2023 04:14:28 -0700
    Subject: [PATCH 45/89] add more readability error output
    
    ---
     archivebox/extractors/readability.py | 4 ++--
     1 file changed, 2 insertions(+), 2 deletions(-)
    
    diff --git a/archivebox/extractors/readability.py b/archivebox/extractors/readability.py
    index a1689f95..e6e5e061 100644
    --- a/archivebox/extractors/readability.py
    +++ b/archivebox/extractors/readability.py
    @@ -71,7 +71,7 @@ def save_readability(link: Link, out_dir: Optional[str]=None, timeout: int=TIMEO
             result = run(cmd, cwd=out_dir, timeout=timeout)
             try:
                 result_json = json.loads(result.stdout)
    -            assert result_json and 'content' in result_json
    +            assert result_json and 'content' in result_json, 'Readability output is not valid JSON'
             except json.JSONDecodeError:
                 raise ArchiveError('Readability was not able to archive the page', result.stdout + result.stderr)
     
    @@ -85,7 +85,7 @@ def save_readability(link: Link, out_dir: Optional[str]=None, timeout: int=TIMEO
             #  "Downloaded: 76 files, 4.0M in 1.6s (2.52 MB/s)"
             output_tail = [
                 line.strip()
    -            for line in (result.stdout + result.stderr).decode().rsplit('\n', 3)[-3:]
    +            for line in (result.stdout + result.stderr).decode().rsplit('\n', 5)[-5:]
                 if line.strip()
             ]
             hints = (
    
    From bf7a6e4c0930457a56c8370c0f846d930896e0e8 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Fri, 20 Oct 2023 04:33:26 -0700
    Subject: [PATCH 46/89] add missing cpython packages needed for arm v8 docker
     build
    
    ---
     Dockerfile | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index db9986b7..fa1e18d6 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -73,10 +73,10 @@ RUN echo "[+] Installing system dependencies..." \
     
     # Install Node environment
     RUN echo "[+] Installing Node environment..." \
    -    && echo 'deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main' >> /etc/apt/sources.list.d/nodejs.list \
    +    && echo 'deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_21.x nodistro main' >> /etc/apt/sources.list.d/nodejs.list \
         && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
         && apt-get update -qq \
    -    && apt-get install -qq -y nodejs \
    +    && apt-get install -qq -y nodejs libatomic1 \
         && npm i -g npm \
         && node --version \
         && npm --version
    @@ -86,7 +86,7 @@ RUN echo "[+] Installing Python environment..." \
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
             python3 python3-pip python3-venv python3-setuptools python3-wheel python-dev-is-python3 \
    -        python3-ldap libldap2-dev libsasl2-dev libssl-dev \
    +        python3-ldap libldap2-dev libsasl2-dev libssl-dev python3-msgpack \
         && rm /usr/lib/python3*/EXTERNALLY-MANAGED \
         && python3 -m venv --system-site-packages --symlinks $GLOBAL_VENV \
         && $GLOBAL_VENV/bin/pip install --upgrade pip pdm setuptools wheel python-ldap \
    
    From 015737b1e46c4c3dcd6017d96411a58bae67a17d Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Fri, 20 Oct 2023 05:10:03 -0700
    Subject: [PATCH 47/89] fix buildx helper script
    
    ---
     Dockerfile          | 12 ++++++------
     bin/build_docker.sh | 28 +++++++++++++++-------------
     2 files changed, 21 insertions(+), 19 deletions(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index fa1e18d6..a975058a 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -12,11 +12,11 @@
     #     docker buildx create --use
     #     docker buildx build . --platform=linux/amd64,linux/arm64,linux/arm/v7 --push -t archivebox/archivebox:latest -t archivebox/archivebox:dev
     #
    -# Read more about [developing
    -# Archivebox](https://github.com/ArchiveBox/ArchiveBox#archivebox-development).
    +# Read more about [developing Archivebox](https://github.com/ArchiveBox/ArchiveBox#archivebox-development).
     
     
     FROM debian:bookworm-backports
    +# Debian 12 w/ faster package updates: https://packages.debian.org/bookworm-backports/
     
     LABEL name="archivebox" \
         maintainer="Nick Sweeting <dockerfile@archivebox.io>" \
    @@ -49,19 +49,19 @@ ENV PATH="$PATH:$GLOBAL_VENV/bin:$APP_VENV/bin:$NODE_MODULES/.bin"
     
     
     # Create non-privileged user for archivebox and chrome
    -RUN echo "[*] Setting up system environment..." \
    +RUN echo "[*] Setting up system environment for $ARCHIVEBOX_USER ($TARGETPLATFORM)..." \
         && groupadd --system $ARCHIVEBOX_USER \
         && useradd --system --create-home --gid $ARCHIVEBOX_USER --groups audio,video $ARCHIVEBOX_USER \
         && mkdir -p /etc/apt/keyrings
     
     # Install system apt dependencies (adding backports to access more recent apt updates)
     RUN echo "[+] Installing system dependencies..." \
    -    && echo 'deb https://deb.debian.org/debian bullseye-backports main contrib non-free' >> /etc/apt/sources.list.d/backports.list \
    +    && echo 'deb https://deb.debian.org/debian bookworm-backports main contrib non-free' >> /etc/apt/sources.list.d/backports.list \
         && apt-get update -qq \
         && apt-get install -qq -y \
             apt-transport-https ca-certificates gnupg2 curl wget \
             zlib1g-dev dumb-init gosu cron unzip \
    -        nano iputils-ping dnsutils htop procps \
    +        # nano iputils-ping dnsutils htop procps \
             # 1. packaging dependencies
             # 2. docker and init system dependencies
             # 3. frivolous CLI helpers to make debugging failed archiving easier
    @@ -108,7 +108,7 @@ RUN echo "[+] Installing extractor APT dependencies..." \
     ENV PLAYWRIGHT_BROWSERS_PATH="/browsers"
     RUN echo "[+] Installing extractor Chromium dependency..." \
         && apt-get update -qq \
    -    && $GLOBAL_VENV/bin/pip install playwright \
    +    && ($GLOBAL_VENV/bin/pip install playwright || [[ "$TARGETPLATFORM" == "linux/arm/v7" ]]) \
         && $GLOBAL_VENV/bin/playwright install --with-deps chromium \
         && CHROME_BINARY="$($GLOBAL_VENV/bin/python -c 'from playwright.sync_api import sync_playwright; print(sync_playwright().start().chromium.executable_path)')" \
         && ln -s "$CHROME_BINARY" /usr/bin/chromium-browser \
    diff --git a/bin/build_docker.sh b/bin/build_docker.sh
    index 65b55d0b..abbd3f20 100755
    --- a/bin/build_docker.sh
    +++ b/bin/build_docker.sh
    @@ -1,4 +1,5 @@
     #!/usr/bin/env bash
    +# ./bin/build_docker.sh dev 'linux/arm/v7'
     
     ### Bash Environment Setup
     # http://redsymbol.net/articles/unofficial-bash-strict-mode/
    @@ -15,10 +16,12 @@ cd "$REPO_DIR"
     which docker > /dev/null || exit 1
     
     
    -TAG_NAME="dev"
    +TAG_NAME="${1:-$(git rev-parse --abbrev-ref HEAD)}"
     VERSION="$(jq -r '.version' < "$REPO_DIR/package.json")"
     SHORT_VERSION="$(echo "$VERSION" | perl -pe 's/(\d+)\.(\d+)\.(\d+)/$1.$2/g')"
    -REQUIRED_PLATFORMS=('linux/arm64','linux/amd64','linux/arm/v8','linux/arm/v7')
    +REQUIRED_PLATFORMS="${2:-"linux/arm64,linux/amd64,linux/arm/v7"}"
    +
    +echo "[+] Building Docker image: tag=$TAG_NAME version=$SHORT_VERSION arch=$REQUIRED_PLATFORMS"
     
     function check_platforms() {
         INSTALLED_PLATFORMS="$(docker buildx inspect | grep 'Platforms:' )"
    @@ -33,34 +36,32 @@ function check_platforms() {
         return 0
     }
     
    +function remove_builder() {
    +    # remove existing xbuilder
    +    docker buildx stop xbuilder || true
    +    docker buildx rm xbuilder || true
    +}
    +
     function create_builder() {
    +    docker buildx use xbuilder && return 0
         echo "[+] Creating new xbuilder for: $REQUIRED_PLATFORMS"
         echo
     
         # Switch to buildx builder if already present / previously created
         docker buildx create --name xbuilder --driver docker-container --bootstrap --use --platform "$REQUIRED_PLATFORMS" || true
         docker buildx inspect --bootstrap || true
    -
    -    echo
     }
     
     function recreate_builder() {
         # Install QEMU binaries for cross-platform building if not installed
         docker run --privileged --rm 'tonistiigi/binfmt' --install all
     
    -    # remove existing xbuilder
    -    docker buildx stop xbuilder || true
    -    docker buildx rm xbuilder || true
    -
    -    # Create Docker builder for cross-platform building
    -    docker buildx use xbuilder && return 0
    -
    +    remove_builder
         create_builder
     }
     
    -
     # Check if docker is ready for cross-plaform builds, if not, recreate builder
    -docker buildx use xbuilder || create_builder
    +docker buildx use xbuilder 2>&1 >/dev/null || create_builder
     check_platforms || (recreate_builder && check_platforms) || exit 1
     
     
    @@ -72,6 +73,7 @@ docker buildx build --platform "$REQUIRED_PLATFORMS" --load . \
                    -t archivebox:$TAG_NAME \
                    -t archivebox:$VERSION \
                    -t archivebox:$SHORT_VERSION \
    +               -t archivebox:latest \
                    -t docker.io/nikisweeting/archivebox:$TAG_NAME \
                    -t docker.io/nikisweeting/archivebox:$VERSION \
                    -t docker.io/nikisweeting/archivebox:$SHORT_VERSION \
    
    From 25d2c17bb12819ad3b09afd5de96266b23e321f7 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Fri, 20 Oct 2023 05:10:18 -0700
    Subject: [PATCH 48/89] add dev build helper script
    
    ---
     bin/build_dev.sh | 35 +++++++++++++++++++++++++++++++++++
     1 file changed, 35 insertions(+)
     create mode 100755 bin/build_dev.sh
    
    diff --git a/bin/build_dev.sh b/bin/build_dev.sh
    new file mode 100755
    index 00000000..b5acda44
    --- /dev/null
    +++ b/bin/build_dev.sh
    @@ -0,0 +1,35 @@
    +#!/usr/bin/env bash
    +# ./bin/build_docker.sh dev 'linux/arm/v7'
    +
    +### Bash Environment Setup
    +# http://redsymbol.net/articles/unofficial-bash-strict-mode/
    +# https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html
    +# set -o xtrace
    +set -o errexit
    +set -o errtrace
    +set -o nounset
    +set -o pipefail
    +IFS=$'\n'
    +
    +REPO_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd .. && pwd )"
    +cd "$REPO_DIR"
    +which docker > /dev/null || exit 1
    +
    +
    +TAG_NAME="${1:-$(git rev-parse --abbrev-ref HEAD)}"
    +VERSION="$(jq -r '.version' < "$REPO_DIR/package.json")"
    +SHORT_VERSION="$(echo "$VERSION" | perl -pe 's/(\d+)\.(\d+)\.(\d+)/$1.$2/g')"
    +REQUIRED_PLATFORMS="${2:-"linux/arm64,linux/amd64,linux/arm/v7"}"
    +
    +echo "[+] Building Docker image: tag=$TAG_NAME version=$SHORT_VERSION arch=$REQUIRED_PLATFORMS"
    +
    +
    +echo "[+] Building archivebox:$VERSION docker image..."
    +# docker builder prune
    +docker build . --no-cache -t archivebox-dev --load
    +
    +# docker buildx build --platform "$REQUIRED_PLATFORMS" --load . \
    +#                -t archivebox \
    +#                -t archivebox:$TAG_NAME \
    +#                -t archivebox:$VERSION \
    +#                -t archivebox:$SHORT_VERSION
    \ No newline at end of file
    
    From 988b6585c96e841e32c2004e39330dd900ce94f9 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Fri, 20 Oct 2023 05:30:45 -0700
    Subject: [PATCH 49/89] better multiarch builds
    
    ---
     Dockerfile | 20 ++++++++++++++------
     1 file changed, 14 insertions(+), 6 deletions(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index a975058a..8ae39e1c 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -46,10 +46,18 @@ ENV CODE_DIR=/app \
         ARCHIVEBOX_USER="archivebox"
     
     ENV PATH="$PATH:$GLOBAL_VENV/bin:$APP_VENV/bin:$NODE_MODULES/.bin"
    +SHELL ["/bin/bash", "-c"] 
    +ARG TARGETPLATFORM
    +ARG TARGETARCH
    +ARG TARGETVARIANT
    +RUN printf "[i] Building for TARGETPLATFORM=${TARGETPLATFORM}" \
    +    && printf ", TARGETARCH=${TARGETARCH}" \
    +    && printf ", TARGETVARIANT=${TARGETVARIANT} \n" \
    +    && printf "uname -a : " && uname -a
     
     
     # Create non-privileged user for archivebox and chrome
    -RUN echo "[*] Setting up system environment for $ARCHIVEBOX_USER ($TARGETPLATFORM)..." \
    +RUN echo "[*] Setting up system environment..." \
         && groupadd --system $ARCHIVEBOX_USER \
         && useradd --system --create-home --gid $ARCHIVEBOX_USER --groups audio,video $ARCHIVEBOX_USER \
         && mkdir -p /etc/apt/keyrings
    @@ -108,12 +116,12 @@ RUN echo "[+] Installing extractor APT dependencies..." \
     ENV PLAYWRIGHT_BROWSERS_PATH="/browsers"
     RUN echo "[+] Installing extractor Chromium dependency..." \
         && apt-get update -qq \
    -    && ($GLOBAL_VENV/bin/pip install playwright || [[ "$TARGETPLATFORM" == "linux/arm/v7" ]]) \
    -    && $GLOBAL_VENV/bin/playwright install --with-deps chromium \
    -    && CHROME_BINARY="$($GLOBAL_VENV/bin/python -c 'from playwright.sync_api import sync_playwright; print(sync_playwright().start().chromium.executable_path)')" \
    +    && $GLOBAL_VENV/bin/pip install playwright || true \
    +    && $GLOBAL_VENV/bin/playwright install --with-deps chromium || true \
    +    && CHROME_BINARY="$($GLOBAL_VENV/bin/python -c 'from playwright.sync_api import sync_playwright; print(sync_playwright().start().chromium.executable_path)')" || true \
         && ln -s "$CHROME_BINARY" /usr/bin/chromium-browser \
         && mkdir -p "/home/${ARCHIVEBOX_USER}/.config/chromium/Crash Reports/pending/" \
    -    && chown -R $ARCHIVEBOX_USER "/home/${ARCHIVEBOX_USER}/.config"
    +    && chown -R $ARCHIVEBOX_USER "/home/${ARCHIVEBOX_USER}/.config" \
     
     # Install Node dependencies
     WORKDIR "$CODE_DIR"
    @@ -124,7 +132,7 @@ RUN echo "[+] Installing extractor Node dependencies..." \
     
     ######### Build Dependencies ####################################
     
    -# # Installing Python dependencies to build from source
    +# # Building ArchiveBox from source with all pdm dev dependencies
     # WORKDIR "$CODE_DIR"
     # COPY --chown=root:root --chmod=755 "./pyproject.toml" "./pdm.lock" "$CODE_DIR/"
     # RUN echo "[+] Installing project Python dependencies..." \
    
    From 2928c19119485279cc592f0d718323b9e5572807 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Fri, 20 Oct 2023 05:45:08 -0700
    Subject: [PATCH 50/89] fix multiarch chromium install
    
    ---
     Dockerfile | 9 +++++----
     1 file changed, 5 insertions(+), 4 deletions(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index 8ae39e1c..fba172bb 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -116,12 +116,13 @@ RUN echo "[+] Installing extractor APT dependencies..." \
     ENV PLAYWRIGHT_BROWSERS_PATH="/browsers"
     RUN echo "[+] Installing extractor Chromium dependency..." \
         && apt-get update -qq \
    -    && $GLOBAL_VENV/bin/pip install playwright || true \
    -    && $GLOBAL_VENV/bin/playwright install --with-deps chromium || true \
    -    && CHROME_BINARY="$($GLOBAL_VENV/bin/python -c 'from playwright.sync_api import sync_playwright; print(sync_playwright().start().chromium.executable_path)')" || true \
    +    && $GLOBAL_VENV/bin/pip install playwright \
    +    && $GLOBAL_VENV/bin/playwright install --with-deps chromium \
    +    && CHROME_BINARY="$($GLOBAL_VENV/bin/python -c 'from playwright.sync_api import sync_playwright; print(sync_playwright().start().chromium.executable_path)')" \
         && ln -s "$CHROME_BINARY" /usr/bin/chromium-browser \
         && mkdir -p "/home/${ARCHIVEBOX_USER}/.config/chromium/Crash Reports/pending/" \
    -    && chown -R $ARCHIVEBOX_USER "/home/${ARCHIVEBOX_USER}/.config" \
    +    && chown -R $ARCHIVEBOX_USER "/home/${ARCHIVEBOX_USER}/.config" š\
    +    ; exit 0
     
     # Install Node dependencies
     WORKDIR "$CODE_DIR"
    
    From 2681f752f1011032240423683cd1a524fa56540f Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Sat, 21 Oct 2023 14:17:50 -0700
    Subject: [PATCH 51/89] ignore playwright chrome install on arm v7
    
    ---
     Dockerfile | 5 +++--
     1 file changed, 3 insertions(+), 2 deletions(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index fba172bb..9d04023a 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -121,8 +121,9 @@ RUN echo "[+] Installing extractor Chromium dependency..." \
         && CHROME_BINARY="$($GLOBAL_VENV/bin/python -c 'from playwright.sync_api import sync_playwright; print(sync_playwright().start().chromium.executable_path)')" \
         && ln -s "$CHROME_BINARY" /usr/bin/chromium-browser \
         && mkdir -p "/home/${ARCHIVEBOX_USER}/.config/chromium/Crash Reports/pending/" \
    -    && chown -R $ARCHIVEBOX_USER "/home/${ARCHIVEBOX_USER}/.config" š\
    -    ; exit 0
    +    && chown -R $ARCHIVEBOX_USER "/home/${ARCHIVEBOX_USER}/.config" \
    +    ; if [[ "$TARGETPLATFORM" == "linux/arm/v7" ]]; then $exit 0; else exit 1
    +    # ignore failure for architectures where no playwright release is available yet
     
     # Install Node dependencies
     WORKDIR "$CODE_DIR"
    
    From 08cffb8742a752f61e3442c71be9bb08d8ad3244 Mon Sep 17 00:00:00 2001
    From: c01o <c01o@users.noreply.github.com>
    Date: Tue, 24 Oct 2023 19:58:23 +0900
    Subject: [PATCH 52/89] Fix docker build
    
    Lack of `fi` resulted in a syntax error.
    Also, change `;` to `||` to ensure it builds successfully on architectures other than `linux/arm/v7`.
    
    
    ```
    [2023-10-24T10:46:49.941Z] ------
     > [dev_container_auto_added_stage_label 11/18] RUN mkdir -p "/home/archivebox/.config/chromium/Crash Reports/pending/"     && chown -R archivebox "/home/archivebox/.config"     ; if [[ "linux/amd64" == "linux/arm/v7" ]]; then $exit 0; else exit 1:
    0.401 /bin/bash: -c: line 2: syntax error: unexpected end of file
    ------
    WARNING: buildx: git was not found in the system. Current commit information was not captured by the build
    [2023-10-24T10:46:49.942Z] Dockerfile-with-features:135
    --------------------
     134 |         && ln -s "$CHROME_BINARY" /usr/bin/chromium-browser
     135 | >>> RUN mkdir -p "/home/${ARCHIVEBOX_USER}/.config/chromium/Crash Reports/pending/" \
     136 | >>>     && chown -R $ARCHIVEBOX_USER "/home/${ARCHIVEBOX_USER}/.config" \
     137 | >>>     ; if [[ "$TARGETPLATFORM" == "linux/arm/v7" ]]; then $exit 0; else exit 1
     138 |         # ignore failure for architectures where no playwright release is available yet
    --------------------
    ERROR: failed to solve: process "/bin/bash -c mkdir -p \"/home/${ARCHIVEBOX_USER}/.config/chromium/Crash Reports/pending/\"     && chown -R $ARCHIVEBOX_USER \"/home/${ARCHIVEBOX_USER}/.config\"     ; if [[ \"$TARGETPLATFORM\" == \"linux/arm/v7\" ]]; then $exit 0; else exit 1" did not complete successfully: exit code: 2
    ```
    ---
     Dockerfile | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index 9d04023a..28019ad5 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -122,7 +122,7 @@ RUN echo "[+] Installing extractor Chromium dependency..." \
         && ln -s "$CHROME_BINARY" /usr/bin/chromium-browser \
         && mkdir -p "/home/${ARCHIVEBOX_USER}/.config/chromium/Crash Reports/pending/" \
         && chown -R $ARCHIVEBOX_USER "/home/${ARCHIVEBOX_USER}/.config" \
    -    ; if [[ "$TARGETPLATFORM" == "linux/arm/v7" ]]; then $exit 0; else exit 1
    +    || if [[ "$TARGETPLATFORM" == "linux/arm/v7" ]]; then exit 0; else exit 1; fi
         # ignore failure for architectures where no playwright release is available yet
     
     # Install Node dependencies
    
    From 8c25a81009ad03a17cc8707f9ff2ce8890e77fa1 Mon Sep 17 00:00:00 2001
    From: c01o <melty.antarcticite@gmail.com>
    Date: Fri, 27 Oct 2023 05:59:25 +0900
    Subject: [PATCH 53/89] Remove playwright from armv7
    
    ---
     README.md          |  1 +
     archivebox/main.py | 43 +++++++++++++++++++++++--------------------
     pyproject.toml     |  2 +-
     3 files changed, 25 insertions(+), 21 deletions(-)
    
    diff --git a/README.md b/README.md
    index 20dac770..58d58c13 100644
    --- a/README.md
    +++ b/README.md
    @@ -107,6 +107,7 @@ ls ./archive/*/index.json                 # or browse directly via the filesyste
     # Quickstart
     
     **🖥  Supported OSs:** Linux/BSD, macOS, Windows (Docker/WSL)   **👾  CPUs:** amd64, x86, arm8, arm7 <sup>(raspi>=3)</sup>
    +<i>Note: On arm7, the `playwright` package, provides easy `chromium` management, is not yet available. Do it manually with alternative methods.</i>
     
     <br/>
     
    diff --git a/archivebox/main.py b/archivebox/main.py
    index e56479f6..83adaba8 100755
    --- a/archivebox/main.py
    +++ b/archivebox/main.py
    @@ -976,27 +976,30 @@ def setup(out_dir: Path=OUTPUT_DIR) -> None:
                 stderr(f'[X] Failed to install python packages: {e}', color='red')
                 raise SystemExit(1)
     
    -    stderr('\n    Installing CHROME_BINARY automatically using playwright...')
    -    if CHROME_VERSION:
    -        print(f'{CHROME_VERSION} is already installed', CHROME_BINARY)
    +    if platform.machine() == 'armv7l':
    +        stderr('\n    Skip the automatic installation of CHROME_BINARY because playwright is not available on armv7.')
         else:
    -        try:
    -            run_shell([
    -                PYTHON_BINARY, '-m', 'pip',
    -                'install',
    -                '--upgrade',
    -                '--no-cache-dir',
    -                '--no-warn-script-location',
    -                'playwright',
    -            ], capture_output=False, cwd=out_dir)
    -            run_shell([PYTHON_BINARY, '-m', 'playwright', 'install', 'chromium'], capture_output=False, cwd=out_dir)
    -            proc = run_shell([PYTHON_BINARY, '-c', 'from playwright.sync_api import sync_playwright; print(sync_playwright().start().chromium.executable_path)'], capture_output=True, text=True, cwd=out_dir)
    -            NEW_CHROME_BINARY = proc.stdout.decode().strip() if isinstance(proc.stdout, bytes) else proc.stdout.strip()
    -            assert NEW_CHROME_BINARY and len(NEW_CHROME_BINARY), 'CHROME_BINARY must contain a path'
    -            config(f'CHROME_BINARY={NEW_CHROME_BINARY}', set=True, out_dir=out_dir)
    -        except BaseException as e:                                              # lgtm [py/catch-base-exception]
    -            stderr(f'[X] Failed to install chromium using playwright: {e.__class__.__name__} {e}', color='red')
    -            raise SystemExit(1)
    +        stderr('\n    Installing CHROME_BINARY automatically using playwright...')
    +        if CHROME_VERSION:
    +            print(f'{CHROME_VERSION} is already installed', CHROME_BINARY)
    +        else:
    +            try:
    +                run_shell([
    +                    PYTHON_BINARY, '-m', 'pip',
    +                    'install',
    +                    '--upgrade',
    +                    '--no-cache-dir',
    +                    '--no-warn-script-location',
    +                    'playwright',
    +                ], capture_output=False, cwd=out_dir)
    +                run_shell([PYTHON_BINARY, '-m', 'playwright', 'install', 'chromium'], capture_output=False, cwd=out_dir)
    +                proc = run_shell([PYTHON_BINARY, '-c', 'from playwright.sync_api import sync_playwright; print(sync_playwright().start().chromium.executable_path)'], capture_output=True, text=True, cwd=out_dir)
    +                NEW_CHROME_BINARY = proc.stdout.decode().strip() if isinstance(proc.stdout, bytes) else proc.stdout.strip()
    +                assert NEW_CHROME_BINARY and len(NEW_CHROME_BINARY), 'CHROME_BINARY must contain a path'
    +                config(f'CHROME_BINARY={NEW_CHROME_BINARY}', set=True, out_dir=out_dir)
    +            except BaseException as e:                                              # lgtm [py/catch-base-exception]
    +                stderr(f'[X] Failed to install chromium using playwright: {e.__class__.__name__} {e}', color='red')
    +                raise SystemExit(1)
     
         stderr('\n    Installing SINGLEFILE_BINARY, READABILITY_BINARY, MERCURY_BINARY automatically using npm...')
         if not NODE_VERSION:
    diff --git a/pyproject.toml b/pyproject.toml
    index aee8ac84..acd8571a 100644
    --- a/pyproject.toml
    +++ b/pyproject.toml
    @@ -18,7 +18,7 @@ dependencies = [
         "w3lib>=1.22.0",
         # "youtube-dl>=2021.04.17",
         "yt-dlp>=2021.4.11",
    -    "playwright>=1.39.0",
    +    "playwright>=1.39.0; platform_machine != 'armv7l'",
     ]
     requires-python = ">=3.9"
     readme = "README.md"
    
    From 619c5ae6a28f4115a5628a63c32f9e601109ccb6 Mon Sep 17 00:00:00 2001
    From: c01o <melty.antarcticite@gmail.com>
    Date: Fri, 27 Oct 2023 07:18:46 +0900
    Subject: [PATCH 54/89] Upgrade test python version
    
    `pyproject.toml` says the minimum requirement is python 3.9, no need to test on 3.7.
    Actually `setuptools 68.1.0+` requires `python 3.8+`.
    ---
     .github/workflows/test.yml | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
    index 50680030..c2c3336a 100644
    --- a/.github/workflows/test.yml
    +++ b/.github/workflows/test.yml
    @@ -14,7 +14,7 @@ jobs:
         strategy:
           matrix:
             os: [ubuntu-20.04, macos-latest, windows-latest]
    -        python: [3.7]
    +        python: [3.9]
     
         steps:
           - uses: actions/checkout@v2
    
    From bb1646ddc1dd6617f2a19c8909a861e3766d2b83 Mon Sep 17 00:00:00 2001
    From: c01o <melty.antarcticite@gmail.com>
    Date: Fri, 27 Oct 2023 07:21:55 +0900
    Subject: [PATCH 55/89] Fix python-tests dependency
    
    Starting from b6113cc, it requires `build` package to be built.
    ---
     .github/workflows/test.yml | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
    index c2c3336a..b19d9128 100644
    --- a/.github/workflows/test.yml
    +++ b/.github/workflows/test.yml
    @@ -51,7 +51,7 @@ jobs:
     
           - name: Install pip dependencies
             run: |
    -          python -m pip install --upgrade pip setuptools wheel pytest bottle
    +          python -m pip install --upgrade pip setuptools wheel pytest bottle build
               ./bin/build_pip.sh
               python -m pip install .
     
    
    From 18e89bee3d39349c137572cbe6d3a50a98e634be Mon Sep 17 00:00:00 2001
    From: mAAdhaTTah <jamesorodig@gmail.com>
    Date: Sun, 29 Oct 2023 17:27:04 -0400
    Subject: [PATCH 56/89] Fix readwise token
    
    Accidentally shipped this hard-coded. Token is long-size revoked,
    but obviously hard to use this way!
    ---
     archivebox/parsers/readwise_reader_api.py | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/archivebox/parsers/readwise_reader_api.py b/archivebox/parsers/readwise_reader_api.py
    index a2a0c29a..7dd44267 100644
    --- a/archivebox/parsers/readwise_reader_api.py
    +++ b/archivebox/parsers/readwise_reader_api.py
    @@ -32,7 +32,7 @@ class ReadwiseReaderAPI:
         def get_archive(self):
             response = requests.get(
                 url="https://readwise.io/api/v3/list/",
    -            headers={"Authorization": "Token s71gNtiNDWquEvlJFFUyDU10ao8fn99lGyNryvyllQcDSnrd7X"},
    +            headers={"Authorization": f"Token {self.api_token}"},
                 params={
                     "location": "archive",
                     "pageCursor": self.cursor,
    
    From e7795550fc7e92d8d22098e725ab8a97257751f3 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Mon, 30 Oct 2023 15:39:12 -0700
    Subject: [PATCH 57/89] add help message to permissions error output
    
    ---
     bin/docker_entrypoint.sh | 8 ++++----
     1 file changed, 4 insertions(+), 4 deletions(-)
    
    diff --git a/bin/docker_entrypoint.sh b/bin/docker_entrypoint.sh
    index b245968f..26d7e9f4 100755
    --- a/bin/docker_entrypoint.sh
    +++ b/bin/docker_entrypoint.sh
    @@ -22,9 +22,9 @@ if [[ -d "$DATA_DIR/archive" ]]; then
             rm "$DATA_DIR/archive/.permissions_test_safe_to_delete"
             # echo "[√] Permissions are correct"
         else
    -        echo "[X] Permissions Error: ArchiveBox is not able to write to your data dir. You need to fix the data dir ownership and retry:" >2
    -        echo "    chown -R $PUID:$PGID data" >2
    -        echo "    https://docs.linuxserver.io/general/understanding-puid-and-pgid" >2
    +        echo "[X] Error: ArchiveBox (uid=$PUID) is not able to write to your ./data dir. Fix the permissions and retry:" >2
    +        echo "    \$ chown -R $PUID:$PGID data" >2
    +        echo "    You may need to pass PUID & PGID to the Docker container: https://docs.linuxserver.io/general/understanding-puid-and-pgid" >2
             exit 1
         fi
     else
    @@ -34,7 +34,7 @@ fi
     chown $ARCHIVEBOX_USER:$ARCHIVEBOX_USER "$DATA_DIR" "$DATA_DIR"/*
     
     # Drop permissions to run commands as the archivebox user
    -if [[ "$1" == /* || "$1" == "echo" || "$1" == "archivebox" ]]; then
    +if [[ "$1" == /* || "$1" == "bash" || "$1" == "sh" || "$1" == "echo" || "$1" == "archivebox" ]]; then
         # arg 1 is a binary, execute it verbatim
         # e.g. "archivebox init"
         #      "/bin/bash"
    
    From db360dea1f2200fce5382e0d7231b30bf91dc924 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Mon, 30 Oct 2023 15:44:33 -0700
    Subject: [PATCH 58/89] Fix writing to stderr from docker entrypoint
    
    ---
     bin/docker_entrypoint.sh | 11 +++++++----
     1 file changed, 7 insertions(+), 4 deletions(-)
    
    diff --git a/bin/docker_entrypoint.sh b/bin/docker_entrypoint.sh
    index 26d7e9f4..29153908 100755
    --- a/bin/docker_entrypoint.sh
    +++ b/bin/docker_entrypoint.sh
    @@ -17,20 +17,23 @@ export PGID="$(id -g archivebox)"
     
     # Check the permissions of the data dir (or create if it doesn't exist)
     if [[ -d "$DATA_DIR/archive" ]]; then
    -    if touch "$DATA_DIR/archive/.permissions_test_safe_to_delete"; then
    +    if touch "$DATA_DIR/archive/.permissions_test_safe_to_delete" 2>/dev/null; then
             # It's fine, we are able to write to the data directory
             rm "$DATA_DIR/archive/.permissions_test_safe_to_delete"
             # echo "[√] Permissions are correct"
         else
    -        echo "[X] Error: ArchiveBox (uid=$PUID) is not able to write to your ./data dir. Fix the permissions and retry:" >2
    -        echo "    \$ chown -R $PUID:$PGID data" >2
    -        echo "    You may need to pass PUID & PGID to the Docker container: https://docs.linuxserver.io/general/understanding-puid-and-pgid" >2
    +        echo "[X] Error: ArchiveBox (uid=$PUID) is not able to write to your ./data dir. Fix the permissions and retry:" >&2
    +        echo "    \$ chown -R $PUID:$PGID data" >&2
    +        echo "    You may need to pass PUID & PGID to the Docker container: https://docs.linuxserver.io/general/understanding-puid-and-pgid" >&2
             exit 1
         fi
     else
         # create data directory
         mkdir -p "$DATA_DIR/logs"
     fi
    +
    +# force set the ownership of the data dir contents to the archivebox user and group
    +# this is needed because Docker Desktop often does not map user permissions from the host properly
     chown $ARCHIVEBOX_USER:$ARCHIVEBOX_USER "$DATA_DIR" "$DATA_DIR"/*
     
     # Drop permissions to run commands as the archivebox user
    
    From 9b0b7c6f645c643c645abd35eac7f44bb10ff8e2 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Mon, 30 Oct 2023 18:40:53 -0700
    Subject: [PATCH 59/89] remove setup.py and youtube-dl dependency
    
    ---
     setup.py  | 150 ------------------------------------------------------
     stdeb.cfg |   2 +-
     2 files changed, 1 insertion(+), 151 deletions(-)
     delete mode 100755 setup.py
    
    diff --git a/setup.py b/setup.py
    deleted file mode 100755
    index 330d89fe..00000000
    --- a/setup.py
    +++ /dev/null
    @@ -1,150 +0,0 @@
    -#####################################################################################
    -# THIS FILE IS DEPRECATED AND WILL BE REMOVED EVENTUALLU
    -# ALL FUTURE CHANGES SHOULD HAPPEN IN pyproject.toml with pdm
    -#####################################################################################
    -
    -# import json
    -# import setuptools
    -# from setuptools.command.test import test
    -
    -# from pathlib import Path
    -
    -
    -# PKG_NAME = "archivebox"
    -# DESCRIPTION = "Self-hosted internet archiving solution."
    -# LICENSE = "MIT"
    -# AUTHOR = "Nick Sweeting"
    -# AUTHOR_EMAIL="setup.py@archivebox.io"
    -# REPO_URL = "https://github.com/ArchiveBox/ArchiveBox"
    -# PROJECT_URLS = {
    -#     "Source":           f"{REPO_URL}",
    -#     "Documentation":    f"{REPO_URL}/wiki",
    -#     "Bug Tracker":      f"{REPO_URL}/issues",
    -#     "Changelog":        f"{REPO_URL}/releases",
    -#     "Roadmap":          f"{REPO_URL}/wiki/Roadmap",
    -#     "Community":        f"{REPO_URL}/wiki/Web-Archiving-Community",
    -#     "Demo":             f"https://demo.archivebox.io",
    -#     "Donate":           f"{REPO_URL}/wiki/Donations",
    -# }
    -
    -# ROOT_DIR = Path(__file__).parent.resolve()
    -# PACKAGE_DIR = ROOT_DIR / PKG_NAME
    -
    -# README = (PACKAGE_DIR / "README.md").read_text(encoding='utf-8', errors='ignore')
    -# VERSION = json.loads((PACKAGE_DIR / "package.json").read_text().strip())['version']
    -
    -# class DisabledTestCommand(test):
    -#     def run(self):
    -#         # setup.py test is deprecated, disable it here by force so stdeb doesnt run it
    -#         print('\n[X] Running tests via setup.py test is deprecated.')
    -#         print('    Hint: Use the ./bin/test.sh script or pytest instead')
    -
    -# To see when setup.py gets called (uncomment for debugging):
    -# import sys
    -# print(PACKAGE_DIR, f"     (v{VERSION})")
    -# print('>', sys.executable, *sys.argv)
    -
    -# PYTHON_REQUIRES = ">=3.9"
    -# SETUP_REQUIRES = ["wheel"]
    -# INSTALL_REQUIRES = [
    -#     # only add things here that have corresponding apt python3-packages available
    -#     # anything added here also needs to be added to our package dependencies in
    -#     # stdeb.cfg (apt), archivebox.rb (brew), Dockerfile, etc.
    -#     # if there is no apt python3-package equivalent, then vendor it instead in
    -#     # ./archivebox/vendor/
    -#     "requests>=2.24.0",
    -#     "mypy-extensions>=0.4.3",
    -#     "django>=3.1.3,<3.2",
    -#     "django-extensions>=3.0.3",
    -#     "dateparser>=1.0.0",
    -#     "youtube-dl>=2021.04.17",
    -#     "yt-dlp>=2021.4.11",
    -#     "python-crontab>=2.5.1",
    -#     "croniter>=0.3.34",
    -#     "w3lib>=1.22.0",
    -#     "ipython>5.0.0",
    -# ]
    -# EXTRAS_REQUIRE = {
    -#     'sonic': [
    -#         "sonic-client>=0.0.5",
    -#     ],
    -#     'ldap': [
    -#         "django-auth-ldap>=4.1.0",
    -#     ],
    -#     'dev': [
    -#         "setuptools",
    -#         "twine",
    -#         "wheel",
    -#         "flake8",
    -#         "ipdb",
    -#         "mypy",
    -#         "django-stubs",
    -#         "sphinx",
    -#         "sphinx-rtd-theme",
    -#         "recommonmark",
    -#         "pytest",
    -#         "bottle",
    -#         "stdeb",
    -#         "django-debug-toolbar",
    -#         "djdt_flamegraph",
    -#     ],
    -# }
    -#
    -# setuptools.setup(
    -#     name=PKG_NAME,
    -#     version=VERSION,
    -#     license=LICENSE,
    -#     author=AUTHOR,
    -#     author_email=AUTHOR_EMAIL,
    -#     description=DESCRIPTION,
    -#     long_description=README,
    -#     long_description_content_type="text/markdown",
    -#     url=REPO_URL,
    -#     project_urls=PROJECT_URLS,
    -#     python_requires=PYTHON_REQUIRES,
    -#     setup_requires=SETUP_REQUIRES,
    -#     install_requires=INSTALL_REQUIRES,
    -#     extras_require=EXTRAS_REQUIRE,
    -#     packages=[PKG_NAME],
    -#     include_package_data=True,   # see MANIFEST.in
    -#     entry_points={
    -#         "console_scripts": [
    -#             f"{PKG_NAME} = {PKG_NAME}.cli:main",
    -#         ],
    -#     },
    -#     classifiers=[
    -#         "License :: OSI Approved :: MIT License",
    -#         "Natural Language :: English",
    -#         "Operating System :: OS Independent",
    -#         "Development Status :: 4 - Beta",
    -
    -#         "Topic :: Utilities",
    -#         "Topic :: System :: Archiving",
    -#         "Topic :: System :: Archiving :: Backup",
    -#         "Topic :: System :: Recovery Tools",
    -#         "Topic :: Sociology :: History",
    -#         "Topic :: Internet :: WWW/HTTP",
    -#         "Topic :: Internet :: WWW/HTTP :: Indexing/Search",
    -#         "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
    -#         "Topic :: Software Development :: Libraries :: Python Modules",
    -
    -#         "Intended Audience :: Developers",
    -#         "Intended Audience :: Education",
    -#         "Intended Audience :: End Users/Desktop",
    -#         "Intended Audience :: Information Technology",
    -#         "Intended Audience :: Legal Industry",
    -#         "Intended Audience :: System Administrators",
    -        
    -#         "Environment :: Console",
    -#         "Environment :: Web Environment",
    -#         "Programming Language :: Python :: 3",
    -#         "Programming Language :: Python :: 3.7",
    -#         "Programming Language :: Python :: 3.8",
    -#         "Programming Language :: Python :: 3.9",
    -#         "Framework :: Django",
    -#         "Typing :: Typed",
    -#     ],
    -#     cmdclass={
    -#         "test": DisabledTestCommand,
    -#     },
    -# )
    diff --git a/stdeb.cfg b/stdeb.cfg
    index 21bd4f1f..40e03a13 100644
    --- a/stdeb.cfg
    +++ b/stdeb.cfg
    @@ -5,7 +5,7 @@ Package3: archivebox
     Suite: focal
     Suite3: focal
     Build-Depends: debhelper, dh-python, python3-all, python3-pip, python3-setuptools, python3-wheel, python3-stdeb
    -Depends3: nodejs, wget, curl, git, ffmpeg, youtube-dl, yt-dlp, python3-all, python3-pip, python3-setuptools, python3-croniter, python3-crontab, python3-dateparser, python3-django, python3-django-extensions, python3-django-jsonfield, python3-mypy-extensions, python3-requests, python3-w3lib, ripgrep
    +Depends3: nodejs, wget, curl, git, ffmpeg, yt-dlp, python3-all, python3-pip, python3-setuptools, python3-croniter, python3-crontab, python3-dateparser, python3-django, python3-django-extensions, python3-django-jsonfield, python3-mypy-extensions, python3-requests, python3-w3lib, ripgrep
     X-Python3-Version: >= 3.9
     XS-Python-Version: >= 3.9
     Setup-Env-Vars: DEB_BUILD_OPTIONS=nocheck
    
    From 3b005b5faf31bc88cdeec4cd240f112e7ecda75a Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Mon, 30 Oct 2023 18:48:10 -0700
    Subject: [PATCH 60/89] Add PDM
    
    ---
     .github/workflows/test.yml | 11 +++++++----
     1 file changed, 7 insertions(+), 4 deletions(-)
    
    diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
    index b19d9128..1a30133a 100644
    --- a/.github/workflows/test.yml
    +++ b/.github/workflows/test.yml
    @@ -24,15 +24,18 @@ jobs:
     
           ### Setup Python & JS Languages
           - name: Set up Python ${{ matrix.python }}
    -        uses: actions/setup-python@v1
    +        uses: actions/setup-python@v4
             with:
               python-version: ${{ matrix.python }}
               architecture: x64
     
           - name: Set up Node JS 14.7.0
    -        uses: actions/setup-node@v1
    +        uses: actions/setup-node@v3
             with:
    -          node-version: 14.7.0
    +          node-version: 18.12.0
    +
    +      - name: Setup PDM
    +        uses: pdm-project/setup-pdm@v3
     
           ### Install Python & JS Dependencies
           - name: Get pip cache dir
    @@ -53,7 +56,7 @@ jobs:
             run: |
               python -m pip install --upgrade pip setuptools wheel pytest bottle build
               ./bin/build_pip.sh
    -          python -m pip install .
    +          pdm install
     
           - name: Get npm cache dir
             id: npm-cache
    
    From 6b35c30e1741f633530264eb22a502ad12d95b3e Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Mon, 30 Oct 2023 23:25:51 -0700
    Subject: [PATCH 61/89] fix armv7 build for Docker and bare metal
    
    ---
     Dockerfile               | 219 +++++++++++++++++++++++++++------------
     bin/docker_entrypoint.sh |  40 +++----
     pyproject.toml           |   1 +
     3 files changed, 174 insertions(+), 86 deletions(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index 28019ad5..65003800 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -24,117 +24,192 @@ LABEL name="archivebox" \
         homepage="https://github.com/ArchiveBox/ArchiveBox" \
         documentation="https://github.com/ArchiveBox/ArchiveBox/wiki/Docker#docker"
     
    -######### Base System Setup ####################################
    +ARG TARGETPLATFORM
    +ARG TARGETARCH
    +ARG TARGETVARIANT
    +
    +######### Environment Variables #################################
     
     # Global system-level config
     ENV TZ=UTC \
         LANGUAGE=en_US:en \
         LC_ALL=C.UTF-8 \
         LANG=C.UTF-8 \
    -    PYTHONIOENCODING=UTF-8 \
    -    PYTHONUNBUFFERED=1 \
         DEBIAN_FRONTEND=noninteractive \
         APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 \
    +    PYTHONIOENCODING=UTF-8 \
    +    PYTHONUNBUFFERED=1 \
         npm_config_loglevel=error
     
    -# Application-level config
    +# Version config
    +ENV PYTHON_VERSION=3.11 \
    +    NODE_VERSION=21
    +
    +# User config
    +ENV ARCHIVEBOX_USER="archivebox" \
    +    DEFAULT_PUID=911 \
    +    DEFAULT_PGID=911
    +
    +# Global paths
     ENV CODE_DIR=/app \
         DATA_DIR=/data \
         GLOBAL_VENV=/venv \
    -    APP_VENV=/app/.venv \
    -    NODE_MODULES=/app/node_modules \
    -    ARCHIVEBOX_USER="archivebox"
    +    PLAYWRIGHT_BROWSERS_PATH=/browsers
     
    +# Application-level paths
    +ENV APP_VENV=/app/.venv \
    +    NODE_MODULES=/app/node_modules
    +
    +# Build shell config
     ENV PATH="$PATH:$GLOBAL_VENV/bin:$APP_VENV/bin:$NODE_MODULES/.bin"
    -SHELL ["/bin/bash", "-c"] 
    -ARG TARGETPLATFORM
    -ARG TARGETARCH
    -ARG TARGETVARIANT
    -RUN printf "[i] Building for TARGETPLATFORM=${TARGETPLATFORM}" \
    -    && printf ", TARGETARCH=${TARGETARCH}" \
    -    && printf ", TARGETVARIANT=${TARGETVARIANT} \n" \
    -    && printf "uname -a : " && uname -a
    +SHELL ["/bin/bash", "-o", "pipefail", "-c"] 
     
    +######### System Environment ####################################
    +
    +# Detect ArchiveBox version number by reading package.json
    +COPY --chown=root:root --chmod=755 package.json "$CODE_DIR/"
    +RUN grep '"version": ' "${CODE_DIR}/package.json" | awk -F'"' '{print $4}' > /VERSION.txt
    +
    +# Print debug info about build and save it to disk
    +RUN (echo "[i] Docker build for ArchiveBox $(cat /VERSION.txt) starting..." \
    +    && echo "PLATFORM=${TARGETPLATFORM} ARCH=$(uname -m) ($(uname -s) ${TARGETARCH} ${TARGETVARIANT})" \
    +    && echo "BUILD_START_TIME=$(date +"%Y-%m-%d %H:%M:%S %s") TZ=${TZ} LANG=${LANG}" \
    +    && echo \
    +    && echo "GLOBAL_VENV=${GLOBAL_VENV} APP_VENV=${APP_VENV} NODE_MODULES=${NODE_MODULES}" \
    +    && echo "PYTHON=${PYTHON_VERSION} NODE=${NODE_VERSION} PATH=${PATH}" \
    +    && echo "CODE_DIR=${CODE_DIR} DATA_DIR=${DATA_DIR}" \
    +    && echo \
    +    && uname -a \
    +    && cat /etc/os-release | head -n7 \
    +    && which bash && bash --version | head -n1 \
    +    && which dpkg && dpkg --version | head -n1 \
    +    && echo -e '\n\n' && env && echo -e '\n\n' \
    +    ) | tee -a /VERSION.txt
     
     # Create non-privileged user for archivebox and chrome
    -RUN echo "[*] Setting up system environment..." \
    +RUN echo "[*] Setting up $ARCHIVEBOX_USER user ${DEFAULT_PUID}..." \
         && groupadd --system $ARCHIVEBOX_USER \
         && useradd --system --create-home --gid $ARCHIVEBOX_USER --groups audio,video $ARCHIVEBOX_USER \
    -    && mkdir -p /etc/apt/keyrings
    +    && usermod -u "$DEFAULT_PUID" "$ARCHIVEBOX_USER" \
    +    && groupmod -g "$DEFAULT_PGID" "$ARCHIVEBOX_USER" \
    +    && echo -e "\nARCHIVEBOX_USER=$ARCHIVEBOX_USER PUID=$(id -u $ARCHIVEBOX_USER) PGID=$(id -g $ARCHIVEBOX_USER)\n\n" \
    +    | tee -a /VERSION.txt
    +    # DEFAULT_PUID and DEFAULT_PID are overriden by PUID and PGID in /bin/docker_entrypoint.sh at runtime
    +    # https://docs.linuxserver.io/general/understanding-puid-and-pgid
     
     # Install system apt dependencies (adding backports to access more recent apt updates)
    -RUN echo "[+] Installing system dependencies..." \
    -    && echo 'deb https://deb.debian.org/debian bookworm-backports main contrib non-free' >> /etc/apt/sources.list.d/backports.list \
    -    && apt-get update -qq \
    -    && apt-get install -qq -y \
    -        apt-transport-https ca-certificates gnupg2 curl wget \
    -        zlib1g-dev dumb-init gosu cron unzip \
    -        # nano iputils-ping dnsutils htop procps \
    -        # 1. packaging dependencies
    -        # 2. docker and init system dependencies
    -        # 3. frivolous CLI helpers to make debugging failed archiving easier
    +RUN echo "[+] Installing system dependencies for $TARGETPLATFORM..." \
    +    # && echo 'deb https://deb.debian.org/debian bookworm-backports main contrib non-free' >> /etc/apt/sources.list.d/backports.list \
         && mkdir -p /etc/apt/keyrings \
    +    && apt-get update -qq \
    +    && apt-get install -qq -y --no-install-recommends \
    +        # 1. packaging dependencies
    +        apt-transport-https ca-certificates gnupg2 curl wget \
    +        # 2. docker and init system dependencies
    +        zlib1g-dev dumb-init gosu cron unzip grep \
    +        # 3. frivolous CLI helpers to make debugging failed archiving easier
    +        # nano iputils-ping dnsutils htop procps jq yq
         && rm -rf /var/lib/apt/lists/*
     
    -
     ######### Language Environments ####################################
     
     # Install Node environment
    -RUN echo "[+] Installing Node environment..." \
    -    && echo 'deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_21.x nodistro main' >> /etc/apt/sources.list.d/nodejs.list \
    +RUN echo "[+] Installing Node $NODE_VERSION environment..." \
    +    && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_VERSION}.x nodistro main" >> /etc/apt/sources.list.d/nodejs.list \
         && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
         && apt-get update -qq \
    -    && apt-get install -qq -y nodejs libatomic1 \
    +    && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    +        nodejs libatomic1 \
    +    && rm -rf /var/lib/apt/lists/* \
    +    # Update NPM to latest version
         && npm i -g npm \
    -    && node --version \
    -    && npm --version
    +    # Save version info
    +    && ( \
    +        which node && node --version \
    +        && which npm && npm --version \
    +        && echo -e '\n\n' \
    +    ) | tee -a /VERSION.txt
     
     # Install Python environment
    -RUN echo "[+] Installing Python environment..." \
    +RUN echo "[+] Installing Python $PYTHON_VERSION environment..." \
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
             python3 python3-pip python3-venv python3-setuptools python3-wheel python-dev-is-python3 \
             python3-ldap libldap2-dev libsasl2-dev libssl-dev python3-msgpack \
    +    && rm -rf /var/lib/apt/lists/* \
    +    # tell PDM to allow using global system python site packages
         && rm /usr/lib/python3*/EXTERNALLY-MANAGED \
    +    # create global virtual environment GLOBAL_VENV to use (better than using pip install --global)
         && python3 -m venv --system-site-packages --symlinks $GLOBAL_VENV \
    +    # install global dependencies / python build dependencies in GLOBAL_VENV
         && $GLOBAL_VENV/bin/pip install --upgrade pip pdm setuptools wheel python-ldap \
    -    && rm -rf /var/lib/apt/lists/*
    +    # Save version info
    +    && ( \
    +        which python3 && python3 --version | grep " $PYTHON_VERSION" \
    +        && which pip3 && pip3 --version \
    +        && which pdm && pdm --version \
    +        && echo -e '\n\n' \
    +    ) | tee -a /VERSION.txt
     
     ######### Extractor Dependencies ##################################
     
     # Install apt dependencies
    -RUN echo "[+] Installing extractor APT dependencies..." \
    +RUN echo "[+] Installing APT extractor dependencies..." \
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
             curl wget git yt-dlp ffmpeg ripgrep \
             # Packages we have also needed in the past:
             # youtube-dl wget2 aria2 python3-pyxattr rtmpdump libfribidi-bin mpv \
             # fontconfig fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-symbola fonts-noto fonts-freefont-ttf \
    -    && rm -rf /var/lib/apt/lists/*
    +    && rm -rf /var/lib/apt/lists/* \
    +    # Save version info
    +    && ( \
    +        which curl && curl --version | head -n1 \
    +        && which wget && wget --version | head -n1 \
    +        && which yt-dlp && yt-dlp --version | head -n1 \
    +        && which git && git --version | head -n1 \
    +        && which rg && rg --version | head -n1 \
    +        && echo -e '\n\n' \
    +    ) | tee -a /VERSION.txt
     
     # Install chromium browser using playwright
    -ENV PLAYWRIGHT_BROWSERS_PATH="/browsers"
    -RUN echo "[+] Installing extractor Chromium dependency..." \
    +RUN echo "[+] Installing Browser binary dependencies for $TARGETPLATFORM..." \
         && apt-get update -qq \
    -    && $GLOBAL_VENV/bin/pip install playwright \
    -    && $GLOBAL_VENV/bin/playwright install --with-deps chromium \
    -    && CHROME_BINARY="$($GLOBAL_VENV/bin/python -c 'from playwright.sync_api import sync_playwright; print(sync_playwright().start().chromium.executable_path)')" \
    +    && if [[ "$TARGETPLATFORM" == "linux/amd64" || "$TARGETPLATFORM" == "linux/arm64" ]]; then \
    +        # install Chromium using playwright
    +        $GLOBAL_VENV/bin/pip install playwright \
    +        && $GLOBAL_VENV/bin/playwright install --with-deps chromium \
    +        && export CHROME_BINARY="$($GLOBAL_VENV/bin/python -c 'from playwright.sync_api import sync_playwright; print(sync_playwright().start().chromium.executable_path)')"; \
    +    else \
    +        # install Chromium on platforms not supported by playwright (e.g. risc, ARMv7, etc.) 
    +        apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    +            chromium fontconfig fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-symbola fonts-noto fonts-freefont-ttf \
    +        && export CHROME_BINARY="$(which chromium)"; \
    +    fi \
    +    && rm -rf /var/lib/apt/lists/* \
         && ln -s "$CHROME_BINARY" /usr/bin/chromium-browser \
         && mkdir -p "/home/${ARCHIVEBOX_USER}/.config/chromium/Crash Reports/pending/" \
         && chown -R $ARCHIVEBOX_USER "/home/${ARCHIVEBOX_USER}/.config" \
    -    || if [[ "$TARGETPLATFORM" == "linux/arm/v7" ]]; then exit 0; else exit 1; fi
    -    # ignore failure for architectures where no playwright release is available yet
    +    # Save version info
    +    && ( \
    +        which chromium-browser && /usr/bin/chromium-browser --version \
    +        && echo -e '\n\n' \
    +    ) | tee -a /VERSION.txt
     
     # Install Node dependencies
     WORKDIR "$CODE_DIR"
     COPY --chown=root:root --chmod=755 "package.json" "package-lock.json" "$CODE_DIR/"
    -RUN echo "[+] Installing extractor Node dependencies..." \
    +RUN echo "[+] Installing NPM extractor dependencies..." \
         && npm ci --prefer-offline --no-audit \
    -    && npm version
    +    && ( \
    +        which node && node --version \
    +        && which npm && npm version \
    +        && echo -e '\n\n' \
    +    ) | tee -a /VERSION.txt
     
     ######### Build Dependencies ####################################
     
    -# # Building ArchiveBox from source with all pdm dev dependencies
    +# # Install ArchiveBox development dependencies
     # WORKDIR "$CODE_DIR"
     # COPY --chown=root:root --chmod=755 "./pyproject.toml" "./pdm.lock" "$CODE_DIR/"
     # RUN echo "[+] Installing project Python dependencies..." \
    @@ -152,38 +227,48 @@ RUN echo "[+] Installing extractor Node dependencies..." \
     
     # Install ArchiveBox Python package from source
     COPY --chown=root:root --chmod=755 "." "$CODE_DIR/"
    -RUN echo "[*] Installing ArchiveBox package from /app..." \
    +RUN echo "[*] Installing PIP ArchiveBox package from $CODE_DIR..." \
         && apt-get update -qq \
    -    && $GLOBAL_VENV/bin/pip install -e "$CODE_DIR"[sonic,ldap]
    +    # install C compiler to build deps on platforms that dont have 32-bit wheels available on pypi
    +    && [[ "$TARGETPLATFORM" == "linux/arm/v7" ]] \
    +        && apt-get install -qq -y --no-install-recommends build-essential python3-regex \
    +    # INSTALL ARCHIVEBOX python package globally from CODE_DIR, with all optional dependencies
    +    && $GLOBAL_VENV/bin/pip3 install -e "$CODE_DIR"[sonic,ldap] \
    +    # save docker image size and always remove compilers / build tools after building is complete
    +    && apt-get purge -y build-essential \
    +    && apt-get autoremove -y \
    +    && rm -rf /var/lib/apt/lists/*
     
     ####################################################
     
     # Setup ArchiveBox runtime config
     WORKDIR "$DATA_DIR"
    -ENV IN_DOCKER=True \
    -    WGET_BINARY="wget" \
    -    YOUTUBEDL_BINARY="yt-dlp" \
    -    CHROME_SANDBOX=False \
    -    CHROME_BINARY="/usr/bin/chromium-browser" \
    -    USE_SINGLEFILE=True \
    -    SINGLEFILE_BINARY="$NODE_MODULES/.bin/single-file" \
    -    USE_READABILITY=True \
    -    READABILITY_BINARY="$NODE_MODULES/.bin/readability-extractor" \
    -    USE_MERCURY=True \
    -    MERCURY_BINARY="$NODE_MODULES/.bin/postlight-parser"
    +ENV IN_DOCKER=True
    +    ## No need to set explicitly, these values will be autodetected by archivebox in docker:
    +    # CHROME_SANDBOX=False \
    +    # WGET_BINARY="wget" \
    +    # YOUTUBEDL_BINARY="yt-dlp" \
    +    # CHROME_BINARY="/usr/bin/chromium-browser" \
    +    # USE_SINGLEFILE=True \
    +    # SINGLEFILE_BINARY="$NODE_MODULES/.bin/single-file" \
    +    # USE_READABILITY=True \
    +    # READABILITY_BINARY="$NODE_MODULES/.bin/readability-extractor" \
    +    # USE_MERCURY=True \
    +    # MERCURY_BINARY="$NODE_MODULES/.bin/postlight-parser"
     
     # Print version for nice docker finish summary
    -# RUN archivebox version
    -RUN echo "[√] Finished Docker build succesfully. Saving build summary in: /version_info.txt" \
    -    && uname -a | tee -a /version_info.txt \
    -    && env --chdir="$NODE_DIR" npm version | tee -a /version_info.txt \
    -    && env --chdir="$CODE_DIR" pdm info | tee -a /version_info.txt \
    -    && "$CODE_DIR/bin/docker_entrypoint.sh" archivebox version 2>&1 | tee -a /version_info.txt
    +RUN (echo -e "\n\n[√] Finished Docker build succesfully. Saving build summary in: /VERSION.txt" \
    +    && echo -e "PLATFORM=${TARGETPLATFORM} ARCH=$(uname -m) ($(uname -s) ${TARGETARCH} ${TARGETVARIANT})" \
    +    && echo -e "BUILD_END_TIME=$(date +"%Y-%m-%d %H:%M:%S %s") TZ=${TZ}\n\n" \
    +    && "$CODE_DIR/bin/docker_entrypoint.sh" \
    +        archivebox version 2>&1 \
    +    ) | tee -a /VERSION.txt
     
     ####################################################
     
     # Open up the interfaces to the outside world
    -VOLUME "/data"
    +WORKDIR "$DATA_DIR"
    +VOLUME "$DATA_DIR"
     EXPOSE 8000
     
     # Optional:
    diff --git a/bin/docker_entrypoint.sh b/bin/docker_entrypoint.sh
    index 29153908..4b31fb08 100755
    --- a/bin/docker_entrypoint.sh
    +++ b/bin/docker_entrypoint.sh
    @@ -3,18 +3,18 @@
     DATA_DIR="${DATA_DIR:-/data}"
     ARCHIVEBOX_USER="${ARCHIVEBOX_USER:-archivebox}"
     
    +export PUID=${PUID:-911}
    +export PGID=${PGID:-911}
     
     # Set the archivebox user UID & GID
    -if [[ -n "$PUID" && "$PUID" != 0 ]]; then
    -    usermod -u "$PUID" "$ARCHIVEBOX_USER" > /dev/null 2>&1
    -fi
    -if [[ -n "$PGID" && "$PGID" != 0 ]]; then
    -    groupmod -g "$PGID" "$ARCHIVEBOX_USER" > /dev/null 2>&1
    -fi
    +usermod -o -u "$PUID" "$ARCHIVEBOX_USER" > /dev/null 2>&1
    +groupmod -o -g "$PGID" "$ARCHIVEBOX_USER" > /dev/null 2>&1
     
     export PUID="$(id -u archivebox)"
     export PGID="$(id -g archivebox)"
     
    +chown $ARCHIVEBOX_USER:$ARCHIVEBOX_USER "$DATA_DIR"
    +
     # Check the permissions of the data dir (or create if it doesn't exist)
     if [[ -d "$DATA_DIR/archive" ]]; then
         if touch "$DATA_DIR/archive/.permissions_test_safe_to_delete" 2>/dev/null; then
    @@ -22,9 +22,11 @@ if [[ -d "$DATA_DIR/archive" ]]; then
             rm "$DATA_DIR/archive/.permissions_test_safe_to_delete"
             # echo "[√] Permissions are correct"
         else
    -        echo "[X] Error: ArchiveBox (uid=$PUID) is not able to write to your ./data dir. Fix the permissions and retry:" >&2
    -        echo "    \$ chown -R $PUID:$PGID data" >&2
    -        echo "    You may need to pass PUID & PGID to the Docker container: https://docs.linuxserver.io/general/understanding-puid-and-pgid" >&2
    +        echo -e "\n[X] Error: archivebox user (PUID=$PUID) is not able to write to your ./data dir." >&2
    +        echo -e "    Change ./data to be owned by PUID=$PUID PGID=$PGID on the host and retry:"
    +        echo -e "       \$ chown -R $PUID:$PGID ./data\n" >&2
    +        echo -e "    Configure the PUID & PGID environment variables to change the desired owner:" >&2
    +        echo -e "       https://docs.linuxserver.io/general/understanding-puid-and-pgid\n" >&2
             exit 1
         fi
     else
    @@ -34,19 +36,19 @@ fi
     
     # force set the ownership of the data dir contents to the archivebox user and group
     # this is needed because Docker Desktop often does not map user permissions from the host properly
    -chown $ARCHIVEBOX_USER:$ARCHIVEBOX_USER "$DATA_DIR" "$DATA_DIR"/*
    +chown $ARCHIVEBOX_USER:$ARCHIVEBOX_USER "$DATA_DIR"/*
     
     # Drop permissions to run commands as the archivebox user
    -if [[ "$1" == /* || "$1" == "bash" || "$1" == "sh" || "$1" == "echo" || "$1" == "archivebox" ]]; then
    -    # arg 1 is a binary, execute it verbatim
    -    # e.g. "archivebox init"
    -    #      "/bin/bash"
    -    #      "echo"
    +if [[ "$1" == /* || "$1" == "bash" || "$1" == "sh" || "$1" == "echo" || "$1" == "cat" || "$1" == "archivebox" ]]; then
    +    # handle "docker run archivebox /some/non-archivebox/command" by executing args as direct bash command
    +    # e.g. "docker run archivebox /venv/bin/archivebox-alt init"
    +    #      "docker run archivebox /bin/bash -c '...'"
    +    #      "docker run archivebox echo test"
         exec gosu "$ARCHIVEBOX_USER" bash -c "$*"
     else
    -    # no command given, assume args were meant to be passed to archivebox cmd
    -    # e.g. "add https://example.com"
    -    #      "manage createsupseruser"
    -    #      "server 0.0.0.0:8000"
    +    # handle "docker run archivebox add ..." by running args as archivebox $subcommand
    +    # e.g. "docker run archivebox add https://example.com"
    +    #      "docker run archivebox manage createsupseruser"
    +    #      "docker run archivebox server 0.0.0.0:8000"
         exec gosu "$ARCHIVEBOX_USER" bash -c "archivebox $*"
     fi
    diff --git a/pyproject.toml b/pyproject.toml
    index acd8571a..b696600c 100644
    --- a/pyproject.toml
    +++ b/pyproject.toml
    @@ -63,6 +63,7 @@ build = [
         "stdeb",
         "twine",
         "wheel",
    +    "regex=2021.9.30; platform_machine == 'armv7l'",
     ]
     lint = [
         "flake8",
    
    From d46c9b9bc8d4f1e672e8122e7f767ee71ac1dd26 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Mon, 30 Oct 2023 23:28:49 -0700
    Subject: [PATCH 62/89] bump pip dist folder
    
    ---
     dist     | 1 +
     pip_dist | 2 +-
     2 files changed, 2 insertions(+), 1 deletion(-)
     create mode 120000 dist
    
    diff --git a/dist b/dist
    new file mode 120000
    index 00000000..7bc6c67a
    --- /dev/null
    +++ b/dist
    @@ -0,0 +1 @@
    +./pip_dist
    \ No newline at end of file
    diff --git a/pip_dist b/pip_dist
    index 53499857..51aed48d 160000
    --- a/pip_dist
    +++ b/pip_dist
    @@ -1 +1 @@
    -Subproject commit 534998571c9a2ddff462a9c8f3ed5ea825f91958
    +Subproject commit 51aed48def01e10bc51a71cb88c506026ad19d31
    
    From 2ab4be71c135f25b3059658e26b17e765a7790ca Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Mon, 30 Oct 2023 23:33:29 -0700
    Subject: [PATCH 63/89] Add instructions to run specific branch in docker
     compose
    
    ---
     README.md | 9 ++++++++-
     1 file changed, 8 insertions(+), 1 deletion(-)
    
    diff --git a/README.md b/README.md
    index 58d58c13..c2653833 100644
    --- a/README.md
    +++ b/README.md
    @@ -947,7 +947,14 @@ https://stackoverflow.com/questions/1074212/how-can-i-see-the-raw-sql-queries-dj
     
     <details><summary><i>Click to expand...</i></summary>
     
    -```bash
    +```bash|
    +# docker-compose.yml:
    +services:
    +    archivebox:
    +        image: archivebox/archivebox:dev
    +        build: 'https://github.com/ArchiveBox/ArchiveBox.git#dev'
    +        ...
    +
     # docker:
     docker build -t archivebox:dev https://github.com/ArchiveBox/ArchiveBox.git#dev
     docker run -it -v $PWD:/data archivebox:dev init --setup
    
    From a677ef7113001894f68acffc03714e5e6b456c03 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Mon, 30 Oct 2023 23:34:24 -0700
    Subject: [PATCH 64/89] fix conditional on architecture
    
    ---
     Dockerfile | 5 +++--
     1 file changed, 3 insertions(+), 2 deletions(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index 65003800..cc4c8c7b 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -230,8 +230,9 @@ COPY --chown=root:root --chmod=755 "." "$CODE_DIR/"
     RUN echo "[*] Installing PIP ArchiveBox package from $CODE_DIR..." \
         && apt-get update -qq \
         # install C compiler to build deps on platforms that dont have 32-bit wheels available on pypi
    -    && [[ "$TARGETPLATFORM" == "linux/arm/v7" ]] \
    -        && apt-get install -qq -y --no-install-recommends build-essential python3-regex \
    +    && if [[ "$TARGETPLATFORM" == "linux/arm/v7" ]]; then \
    +        apt-get install -qq -y --no-install-recommends build-essential python3-regex; \
    +    fi \
         # INSTALL ARCHIVEBOX python package globally from CODE_DIR, with all optional dependencies
         && $GLOBAL_VENV/bin/pip3 install -e "$CODE_DIR"[sonic,ldap] \
         # save docker image size and always remove compilers / build tools after building is complete
    
    From 019c012951cc9ea90aefdd35b7e67be9c5dfa2b9 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Mon, 30 Oct 2023 23:42:12 -0700
    Subject: [PATCH 65/89] fix entrypoint chowning
    
    ---
     bin/docker_entrypoint.sh | 16 +++++++---------
     1 file changed, 7 insertions(+), 9 deletions(-)
    
    diff --git a/bin/docker_entrypoint.sh b/bin/docker_entrypoint.sh
    index 4b31fb08..964a90f5 100755
    --- a/bin/docker_entrypoint.sh
    +++ b/bin/docker_entrypoint.sh
    @@ -1,20 +1,17 @@
     #!/bin/bash
     
    -DATA_DIR="${DATA_DIR:-/data}"
    -ARCHIVEBOX_USER="${ARCHIVEBOX_USER:-archivebox}"
    -
    +export DATA_DIR="${DATA_DIR:-/data}"
    +export ARCHIVEBOX_USER="${ARCHIVEBOX_USER:-archivebox}"
     export PUID=${PUID:-911}
     export PGID=${PGID:-911}
     
     # Set the archivebox user UID & GID
    -usermod -o -u "$PUID" "$ARCHIVEBOX_USER" > /dev/null 2>&1
     groupmod -o -g "$PGID" "$ARCHIVEBOX_USER" > /dev/null 2>&1
    +usermod -o -u "$PUID" "$ARCHIVEBOX_USER" > /dev/null 2>&1
     
     export PUID="$(id -u archivebox)"
     export PGID="$(id -g archivebox)"
     
    -chown $ARCHIVEBOX_USER:$ARCHIVEBOX_USER "$DATA_DIR"
    -
     # Check the permissions of the data dir (or create if it doesn't exist)
     if [[ -d "$DATA_DIR/archive" ]]; then
         if touch "$DATA_DIR/archive/.permissions_test_safe_to_delete" 2>/dev/null; then
    @@ -36,7 +33,8 @@ fi
     
     # force set the ownership of the data dir contents to the archivebox user and group
     # this is needed because Docker Desktop often does not map user permissions from the host properly
    -chown $ARCHIVEBOX_USER:$ARCHIVEBOX_USER "$DATA_DIR"/*
    +chown $PUID:$PGID "$DATA_DIR"
    +chown $PUID:$PGID "$DATA_DIR"/*
     
     # Drop permissions to run commands as the archivebox user
     if [[ "$1" == /* || "$1" == "bash" || "$1" == "sh" || "$1" == "echo" || "$1" == "cat" || "$1" == "archivebox" ]]; then
    @@ -44,11 +42,11 @@ if [[ "$1" == /* || "$1" == "bash" || "$1" == "sh" || "$1" == "echo" || "$1" ==
         # e.g. "docker run archivebox /venv/bin/archivebox-alt init"
         #      "docker run archivebox /bin/bash -c '...'"
         #      "docker run archivebox echo test"
    -    exec gosu "$ARCHIVEBOX_USER" bash -c "$*"
    +    exec gosu "$PUID" bash -c "$*"
     else
         # handle "docker run archivebox add ..." by running args as archivebox $subcommand
         # e.g. "docker run archivebox add https://example.com"
         #      "docker run archivebox manage createsupseruser"
         #      "docker run archivebox server 0.0.0.0:8000"
    -    exec gosu "$ARCHIVEBOX_USER" bash -c "archivebox $*"
    +    exec gosu "$PUID" bash -c "archivebox $*"
     fi
    
    From ce76c324a5b74024d6904ab5795de54fe3aebb20 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Mon, 30 Oct 2023 23:50:27 -0700
    Subject: [PATCH 66/89] autodetect uid and gid from data dir contents
    
    ---
     bin/docker_entrypoint.sh | 13 +++++++++----
     1 file changed, 9 insertions(+), 4 deletions(-)
    
    diff --git a/bin/docker_entrypoint.sh b/bin/docker_entrypoint.sh
    index 964a90f5..92fb46a6 100755
    --- a/bin/docker_entrypoint.sh
    +++ b/bin/docker_entrypoint.sh
    @@ -2,13 +2,18 @@
     
     export DATA_DIR="${DATA_DIR:-/data}"
     export ARCHIVEBOX_USER="${ARCHIVEBOX_USER:-archivebox}"
    -export PUID=${PUID:-911}
    -export PGID=${PGID:-911}
     
    -# Set the archivebox user UID & GID
    +# if data directory already exists, autodetect detect owner by looking at files within
    +DETECTED_UID="$(stat -c '%u' "$DATA_DIR/logs/errors.log" 2>/dev/null || echo 911)"
    +DETECTED_GID="$(stat -c '%g' "$DATA_DIR/logs/errors.log" 2>/dev/null || echo 911)"
    +
    +# prefer PUID and PGID passsed in explicitly as env vars to autodetected defaults
    +export PUID=${PUID:-$DETECTED_UID}
    +export PGID=${PGID:-$DETECTED_GID}
    +
    +# Set the archivebox user to use the configured UID & GID
     groupmod -o -g "$PGID" "$ARCHIVEBOX_USER" > /dev/null 2>&1
     usermod -o -u "$PUID" "$ARCHIVEBOX_USER" > /dev/null 2>&1
    -
     export PUID="$(id -u archivebox)"
     export PGID="$(id -g archivebox)"
     
    
    From 1bfbf5e9c3c7e49c347ac47786ca077a0d467b4c Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Mon, 30 Oct 2023 23:58:13 -0700
    Subject: [PATCH 67/89] add pip packages build step
    
    ---
     Dockerfile     | 29 ++++++++++++++---------------
     pdm.lock       | 16 +++-------------
     pyproject.toml |  1 -
     3 files changed, 17 insertions(+), 29 deletions(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index cc4c8c7b..9d935955 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -209,21 +209,20 @@ RUN echo "[+] Installing NPM extractor dependencies..." \
     
     ######### Build Dependencies ####################################
     
    -# # Install ArchiveBox development dependencies
    -# WORKDIR "$CODE_DIR"
    -# COPY --chown=root:root --chmod=755 "./pyproject.toml" "./pdm.lock" "$CODE_DIR/"
    -# RUN echo "[+] Installing project Python dependencies..." \
    -#     && apt-get update -qq \
    -#     && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    -#         build-essential libssl-dev libldap2-dev libsasl2-dev \
    -#     && pdm use -f $GLOBAL_VENV \
    -#     && pdm install --fail-fast --no-lock --group :all --no-self \
    -#     && pdm build \
    -#     && apt-get purge -y \
    -#         build-essential libssl-dev libldap2-dev libsasl2-dev \
    -#         # these are only needed to build CPython libs, we discard after build phase to shrink layer size
    -#     && apt-get autoremove -y \
    -#     && rm -rf /var/lib/apt/lists/*
    +# Install ArchiveBox Python dependencies
    +WORKDIR "$CODE_DIR"
    +COPY --chown=root:root --chmod=755 "./pyproject.toml" "./pdm.lock" "$CODE_DIR/"
    +RUN echo "[+] Installing PIP ArchiveBox dependencies..." \
    +    && apt-get update -qq \
    +    && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    +        build-essential libssl-dev libldap2-dev libsasl2-dev \
    +    && pdm use -f $GLOBAL_VENV \
    +    && pdm install --fail-fast --no-lock --prod --no-self \
    +    && apt-get purge -y \
    +        build-essential libssl-dev libldap2-dev libsasl2-dev \
    +        # these are only needed to build CPython libs, we discard after build phase to shrink layer size
    +    && apt-get autoremove -y \
    +    && rm -rf /var/lib/apt/lists/*
     
     # Install ArchiveBox Python package from source
     COPY --chown=root:root --chmod=755 "." "$CODE_DIR/"
    diff --git a/pdm.lock b/pdm.lock
    index daa74436..d2d83727 100644
    --- a/pdm.lock
    +++ b/pdm.lock
    @@ -3,10 +3,9 @@
     
     [metadata]
     groups = ["default", "build", "debug", "doc", "ldap", "lint", "sonic", "test"]
    -cross_platform = true
    -static_urls = false
    -lock_version = "4.3"
    -content_hash = "sha256:ae301f566235b00b28cb62a560f1ff1e30f2e0f3e16b0ddae12e97502214b02c"
    +strategy = ["cross_platform"]
    +lock_version = "4.4"
    +content_hash = "sha256:827692ea8b95a8d0033ad1ae915f475e8b5cc46bafd947499ca892d516125c68"
     
     [[package]]
     name = "alabaster"
    @@ -2039,15 +2038,6 @@ files = [
         {file = "wheel-0.41.2.tar.gz", hash = "sha256:0c5ac5ff2afb79ac23ab82bab027a0be7b5dbcf2e54dc50efe4bf507de1f7985"},
     ]
     
    -[[package]]
    -name = "youtube-dl"
    -version = "2021.12.17"
    -summary = "YouTube video downloader"
    -files = [
    -    {file = "youtube_dl-2021.12.17-py2.py3-none-any.whl", hash = "sha256:f1336d5de68647e0364a47b3c0712578e59ec76f02048ff5c50ef1c69d79cd55"},
    -    {file = "youtube_dl-2021.12.17.tar.gz", hash = "sha256:bc59e86c5d15d887ac590454511f08ce2c47698d5a82c27bfe27b5d814bbaed2"},
    -]
    -
     [[package]]
     name = "yt-dlp"
     version = "2023.10.13"
    diff --git a/pyproject.toml b/pyproject.toml
    index b696600c..acd8571a 100644
    --- a/pyproject.toml
    +++ b/pyproject.toml
    @@ -63,7 +63,6 @@ build = [
         "stdeb",
         "twine",
         "wheel",
    -    "regex=2021.9.30; platform_machine == 'armv7l'",
     ]
     lint = [
         "flake8",
    
    From 32e363848e8e5140018470d2a27bbe4af146b126 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 00:00:09 -0700
    Subject: [PATCH 68/89] install all optionall dependencies in docker
    
    ---
     Dockerfile | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index 9d935955..252615ff 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -217,7 +217,7 @@ RUN echo "[+] Installing PIP ArchiveBox dependencies..." \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
             build-essential libssl-dev libldap2-dev libsasl2-dev \
         && pdm use -f $GLOBAL_VENV \
    -    && pdm install --fail-fast --no-lock --prod --no-self \
    +    && pdm install --fail-fast --no-lock --group :all --no-self \
         && apt-get purge -y \
             build-essential libssl-dev libldap2-dev libsasl2-dev \
             # these are only needed to build CPython libs, we discard after build phase to shrink layer size
    
    From 166573d4172798eaf154f276db74b01594dd1681 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 00:23:19 -0700
    Subject: [PATCH 69/89] autodetect qemu and warn about broken chrome in
     emulated containers
    
    ---
     archivebox/config.py     | 1 +
     archivebox/main.py       | 4 +++-
     bin/docker_entrypoint.sh | 8 ++++++++
     3 files changed, 12 insertions(+), 1 deletion(-)
    
    diff --git a/archivebox/config.py b/archivebox/config.py
    index e07af3d7..67d84d93 100644
    --- a/archivebox/config.py
    +++ b/archivebox/config.py
    @@ -77,6 +77,7 @@ CONFIG_SCHEMA: Dict[str, ConfigDefaultDict] = {
             'USE_COLOR':                {'type': bool,  'default': lambda c: c['IS_TTY']},
             'SHOW_PROGRESS':            {'type': bool,  'default': lambda c: (c['IS_TTY'] and platform.system() != 'Darwin')},  # progress bars are buggy on mac, disable for now
             'IN_DOCKER':                {'type': bool,  'default': False},
    +        'IN_QEMU':                  {'type': bool,  'default': False},
             'PUID':                     {'type': int,   'default': os.getuid()},
             'PGID':                     {'type': int,   'default': os.getgid()},
             # TODO: 'SHOW_HINTS':       {'type:  bool,  'default': True},
    diff --git a/archivebox/main.py b/archivebox/main.py
    index 83adaba8..5ce1e288 100755
    --- a/archivebox/main.py
    +++ b/archivebox/main.py
    @@ -71,6 +71,7 @@ from .config import (
         IS_TTY,
         DEBUG,
         IN_DOCKER,
    +    IN_QEMU,
         PUID,
         PGID,
         USER,
    @@ -218,7 +219,7 @@ def version(quiet: bool=False,
         if not quiet:
             # 0.6.3
             # ArchiveBox v0.6.3 Cpython Linux Linux-4.19.121-linuxkit-x86_64-with-glibc2.28 x86_64 (in Docker) (in TTY)
    -        # DEBUG=False IN_DOCKER=True IS_TTY=True TZ=UTC FS_ATOMIC=True FS_REMOTE=False FS_PERMS=644 FS_USER=501:20 SEARCH_BACKEND=ripgrep
    +        # DEBUG=False IN_DOCKER=True IN_QEMU=False IS_TTY=True TZ=UTC FS_ATOMIC=True FS_REMOTE=False FS_PERMS=644 FS_USER=501:20 SEARCH_BACKEND=ripgrep
             
             p = platform.uname()
             print(
    @@ -233,6 +234,7 @@ def version(quiet: bool=False,
             print(
                 f'DEBUG={DEBUG}',
                 f'IN_DOCKER={IN_DOCKER}',
    +            f'IN_QEMU={IN_QEMU}',
                 f'IS_TTY={IS_TTY}',
                 f'TZ={TIMEZONE}',
                 #f'DB=django.db.backends.sqlite3 (({CONFIG["SQLITE_JOURNAL_MODE"]})',  # add this if we have more useful info to show eventually
    diff --git a/bin/docker_entrypoint.sh b/bin/docker_entrypoint.sh
    index 92fb46a6..35e3c365 100755
    --- a/bin/docker_entrypoint.sh
    +++ b/bin/docker_entrypoint.sh
    @@ -41,6 +41,14 @@ fi
     chown $PUID:$PGID "$DATA_DIR"
     chown $PUID:$PGID "$DATA_DIR"/*
     
    +
    +export IN_QEMU="$(pmap 1 | grep qemu | wc -l | grep -E '^0$' >/dev/null && echo 'False' || echo 'True')"
    +if [[ "$IN_QEMU" == 'True' ]]; then
    +    echo -e "\n[!] Warning: Running $(uname -m) emulated container in QEMU, some things will break!" >&2
    +    echo -e "    chromium (screenshot, pdf, dom), singlefile, and any dependencies that rely on inotify will not run in QEMU." >&2
    +    echo -e "    See here for more info: https://github.com/microsoft/playwright/issues/17395#issuecomment-1250830493\n" >&2
    +fi
    +
     # Drop permissions to run commands as the archivebox user
     if [[ "$1" == /* || "$1" == "bash" || "$1" == "sh" || "$1" == "echo" || "$1" == "cat" || "$1" == "archivebox" ]]; then
         # handle "docker run archivebox /some/non-archivebox/command" by executing args as direct bash command
    
    From 479a6f44ea637fca7e082d3ff15da529497a986f Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 00:27:31 -0700
    Subject: [PATCH 70/89] dont install site packages as editable
    
    ---
     Dockerfile | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index 252615ff..e7d2ef16 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -217,7 +217,7 @@ RUN echo "[+] Installing PIP ArchiveBox dependencies..." \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
             build-essential libssl-dev libldap2-dev libsasl2-dev \
         && pdm use -f $GLOBAL_VENV \
    -    && pdm install --fail-fast --no-lock --group :all --no-self \
    +    && pdm install --fail-fast --no-lock --no-editable --group :all --no-self \
         && apt-get purge -y \
             build-essential libssl-dev libldap2-dev libsasl2-dev \
             # these are only needed to build CPython libs, we discard after build phase to shrink layer size
    
    From b87af192353c1e5d969f15eb07d7eadf5f0f30b3 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 00:30:27 -0700
    Subject: [PATCH 71/89] use pdm sync instead of pdm install in docker
    
    ---
     Dockerfile | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index e7d2ef16..0ad01712 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -217,7 +217,7 @@ RUN echo "[+] Installing PIP ArchiveBox dependencies..." \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
             build-essential libssl-dev libldap2-dev libsasl2-dev \
         && pdm use -f $GLOBAL_VENV \
    -    && pdm install --fail-fast --no-lock --no-editable --group :all --no-self \
    +    && pdm sync --fail-fast --no-lock --no-editable --group :all --no-self \
         && apt-get purge -y \
             build-essential libssl-dev libldap2-dev libsasl2-dev \
             # these are only needed to build CPython libs, we discard after build phase to shrink layer size
    
    From 214016d8a1d826482fe644e7f1a025c624bb0d8c Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 00:31:14 -0700
    Subject: [PATCH 72/89] fix broken arg
    
    ---
     Dockerfile | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index 0ad01712..ce4229dd 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -217,7 +217,7 @@ RUN echo "[+] Installing PIP ArchiveBox dependencies..." \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
             build-essential libssl-dev libldap2-dev libsasl2-dev \
         && pdm use -f $GLOBAL_VENV \
    -    && pdm sync --fail-fast --no-lock --no-editable --group :all --no-self \
    +    && pdm sync --fail-fast --no-editable --group :all --no-self \
         && apt-get purge -y \
             build-essential libssl-dev libldap2-dev libsasl2-dev \
             # these are only needed to build CPython libs, we discard after build phase to shrink layer size
    
    From f0d51c377bce3075616a307a7d40664a2a04f327 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 01:05:39 -0700
    Subject: [PATCH 73/89] attempt fix for python build
    
    ---
     Dockerfile       |  21 +-
     requirements.txt | 752 +++++++++++++++++++++++++++++++++++++++++++++++
     2 files changed, 765 insertions(+), 8 deletions(-)
     create mode 100644 requirements.txt
    
    diff --git a/Dockerfile b/Dockerfile
    index ce4229dd..e61a2eb8 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -214,14 +214,19 @@ WORKDIR "$CODE_DIR"
     COPY --chown=root:root --chmod=755 "./pyproject.toml" "./pdm.lock" "$CODE_DIR/"
     RUN echo "[+] Installing PIP ArchiveBox dependencies..." \
         && apt-get update -qq \
    -    && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    -        build-essential libssl-dev libldap2-dev libsasl2-dev \
    -    && pdm use -f $GLOBAL_VENV \
    -    && pdm sync --fail-fast --no-editable --group :all --no-self \
    -    && apt-get purge -y \
    -        build-essential libssl-dev libldap2-dev libsasl2-dev \
    -        # these are only needed to build CPython libs, we discard after build phase to shrink layer size
    -    && apt-get autoremove -y \
    +    # && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    +        # build-essential libssl-dev libldap2-dev libsasl2-dev \
    +    && ln -s "$GLOBAL_VENV" "$APP_VENV" \
    +    && pdm use --venv in-project \
    +    && pdm run python -m ensurepip \
    +    # && pdm sync --fail-fast --no-editable --group :all --no-self \
    +    # && source "$GLOBAL_VENV/bin/activate" \
    +    # && pdm export -o requirements.txt --without-hashes \
    +    && $GLOBAL_VENV/bin/pip install --upgrade -r requirements.txt \
    +    # && apt-get purge -y \
    +    #     build-essential libssl-dev libldap2-dev libsasl2-dev \
    +    #     # these are only needed to build CPython libs, we discard after build phase to shrink layer size
    +    # && apt-get autoremove -y \
         && rm -rf /var/lib/apt/lists/*
     
     # Install ArchiveBox Python package from source
    diff --git a/requirements.txt b/requirements.txt
    new file mode 100644
    index 00000000..793e32e0
    --- /dev/null
    +++ b/requirements.txt
    @@ -0,0 +1,752 @@
    +# This file is @generated by PDM.
    +# Please do not edit it manually.
    +
    +alabaster==0.7.13 \
    +    --hash=sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3 \
    +    --hash=sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2
    +appnope==0.1.3 \
    +    --hash=sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24 \
    +    --hash=sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e
    +asgiref==3.7.2 \
    +    --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \
    +    --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed
    +asttokens==2.4.0 \
    +    --hash=sha256:2e0171b991b2c959acc6c49318049236844a5da1d65ba2672c4880c1c894834e \
    +    --hash=sha256:cf8fc9e61a86461aa9fb161a14a0841a03c405fa829ac6b202670b3495d2ce69
    +babel==2.13.0 \
    +    --hash=sha256:04c3e2d28d2b7681644508f836be388ae49e0cfe91465095340395b60d00f210 \
    +    --hash=sha256:fbfcae1575ff78e26c7449136f1abbefc3c13ce542eeb13d43d50d8b047216ec
    +backcall==0.2.0 \
    +    --hash=sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e \
    +    --hash=sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255
    +blinker==1.6.3 \
    +    --hash=sha256:152090d27c1c5c722ee7e48504b02d76502811ce02e1523553b4cf8c8b3d3a8d \
    +    --hash=sha256:296320d6c28b006eb5e32d4712202dbcdcbf5dc482da298c2f44881c43884aaa
    +bottle==0.12.25 \
    +    --hash=sha256:d6f15f9d422670b7c073d63bd8d287b135388da187a0f3e3c19293626ce034ea \
    +    --hash=sha256:e1a9c94970ae6d710b3fb4526294dfeb86f2cb4a81eff3a4b98dc40fb0e5e021
    +brotli==1.1.0 \
    +    --hash=sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128 \
    +    --hash=sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9 \
    +    --hash=sha256:1ae56aca0402a0f9a3431cddda62ad71666ca9d4dc3a10a142b9dce2e3c0cda3 \
    +    --hash=sha256:22fc2a8549ffe699bfba2256ab2ed0421a7b8fadff114a3d201794e45a9ff578 \
    +    --hash=sha256:30924eb4c57903d5a7526b08ef4a584acc22ab1ffa085faceb521521d2de32dd \
    +    --hash=sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409 \
    +    --hash=sha256:38025d9f30cf4634f8309c6874ef871b841eb3c347e90b0851f63d1ded5212da \
    +    --hash=sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50 \
    +    --hash=sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180 \
    +    --hash=sha256:43ce1b9935bfa1ede40028054d7f48b5469cd02733a365eec8a329ffd342915d \
    +    --hash=sha256:4ed11165dd45ce798d99a136808a794a748d5dc38511303239d4e2363c0695dc \
    +    --hash=sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265 \
    +    --hash=sha256:524f35912131cc2cabb00edfd8d573b07f2d9f21fa824bd3fb19725a9cf06327 \
    +    --hash=sha256:5b3cc074004d968722f51e550b41a27be656ec48f8afaeeb45ebf65b561481dd \
    +    --hash=sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0 \
    +    --hash=sha256:5fb2ce4b8045c78ebbc7b8f3c15062e435d47e7393cc57c25115cfd49883747a \
    +    --hash=sha256:6c3020404e0b5eefd7c9485ccf8393cfb75ec38ce75586e046573c9dc29967a0 \
    +    --hash=sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451 \
    +    --hash=sha256:7905193081db9bfa73b1219140b3d315831cbff0d8941f22da695832f0dd188f \
    +    --hash=sha256:7c4855522edb2e6ae7fdb58e07c3ba9111e7621a8956f481c68d5d979c93032e \
    +    --hash=sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248 \
    +    --hash=sha256:7f4bf76817c14aa98cc6697ac02f3972cb8c3da93e9ef16b9c66573a68014f91 \
    +    --hash=sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724 \
    +    --hash=sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966 \
    +    --hash=sha256:89f4988c7203739d48c6f806f1e87a1d96e0806d44f0fba61dba81392c9e474d \
    +    --hash=sha256:8dadd1314583ec0bf2d1379f7008ad627cd6336625d6679cf2f8e67081b83acf \
    +    --hash=sha256:901032ff242d479a0efa956d853d16875d42157f98951c0230f69e69f9c09bac \
    +    --hash=sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951 \
    +    --hash=sha256:949f3b7c29912693cee0afcf09acd6ebc04c57af949d9bf77d6101ebb61e388c \
    +    --hash=sha256:a1fd8a29719ccce974d523580987b7f8229aeace506952fa9ce1d53a033873c8 \
    +    --hash=sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d \
    +    --hash=sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc \
    +    --hash=sha256:a469274ad18dc0e4d316eefa616d1d0c2ff9da369af19fa6f3daa4f09671fd61 \
    +    --hash=sha256:a77def80806c421b4b0af06f45d65a136e7ac0bdca3c09d9e2ea4e515367c7e9 \
    +    --hash=sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1 \
    +    --hash=sha256:ae15b066e5ad21366600ebec29a7ccbc86812ed267e4b28e860b8ca16a2bc474 \
    +    --hash=sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2 \
    +    --hash=sha256:c8146669223164fc87a7e3de9f81e9423c67a79d6b3447994dfb9c95da16e2d6 \
    +    --hash=sha256:c8fd5270e906eef71d4a8d19b7c6a43760c6abcfcc10c9101d14eb2357418de9 \
    +    --hash=sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2 \
    +    --hash=sha256:cdad5b9014d83ca68c25d2e9444e28e967ef16e80f6b436918c700c117a85467 \
    +    --hash=sha256:ceb64bbc6eac5a140ca649003756940f8d6a7c444a68af170b3187623b43bebf \
    +    --hash=sha256:d0c5516f0aed654134a2fc936325cc2e642f8a0e096d075209672eb321cff408 \
    +    --hash=sha256:de6551e370ef19f8de1807d0a9aa2cdfdce2e85ce88b122fe9f6b2b076837e59 \
    +    --hash=sha256:e1140c64812cb9b06c922e77f1c26a75ec5e3f0fb2bf92cc8c58720dec276752 \
    +    --hash=sha256:e6a904cb26bfefc2f0a6f240bdf5233be78cd2488900a2f846f3c3ac8489ab80 \
    +    --hash=sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0 \
    +    --hash=sha256:f0d8a7a6b5983c2496e364b969f0e526647a06b075d034f3297dc66f3b360c64 \
    +    --hash=sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e
    +cachecontrol==0.13.1 \
    +    --hash=sha256:95dedbec849f46dda3137866dc28b9d133fc9af55f5b805ab1291833e4457aa4 \
    +    --hash=sha256:f012366b79d2243a6118309ce73151bf52a38d4a5dac8ea57f09bd29087e506b
    +certifi==2023.7.22 \
    +    --hash=sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082 \
    +    --hash=sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9
    +charset-normalizer==3.3.0 \
    +    --hash=sha256:02673e456dc5ab13659f85196c534dc596d4ef260e4d86e856c3b2773ce09843 \
    +    --hash=sha256:02af06682e3590ab952599fbadac535ede5d60d78848e555aa58d0c0abbde786 \
    +    --hash=sha256:03680bb39035fbcffe828eae9c3f8afc0428c91d38e7d61aa992ef7a59fb120e \
    +    --hash=sha256:0570d21da019941634a531444364f2482e8db0b3425fcd5ac0c36565a64142c8 \
    +    --hash=sha256:09c77f964f351a7369cc343911e0df63e762e42bac24cd7d18525961c81754f4 \
    +    --hash=sha256:0d3d5b7db9ed8a2b11a774db2bbea7ba1884430a205dbd54a32d61d7c2a190fa \
    +    --hash=sha256:12ebea541c44fdc88ccb794a13fe861cc5e35d64ed689513a5c03d05b53b7c82 \
    +    --hash=sha256:153e7b6e724761741e0974fc4dcd406d35ba70b92bfe3fedcb497226c93b9da7 \
    +    --hash=sha256:1872d01ac8c618a8da634e232f24793883d6e456a66593135aeafe3784b0848d \
    +    --hash=sha256:1b2919306936ac6efb3aed1fbf81039f7087ddadb3160882a57ee2ff74fd2382 \
    +    --hash=sha256:232ac332403e37e4a03d209a3f92ed9071f7d3dbda70e2a5e9cff1c4ba9f0678 \
    +    --hash=sha256:23e8565ab7ff33218530bc817922fae827420f143479b753104ab801145b1d5b \
    +    --hash=sha256:24817cb02cbef7cd499f7c9a2735286b4782bd47a5b3516a0e84c50eab44b98e \
    +    --hash=sha256:2502dd2a736c879c0f0d3e2161e74d9907231e25d35794584b1ca5284e43f596 \
    +    --hash=sha256:278c296c6f96fa686d74eb449ea1697f3c03dc28b75f873b65b5201806346a69 \
    +    --hash=sha256:2935ffc78db9645cb2086c2f8f4cfd23d9b73cc0dc80334bc30aac6f03f68f8c \
    +    --hash=sha256:380c4bde80bce25c6e4f77b19386f5ec9db230df9f2f2ac1e5ad7af2caa70459 \
    +    --hash=sha256:3b447982ad46348c02cb90d230b75ac34e9886273df3a93eec0539308a6296d7 \
    +    --hash=sha256:3debd1150027933210c2fc321527c2299118aa929c2f5a0a80ab6953e3bd1908 \
    +    --hash=sha256:4162918ef3098851fcd8a628bf9b6a98d10c380725df9e04caf5ca6dd48c847a \
    +    --hash=sha256:4cc152c5dd831641e995764f9f0b6589519f6f5123258ccaca8c6d34572fefa8 \
    +    --hash=sha256:557b21a44ceac6c6b9773bc65aa1b4cc3e248a5ad2f5b914b91579a32e22204d \
    +    --hash=sha256:5707a746c6083a3a74b46b3a631d78d129edab06195a92a8ece755aac25a3f3d \
    +    --hash=sha256:5adf257bd58c1b8632046bbe43ee38c04e1038e9d37de9c57a94d6bd6ce5da34 \
    +    --hash=sha256:619d1c96099be5823db34fe89e2582b336b5b074a7f47f819d6b3a57ff7bdb86 \
    +    --hash=sha256:63563193aec44bce707e0c5ca64ff69fa72ed7cf34ce6e11d5127555756fd2f6 \
    +    --hash=sha256:6a685067d05e46641d5d1623d7c7fdf15a357546cbb2f71b0ebde91b175ffc3e \
    +    --hash=sha256:7966951325782121e67c81299a031f4c115615e68046f79b85856b86ebffc4cd \
    +    --hash=sha256:7b8b8bf1189b3ba9b8de5c8db4d541b406611a71a955bbbd7385bbc45fcb786c \
    +    --hash=sha256:805dfea4ca10411a5296bcc75638017215a93ffb584c9e344731eef0dcfb026a \
    +    --hash=sha256:82eb849f085624f6a607538ee7b83a6d8126df6d2f7d3b319cb837b289123078 \
    +    --hash=sha256:86d1f65ac145e2c9ed71d8ffb1905e9bba3a91ae29ba55b4c46ae6fc31d7c0d4 \
    +    --hash=sha256:86f63face3a527284f7bb8a9d4f78988e3c06823f7bea2bd6f0e0e9298ca0403 \
    +    --hash=sha256:8eaf82f0eccd1505cf39a45a6bd0a8cf1c70dcfc30dba338207a969d91b965c0 \
    +    --hash=sha256:93aa7eef6ee71c629b51ef873991d6911b906d7312c6e8e99790c0f33c576f89 \
    +    --hash=sha256:96c2b49eb6a72c0e4991d62406e365d87067ca14c1a729a870d22354e6f68115 \
    +    --hash=sha256:9cf3126b85822c4e53aa28c7ec9869b924d6fcfb76e77a45c44b83d91afd74f9 \
    +    --hash=sha256:9fe359b2e3a7729010060fbca442ca225280c16e923b37db0e955ac2a2b72a05 \
    +    --hash=sha256:a0ac5e7015a5920cfce654c06618ec40c33e12801711da6b4258af59a8eff00a \
    +    --hash=sha256:a3f93dab657839dfa61025056606600a11d0b696d79386f974e459a3fbc568ec \
    +    --hash=sha256:a4b71f4d1765639372a3b32d2638197f5cd5221b19531f9245fcc9ee62d38f56 \
    +    --hash=sha256:aaf7b34c5bc56b38c931a54f7952f1ff0ae77a2e82496583b247f7c969eb1479 \
    +    --hash=sha256:abf0d9f45ea5fb95051c8bfe43cb40cda383772f7e5023a83cc481ca2604d74e \
    +    --hash=sha256:b09719a17a2301178fac4470d54b1680b18a5048b481cb8890e1ef820cb80455 \
    +    --hash=sha256:b3b2316b25644b23b54a6f6401074cebcecd1244c0b8e80111c9a3f1c8e83d65 \
    +    --hash=sha256:b3d9b48ee6e3967b7901c052b670c7dda6deb812c309439adaffdec55c6d7b78 \
    +    --hash=sha256:b8f3307af845803fb0b060ab76cf6dd3a13adc15b6b451f54281d25911eb92df \
    +    --hash=sha256:c2af80fb58f0f24b3f3adcb9148e6203fa67dd3f61c4af146ecad033024dde43 \
    +    --hash=sha256:c350354efb159b8767a6244c166f66e67506e06c8924ed74669b2c70bc8735b1 \
    +    --hash=sha256:c71f16da1ed8949774ef79f4a0260d28b83b3a50c6576f8f4f0288d109777989 \
    +    --hash=sha256:d47ecf253780c90ee181d4d871cd655a789da937454045b17b5798da9393901a \
    +    --hash=sha256:d7eff0f27edc5afa9e405f7165f85a6d782d308f3b6b9d96016c010597958e63 \
    +    --hash=sha256:d97d85fa63f315a8bdaba2af9a6a686e0eceab77b3089af45133252618e70884 \
    +    --hash=sha256:db756e48f9c5c607b5e33dd36b1d5872d0422e960145b08ab0ec7fd420e9d649 \
    +    --hash=sha256:e0fc42822278451bc13a2e8626cf2218ba570f27856b536e00cfa53099724828 \
    +    --hash=sha256:e46cd37076971c1040fc8c41273a8b3e2c624ce4f2be3f5dfcb7a430c1d3acc2 \
    +    --hash=sha256:e5c1502d4ace69a179305abb3f0bb6141cbe4714bc9b31d427329a95acfc8bdd \
    +    --hash=sha256:edfe077ab09442d4ef3c52cb1f9dab89bff02f4524afc0acf2d46be17dc479f5 \
    +    --hash=sha256:effe5406c9bd748a871dbcaf3ac69167c38d72db8c9baf3ff954c344f31c4cbe \
    +    --hash=sha256:f0d1e3732768fecb052d90d62b220af62ead5748ac51ef61e7b32c266cac9293 \
    +    --hash=sha256:f5969baeaea61c97efa706b9b107dcba02784b1601c74ac84f2a532ea079403e \
    +    --hash=sha256:f8888e31e3a85943743f8fc15e71536bda1c81d5aa36d014a3c0c44481d7db6e
    +commonmark==0.9.1 \
    +    --hash=sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60 \
    +    --hash=sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9
    +croniter==2.0.1 \
    +    --hash=sha256:4cb064ce2d8f695b3b078be36ff50115cf8ac306c10a7e8653ee2a5b534673d7 \
    +    --hash=sha256:d199b2ec3ea5e82988d1f72022433c5f9302b3b3ea9e6bfd6a1518f6ea5e700a
    +dateparser==1.1.8 \
    +    --hash=sha256:070b29b5bbf4b1ec2cd51c96ea040dc68a614de703910a91ad1abba18f9f379f \
    +    --hash=sha256:86b8b7517efcc558f085a142cdb7620f0921543fcabdb538c8a4c4001d8178e3
    +decorator==5.1.1 \
    +    --hash=sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330 \
    +    --hash=sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186
    +distlib==0.3.7 \
    +    --hash=sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057 \
    +    --hash=sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8
    +django==3.1.14 \
    +    --hash=sha256:0fabc786489af16ad87a8c170ba9d42bfd23f7b699bd5ef05675864e8d012859 \
    +    --hash=sha256:72a4a5a136a214c39cf016ccdd6b69e2aa08c7479c66d93f3a9b5e4bb9d8a347
    +django-auth-ldap==4.1.0 \
    +    --hash=sha256:68870e7921e84b1a9867e268a9c8a3e573e8a0d95ea08bcf31be178f5826ff36 \
    +    --hash=sha256:77f749d3b17807ce8eb56a9c9c8e5746ff316567f81d5ba613495d9c7495a949
    +django-debug-toolbar==3.2.4 \
    +    --hash=sha256:644bbd5c428d3283aa9115722471769cac1bec189edf3a0c855fd8ff870375a9 \
    +    --hash=sha256:6b633b6cfee24f232d73569870f19aa86c819d750e7f3e833f2344a9eb4b4409
    +django-extensions==3.1.5 \
    +    --hash=sha256:28e1e1bf49f0e00307ba574d645b0af3564c981a6dfc87209d48cb98f77d0b1a \
    +    --hash=sha256:9238b9e016bb0009d621e05cf56ea8ce5cce9b32e91ad2026996a7377ca28069
    +django-stubs==4.2.5 \
    +    --hash=sha256:5a23cf622f1426a0b0c48bd6e2ef709a66275d72073baf6fdf5ac36fc4cce736 \
    +    --hash=sha256:706b2456bd0e56c468dfd8f27b0e7dde001c5c7cd3010d67fcbda9d95467e050
    +django-stubs-ext==4.2.5 \
    +    --hash=sha256:8c4d1fb5f68419b3b2474c659681a189803e27d6a5e5abf5aa0da57601b58633 \
    +    --hash=sha256:921cd7ae4614e74c234bc0fe86ee75537d163addfe1fc6f134bf03e29d86c01e
    +djdt-flamegraph==0.2.13 \
    +    --hash=sha256:b3252b8cc9b586829166cc158b26952626cd6f41a3ffa92dceef2f5dbe5b99a0 \
    +    --hash=sha256:c07a71be58484636e021d4c49b129fd819f24c9128849cb59558e5141192dbf3
    +docutils==0.18.1 \
    +    --hash=sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c \
    +    --hash=sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06
    +executing==2.0.0 \
    +    --hash=sha256:06df6183df67389625f4e763921c6cf978944721abf3e714000200aab95b0657 \
    +    --hash=sha256:0ff053696fdeef426cda5bd18eacd94f82c91f49823a2e9090124212ceea9b08
    +filelock==3.12.4 \
    +    --hash=sha256:08c21d87ded6e2b9da6728c3dff51baf1dcecf973b768ef35bcbc3447edb9ad4 \
    +    --hash=sha256:2e6f249f1f3654291606e046b09f1fd5eac39b360664c27f5aad072012f8bcbd
    +findpython==0.4.0 \
    +    --hash=sha256:087148ac5935f9be458f36a05f3fa479efdf2c629f5d386c73ea481cfecff15e \
    +    --hash=sha256:18b14d115678da18ae92ee22d7001cc30915ea531053f77010ee05a39680f438
    +flake8==6.1.0 \
    +    --hash=sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23 \
    +    --hash=sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5
    +greenlet==3.0.0 \
    +    --hash=sha256:02a807b2a58d5cdebb07050efe3d7deaf915468d112dfcf5e426d0564aa3aa4a \
    +    --hash=sha256:0b72b802496cccbd9b31acea72b6f87e7771ccfd7f7927437d592e5c92ed703c \
    +    --hash=sha256:0d3f83ffb18dc57243e0151331e3c383b05e5b6c5029ac29f754745c800f8ed9 \
    +    --hash=sha256:123910c58234a8d40eaab595bc56a5ae49bdd90122dde5bdc012c20595a94c14 \
    +    --hash=sha256:1482fba7fbed96ea7842b5a7fc11d61727e8be75a077e603e8ab49d24e234383 \
    +    --hash=sha256:19834e3f91f485442adc1ee440171ec5d9a4840a1f7bd5ed97833544719ce10b \
    +    --hash=sha256:1d363666acc21d2c204dd8705c0e0457d7b2ee7a76cb16ffc099d6799744ac99 \
    +    --hash=sha256:211ef8d174601b80e01436f4e6905aca341b15a566f35a10dd8d1e93f5dbb3b7 \
    +    --hash=sha256:269d06fa0f9624455ce08ae0179430eea61085e3cf6457f05982b37fd2cefe17 \
    +    --hash=sha256:2e7dcdfad252f2ca83c685b0fa9fba00e4d8f243b73839229d56ee3d9d219314 \
    +    --hash=sha256:334ef6ed8337bd0b58bb0ae4f7f2dcc84c9f116e474bb4ec250a8bb9bd797a66 \
    +    --hash=sha256:37f60b3a42d8b5499be910d1267b24355c495064f271cfe74bf28b17b099133c \
    +    --hash=sha256:38ad562a104cd41e9d4644f46ea37167b93190c6d5e4048fcc4b80d34ecb278f \
    +    --hash=sha256:4cd83fb8d8e17633ad534d9ac93719ef8937568d730ef07ac3a98cb520fd93e4 \
    +    --hash=sha256:527cd90ba3d8d7ae7dceb06fda619895768a46a1b4e423bdb24c1969823b8362 \
    +    --hash=sha256:56867a3b3cf26dc8a0beecdb4459c59f4c47cdd5424618c08515f682e1d46692 \
    +    --hash=sha256:6512592cc49b2c6d9b19fbaa0312124cd4c4c8a90d28473f86f92685cc5fef8e \
    +    --hash=sha256:6672fdde0fd1a60b44fb1751a7779c6db487e42b0cc65e7caa6aa686874e79fb \
    +    --hash=sha256:6a5b2d4cdaf1c71057ff823a19d850ed5c6c2d3686cb71f73ae4d6382aaa7a06 \
    +    --hash=sha256:6a68d670c8f89ff65c82b936275369e532772eebc027c3be68c6b87ad05ca695 \
    +    --hash=sha256:73b2f1922a39d5d59cc0e597987300df3396b148a9bd10b76a058a2f2772fc04 \
    +    --hash=sha256:7709fd7bb02b31908dc8fd35bfd0a29fc24681d5cc9ac1d64ad07f8d2b7db62f \
    +    --hash=sha256:813720bd57e193391dfe26f4871186cf460848b83df7e23e6bef698a7624b4c9 \
    +    --hash=sha256:831d6f35037cf18ca5e80a737a27d822d87cd922521d18ed3dbc8a6967be50ce \
    +    --hash=sha256:871b0a8835f9e9d461b7fdaa1b57e3492dd45398e87324c047469ce2fc9f516c \
    +    --hash=sha256:952256c2bc5b4ee8df8dfc54fc4de330970bf5d79253c863fb5e6761f00dda35 \
    +    --hash=sha256:96d9ea57292f636ec851a9bb961a5cc0f9976900e16e5d5647f19aa36ba6366b \
    +    --hash=sha256:9a812224a5fb17a538207e8cf8e86f517df2080c8ee0f8c1ed2bdaccd18f38f4 \
    +    --hash=sha256:9adbd8ecf097e34ada8efde9b6fec4dd2a903b1e98037adf72d12993a1c80b51 \
    +    --hash=sha256:a048293392d4e058298710a54dfaefcefdf49d287cd33fb1f7d63d55426e4355 \
    +    --hash=sha256:aa15a2ec737cb609ed48902b45c5e4ff6044feb5dcdfcf6fa8482379190330d7 \
    +    --hash=sha256:ad6fb737e46b8bd63156b8f59ba6cdef46fe2b7db0c5804388a2d0519b8ddb99 \
    +    --hash=sha256:b1660a15a446206c8545edc292ab5c48b91ff732f91b3d3b30d9a915d5ec4779 \
    +    --hash=sha256:b505fcfc26f4148551826a96f7317e02c400665fa0883fe505d4fcaab1dabfdd \
    +    --hash=sha256:bdfaeecf8cc705d35d8e6de324bf58427d7eafb55f67050d8f28053a3d57118c \
    +    --hash=sha256:be557119bf467d37a8099d91fbf11b2de5eb1fd5fc5b91598407574848dc910f \
    +    --hash=sha256:c94e4e924d09b5a3e37b853fe5924a95eac058cb6f6fb437ebb588b7eda79870 \
    +    --hash=sha256:d1e22c22f7826096ad503e9bb681b05b8c1f5a8138469b255eb91f26a76634f2 \
    +    --hash=sha256:d55db1db455c59b46f794346efce896e754b8942817f46a1bada2d29446e305a \
    +    --hash=sha256:e09dea87cc91aea5500262993cbd484b41edf8af74f976719dd83fe724644cd6 \
    +    --hash=sha256:f47932c434a3c8d3c86d865443fadc1fbf574e9b11d6650b656e602b1797908a
    +idna==3.4 \
    +    --hash=sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4 \
    +    --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2
    +imagesize==1.4.1 \
    +    --hash=sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b \
    +    --hash=sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a
    +importlib-metadata==6.8.0 \
    +    --hash=sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb \
    +    --hash=sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743
    +iniconfig==2.0.0 \
    +    --hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \
    +    --hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374
    +installer==0.7.0 \
    +    --hash=sha256:05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53 \
    +    --hash=sha256:a26d3e3116289bb08216e0d0f7d925fcef0b0194eedfa0c944bcaaa106c4b631
    +ipdb==0.13.13 \
    +    --hash=sha256:45529994741c4ab6d2388bfa5d7b725c2cf7fe9deffabdb8a6113aa5ed449ed4 \
    +    --hash=sha256:e3ac6018ef05126d442af680aad863006ec19d02290561ac88b8b1c0b0cfc726
    +ipython==8.16.1 \
    +    --hash=sha256:0852469d4d579d9cd613c220af7bf0c9cc251813e12be647cb9d463939db9b1e \
    +    --hash=sha256:ad52f58fca8f9f848e256c629eff888efc0528c12fe0f8ec14f33205f23ef938
    +jaraco-classes==3.3.0 \
    +    --hash=sha256:10afa92b6743f25c0cf5f37c6bb6e18e2c5bb84a16527ccfc0040ea377e7aaeb \
    +    --hash=sha256:c063dd08e89217cee02c8d5e5ec560f2c8ce6cdc2fcdc2e68f7b2e5547ed3621
    +jedi==0.19.1 \
    +    --hash=sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd \
    +    --hash=sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0
    +Jinja2==3.1.2 \
    +    --hash=sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852 \
    +    --hash=sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61
    +keyring==24.2.0 \
    +    --hash=sha256:4901caaf597bfd3bbd78c9a0c7c4c29fcd8310dab2cffefe749e916b6527acd6 \
    +    --hash=sha256:ca0746a19ec421219f4d713f848fa297a661a8a8c1504867e55bfb5e09091509
    +markdown-it-py==3.0.0 \
    +    --hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \
    +    --hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb
    +MarkupSafe==2.1.3 \
    +    --hash=sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e \
    +    --hash=sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e \
    +    --hash=sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431 \
    +    --hash=sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686 \
    +    --hash=sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c \
    +    --hash=sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559 \
    +    --hash=sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb \
    +    --hash=sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939 \
    +    --hash=sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c \
    +    --hash=sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9 \
    +    --hash=sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575 \
    +    --hash=sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba \
    +    --hash=sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd \
    +    --hash=sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00 \
    +    --hash=sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac \
    +    --hash=sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52 \
    +    --hash=sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f \
    +    --hash=sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b \
    +    --hash=sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007 \
    +    --hash=sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea \
    +    --hash=sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198 \
    +    --hash=sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1 \
    +    --hash=sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6 \
    +    --hash=sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c \
    +    --hash=sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58 \
    +    --hash=sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823 \
    +    --hash=sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779 \
    +    --hash=sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636 \
    +    --hash=sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c \
    +    --hash=sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad \
    +    --hash=sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee \
    +    --hash=sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2 \
    +    --hash=sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7 \
    +    --hash=sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa \
    +    --hash=sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb \
    +    --hash=sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9 \
    +    --hash=sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57 \
    +    --hash=sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc \
    +    --hash=sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc \
    +    --hash=sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2 \
    +    --hash=sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11
    +matplotlib-inline==0.1.6 \
    +    --hash=sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311 \
    +    --hash=sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304
    +mccabe==0.7.0 \
    +    --hash=sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325 \
    +    --hash=sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e
    +mdurl==0.1.2 \
    +    --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \
    +    --hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba
    +more-itertools==10.1.0 \
    +    --hash=sha256:626c369fa0eb37bac0291bce8259b332fd59ac792fa5497b59837309cd5b114a \
    +    --hash=sha256:64e0735fcfdc6f3464ea133afe8ea4483b1c5fe3a3d69852e6503b43a0b222e6
    +msgpack==1.0.7 \
    +    --hash=sha256:04ad6069c86e531682f9e1e71b71c1c3937d6014a7c3e9edd2aa81ad58842862 \
    +    --hash=sha256:1dc93e8e4653bdb5910aed79f11e165c85732067614f180f70534f056da97db3 \
    +    --hash=sha256:1e2d69948e4132813b8d1131f29f9101bc2c915f26089a6d632001a5c1349672 \
    +    --hash=sha256:27dcd6f46a21c18fa5e5deed92a43d4554e3df8d8ca5a47bf0615d6a5f39dbc9 \
    +    --hash=sha256:28efb066cde83c479dfe5a48141a53bc7e5f13f785b92ddde336c716663039ee \
    +    --hash=sha256:3476fae43db72bd11f29a5147ae2f3cb22e2f1a91d575ef130d2bf49afd21c46 \
    +    --hash=sha256:384d779f0d6f1b110eae74cb0659d9aa6ff35aaf547b3955abf2ab4c901c4819 \
    +    --hash=sha256:3967e4ad1aa9da62fd53e346ed17d7b2e922cba5ab93bdd46febcac39be636fc \
    +    --hash=sha256:3e7bf4442b310ff154b7bb9d81eb2c016b7d597e364f97d72b1acc3817a0fdc1 \
    +    --hash=sha256:3f0c8c6dfa6605ab8ff0611995ee30d4f9fcff89966cf562733b4008a3d60d82 \
    +    --hash=sha256:484ae3240666ad34cfa31eea7b8c6cd2f1fdaae21d73ce2974211df099a95d81 \
    +    --hash=sha256:4a7b4f35de6a304b5533c238bee86b670b75b03d31b7797929caa7a624b5dda6 \
    +    --hash=sha256:4cb14ce54d9b857be9591ac364cb08dc2d6a5c4318c1182cb1d02274029d590d \
    +    --hash=sha256:52700dc63a4676669b341ba33520f4d6e43d3ca58d422e22ba66d1736b0a6e4c \
    +    --hash=sha256:572efc93db7a4d27e404501975ca6d2d9775705c2d922390d878fcf768d92c87 \
    +    --hash=sha256:576eb384292b139821c41995523654ad82d1916da6a60cff129c715a6223ea84 \
    +    --hash=sha256:5b0bf0effb196ed76b7ad883848143427a73c355ae8e569fa538365064188b8e \
    +    --hash=sha256:5ed82f5a7af3697b1c4786053736f24a0efd0a1b8a130d4c7bfee4b9ded0f08f \
    +    --hash=sha256:6d4c80667de2e36970ebf74f42d1088cc9ee7ef5f4e8c35eee1b40eafd33ca5b \
    +    --hash=sha256:730076207cb816138cf1af7f7237b208340a2c5e749707457d70705715c93b93 \
    +    --hash=sha256:7687e22a31e976a0e7fc99c2f4d11ca45eff652a81eb8c8085e9609298916dcf \
    +    --hash=sha256:822ea70dc4018c7e6223f13affd1c5c30c0f5c12ac1f96cd8e9949acddb48a61 \
    +    --hash=sha256:84b0daf226913133f899ea9b30618722d45feffa67e4fe867b0b5ae83a34060c \
    +    --hash=sha256:85765fdf4b27eb5086f05ac0491090fc76f4f2b28e09d9350c31aac25a5aaff8 \
    +    --hash=sha256:8dd178c4c80706546702c59529ffc005681bd6dc2ea234c450661b205445a34d \
    +    --hash=sha256:98bbd754a422a0b123c66a4c341de0474cad4a5c10c164ceed6ea090f3563db4 \
    +    --hash=sha256:993584fc821c58d5993521bfdcd31a4adf025c7d745bbd4d12ccfecf695af5ba \
    +    --hash=sha256:a40821a89dc373d6427e2b44b572efc36a2778d3f543299e2f24eb1a5de65415 \
    +    --hash=sha256:b291f0ee7961a597cbbcc77709374087fa2a9afe7bdb6a40dbbd9b127e79afee \
    +    --hash=sha256:b573a43ef7c368ba4ea06050a957c2a7550f729c31f11dd616d2ac4aba99888d \
    +    --hash=sha256:b610ff0f24e9f11c9ae653c67ff8cc03c075131401b3e5ef4b82570d1728f8a9 \
    +    --hash=sha256:bdf38ba2d393c7911ae989c3bbba510ebbcdf4ecbdbfec36272abe350c454075 \
    +    --hash=sha256:bfef2bb6ef068827bbd021017a107194956918ab43ce4d6dc945ffa13efbc25f \
    +    --hash=sha256:cb70766519500281815dfd7a87d3a178acf7ce95390544b8c90587d76b227681 \
    +    --hash=sha256:cca1b62fe70d761a282496b96a5e51c44c213e410a964bdffe0928e611368329 \
    +    --hash=sha256:ccf9a39706b604d884d2cb1e27fe973bc55f2890c52f38df742bc1d79ab9f5e1 \
    +    --hash=sha256:e45ae4927759289c30ccba8d9fdce62bb414977ba158286b5ddaf8df2cddb5c5 \
    +    --hash=sha256:e50ebce52f41370707f1e21a59514e3375e3edd6e1832f5e5235237db933c98b \
    +    --hash=sha256:ebbbba226f0a108a7366bf4b59bf0f30a12fd5e75100c630267d94d7f0ad20e5 \
    +    --hash=sha256:ec79ff6159dffcc30853b2ad612ed572af86c92b5168aa3fc01a67b0fa40665e \
    +    --hash=sha256:f0936e08e0003f66bfd97e74ee530427707297b0d0361247e9b4f59ab78ddc8b \
    +    --hash=sha256:f26a07a6e877c76a88e3cecac8531908d980d3d5067ff69213653649ec0f60ad \
    +    --hash=sha256:f64e376cd20d3f030190e8c32e1c64582eba56ac6dc7d5b0b49a9d44021b52fd \
    +    --hash=sha256:f6ffbc252eb0d229aeb2f9ad051200668fc3a9aaa8994e49f0cb2ffe2b7867e7 \
    +    --hash=sha256:f9a7c509542db4eceed3dcf21ee5267ab565a83555c9b88a8109dcecc4709002
    +mutagen==1.47.0 \
    +    --hash=sha256:719fadef0a978c31b4cf3c956261b3c58b6948b32023078a2117b1de09f0fc99 \
    +    --hash=sha256:edd96f50c5907a9539d8e5bba7245f62c9f520aef333d13392a79a4f70aca719
    +mypy==1.6.1 \
    +    --hash=sha256:19f905bcfd9e167159b3d63ecd8cb5e696151c3e59a1742e79bc3bcb540c42c7 \
    +    --hash=sha256:21a1ad938fee7d2d96ca666c77b7c494c3c5bd88dff792220e1afbebb2925b5e \
    +    --hash=sha256:40b1844d2e8b232ed92e50a4bd11c48d2daa351f9deee6c194b83bf03e418b0c \
    +    --hash=sha256:49ae115da099dcc0922a7a895c1eec82c1518109ea5c162ed50e3b3594c71208 \
    +    --hash=sha256:4c46b51de523817a0045b150ed11b56f9fff55f12b9edd0f3ed35b15a2809de0 \
    +    --hash=sha256:4cbe68ef919c28ea561165206a2dcb68591c50f3bcf777932323bc208d949cf1 \
    +    --hash=sha256:4d01c00d09a0be62a4ca3f933e315455bde83f37f892ba4b08ce92f3cf44bcc1 \
    +    --hash=sha256:59a0d7d24dfb26729e0a068639a6ce3500e31d6655df8557156c51c1cb874ce7 \
    +    --hash=sha256:81af8adaa5e3099469e7623436881eff6b3b06db5ef75e6f5b6d4871263547e5 \
    +    --hash=sha256:82e469518d3e9a321912955cc702d418773a2fd1e91c651280a1bda10622f02f \
    +    --hash=sha256:8b27958f8c76bed8edaa63da0739d76e4e9ad4ed325c814f9b3851425582a3cd \
    +    --hash=sha256:8c223fa57cb154c7eab5156856c231c3f5eace1e0bed9b32a24696b7ba3c3245 \
    +    --hash=sha256:8f57e6b6927a49550da3d122f0cb983d400f843a8a82e65b3b380d3d7259468f \
    +    --hash=sha256:925cd6a3b7b55dfba252b7c4561892311c5358c6b5a601847015a1ad4eb7d332 \
    +    --hash=sha256:a43ef1c8ddfdb9575691720b6352761f3f53d85f1b57d7745701041053deff30 \
    +    --hash=sha256:a8032e00ce71c3ceb93eeba63963b864bf635a18f6c0c12da6c13c450eedb183 \
    +    --hash=sha256:b96ae2c1279d1065413965c607712006205a9ac541895004a1e0d4f281f2ff9f \
    +    --hash=sha256:cfd13d47b29ed3bbaafaff7d8b21e90d827631afda134836962011acb5904b71 \
    +    --hash=sha256:d4473c22cc296425bbbce7e9429588e76e05bc7342da359d6520b6427bf76660 \
    +    --hash=sha256:d8fbb68711905f8912e5af474ca8b78d077447d8f3918997fecbf26943ff3cbb \
    +    --hash=sha256:e5012e5cc2ac628177eaac0e83d622b2dd499e28253d4107a08ecc59ede3fc2c \
    +    --hash=sha256:eb4f18589d196a4cbe5290b435d135dee96567e07c2b2d43b5c4621b6501531a
    +mypy-extensions==1.0.0 \
    +    --hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \
    +    --hash=sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782
    +nh3==0.2.14 \
    +    --hash=sha256:116c9515937f94f0057ef50ebcbcc10600860065953ba56f14473ff706371873 \
    +    --hash=sha256:18415df36db9b001f71a42a3a5395db79cf23d556996090d293764436e98e8ad \
    +    --hash=sha256:203cac86e313cf6486704d0ec620a992c8bc164c86d3a4fd3d761dd552d839b5 \
    +    --hash=sha256:2b0be5c792bd43d0abef8ca39dd8acb3c0611052ce466d0401d51ea0d9aa7525 \
    +    --hash=sha256:377aaf6a9e7c63962f367158d808c6a1344e2b4f83d071c43fbd631b75c4f0b2 \
    +    --hash=sha256:525846c56c2bcd376f5eaee76063ebf33cf1e620c1498b2a40107f60cfc6054e \
    +    --hash=sha256:5529a3bf99402c34056576d80ae5547123f1078da76aa99e8ed79e44fa67282d \
    +    --hash=sha256:7771d43222b639a4cd9e341f870cee336b9d886de1ad9bec8dddab22fe1de450 \
    +    --hash=sha256:88c753efbcdfc2644a5012938c6b9753f1c64a5723a67f0301ca43e7b85dcf0e \
    +    --hash=sha256:93a943cfd3e33bd03f77b97baa11990148687877b74193bf777956b67054dcc6 \
    +    --hash=sha256:9be2f68fb9a40d8440cbf34cbf40758aa7f6093160bfc7fb018cce8e424f0c3a \
    +    --hash=sha256:a0c509894fd4dccdff557068e5074999ae3b75f4c5a2d6fb5415e782e25679c4 \
    +    --hash=sha256:ac8056e937f264995a82bf0053ca898a1cb1c9efc7cd68fa07fe0060734df7e4 \
    +    --hash=sha256:aed56a86daa43966dd790ba86d4b810b219f75b4bb737461b6886ce2bde38fd6 \
    +    --hash=sha256:e8986f1dd3221d1e741fda0a12eaa4a273f1d80a35e31a1ffe579e7c621d069e \
    +    --hash=sha256:f99212a81c62b5f22f9e7c3e347aa00491114a5647e1f13bbebd79c3e5f08d75
    +packaging==23.2 \
    +    --hash=sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5 \
    +    --hash=sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7
    +parso==0.8.3 \
    +    --hash=sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0 \
    +    --hash=sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75
    +pdm==2.9.3 \
    +    --hash=sha256:0b1195b51e9630b5a0b063f27dfcb0120cb6ea284f1a4cd975a3a26f0856d253 \
    +    --hash=sha256:0b55fcaa61ed70b9dacd03c4a937f15e908c8c031b621523890de9cdf04325fd
    +pexpect==4.8.0 \
    +    --hash=sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937 \
    +    --hash=sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c
    +pickleshare==0.7.5 \
    +    --hash=sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca \
    +    --hash=sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56
    +pkginfo==1.9.6 \
    +    --hash=sha256:4b7a555a6d5a22169fcc9cf7bfd78d296b0361adad412a346c1226849af5e546 \
    +    --hash=sha256:8fd5896e8718a4372f0ea9cc9d96f6417c9b986e23a4d116dda26b62cc29d046
    +platformdirs==3.11.0 \
    +    --hash=sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3 \
    +    --hash=sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e
    +playwright==1.39.0 \
    +    --hash=sha256:384e195a6d09343f319031cf552e9cd601ede78fe9c082b9fa197537c5cbfe7a \
    +    --hash=sha256:40ed7f2546c64f1bb3d22b2295b4d43ed5a2f0b7ea7599d93a72f723a1883e1e \
    +    --hash=sha256:654bb3ae0dc3c69ffddc0c38c127c3b8e93032d8cf3928e2c4f21890cb39514b \
    +    --hash=sha256:699a8e707ca5f3567aa28223ee1be7e42d2bf25eda7d3d86babda71e36e5f16f \
    +    --hash=sha256:a420d814e21b05e1156747e2a9fae6c3cca2b46bb4a0226fb26ee65538ce09c9 \
    +    --hash=sha256:d2c3634411828d9273196ed6f69f2fa7645c89732b3c982dcf09ab03ed4c5d2b \
    +    --hash=sha256:d2fd90f370599cf9a2c6a041bd79a5eeec62baf0e943c7c5c2079b29be476d2a
    +pluggy==1.3.0 \
    +    --hash=sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12 \
    +    --hash=sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7
    +prompt-toolkit==3.0.39 \
    +    --hash=sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac \
    +    --hash=sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88
    +ptyprocess==0.7.0 \
    +    --hash=sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35 \
    +    --hash=sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220
    +pure-eval==0.2.2 \
    +    --hash=sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350 \
    +    --hash=sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3
    +pyasn1==0.5.0 \
    +    --hash=sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57 \
    +    --hash=sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde
    +pyasn1-modules==0.3.0 \
    +    --hash=sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c \
    +    --hash=sha256:d3ccd6ed470d9ffbc716be08bd90efbd44d0734bc9303818f7336070984a162d
    +pycodestyle==2.11.1 \
    +    --hash=sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f \
    +    --hash=sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67
    +pycryptodomex==3.19.0 \
    +    --hash=sha256:09c9401dc06fb3d94cb1ec23b4ea067a25d1f4c6b7b118ff5631d0b5daaab3cc \
    +    --hash=sha256:0b2f1982c5bc311f0aab8c293524b861b485d76f7c9ab2c3ac9a25b6f7655975 \
    +    --hash=sha256:136b284e9246b4ccf4f752d435c80f2c44fc2321c198505de1d43a95a3453b3c \
    +    --hash=sha256:2126bc54beccbede6eade00e647106b4f4c21e5201d2b0a73e9e816a01c50905 \
    +    --hash=sha256:263de9a96d2fcbc9f5bd3a279f14ea0d5f072adb68ebd324987576ec25da084d \
    +    --hash=sha256:50cb18d4dd87571006fd2447ccec85e6cec0136632a550aa29226ba075c80644 \
    +    --hash=sha256:5b883e1439ab63af976656446fb4839d566bb096f15fc3c06b5a99cde4927188 \
    +    --hash=sha256:5d73e9fa3fe830e7b6b42afc49d8329b07a049a47d12e0ef9225f2fd220f19b2 \
    +    --hash=sha256:67c8eb79ab33d0fbcb56842992298ddb56eb6505a72369c20f60bc1d2b6fb002 \
    +    --hash=sha256:7cb51096a6a8d400724104db8a7e4f2206041a1f23e58924aa3d8d96bcb48338 \
    +    --hash=sha256:800a2b05cfb83654df80266692f7092eeefe2a314fa7901dcefab255934faeec \
    +    --hash=sha256:a3866d68e2fc345162b1b9b83ef80686acfe5cec0d134337f3b03950a0a8bf56 \
    +    --hash=sha256:a588a1cb7781da9d5e1c84affd98c32aff9c89771eac8eaa659d2760666f7139 \
    +    --hash=sha256:a77b79852175064c822b047fee7cf5a1f434f06ad075cc9986aa1c19a0c53eb0 \
    +    --hash=sha256:af83a554b3f077564229865c45af0791be008ac6469ef0098152139e6bd4b5b6 \
    +    --hash=sha256:b801216c48c0886742abf286a9a6b117e248ca144d8ceec1f931ce2dd0c9cb40 \
    +    --hash=sha256:bfb040b5dda1dff1e197d2ef71927bd6b8bfcb9793bc4dfe0bb6df1e691eaacb \
    +    --hash=sha256:c01678aee8ac0c1a461cbc38ad496f953f9efcb1fa19f5637cbeba7544792a53 \
    +    --hash=sha256:c74eb1f73f788facece7979ce91594dc177e1a9b5d5e3e64697dd58299e5cb4d \
    +    --hash=sha256:d4dd3b381ff5a5907a3eb98f5f6d32c64d319a840278ceea1dcfcc65063856f3 \
    +    --hash=sha256:edbe083c299835de7e02c8aa0885cb904a75087d35e7bab75ebe5ed336e8c3e2
    +pyee==11.0.1 \
    +    --hash=sha256:9bcc9647822234f42c228d88de63d0f9ffa881e87a87f9d36ddf5211f6ac977d \
    +    --hash=sha256:a642c51e3885a33ead087286e35212783a4e9b8d6514a10a5db4e57ac57b2b29
    +pyflakes==3.1.0 \
    +    --hash=sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774 \
    +    --hash=sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc
    +pygments==2.16.1 \
    +    --hash=sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692 \
    +    --hash=sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29
    +pyproject-hooks==1.0.0 \
    +    --hash=sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8 \
    +    --hash=sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5
    +pytest==7.4.2 \
    +    --hash=sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002 \
    +    --hash=sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069
    +python-crontab==3.0.0 \
    +    --hash=sha256:6d5ba3c190ec76e4d252989a1644fcb233dbf53fbc8fceeb9febe1657b9fb1d4 \
    +    --hash=sha256:79fb7465039ddfd4fb93d072d6ee0d45c1ac8bf1597f0686ea14fd4361dba379
    +python-dateutil==2.8.2 \
    +    --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \
    +    --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9
    +python-dotenv==1.0.0 \
    +    --hash=sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba \
    +    --hash=sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a
    +python-ldap==3.4.3 \
    +    --hash=sha256:ab26c519a0ef2a443a2a10391fa3c5cb52d7871323399db949ebfaa9f25ee2a0
    +pytz==2023.3.post1 \
    +    --hash=sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b \
    +    --hash=sha256:ce42d816b81b68506614c11e8937d3aa9e41007ceb50bfdcb0749b921bf646c7
    +readme-renderer==42.0 \
    +    --hash=sha256:13d039515c1f24de668e2c93f2e877b9dbe6c6c32328b90a40a49d8b2b85f36d \
    +    --hash=sha256:2d55489f83be4992fe4454939d1a051c33edbab778e82761d060c9fc6b308cd1
    +recommonmark==0.7.1 \
    +    --hash=sha256:1b1db69af0231efce3fa21b94ff627ea33dee7079a01dd0a7f8482c3da148b3f \
    +    --hash=sha256:bdb4db649f2222dcd8d2d844f0006b958d627f732415d399791ee436a3686d67
    +regex==2023.10.3 \
    +    --hash=sha256:00ba3c9818e33f1fa974693fb55d24cdc8ebafcb2e4207680669d8f8d7cca79a \
    +    --hash=sha256:06e9abc0e4c9ab4779c74ad99c3fc10d3967d03114449acc2c2762ad4472b8ca \
    +    --hash=sha256:0b9ac09853b2a3e0d0082104036579809679e7715671cfbf89d83c1cb2a30f58 \
    +    --hash=sha256:0d47840dc05e0ba04fe2e26f15126de7c755496d5a8aae4a08bda4dd8d646c54 \
    +    --hash=sha256:107ac60d1bfdc3edb53be75e2a52aff7481b92817cfdddd9b4519ccf0e54a6ff \
    +    --hash=sha256:11175910f62b2b8c055f2b089e0fedd694fe2be3941b3e2633653bc51064c528 \
    +    --hash=sha256:12bd4bc2c632742c7ce20db48e0d99afdc05e03f0b4c1af90542e05b809a03d9 \
    +    --hash=sha256:1c0e8fae5b27caa34177bdfa5a960c46ff2f78ee2d45c6db15ae3f64ecadde14 \
    +    --hash=sha256:2c54e23836650bdf2c18222c87f6f840d4943944146ca479858404fedeb9f9af \
    +    --hash=sha256:36362386b813fa6c9146da6149a001b7bd063dabc4d49522a1f7aa65b725c7ec \
    +    --hash=sha256:39cdf8d141d6d44e8d5a12a8569d5a227f645c87df4f92179bd06e2e2705e76b \
    +    --hash=sha256:3b2c3502603fab52d7619b882c25a6850b766ebd1b18de3df23b2f939360e1bd \
    +    --hash=sha256:3ccf2716add72f80714b9a63899b67fa711b654be3fcdd34fa391d2d274ce767 \
    +    --hash=sha256:3fef4f844d2290ee0ba57addcec17eec9e3df73f10a2748485dfd6a3a188cc0f \
    +    --hash=sha256:4023e2efc35a30e66e938de5aef42b520c20e7eda7bb5fb12c35e5d09a4c43f6 \
    +    --hash=sha256:4a8bf76e3182797c6b1afa5b822d1d5802ff30284abe4599e1247be4fd6b03be \
    +    --hash=sha256:4a992f702c9be9c72fa46f01ca6e18d131906a7180950958f766c2aa294d4b41 \
    +    --hash=sha256:4c34d4f73ea738223a094d8e0ffd6d2c1a1b4c175da34d6b0de3d8d69bee6bcc \
    +    --hash=sha256:4cd1bccf99d3ef1ab6ba835308ad85be040e6a11b0977ef7ea8c8005f01a3c29 \
    +    --hash=sha256:4ef80829117a8061f974b2fda8ec799717242353bff55f8a29411794d635d964 \
    +    --hash=sha256:5a8f91c64f390ecee09ff793319f30a0f32492e99f5dc1c72bc361f23ccd0a9a \
    +    --hash=sha256:5addc9d0209a9afca5fc070f93b726bf7003bd63a427f65ef797a931782e7edc \
    +    --hash=sha256:6239d4e2e0b52c8bd38c51b760cd870069f0bdf99700a62cd509d7a031749a55 \
    +    --hash=sha256:66e2fe786ef28da2b28e222c89502b2af984858091675044d93cb50e6f46d7af \
    +    --hash=sha256:69c0771ca5653c7d4b65203cbfc5e66db9375f1078689459fe196fe08b7b4930 \
    +    --hash=sha256:6ac965a998e1388e6ff2e9781f499ad1eaa41e962a40d11c7823c9952c77123e \
    +    --hash=sha256:6c56c3d47da04f921b73ff9415fbaa939f684d47293f071aa9cbb13c94afc17d \
    +    --hash=sha256:7434a61b158be563c1362d9071358f8ab91b8d928728cd2882af060481244c9e \
    +    --hash=sha256:7ef1e014eed78ab650bef9a6a9cbe50b052c0aebe553fb2881e0453717573f52 \
    +    --hash=sha256:81dce2ddc9f6e8f543d94b05d56e70d03a0774d32f6cca53e978dc01e4fc75b8 \
    +    --hash=sha256:8d1f21af4c1539051049796a0f50aa342f9a27cde57318f2fc41ed50b0dbc4ac \
    +    --hash=sha256:90a79bce019c442604662d17bf69df99090e24cdc6ad95b18b6725c2988a490e \
    +    --hash=sha256:9145f092b5d1977ec8c0ab46e7b3381b2fd069957b9862a43bd383e5c01d18c2 \
    +    --hash=sha256:994645a46c6a740ee8ce8df7911d4aee458d9b1bc5639bc968226763d07f00fa \
    +    --hash=sha256:9c6b4d23c04831e3ab61717a707a5d763b300213db49ca680edf8bf13ab5d91b \
    +    --hash=sha256:9c6d0ced3c06d0f183b73d3c5920727268d2201aa0fe6d55c60d68c792ff3588 \
    +    --hash=sha256:a8f4e49fc3ce020f65411432183e6775f24e02dff617281094ba6ab079ef0915 \
    +    --hash=sha256:a9e908ef5889cda4de038892b9accc36d33d72fb3e12c747e2799a0e806ec841 \
    +    --hash=sha256:ad08a69728ff3c79866d729b095872afe1e0557251da4abb2c5faff15a91d19a \
    +    --hash=sha256:adbccd17dcaff65704c856bd29951c58a1bd4b2b0f8ad6b826dbd543fe740988 \
    +    --hash=sha256:b0c7d2f698e83f15228ba41c135501cfe7d5740181d5903e250e47f617eb4292 \
    +    --hash=sha256:b6104f9a46bd8743e4f738afef69b153c4b8b592d35ae46db07fc28ae3d5fb7c \
    +    --hash=sha256:ba7cd6dc4d585ea544c1412019921570ebd8a597fabf475acc4528210d7c4a6f \
    +    --hash=sha256:bc72c231f5449d86d6c7d9cc7cd819b6eb30134bb770b8cfdc0765e48ef9c420 \
    +    --hash=sha256:bce8814b076f0ce5766dc87d5a056b0e9437b8e0cd351b9a6c4e1134a7dfbda9 \
    +    --hash=sha256:be5e22bbb67924dea15039c3282fa4cc6cdfbe0cbbd1c0515f9223186fc2ec5f \
    +    --hash=sha256:be6b7b8d42d3090b6c80793524fa66c57ad7ee3fe9722b258aec6d0672543fd0 \
    +    --hash=sha256:bff507ae210371d4b1fe316d03433ac099f184d570a1a611e541923f78f05037 \
    +    --hash=sha256:c148bec483cc4b421562b4bcedb8e28a3b84fcc8f0aa4418e10898f3c2c0eb9b \
    +    --hash=sha256:c15ad0aee158a15e17e0495e1e18741573d04eb6da06d8b84af726cfc1ed02ee \
    +    --hash=sha256:c2169b2dcabf4e608416f7f9468737583ce5f0a6e8677c4efbf795ce81109d7c \
    +    --hash=sha256:c65a3b5330b54103e7d21cac3f6bf3900d46f6d50138d73343d9e5b2900b2353 \
    +    --hash=sha256:c7964c2183c3e6cce3f497e3a9f49d182e969f2dc3aeeadfa18945ff7bdd7051 \
    +    --hash=sha256:d29338556a59423d9ff7b6eb0cb89ead2b0875e08fe522f3e068b955c3e7b59b \
    +    --hash=sha256:d8a993c0a0ffd5f2d3bda23d0cd75e7086736f8f8268de8a82fbc4bd0ac6791e \
    +    --hash=sha256:d9c727bbcf0065cbb20f39d2b4f932f8fa1631c3e01fcedc979bd4f51fe051c5 \
    +    --hash=sha256:ebedc192abbc7fd13c5ee800e83a6df252bec691eb2c4bedc9f8b2e2903f5e2a \
    +    --hash=sha256:f0a47efb1dbef13af9c9a54a94a0b814902e547b7f21acb29434504d18f36e3a \
    +    --hash=sha256:fb02e4257376ae25c6dd95a5aec377f9b18c09be6ebdefa7ad209b9137b73d48
    +requests==2.31.0 \
    +    --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \
    +    --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1
    +requests-toolbelt==1.0.0 \
    +    --hash=sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6 \
    +    --hash=sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06
    +resolvelib==1.0.1 \
    +    --hash=sha256:04ce76cbd63fded2078ce224785da6ecd42b9564b1390793f64ddecbe997b309 \
    +    --hash=sha256:d2da45d1a8dfee81bdd591647783e340ef3bcb104b54c383f70d422ef5cc7dbf
    +rfc3986==2.0.0 \
    +    --hash=sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd \
    +    --hash=sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c
    +rich==13.6.0 \
    +    --hash=sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245 \
    +    --hash=sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef
    +setuptools==68.2.2 \
    +    --hash=sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87 \
    +    --hash=sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a
    +shellingham==1.5.3 \
    +    --hash=sha256:419c6a164770c9c7cfcaeddfacb3d31ac7a8db0b0f3e9c1287679359734107e9 \
    +    --hash=sha256:cb4a6fec583535bc6da17b647dd2330cf7ef30239e05d547d99ae3705fd0f7f8
    +six==1.16.0 \
    +    --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
    +    --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
    +snowballstemmer==2.2.0 \
    +    --hash=sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1 \
    +    --hash=sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a
    +sonic-client==1.0.0 \
    +    --hash=sha256:291bf292861e97a2dd765ff0c8754ea9631383680d31a63ec3da6f5aa5f4beda \
    +    --hash=sha256:fe324c7354670488ed84847f6a6727d3cb5fb3675cb9b61396dcf5720e5aca66
    +sphinx==7.2.6 \
    +    --hash=sha256:1e09160a40b956dc623c910118fa636da93bd3ca0b9876a7b3df90f07d691560 \
    +    --hash=sha256:9a5160e1ea90688d5963ba09a2dcd8bdd526620edbb65c328728f1b2228d5ab5
    +sphinx-rtd-theme==1.3.0 \
    +    --hash=sha256:46ddef89cc2416a81ecfbeaceab1881948c014b1b6e4450b815311a89fb977b0 \
    +    --hash=sha256:590b030c7abb9cf038ec053b95e5380b5c70d61591eb0b552063fbe7c41f0931
    +sphinxcontrib-applehelp==1.0.7 \
    +    --hash=sha256:094c4d56209d1734e7d252f6e0b3ccc090bd52ee56807a5d9315b19c122ab15d \
    +    --hash=sha256:39fdc8d762d33b01a7d8f026a3b7d71563ea3b72787d5f00ad8465bd9d6dfbfa
    +sphinxcontrib-devhelp==1.0.5 \
    +    --hash=sha256:63b41e0d38207ca40ebbeabcf4d8e51f76c03e78cd61abe118cf4435c73d4212 \
    +    --hash=sha256:fe8009aed765188f08fcaadbb3ea0d90ce8ae2d76710b7e29ea7d047177dae2f
    +sphinxcontrib-htmlhelp==2.0.4 \
    +    --hash=sha256:6c26a118a05b76000738429b724a0568dbde5b72391a688577da08f11891092a \
    +    --hash=sha256:8001661c077a73c29beaf4a79968d0726103c5605e27db92b9ebed8bab1359e9
    +sphinxcontrib-jquery==4.1 \
    +    --hash=sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a \
    +    --hash=sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae
    +sphinxcontrib-jsmath==1.0.1 \
    +    --hash=sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178 \
    +    --hash=sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8
    +sphinxcontrib-qthelp==1.0.6 \
    +    --hash=sha256:62b9d1a186ab7f5ee3356d906f648cacb7a6bdb94d201ee7adf26db55092982d \
    +    --hash=sha256:bf76886ee7470b934e363da7a954ea2825650013d367728588732c7350f49ea4
    +sphinxcontrib-serializinghtml==1.1.9 \
    +    --hash=sha256:0c64ff898339e1fac29abd2bf5f11078f3ec413cfe9c046d3120d7ca65530b54 \
    +    --hash=sha256:9b36e503703ff04f20e9675771df105e58aa029cfcbc23b8ed716019b7416ae1
    +sqlparse==0.4.4 \
    +    --hash=sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3 \
    +    --hash=sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c
    +stack-data==0.6.3 \
    +    --hash=sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9 \
    +    --hash=sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695
    +stdeb==0.10.0 \
    +    --hash=sha256:08c22c9c03b28a140fe3ec5064b53a5288279f22e596ca06b0be698d50c93cf2
    +tomlkit==0.12.1 \
    +    --hash=sha256:38e1ff8edb991273ec9f6181244a6a391ac30e9f5098e7535640ea6be97a7c86 \
    +    --hash=sha256:712cbd236609acc6a3e2e97253dfc52d4c2082982a88f61b640ecf0817eab899
    +traitlets==5.11.2 \
    +    --hash=sha256:7564b5bf8d38c40fa45498072bf4dc5e8346eb087bbf1e2ae2d8774f6a0f078e \
    +    --hash=sha256:98277f247f18b2c5cabaf4af369187754f4fb0e85911d473f72329db8a7f4fae
    +truststore==0.8.0 \
    +    --hash=sha256:dc70da89634944a579bfeec70a7a4523c53ffdb3cf52d1bb4a431fda278ddb96 \
    +    --hash=sha256:e37a5642ae9fc48caa8f120b6283d77225d600d224965a672c9e8ef49ce4bb4c
    +twine==4.0.2 \
    +    --hash=sha256:929bc3c280033347a00f847236564d1c52a3e61b1ac2516c97c48f3ceab756d8 \
    +    --hash=sha256:9e102ef5fdd5a20661eb88fad46338806c3bd32cf1db729603fe3697b1bc83c8
    +types-pytz==2023.3.1.1 \
    +    --hash=sha256:1999a123a3dc0e39a2ef6d19f3f8584211de9e6a77fe7a0259f04a524e90a5cf \
    +    --hash=sha256:cc23d0192cd49c8f6bba44ee0c81e4586a8f30204970fc0894d209a6b08dab9a
    +types-PyYAML==6.0.12.12 \
    +    --hash=sha256:334373d392fde0fdf95af5c3f1661885fa10c52167b14593eb856289e1855062 \
    +    --hash=sha256:c05bc6c158facb0676674b7f11fe3960db4f389718e19e62bd2b84d6205cfd24
    +typing-extensions==4.8.0 \
    +    --hash=sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0 \
    +    --hash=sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef
    +tzlocal==5.1 \
    +    --hash=sha256:2938498395d5f6a898ab8009555cb37a4d360913ad375d4747ef16826b03ef23 \
    +    --hash=sha256:a5ccb2365b295ed964e0a98ad076fe10c495591e75505d34f154d60a7f1ed722
    +unearth==0.11.2 \
    +    --hash=sha256:046a996466de40a16e257fc883ae08157e7ab78a85bcec00313f3fdf9131bd37 \
    +    --hash=sha256:0eb5a8800fda0610e095fef768b48d47c858c9b8417a785af647046c2df5ed2b
    +urllib3==2.0.7 \
    +    --hash=sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84 \
    +    --hash=sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e
    +virtualenv==20.24.5 \
    +    --hash=sha256:b80039f280f4919c77b30f1c23294ae357c4c8701042086e3fc005963e4e537b \
    +    --hash=sha256:e8361967f6da6fbdf1426483bfe9fca8287c242ac0bc30429905721cefbff752
    +w3lib==2.1.2 \
    +    --hash=sha256:c4432926e739caa8e3f49f5de783f336df563d9490416aebd5d39fb896d264e7 \
    +    --hash=sha256:ed5b74e997eea2abe3c1321f916e344144ee8e9072a6f33463ee8e57f858a4b1
    +wcwidth==0.2.8 \
    +    --hash=sha256:77f719e01648ed600dfa5402c347481c0992263b81a027344f3e1ba25493a704 \
    +    --hash=sha256:8705c569999ffbb4f6a87c6d1b80f324bd6db952f5eb0b95bc07517f4c1813d4
    +websockets==11.0.3 \
    +    --hash=sha256:01f5567d9cf6f502d655151645d4e8b72b453413d3819d2b6f1185abc23e82dd \
    +    --hash=sha256:0ac56b661e60edd453585f4bd68eb6a29ae25b5184fd5ba51e97652580458998 \
    +    --hash=sha256:0ee68fe502f9031f19d495dae2c268830df2760c0524cbac5d759921ba8c8e82 \
    +    --hash=sha256:1d2256283fa4b7f4c7d7d3e84dc2ece74d341bce57d5b9bf385df109c2a1a82f \
    +    --hash=sha256:1d5023a4b6a5b183dc838808087033ec5df77580485fc533e7dab2567851b0a4 \
    +    --hash=sha256:1fdf26fa8a6a592f8f9235285b8affa72748dc12e964a5518c6c5e8f916716f7 \
    +    --hash=sha256:279e5de4671e79a9ac877427f4ac4ce93751b8823f276b681d04b2156713b9dd \
    +    --hash=sha256:2d903ad4419f5b472de90cd2d40384573b25da71e33519a67797de17ef849b69 \
    +    --hash=sha256:3580dd9c1ad0701169e4d6fc41e878ffe05e6bdcaf3c412f9d559389d0c9e016 \
    +    --hash=sha256:3ccc8a0c387629aec40f2fc9fdcb4b9d5431954f934da3eaf16cdc94f67dbfac \
    +    --hash=sha256:41f696ba95cd92dc047e46b41b26dd24518384749ed0d99bea0a941ca87404c4 \
    +    --hash=sha256:42cc5452a54a8e46a032521d7365da775823e21bfba2895fb7b77633cce031bb \
    +    --hash=sha256:54c6e5b3d3a8936a4ab6870d46bdd6ec500ad62bde9e44462c32d18f1e9a8e54 \
    +    --hash=sha256:619d9f06372b3a42bc29d0cd0354c9bb9fb39c2cbc1a9c5025b4538738dbffaf \
    +    --hash=sha256:660e2d9068d2bedc0912af508f30bbeb505bbbf9774d98def45f68278cea20d3 \
    +    --hash=sha256:6681ba9e7f8f3b19440921e99efbb40fc89f26cd71bf539e45d8c8a25c976dc6 \
    +    --hash=sha256:69269f3a0b472e91125b503d3c0b3566bda26da0a3261c49f0027eb6075086d1 \
    +    --hash=sha256:6f1a3f10f836fab6ca6efa97bb952300b20ae56b409414ca85bff2ad241d2a61 \
    +    --hash=sha256:7622a89d696fc87af8e8d280d9b421db5133ef5b29d3f7a1ce9f1a7bf7fcfa11 \
    +    --hash=sha256:777354ee16f02f643a4c7f2b3eff8027a33c9861edc691a2003531f5da4f6bc8 \
    +    --hash=sha256:84d27a4832cc1a0ee07cdcf2b0629a8a72db73f4cf6de6f0904f6661227f256f \
    +    --hash=sha256:8531fdcad636d82c517b26a448dcfe62f720e1922b33c81ce695d0edb91eb931 \
    +    --hash=sha256:86d2a77fd490ae3ff6fae1c6ceaecad063d3cc2320b44377efdde79880e11526 \
    +    --hash=sha256:88fc51d9a26b10fc331be344f1781224a375b78488fc343620184e95a4b27016 \
    +    --hash=sha256:8c82f11964f010053e13daafdc7154ce7385ecc538989a354ccc7067fd7028fd \
    +    --hash=sha256:92b2065d642bf8c0a82d59e59053dd2fdde64d4ed44efe4870fa816c1232647b \
    +    --hash=sha256:97b52894d948d2f6ea480171a27122d77af14ced35f62e5c892ca2fae9344311 \
    +    --hash=sha256:aa5003845cdd21ac0dc6c9bf661c5beddd01116f6eb9eb3c8e272353d45b3288 \
    +    --hash=sha256:b30c6590146e53149f04e85a6e4fcae068df4289e31e4aee1fdf56a0dead8f97 \
    +    --hash=sha256:b58cbf0697721120866820b89f93659abc31c1e876bf20d0b3d03cef14faf84d \
    +    --hash=sha256:b67c6f5e5a401fc56394f191f00f9b3811fe843ee93f4a70df3c389d1adf857d \
    +    --hash=sha256:bceab846bac555aff6427d060f2fcfff71042dba6f5fca7dc4f75cac815e57ca \
    +    --hash=sha256:c114e8da9b475739dde229fd3bc6b05a6537a88a578358bc8eb29b4030fac9c9 \
    +    --hash=sha256:c1f0524f203e3bd35149f12157438f406eff2e4fb30f71221c8a5eceb3617b6b \
    +    --hash=sha256:c792ea4eabc0159535608fc5658a74d1a81020eb35195dd63214dcf07556f67e \
    +    --hash=sha256:c7f3cb904cce8e1be667c7e6fef4516b98d1a6a0635a58a57528d577ac18a128 \
    +    --hash=sha256:d67ac60a307f760c6e65dad586f556dde58e683fab03323221a4e530ead6f74d \
    +    --hash=sha256:dcacf2c7a6c3a84e720d1bb2b543c675bf6c40e460300b628bab1b1efc7c034c \
    +    --hash=sha256:de36fe9c02995c7e6ae6efe2e205816f5f00c22fd1fbf343d4d18c3d5ceac2f5 \
    +    --hash=sha256:def07915168ac8f7853812cc593c71185a16216e9e4fa886358a17ed0fd9fcf6 \
    +    --hash=sha256:df41b9bc27c2c25b486bae7cf42fccdc52ff181c8c387bfd026624a491c2671b \
    +    --hash=sha256:e052b8467dd07d4943936009f46ae5ce7b908ddcac3fda581656b1b19c083d9b \
    +    --hash=sha256:e063b1865974611313a3849d43f2c3f5368093691349cf3c7c8f8f75ad7cb280 \
    +    --hash=sha256:e1459677e5d12be8bbc7584c35b992eea142911a6236a3278b9b5ce3326f282c \
    +    --hash=sha256:e6316827e3e79b7b8e7d8e3b08f4e331af91a48e794d5d8b099928b6f0b85f20 \
    +    --hash=sha256:e7837cb169eca3b3ae94cc5787c4fed99eef74c0ab9506756eea335e0d6f3ed8 \
    +    --hash=sha256:e848f46a58b9fcf3d06061d17be388caf70ea5b8cc3466251963c8345e13f7eb \
    +    --hash=sha256:ed058398f55163a79bb9f06a90ef9ccc063b204bb346c4de78efc5d15abfe602 \
    +    --hash=sha256:f2e58f2c36cc52d41f2659e4c0cbf7353e28c8c9e63e30d8c6d3494dc9fdedcf \
    +    --hash=sha256:ffd7dcaf744f25f82190856bc26ed81721508fc5cbf2a330751e135ff1283564
    +wheel==0.41.2 \
    +    --hash=sha256:0c5ac5ff2afb79ac23ab82bab027a0be7b5dbcf2e54dc50efe4bf507de1f7985 \
    +    --hash=sha256:75909db2664838d015e3d9139004ee16711748a52c8f336b52882266540215d8
    +yt-dlp==2023.10.13 \
    +    --hash=sha256:2b069f22675532eebacdfd6372b1825651a751fef848de9ae6efe6491b2dc38a \
    +    --hash=sha256:e026ea1c435ff36eef1215bc4c5bb8c479938b90054997ba99f63a4541fe63b4
    +zipp==3.17.0 \
    +    --hash=sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31 \
    +    --hash=sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0
    
    From aabc89d6a7f139ae19cd423152390d8142db417b Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 01:06:57 -0700
    Subject: [PATCH 74/89] add requirements.txt
    
    ---
     Dockerfile | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index e61a2eb8..a0725638 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -211,7 +211,7 @@ RUN echo "[+] Installing NPM extractor dependencies..." \
     
     # Install ArchiveBox Python dependencies
     WORKDIR "$CODE_DIR"
    -COPY --chown=root:root --chmod=755 "./pyproject.toml" "./pdm.lock" "$CODE_DIR/"
    +COPY --chown=root:root --chmod=755 "./pyproject.toml" "./pdm.lock" "requirements.txt" "$CODE_DIR/"
     RUN echo "[+] Installing PIP ArchiveBox dependencies..." \
         && apt-get update -qq \
         # && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    
    From 47d91611682aded668405043e7dcc230ba712095 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 03:06:02 -0700
    Subject: [PATCH 75/89] fix Dockerfile
    
    ---
     Dockerfile          |   51 +-
     bin/build_docker.sh |   13 +-
     bin/build_pip.sh    |   15 +-
     pdm.lock            | 1352 +++++--------------------------------------
     pyproject.toml      |    8 +-
     requirements.txt    |  799 ++-----------------------
     6 files changed, 246 insertions(+), 1992 deletions(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index a0725638..76bc3360 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -62,7 +62,7 @@ ENV APP_VENV=/app/.venv \
     
     # Build shell config
     ENV PATH="$PATH:$GLOBAL_VENV/bin:$APP_VENV/bin:$NODE_MODULES/.bin"
    -SHELL ["/bin/bash", "-o", "pipefail", "-c"] 
    +SHELL ["/bin/bash", "-o", "pipefail", "-o", "errexit", "-o", "errtrace", "-o", "nounset", "-c"] 
     
     ######### System Environment ####################################
     
    @@ -87,7 +87,7 @@ RUN (echo "[i] Docker build for ArchiveBox $(cat /VERSION.txt) starting..." \
         ) | tee -a /VERSION.txt
     
     # Create non-privileged user for archivebox and chrome
    -RUN echo "[*] Setting up $ARCHIVEBOX_USER user ${DEFAULT_PUID}..." \
    +RUN echo "[*] Setting up $ARCHIVEBOX_USER user uid=${DEFAULT_PUID}..." \
         && groupadd --system $ARCHIVEBOX_USER \
         && useradd --system --create-home --gid $ARCHIVEBOX_USER --groups audio,video $ARCHIVEBOX_USER \
         && usermod -u "$DEFAULT_PUID" "$ARCHIVEBOX_USER" \
    @@ -98,7 +98,7 @@ RUN echo "[*] Setting up $ARCHIVEBOX_USER user ${DEFAULT_PUID}..." \
         # https://docs.linuxserver.io/general/understanding-puid-and-pgid
     
     # Install system apt dependencies (adding backports to access more recent apt updates)
    -RUN echo "[+] Installing system dependencies for $TARGETPLATFORM..." \
    +RUN echo "[+] Installing APT base system dependencies for $TARGETPLATFORM..." \
         # && echo 'deb https://deb.debian.org/debian bookworm-backports main contrib non-free' >> /etc/apt/sources.list.d/backports.list \
         && mkdir -p /etc/apt/keyrings \
         && apt-get update -qq \
    @@ -114,7 +114,7 @@ RUN echo "[+] Installing system dependencies for $TARGETPLATFORM..." \
     ######### Language Environments ####################################
     
     # Install Node environment
    -RUN echo "[+] Installing Node $NODE_VERSION environment..." \
    +RUN echo "[+] Installing Node $NODE_VERSION environment in $NODE_MODULES..." \
         && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_VERSION}.x nodistro main" >> /etc/apt/sources.list.d/nodejs.list \
         && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
         && apt-get update -qq \
    @@ -131,18 +131,18 @@ RUN echo "[+] Installing Node $NODE_VERSION environment..." \
         ) | tee -a /VERSION.txt
     
     # Install Python environment
    -RUN echo "[+] Installing Python $PYTHON_VERSION environment..." \
    +RUN echo "[+] Installing Python $PYTHON_VERSION environment in $GLOBAL_VENV and $APP_VENV..." \
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    -        python3 python3-pip python3-venv python3-setuptools python3-wheel python-dev-is-python3 \
    -        python3-ldap libldap2-dev libsasl2-dev libssl-dev python3-msgpack \
    +        python3 python3-pip python3-setuptools python3-wheel python3-venv python3-pdm python-dev-is-python3 \
    +        #python3-ldap libldap2-dev libsasl2-dev libssl-dev python3-msgpack \
         && rm -rf /var/lib/apt/lists/* \
         # tell PDM to allow using global system python site packages
         && rm /usr/lib/python3*/EXTERNALLY-MANAGED \
         # create global virtual environment GLOBAL_VENV to use (better than using pip install --global)
         && python3 -m venv --system-site-packages --symlinks $GLOBAL_VENV \
         # install global dependencies / python build dependencies in GLOBAL_VENV
    -    && $GLOBAL_VENV/bin/pip install --upgrade pip pdm setuptools wheel python-ldap \
    +    && $GLOBAL_VENV/bin/pip install --break-system-packages --upgrade pip pdm setuptools wheel \
         # Save version info
         && ( \
             which python3 && python3 --version | grep " $PYTHON_VERSION" \
    @@ -154,7 +154,7 @@ RUN echo "[+] Installing Python $PYTHON_VERSION environment..." \
     ######### Extractor Dependencies ##################################
     
     # Install apt dependencies
    -RUN echo "[+] Installing APT extractor dependencies..." \
    +RUN echo "[+] Installing APT extractor dependencies globally using apt..." \
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
             curl wget git yt-dlp ffmpeg ripgrep \
    @@ -173,7 +173,7 @@ RUN echo "[+] Installing APT extractor dependencies..." \
         ) | tee -a /VERSION.txt
     
     # Install chromium browser using playwright
    -RUN echo "[+] Installing Browser binary dependencies for $TARGETPLATFORM..." \
    +RUN echo "[+] Installing Browser binary dependencies to $PLAYWRIGHT_BROWSERS_PATH..." \
         && apt-get update -qq \
         && if [[ "$TARGETPLATFORM" == "linux/amd64" || "$TARGETPLATFORM" == "linux/arm64" ]]; then \
             # install Chromium using playwright
    @@ -181,7 +181,7 @@ RUN echo "[+] Installing Browser binary dependencies for $TARGETPLATFORM..." \
             && $GLOBAL_VENV/bin/playwright install --with-deps chromium \
             && export CHROME_BINARY="$($GLOBAL_VENV/bin/python -c 'from playwright.sync_api import sync_playwright; print(sync_playwright().start().chromium.executable_path)')"; \
         else \
    -        # install Chromium on platforms not supported by playwright (e.g. risc, ARMv7, etc.) 
    +        # fall back to installing Chromium via apt-get on platforms not supported by playwright (e.g. risc, ARMv7, etc.) 
             apt-get install -qq -y -t bookworm-backports --no-install-recommends \
                 chromium fontconfig fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-symbola fonts-noto fonts-freefont-ttf \
             && export CHROME_BINARY="$(which chromium)"; \
    @@ -199,7 +199,7 @@ RUN echo "[+] Installing Browser binary dependencies for $TARGETPLATFORM..." \
     # Install Node dependencies
     WORKDIR "$CODE_DIR"
     COPY --chown=root:root --chmod=755 "package.json" "package-lock.json" "$CODE_DIR/"
    -RUN echo "[+] Installing NPM extractor dependencies..." \
    +RUN echo "[+] Installing NPM extractor dependencies from package.json into $NODE_MODULES..." \
         && npm ci --prefer-offline --no-audit \
         && ( \
             which node && node --version \
    @@ -212,21 +212,20 @@ RUN echo "[+] Installing NPM extractor dependencies..." \
     # Install ArchiveBox Python dependencies
     WORKDIR "$CODE_DIR"
     COPY --chown=root:root --chmod=755 "./pyproject.toml" "./pdm.lock" "requirements.txt" "$CODE_DIR/"
    -RUN echo "[+] Installing PIP ArchiveBox dependencies..." \
    +RUN echo "[+] Installing PIP ArchiveBox dependencies from requirements.txt into $GLOBAL_VENV..." \
         && apt-get update -qq \
    -    # && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    -        # build-essential libssl-dev libldap2-dev libsasl2-dev \
    +    && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    +        build-essential libssl-dev libldap2-dev libsasl2-dev \
         && ln -s "$GLOBAL_VENV" "$APP_VENV" \
    -    && pdm use --venv in-project \
    -    && pdm run python -m ensurepip \
    +    # && pdm use --venv in-project \
    +    # && pdm run python -m ensurepip \
         # && pdm sync --fail-fast --no-editable --group :all --no-self \
    -    # && source "$GLOBAL_VENV/bin/activate" \
         # && pdm export -o requirements.txt --without-hashes \
    -    && $GLOBAL_VENV/bin/pip install --upgrade -r requirements.txt \
    -    # && apt-get purge -y \
    -    #     build-essential libssl-dev libldap2-dev libsasl2-dev \
    -    #     # these are only needed to build CPython libs, we discard after build phase to shrink layer size
    -    # && apt-get autoremove -y \
    +    && $GLOBAL_VENV/bin/pip install -r requirements.txt \
    +    && apt-get purge -y \
    +        build-essential libssl-dev libldap2-dev libsasl2-dev \
    +        # these are only needed to build CPython libs, we discard after build phase to shrink layer size
    +    && apt-get autoremove -y \
         && rm -rf /var/lib/apt/lists/*
     
     # Install ArchiveBox Python package from source
    @@ -235,10 +234,12 @@ RUN echo "[*] Installing PIP ArchiveBox package from $CODE_DIR..." \
         && apt-get update -qq \
         # install C compiler to build deps on platforms that dont have 32-bit wheels available on pypi
         && if [[ "$TARGETPLATFORM" == "linux/arm/v7" ]]; then \
    -        apt-get install -qq -y --no-install-recommends build-essential python3-regex; \
    +        apt-get install -qq -y --no-install-recommends build-essential python3-regex procps; \
    +    else \
    +        apt-get install -qq -y --no-install-recommends procps; \
         fi \
         # INSTALL ARCHIVEBOX python package globally from CODE_DIR, with all optional dependencies
    -    && $GLOBAL_VENV/bin/pip3 install -e "$CODE_DIR"[sonic,ldap] \
    +    && $GLOBAL_VENV/bin/pip3 install --break-system-packages -e "$CODE_DIR"[sonic,ldap] \
         # save docker image size and always remove compilers / build tools after building is complete
         && apt-get purge -y build-essential \
         && apt-get autoremove -y \
    diff --git a/bin/build_docker.sh b/bin/build_docker.sh
    index abbd3f20..4fd4fa5a 100755
    --- a/bin/build_docker.sh
    +++ b/bin/build_docker.sh
    @@ -13,13 +13,19 @@ IFS=$'\n'
     
     REPO_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd .. && pwd )"
     cd "$REPO_DIR"
    +
     which docker > /dev/null || exit 1
    +which jq > /dev/null || exit 1
    +# which pdm > /dev/null || exit 1
    +
    +SUPPORTED_PLATFORMS="linux/arm64,linux/amd64,linux/arm/v7"
    +
     
     
     TAG_NAME="${1:-$(git rev-parse --abbrev-ref HEAD)}"
     VERSION="$(jq -r '.version' < "$REPO_DIR/package.json")"
     SHORT_VERSION="$(echo "$VERSION" | perl -pe 's/(\d+)\.(\d+)\.(\d+)/$1.$2/g')"
    -REQUIRED_PLATFORMS="${2:-"linux/arm64,linux/amd64,linux/arm/v7"}"
    +REQUIRED_PLATFORMS="${2:-$SUPPORTED_PLATFORMS}"
     
     echo "[+] Building Docker image: tag=$TAG_NAME version=$SHORT_VERSION arch=$REQUIRED_PLATFORMS"
     
    @@ -65,6 +71,11 @@ docker buildx use xbuilder 2>&1 >/dev/null || create_builder
     check_platforms || (recreate_builder && check_platforms) || exit 1
     
     
    +# Build python package lists
    +echo "[+] Generating requirements.txt and pdm.lock from pyproject.toml..."
    +pdm lock --group=':all' --strategy="cross_platform" --production
    +pdm export --group=':all' --production --without-hashes -o requirements.txt
    +
     echo "[+] Building archivebox:$VERSION docker image..."
     # docker builder prune
     # docker build . --no-cache -t archivebox-dev \
    diff --git a/bin/build_pip.sh b/bin/build_pip.sh
    index e2edace2..f86a3e21 100755
    --- a/bin/build_pip.sh
    +++ b/bin/build_pip.sh
    @@ -15,20 +15,17 @@ REPO_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd .. && p
     if [[ -f "$REPO_DIR/.venv/bin/activate" ]]; then
         source "$REPO_DIR/.venv/bin/activate"
     else
    -    echo "[!] Warning: No virtualenv presesnt in $REPO_DIR.venv"
    +    echo "[!] Warning: No virtualenv presesnt in $REPO_DIR/.venv, creating one now..."
    +    python3 -m venv --system-site-packages --symlinks $REPO_DIR/.venv
     fi
     cd "$REPO_DIR"
     
    -
     echo "[*] Cleaning up build dirs"
     cd "$REPO_DIR"
     rm -Rf build dist
     
     echo "[+] Building sdist, bdist_wheel, and egg_info"
    -# python3 setup.py \
    -#     sdist --dist-dir=./pip_dist \
    -#     bdist_wheel --dist-dir=./pip_dist \
    -#     egg_info --egg-base=./pip_dist
    -
    -# pip install --upgrade pip setuptools build
    -python -m build
    +pdm self update
    +pdm install
    +pdm build
    +pdm export --without-hashes -o requirements.txt
    \ No newline at end of file
    diff --git a/pdm.lock b/pdm.lock
    index d2d83727..2a8610fa 100644
    --- a/pdm.lock
    +++ b/pdm.lock
    @@ -2,20 +2,10 @@
     # It is not intended for manual editing.
     
     [metadata]
    -groups = ["default", "build", "debug", "doc", "ldap", "lint", "sonic", "test"]
    +groups = ["default", "ldap", "sonic"]
     strategy = ["cross_platform"]
     lock_version = "4.4"
    -content_hash = "sha256:827692ea8b95a8d0033ad1ae915f475e8b5cc46bafd947499ca892d516125c68"
    -
    -[[package]]
    -name = "alabaster"
    -version = "0.7.13"
    -requires_python = ">=3.6"
    -summary = "A configurable sidebar-enabled Sphinx theme"
    -files = [
    -    {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"},
    -    {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"},
    -]
    +content_hash = "sha256:dc6df5fe3c05dc53c4a12a47dc11fa88863c819d0487e21770fd5fed1b57ec5d"
     
     [[package]]
     name = "appnope"
    @@ -41,52 +31,14 @@ files = [
     
     [[package]]
     name = "asttokens"
    -version = "2.4.0"
    +version = "2.4.1"
     summary = "Annotate AST trees with source code positions"
     dependencies = [
         "six>=1.12.0",
     ]
     files = [
    -    {file = "asttokens-2.4.0-py2.py3-none-any.whl", hash = "sha256:cf8fc9e61a86461aa9fb161a14a0841a03c405fa829ac6b202670b3495d2ce69"},
    -    {file = "asttokens-2.4.0.tar.gz", hash = "sha256:2e0171b991b2c959acc6c49318049236844a5da1d65ba2672c4880c1c894834e"},
    -]
    -
    -[[package]]
    -name = "babel"
    -version = "2.13.0"
    -requires_python = ">=3.7"
    -summary = "Internationalization utilities"
    -files = [
    -    {file = "Babel-2.13.0-py3-none-any.whl", hash = "sha256:fbfcae1575ff78e26c7449136f1abbefc3c13ce542eeb13d43d50d8b047216ec"},
    -    {file = "Babel-2.13.0.tar.gz", hash = "sha256:04c3e2d28d2b7681644508f836be388ae49e0cfe91465095340395b60d00f210"},
    -]
    -
    -[[package]]
    -name = "backcall"
    -version = "0.2.0"
    -summary = "Specifications for callback functions passed in to an API"
    -files = [
    -    {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"},
    -    {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"},
    -]
    -
    -[[package]]
    -name = "blinker"
    -version = "1.6.3"
    -requires_python = ">=3.7"
    -summary = "Fast, simple object-to-object and broadcast signaling"
    -files = [
    -    {file = "blinker-1.6.3-py3-none-any.whl", hash = "sha256:296320d6c28b006eb5e32d4712202dbcdcbf5dc482da298c2f44881c43884aaa"},
    -    {file = "blinker-1.6.3.tar.gz", hash = "sha256:152090d27c1c5c722ee7e48504b02d76502811ce02e1523553b4cf8c8b3d3a8d"},
    -]
    -
    -[[package]]
    -name = "bottle"
    -version = "0.12.25"
    -summary = "Fast and simple WSGI-framework for small web-applications."
    -files = [
    -    {file = "bottle-0.12.25-py3-none-any.whl", hash = "sha256:d6f15f9d422670b7c073d63bd8d287b135388da187a0f3e3c19293626ce034ea"},
    -    {file = "bottle-0.12.25.tar.gz", hash = "sha256:e1a9c94970ae6d710b3fb4526294dfeb86f2cb4a81eff3a4b98dc40fb0e5e021"},
    +    {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"},
    +    {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"},
     ]
     
     [[package]]
    @@ -183,35 +135,6 @@ files = [
         {file = "brotlicffi-1.1.0.0.tar.gz", hash = "sha256:b77827a689905143f87915310b93b273ab17888fd43ef350d4832c4a71083c13"},
     ]
     
    -[[package]]
    -name = "cachecontrol"
    -version = "0.13.1"
    -requires_python = ">=3.7"
    -summary = "httplib2 caching for requests"
    -dependencies = [
    -    "msgpack>=0.5.2",
    -    "requests>=2.16.0",
    -]
    -files = [
    -    {file = "cachecontrol-0.13.1-py3-none-any.whl", hash = "sha256:95dedbec849f46dda3137866dc28b9d133fc9af55f5b805ab1291833e4457aa4"},
    -    {file = "cachecontrol-0.13.1.tar.gz", hash = "sha256:f012366b79d2243a6118309ce73151bf52a38d4a5dac8ea57f09bd29087e506b"},
    -]
    -
    -[[package]]
    -name = "cachecontrol"
    -version = "0.13.1"
    -extras = ["filecache"]
    -requires_python = ">=3.7"
    -summary = "httplib2 caching for requests"
    -dependencies = [
    -    "cachecontrol==0.13.1",
    -    "filelock>=3.8.0",
    -]
    -files = [
    -    {file = "cachecontrol-0.13.1-py3-none-any.whl", hash = "sha256:95dedbec849f46dda3137866dc28b9d133fc9af55f5b805ab1291833e4457aa4"},
    -    {file = "cachecontrol-0.13.1.tar.gz", hash = "sha256:f012366b79d2243a6118309ce73151bf52a38d4a5dac8ea57f09bd29087e506b"},
    -]
    -
     [[package]]
     name = "certifi"
     version = "2023.7.22"
    @@ -279,72 +202,72 @@ files = [
     
     [[package]]
     name = "charset-normalizer"
    -version = "3.3.0"
    +version = "3.3.1"
     requires_python = ">=3.7.0"
     summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
     files = [
    -    {file = "charset-normalizer-3.3.0.tar.gz", hash = "sha256:63563193aec44bce707e0c5ca64ff69fa72ed7cf34ce6e11d5127555756fd2f6"},
    -    {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:effe5406c9bd748a871dbcaf3ac69167c38d72db8c9baf3ff954c344f31c4cbe"},
    -    {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4162918ef3098851fcd8a628bf9b6a98d10c380725df9e04caf5ca6dd48c847a"},
    -    {file = "charset_normalizer-3.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0570d21da019941634a531444364f2482e8db0b3425fcd5ac0c36565a64142c8"},
    -    {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5707a746c6083a3a74b46b3a631d78d129edab06195a92a8ece755aac25a3f3d"},
    -    {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:278c296c6f96fa686d74eb449ea1697f3c03dc28b75f873b65b5201806346a69"},
    -    {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a4b71f4d1765639372a3b32d2638197f5cd5221b19531f9245fcc9ee62d38f56"},
    -    {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5969baeaea61c97efa706b9b107dcba02784b1601c74ac84f2a532ea079403e"},
    -    {file = "charset_normalizer-3.3.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3f93dab657839dfa61025056606600a11d0b696d79386f974e459a3fbc568ec"},
    -    {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:db756e48f9c5c607b5e33dd36b1d5872d0422e960145b08ab0ec7fd420e9d649"},
    -    {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:232ac332403e37e4a03d209a3f92ed9071f7d3dbda70e2a5e9cff1c4ba9f0678"},
    -    {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e5c1502d4ace69a179305abb3f0bb6141cbe4714bc9b31d427329a95acfc8bdd"},
    -    {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:2502dd2a736c879c0f0d3e2161e74d9907231e25d35794584b1ca5284e43f596"},
    -    {file = "charset_normalizer-3.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23e8565ab7ff33218530bc817922fae827420f143479b753104ab801145b1d5b"},
    -    {file = "charset_normalizer-3.3.0-cp310-cp310-win32.whl", hash = "sha256:1872d01ac8c618a8da634e232f24793883d6e456a66593135aeafe3784b0848d"},
    -    {file = "charset_normalizer-3.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:557b21a44ceac6c6b9773bc65aa1b4cc3e248a5ad2f5b914b91579a32e22204d"},
    -    {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d7eff0f27edc5afa9e405f7165f85a6d782d308f3b6b9d96016c010597958e63"},
    -    {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a685067d05e46641d5d1623d7c7fdf15a357546cbb2f71b0ebde91b175ffc3e"},
    -    {file = "charset_normalizer-3.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0d3d5b7db9ed8a2b11a774db2bbea7ba1884430a205dbd54a32d61d7c2a190fa"},
    -    {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2935ffc78db9645cb2086c2f8f4cfd23d9b73cc0dc80334bc30aac6f03f68f8c"},
    -    {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fe359b2e3a7729010060fbca442ca225280c16e923b37db0e955ac2a2b72a05"},
    -    {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:380c4bde80bce25c6e4f77b19386f5ec9db230df9f2f2ac1e5ad7af2caa70459"},
    -    {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0d1e3732768fecb052d90d62b220af62ead5748ac51ef61e7b32c266cac9293"},
    -    {file = "charset_normalizer-3.3.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1b2919306936ac6efb3aed1fbf81039f7087ddadb3160882a57ee2ff74fd2382"},
    -    {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f8888e31e3a85943743f8fc15e71536bda1c81d5aa36d014a3c0c44481d7db6e"},
    -    {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:82eb849f085624f6a607538ee7b83a6d8126df6d2f7d3b319cb837b289123078"},
    -    {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7b8b8bf1189b3ba9b8de5c8db4d541b406611a71a955bbbd7385bbc45fcb786c"},
    -    {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5adf257bd58c1b8632046bbe43ee38c04e1038e9d37de9c57a94d6bd6ce5da34"},
    -    {file = "charset_normalizer-3.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c350354efb159b8767a6244c166f66e67506e06c8924ed74669b2c70bc8735b1"},
    -    {file = "charset_normalizer-3.3.0-cp311-cp311-win32.whl", hash = "sha256:02af06682e3590ab952599fbadac535ede5d60d78848e555aa58d0c0abbde786"},
    -    {file = "charset_normalizer-3.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:86d1f65ac145e2c9ed71d8ffb1905e9bba3a91ae29ba55b4c46ae6fc31d7c0d4"},
    -    {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3b447982ad46348c02cb90d230b75ac34e9886273df3a93eec0539308a6296d7"},
    -    {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:abf0d9f45ea5fb95051c8bfe43cb40cda383772f7e5023a83cc481ca2604d74e"},
    -    {file = "charset_normalizer-3.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b09719a17a2301178fac4470d54b1680b18a5048b481cb8890e1ef820cb80455"},
    -    {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b3d9b48ee6e3967b7901c052b670c7dda6deb812c309439adaffdec55c6d7b78"},
    -    {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:edfe077ab09442d4ef3c52cb1f9dab89bff02f4524afc0acf2d46be17dc479f5"},
    -    {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3debd1150027933210c2fc321527c2299118aa929c2f5a0a80ab6953e3bd1908"},
    -    {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86f63face3a527284f7bb8a9d4f78988e3c06823f7bea2bd6f0e0e9298ca0403"},
    -    {file = "charset_normalizer-3.3.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:24817cb02cbef7cd499f7c9a2735286b4782bd47a5b3516a0e84c50eab44b98e"},
    -    {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c71f16da1ed8949774ef79f4a0260d28b83b3a50c6576f8f4f0288d109777989"},
    -    {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:9cf3126b85822c4e53aa28c7ec9869b924d6fcfb76e77a45c44b83d91afd74f9"},
    -    {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:b3b2316b25644b23b54a6f6401074cebcecd1244c0b8e80111c9a3f1c8e83d65"},
    -    {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:03680bb39035fbcffe828eae9c3f8afc0428c91d38e7d61aa992ef7a59fb120e"},
    -    {file = "charset_normalizer-3.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4cc152c5dd831641e995764f9f0b6589519f6f5123258ccaca8c6d34572fefa8"},
    -    {file = "charset_normalizer-3.3.0-cp312-cp312-win32.whl", hash = "sha256:b8f3307af845803fb0b060ab76cf6dd3a13adc15b6b451f54281d25911eb92df"},
    -    {file = "charset_normalizer-3.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:8eaf82f0eccd1505cf39a45a6bd0a8cf1c70dcfc30dba338207a969d91b965c0"},
    -    {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e0fc42822278451bc13a2e8626cf2218ba570f27856b536e00cfa53099724828"},
    -    {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:09c77f964f351a7369cc343911e0df63e762e42bac24cd7d18525961c81754f4"},
    -    {file = "charset_normalizer-3.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:12ebea541c44fdc88ccb794a13fe861cc5e35d64ed689513a5c03d05b53b7c82"},
    -    {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:805dfea4ca10411a5296bcc75638017215a93ffb584c9e344731eef0dcfb026a"},
    -    {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96c2b49eb6a72c0e4991d62406e365d87067ca14c1a729a870d22354e6f68115"},
    -    {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aaf7b34c5bc56b38c931a54f7952f1ff0ae77a2e82496583b247f7c969eb1479"},
    -    {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:619d1c96099be5823db34fe89e2582b336b5b074a7f47f819d6b3a57ff7bdb86"},
    -    {file = "charset_normalizer-3.3.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0ac5e7015a5920cfce654c06618ec40c33e12801711da6b4258af59a8eff00a"},
    -    {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:93aa7eef6ee71c629b51ef873991d6911b906d7312c6e8e99790c0f33c576f89"},
    -    {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7966951325782121e67c81299a031f4c115615e68046f79b85856b86ebffc4cd"},
    -    {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:02673e456dc5ab13659f85196c534dc596d4ef260e4d86e856c3b2773ce09843"},
    -    {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:c2af80fb58f0f24b3f3adcb9148e6203fa67dd3f61c4af146ecad033024dde43"},
    -    {file = "charset_normalizer-3.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:153e7b6e724761741e0974fc4dcd406d35ba70b92bfe3fedcb497226c93b9da7"},
    -    {file = "charset_normalizer-3.3.0-cp39-cp39-win32.whl", hash = "sha256:d47ecf253780c90ee181d4d871cd655a789da937454045b17b5798da9393901a"},
    -    {file = "charset_normalizer-3.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:d97d85fa63f315a8bdaba2af9a6a686e0eceab77b3089af45133252618e70884"},
    -    {file = "charset_normalizer-3.3.0-py3-none-any.whl", hash = "sha256:e46cd37076971c1040fc8c41273a8b3e2c624ce4f2be3f5dfcb7a430c1d3acc2"},
    +    {file = "charset-normalizer-3.3.1.tar.gz", hash = "sha256:d9137a876020661972ca6eec0766d81aef8a5627df628b664b234b73396e727e"},
    +    {file = "charset_normalizer-3.3.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8aee051c89e13565c6bd366813c386939f8e928af93c29fda4af86d25b73d8f8"},
    +    {file = "charset_normalizer-3.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:352a88c3df0d1fa886562384b86f9a9e27563d4704ee0e9d56ec6fcd270ea690"},
    +    {file = "charset_normalizer-3.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:223b4d54561c01048f657fa6ce41461d5ad8ff128b9678cfe8b2ecd951e3f8a2"},
    +    {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f861d94c2a450b974b86093c6c027888627b8082f1299dfd5a4bae8e2292821"},
    +    {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1171ef1fc5ab4693c5d151ae0fdad7f7349920eabbaca6271f95969fa0756c2d"},
    +    {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28f512b9a33235545fbbdac6a330a510b63be278a50071a336afc1b78781b147"},
    +    {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0e842112fe3f1a4ffcf64b06dc4c61a88441c2f02f373367f7b4c1aa9be2ad5"},
    +    {file = "charset_normalizer-3.3.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f9bc2ce123637a60ebe819f9fccc614da1bcc05798bbbaf2dd4ec91f3e08846"},
    +    {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f194cce575e59ffe442c10a360182a986535fd90b57f7debfaa5c845c409ecc3"},
    +    {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:9a74041ba0bfa9bc9b9bb2cd3238a6ab3b7618e759b41bd15b5f6ad958d17605"},
    +    {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b578cbe580e3b41ad17b1c428f382c814b32a6ce90f2d8e39e2e635d49e498d1"},
    +    {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:6db3cfb9b4fcecb4390db154e75b49578c87a3b9979b40cdf90d7e4b945656e1"},
    +    {file = "charset_normalizer-3.3.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:debb633f3f7856f95ad957d9b9c781f8e2c6303ef21724ec94bea2ce2fcbd056"},
    +    {file = "charset_normalizer-3.3.1-cp310-cp310-win32.whl", hash = "sha256:87071618d3d8ec8b186d53cb6e66955ef2a0e4fa63ccd3709c0c90ac5a43520f"},
    +    {file = "charset_normalizer-3.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:e372d7dfd154009142631de2d316adad3cc1c36c32a38b16a4751ba78da2a397"},
    +    {file = "charset_normalizer-3.3.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ae4070f741f8d809075ef697877fd350ecf0b7c5837ed68738607ee0a2c572cf"},
    +    {file = "charset_normalizer-3.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:58e875eb7016fd014c0eea46c6fa92b87b62c0cb31b9feae25cbbe62c919f54d"},
    +    {file = "charset_normalizer-3.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dbd95e300367aa0827496fe75a1766d198d34385a58f97683fe6e07f89ca3e3c"},
    +    {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de0b4caa1c8a21394e8ce971997614a17648f94e1cd0640fbd6b4d14cab13a72"},
    +    {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:985c7965f62f6f32bf432e2681173db41336a9c2611693247069288bcb0c7f8b"},
    +    {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a15c1fe6d26e83fd2e5972425a772cca158eae58b05d4a25a4e474c221053e2d"},
    +    {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ae55d592b02c4349525b6ed8f74c692509e5adffa842e582c0f861751701a673"},
    +    {file = "charset_normalizer-3.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:be4d9c2770044a59715eb57c1144dedea7c5d5ae80c68fb9959515037cde2008"},
    +    {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:851cf693fb3aaef71031237cd68699dded198657ec1e76a76eb8be58c03a5d1f"},
    +    {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:31bbaba7218904d2eabecf4feec0d07469284e952a27400f23b6628439439fa7"},
    +    {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:871d045d6ccc181fd863a3cd66ee8e395523ebfbc57f85f91f035f50cee8e3d4"},
    +    {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:501adc5eb6cd5f40a6f77fbd90e5ab915c8fd6e8c614af2db5561e16c600d6f3"},
    +    {file = "charset_normalizer-3.3.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f5fb672c396d826ca16a022ac04c9dce74e00a1c344f6ad1a0fdc1ba1f332213"},
    +    {file = "charset_normalizer-3.3.1-cp311-cp311-win32.whl", hash = "sha256:bb06098d019766ca16fc915ecaa455c1f1cd594204e7f840cd6258237b5079a8"},
    +    {file = "charset_normalizer-3.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:8af5a8917b8af42295e86b64903156b4f110a30dca5f3b5aedea123fbd638bff"},
    +    {file = "charset_normalizer-3.3.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:7ae8e5142dcc7a49168f4055255dbcced01dc1714a90a21f87448dc8d90617d1"},
    +    {file = "charset_normalizer-3.3.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5b70bab78accbc672f50e878a5b73ca692f45f5b5e25c8066d748c09405e6a55"},
    +    {file = "charset_normalizer-3.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5ceca5876032362ae73b83347be8b5dbd2d1faf3358deb38c9c88776779b2e2f"},
    +    {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34d95638ff3613849f473afc33f65c401a89f3b9528d0d213c7037c398a51296"},
    +    {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9edbe6a5bf8b56a4a84533ba2b2f489d0046e755c29616ef8830f9e7d9cf5728"},
    +    {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6a02a3c7950cafaadcd46a226ad9e12fc9744652cc69f9e5534f98b47f3bbcf"},
    +    {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10b8dd31e10f32410751b3430996f9807fc4d1587ca69772e2aa940a82ab571a"},
    +    {file = "charset_normalizer-3.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edc0202099ea1d82844316604e17d2b175044f9bcb6b398aab781eba957224bd"},
    +    {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b891a2f68e09c5ef989007fac11476ed33c5c9994449a4e2c3386529d703dc8b"},
    +    {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:71ef3b9be10070360f289aea4838c784f8b851be3ba58cf796262b57775c2f14"},
    +    {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:55602981b2dbf8184c098bc10287e8c245e351cd4fdcad050bd7199d5a8bf514"},
    +    {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:46fb9970aa5eeca547d7aa0de5d4b124a288b42eaefac677bde805013c95725c"},
    +    {file = "charset_normalizer-3.3.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:520b7a142d2524f999447b3a0cf95115df81c4f33003c51a6ab637cbda9d0bf4"},
    +    {file = "charset_normalizer-3.3.1-cp312-cp312-win32.whl", hash = "sha256:8ec8ef42c6cd5856a7613dcd1eaf21e5573b2185263d87d27c8edcae33b62a61"},
    +    {file = "charset_normalizer-3.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:baec8148d6b8bd5cee1ae138ba658c71f5b03e0d69d5907703e3e1df96db5e41"},
    +    {file = "charset_normalizer-3.3.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bc791ec3fd0c4309a753f95bb6c749ef0d8ea3aea91f07ee1cf06b7b02118f2f"},
    +    {file = "charset_normalizer-3.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0c8c61fb505c7dad1d251c284e712d4e0372cef3b067f7ddf82a7fa82e1e9a93"},
    +    {file = "charset_normalizer-3.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2c092be3885a1b7899cd85ce24acedc1034199d6fca1483fa2c3a35c86e43041"},
    +    {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2000c54c395d9e5e44c99dc7c20a64dc371f777faf8bae4919ad3e99ce5253e"},
    +    {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4cb50a0335382aac15c31b61d8531bc9bb657cfd848b1d7158009472189f3d62"},
    +    {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c30187840d36d0ba2893bc3271a36a517a717f9fd383a98e2697ee890a37c273"},
    +    {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe81b35c33772e56f4b6cf62cf4aedc1762ef7162a31e6ac7fe5e40d0149eb67"},
    +    {file = "charset_normalizer-3.3.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0bf89afcbcf4d1bb2652f6580e5e55a840fdf87384f6063c4a4f0c95e378656"},
    +    {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:06cf46bdff72f58645434d467bf5228080801298fbba19fe268a01b4534467f5"},
    +    {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:3c66df3f41abee950d6638adc7eac4730a306b022570f71dd0bd6ba53503ab57"},
    +    {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:cd805513198304026bd379d1d516afbf6c3c13f4382134a2c526b8b854da1c2e"},
    +    {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:9505dc359edb6a330efcd2be825fdb73ee3e628d9010597aa1aee5aa63442e97"},
    +    {file = "charset_normalizer-3.3.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:31445f38053476a0c4e6d12b047b08ced81e2c7c712e5a1ad97bc913256f91b2"},
    +    {file = "charset_normalizer-3.3.1-cp39-cp39-win32.whl", hash = "sha256:bd28b31730f0e982ace8663d108e01199098432a30a4c410d06fe08fdb9e93f4"},
    +    {file = "charset_normalizer-3.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:555fe186da0068d3354cdf4bbcbc609b0ecae4d04c921cc13e209eece7720727"},
    +    {file = "charset_normalizer-3.3.1-py3-none-any.whl", hash = "sha256:800561453acdecedaac137bf09cd719c7a440b6800ec182f077bb8e7025fb708"},
     ]
     
     [[package]]
    @@ -357,15 +280,6 @@ files = [
         {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
     ]
     
    -[[package]]
    -name = "commonmark"
    -version = "0.9.1"
    -summary = "Python parser for the CommonMark Markdown spec"
    -files = [
    -    {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"},
    -    {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"},
    -]
    -
     [[package]]
     name = "croniter"
     version = "2.0.1"
    @@ -380,40 +294,6 @@ files = [
         {file = "croniter-2.0.1.tar.gz", hash = "sha256:d199b2ec3ea5e82988d1f72022433c5f9302b3b3ea9e6bfd6a1518f6ea5e700a"},
     ]
     
    -[[package]]
    -name = "cryptography"
    -version = "41.0.4"
    -requires_python = ">=3.7"
    -summary = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
    -dependencies = [
    -    "cffi>=1.12",
    -]
    -files = [
    -    {file = "cryptography-41.0.4-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:80907d3faa55dc5434a16579952ac6da800935cd98d14dbd62f6f042c7f5e839"},
    -    {file = "cryptography-41.0.4-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:35c00f637cd0b9d5b6c6bd11b6c3359194a8eba9c46d4e875a3660e3b400005f"},
    -    {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cecfefa17042941f94ab54f769c8ce0fe14beff2694e9ac684176a2535bf9714"},
    -    {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e40211b4923ba5a6dc9769eab704bdb3fbb58d56c5b336d30996c24fcf12aadb"},
    -    {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:23a25c09dfd0d9f28da2352503b23e086f8e78096b9fd585d1d14eca01613e13"},
    -    {file = "cryptography-41.0.4-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2ed09183922d66c4ec5fdaa59b4d14e105c084dd0febd27452de8f6f74704143"},
    -    {file = "cryptography-41.0.4-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5a0f09cefded00e648a127048119f77bc2b2ec61e736660b5789e638f43cc397"},
    -    {file = "cryptography-41.0.4-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:9eeb77214afae972a00dee47382d2591abe77bdae166bda672fb1e24702a3860"},
    -    {file = "cryptography-41.0.4-cp37-abi3-win32.whl", hash = "sha256:3b224890962a2d7b57cf5eeb16ccaafba6083f7b811829f00476309bce2fe0fd"},
    -    {file = "cryptography-41.0.4-cp37-abi3-win_amd64.whl", hash = "sha256:c880eba5175f4307129784eca96f4e70b88e57aa3f680aeba3bab0e980b0f37d"},
    -    {file = "cryptography-41.0.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:004b6ccc95943f6a9ad3142cfabcc769d7ee38a3f60fb0dddbfb431f818c3a67"},
    -    {file = "cryptography-41.0.4-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:86defa8d248c3fa029da68ce61fe735432b047e32179883bdb1e79ed9bb8195e"},
    -    {file = "cryptography-41.0.4-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:37480760ae08065437e6573d14be973112c9e6dcaf5f11d00147ee74f37a3829"},
    -    {file = "cryptography-41.0.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b5f4dfe950ff0479f1f00eda09c18798d4f49b98f4e2006d644b3301682ebdca"},
    -    {file = "cryptography-41.0.4-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7e53db173370dea832190870e975a1e09c86a879b613948f09eb49324218c14d"},
    -    {file = "cryptography-41.0.4-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5b72205a360f3b6176485a333256b9bcd48700fc755fef51c8e7e67c4b63e3ac"},
    -    {file = "cryptography-41.0.4-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:93530900d14c37a46ce3d6c9e6fd35dbe5f5601bf6b3a5c325c7bffc030344d9"},
    -    {file = "cryptography-41.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efc8ad4e6fc4f1752ebfb58aefece8b4e3c4cae940b0994d43649bdfce8d0d4f"},
    -    {file = "cryptography-41.0.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c3391bd8e6de35f6f1140e50aaeb3e2b3d6a9012536ca23ab0d9c35ec18c8a91"},
    -    {file = "cryptography-41.0.4-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:0d9409894f495d465fe6fda92cb70e8323e9648af912d5b9141d616df40a87b8"},
    -    {file = "cryptography-41.0.4-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:8ac4f9ead4bbd0bc8ab2d318f97d85147167a488be0e08814a37eb2f439d5cf6"},
    -    {file = "cryptography-41.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:047c4603aeb4bbd8db2756e38f5b8bd7e94318c047cfe4efeb5d715e08b49311"},
    -    {file = "cryptography-41.0.4.tar.gz", hash = "sha256:7febc3094125fc126a7f6fb1f420d0da639f3f32cb15c8ff0dc3997c4549f51a"},
    -]
    -
     [[package]]
     name = "dateparser"
     version = "1.1.8"
    @@ -440,15 +320,6 @@ files = [
         {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"},
     ]
     
    -[[package]]
    -name = "distlib"
    -version = "0.3.7"
    -summary = "Distribution utilities"
    -files = [
    -    {file = "distlib-0.3.7-py2.py3-none-any.whl", hash = "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057"},
    -    {file = "distlib-0.3.7.tar.gz", hash = "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8"},
    -]
    -
     [[package]]
     name = "django"
     version = "3.1.14"
    @@ -478,20 +349,6 @@ files = [
         {file = "django_auth_ldap-4.1.0-py3-none-any.whl", hash = "sha256:68870e7921e84b1a9867e268a9c8a3e573e8a0d95ea08bcf31be178f5826ff36"},
     ]
     
    -[[package]]
    -name = "django-debug-toolbar"
    -version = "3.2.4"
    -requires_python = ">=3.6"
    -summary = "A configurable set of panels that display various debug information about the current request/response."
    -dependencies = [
    -    "Django>=2.2",
    -    "sqlparse>=0.2.0",
    -]
    -files = [
    -    {file = "django-debug-toolbar-3.2.4.tar.gz", hash = "sha256:644bbd5c428d3283aa9115722471769cac1bec189edf3a0c855fd8ff870375a9"},
    -    {file = "django_debug_toolbar-3.2.4-py3-none-any.whl", hash = "sha256:6b633b6cfee24f232d73569870f19aa86c819d750e7f3e833f2344a9eb4b4409"},
    -]
    -
     [[package]]
     name = "django-extensions"
     version = "3.1.5"
    @@ -505,58 +362,6 @@ files = [
         {file = "django_extensions-3.1.5-py3-none-any.whl", hash = "sha256:9238b9e016bb0009d621e05cf56ea8ce5cce9b32e91ad2026996a7377ca28069"},
     ]
     
    -[[package]]
    -name = "django-stubs"
    -version = "4.2.5"
    -requires_python = ">=3.8"
    -summary = "Mypy stubs for Django"
    -dependencies = [
    -    "django",
    -    "django-stubs-ext>=4.2.5",
    -    "mypy>=1.0.0",
    -    "tomli; python_version < \"3.11\"",
    -    "types-PyYAML",
    -    "types-pytz",
    -    "typing-extensions",
    -]
    -files = [
    -    {file = "django-stubs-4.2.5.tar.gz", hash = "sha256:5a23cf622f1426a0b0c48bd6e2ef709a66275d72073baf6fdf5ac36fc4cce736"},
    -    {file = "django_stubs-4.2.5-py3-none-any.whl", hash = "sha256:706b2456bd0e56c468dfd8f27b0e7dde001c5c7cd3010d67fcbda9d95467e050"},
    -]
    -
    -[[package]]
    -name = "django-stubs-ext"
    -version = "4.2.5"
    -requires_python = ">=3.8"
    -summary = "Monkey-patching and extensions for django-stubs"
    -dependencies = [
    -    "django",
    -    "typing-extensions",
    -]
    -files = [
    -    {file = "django-stubs-ext-4.2.5.tar.gz", hash = "sha256:8c4d1fb5f68419b3b2474c659681a189803e27d6a5e5abf5aa0da57601b58633"},
    -    {file = "django_stubs_ext-4.2.5-py3-none-any.whl", hash = "sha256:921cd7ae4614e74c234bc0fe86ee75537d163addfe1fc6f134bf03e29d86c01e"},
    -]
    -
    -[[package]]
    -name = "djdt-flamegraph"
    -version = "0.2.13"
    -summary = "Flamegraphs for Django Debug Toolbar"
    -files = [
    -    {file = "djdt_flamegraph-0.2.13-py2.py3-none-any.whl", hash = "sha256:b3252b8cc9b586829166cc158b26952626cd6f41a3ffa92dceef2f5dbe5b99a0"},
    -    {file = "djdt_flamegraph-0.2.13.tar.gz", hash = "sha256:c07a71be58484636e021d4c49b129fd819f24c9128849cb59558e5141192dbf3"},
    -]
    -
    -[[package]]
    -name = "docutils"
    -version = "0.18.1"
    -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
    -summary = "Docutils -- Python Documentation Utilities"
    -files = [
    -    {file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"},
    -    {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"},
    -]
    -
     [[package]]
     name = "exceptiongroup"
     version = "1.1.3"
    @@ -569,49 +374,12 @@ files = [
     
     [[package]]
     name = "executing"
    -version = "2.0.0"
    +version = "2.0.1"
    +requires_python = ">=3.5"
     summary = "Get the currently executing AST node of a frame, and other information"
     files = [
    -    {file = "executing-2.0.0-py2.py3-none-any.whl", hash = "sha256:06df6183df67389625f4e763921c6cf978944721abf3e714000200aab95b0657"},
    -    {file = "executing-2.0.0.tar.gz", hash = "sha256:0ff053696fdeef426cda5bd18eacd94f82c91f49823a2e9090124212ceea9b08"},
    -]
    -
    -[[package]]
    -name = "filelock"
    -version = "3.12.4"
    -requires_python = ">=3.8"
    -summary = "A platform independent file lock."
    -files = [
    -    {file = "filelock-3.12.4-py3-none-any.whl", hash = "sha256:08c21d87ded6e2b9da6728c3dff51baf1dcecf973b768ef35bcbc3447edb9ad4"},
    -    {file = "filelock-3.12.4.tar.gz", hash = "sha256:2e6f249f1f3654291606e046b09f1fd5eac39b360664c27f5aad072012f8bcbd"},
    -]
    -
    -[[package]]
    -name = "findpython"
    -version = "0.4.0"
    -requires_python = ">=3.7"
    -summary = "A utility to find python versions on your system"
    -dependencies = [
    -    "packaging>=20",
    -]
    -files = [
    -    {file = "findpython-0.4.0-py3-none-any.whl", hash = "sha256:087148ac5935f9be458f36a05f3fa479efdf2c629f5d386c73ea481cfecff15e"},
    -    {file = "findpython-0.4.0.tar.gz", hash = "sha256:18b14d115678da18ae92ee22d7001cc30915ea531053f77010ee05a39680f438"},
    -]
    -
    -[[package]]
    -name = "flake8"
    -version = "6.1.0"
    -requires_python = ">=3.8.1"
    -summary = "the modular source code checker: pep8 pyflakes and co"
    -dependencies = [
    -    "mccabe<0.8.0,>=0.7.0",
    -    "pycodestyle<2.12.0,>=2.11.0",
    -    "pyflakes<3.2.0,>=3.1.0",
    -]
    -files = [
    -    {file = "flake8-6.1.0-py2.py3-none-any.whl", hash = "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"},
    -    {file = "flake8-6.1.0.tar.gz", hash = "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23"},
    +    {file = "executing-2.0.1-py2.py3-none-any.whl", hash = "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc"},
    +    {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"},
     ]
     
     [[package]]
    @@ -673,81 +441,19 @@ files = [
         {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
     ]
     
    -[[package]]
    -name = "imagesize"
    -version = "1.4.1"
    -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
    -summary = "Getting image size from png/jpeg/jpeg2000/gif file"
    -files = [
    -    {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"},
    -    {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"},
    -]
    -
    -[[package]]
    -name = "importlib-metadata"
    -version = "6.8.0"
    -requires_python = ">=3.8"
    -summary = "Read metadata from Python packages"
    -dependencies = [
    -    "zipp>=0.5",
    -]
    -files = [
    -    {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"},
    -    {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"},
    -]
    -
    -[[package]]
    -name = "iniconfig"
    -version = "2.0.0"
    -requires_python = ">=3.7"
    -summary = "brain-dead simple config-ini parsing"
    -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 = "installer"
    -version = "0.7.0"
    -requires_python = ">=3.7"
    -summary = "A library for installing Python wheels."
    -files = [
    -    {file = "installer-0.7.0-py3-none-any.whl", hash = "sha256:05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53"},
    -    {file = "installer-0.7.0.tar.gz", hash = "sha256:a26d3e3116289bb08216e0d0f7d925fcef0b0194eedfa0c944bcaaa106c4b631"},
    -]
    -
    -[[package]]
    -name = "ipdb"
    -version = "0.13.13"
    -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
    -summary = "IPython-enabled pdb"
    -dependencies = [
    -    "decorator; python_version > \"3.6\" and python_version < \"3.11\"",
    -    "decorator; python_version >= \"3.11\"",
    -    "ipython>=7.31.1; python_version > \"3.6\" and python_version < \"3.11\"",
    -    "ipython>=7.31.1; python_version >= \"3.11\"",
    -    "tomli; python_version > \"3.6\" and python_version < \"3.11\"",
    -]
    -files = [
    -    {file = "ipdb-0.13.13-py3-none-any.whl", hash = "sha256:45529994741c4ab6d2388bfa5d7b725c2cf7fe9deffabdb8a6113aa5ed449ed4"},
    -    {file = "ipdb-0.13.13.tar.gz", hash = "sha256:e3ac6018ef05126d442af680aad863006ec19d02290561ac88b8b1c0b0cfc726"},
    -]
    -
     [[package]]
     name = "ipython"
    -version = "8.16.1"
    +version = "8.17.1"
     requires_python = ">=3.9"
     summary = "IPython: Productive Interactive Computing"
     dependencies = [
         "appnope; sys_platform == \"darwin\"",
    -    "backcall",
         "colorama; sys_platform == \"win32\"",
         "decorator",
         "exceptiongroup; python_version < \"3.11\"",
         "jedi>=0.16",
         "matplotlib-inline",
         "pexpect>4.3; sys_platform != \"win32\"",
    -    "pickleshare",
         "prompt-toolkit!=3.0.37,<3.1.0,>=3.0.30",
         "pygments>=2.4.0",
         "stack-data",
    @@ -755,21 +461,8 @@ dependencies = [
         "typing-extensions; python_version < \"3.10\"",
     ]
     files = [
    -    {file = "ipython-8.16.1-py3-none-any.whl", hash = "sha256:0852469d4d579d9cd613c220af7bf0c9cc251813e12be647cb9d463939db9b1e"},
    -    {file = "ipython-8.16.1.tar.gz", hash = "sha256:ad52f58fca8f9f848e256c629eff888efc0528c12fe0f8ec14f33205f23ef938"},
    -]
    -
    -[[package]]
    -name = "jaraco-classes"
    -version = "3.3.0"
    -requires_python = ">=3.8"
    -summary = "Utility functions for Python class constructs"
    -dependencies = [
    -    "more-itertools",
    -]
    -files = [
    -    {file = "jaraco.classes-3.3.0-py3-none-any.whl", hash = "sha256:10afa92b6743f25c0cf5f37c6bb6e18e2c5bb84a16527ccfc0040ea377e7aaeb"},
    -    {file = "jaraco.classes-3.3.0.tar.gz", hash = "sha256:c063dd08e89217cee02c8d5e5ec560f2c8ce6cdc2fcdc2e68f7b2e5547ed3621"},
    +    {file = "ipython-8.17.1-py3-none-any.whl", hash = "sha256:b4510d0a163c89c78cf81be68acc841dde4a8290b6ee3f3c9578ccdd2574553c"},
    +    {file = "ipython-8.17.1.tar.gz", hash = "sha256:9e12020f4bf74f08631c0f033bb580e074fbe36c64903195f3e63b9c0a986cbe"},
     ]
     
     [[package]]
    @@ -785,108 +478,6 @@ files = [
         {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"},
     ]
     
    -[[package]]
    -name = "jeepney"
    -version = "0.8.0"
    -requires_python = ">=3.7"
    -summary = "Low-level, pure Python DBus protocol wrapper."
    -files = [
    -    {file = "jeepney-0.8.0-py3-none-any.whl", hash = "sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755"},
    -    {file = "jeepney-0.8.0.tar.gz", hash = "sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806"},
    -]
    -
    -[[package]]
    -name = "jinja2"
    -version = "3.1.2"
    -requires_python = ">=3.7"
    -summary = "A very fast and expressive template engine."
    -dependencies = [
    -    "MarkupSafe>=2.0",
    -]
    -files = [
    -    {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
    -    {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
    -]
    -
    -[[package]]
    -name = "keyring"
    -version = "24.2.0"
    -requires_python = ">=3.8"
    -summary = "Store and access your passwords safely."
    -dependencies = [
    -    "SecretStorage>=3.2; sys_platform == \"linux\"",
    -    "importlib-metadata>=4.11.4; python_version < \"3.12\"",
    -    "jaraco-classes",
    -    "jeepney>=0.4.2; sys_platform == \"linux\"",
    -    "pywin32-ctypes>=0.2.0; sys_platform == \"win32\"",
    -]
    -files = [
    -    {file = "keyring-24.2.0-py3-none-any.whl", hash = "sha256:4901caaf597bfd3bbd78c9a0c7c4c29fcd8310dab2cffefe749e916b6527acd6"},
    -    {file = "keyring-24.2.0.tar.gz", hash = "sha256:ca0746a19ec421219f4d713f848fa297a661a8a8c1504867e55bfb5e09091509"},
    -]
    -
    -[[package]]
    -name = "markdown-it-py"
    -version = "3.0.0"
    -requires_python = ">=3.8"
    -summary = "Python port of markdown-it. Markdown parsing, done right!"
    -dependencies = [
    -    "mdurl~=0.1",
    -]
    -files = [
    -    {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"},
    -    {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"},
    -]
    -
    -[[package]]
    -name = "markupsafe"
    -version = "2.1.3"
    -requires_python = ">=3.7"
    -summary = "Safely add untrusted strings to HTML/XML markup."
    -files = [
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"},
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"},
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"},
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"},
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"},
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"},
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"},
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"},
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"},
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"},
    -    {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"},
    -]
    -
     [[package]]
     name = "matplotlib-inline"
     version = "0.1.6"
    @@ -900,89 +491,6 @@ files = [
         {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"},
     ]
     
    -[[package]]
    -name = "mccabe"
    -version = "0.7.0"
    -requires_python = ">=3.6"
    -summary = "McCabe checker, plugin for flake8"
    -files = [
    -    {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
    -    {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
    -]
    -
    -[[package]]
    -name = "mdurl"
    -version = "0.1.2"
    -requires_python = ">=3.7"
    -summary = "Markdown URL utilities"
    -files = [
    -    {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"},
    -    {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
    -]
    -
    -[[package]]
    -name = "more-itertools"
    -version = "10.1.0"
    -requires_python = ">=3.8"
    -summary = "More routines for operating on iterables, beyond itertools"
    -files = [
    -    {file = "more-itertools-10.1.0.tar.gz", hash = "sha256:626c369fa0eb37bac0291bce8259b332fd59ac792fa5497b59837309cd5b114a"},
    -    {file = "more_itertools-10.1.0-py3-none-any.whl", hash = "sha256:64e0735fcfdc6f3464ea133afe8ea4483b1c5fe3a3d69852e6503b43a0b222e6"},
    -]
    -
    -[[package]]
    -name = "msgpack"
    -version = "1.0.7"
    -requires_python = ">=3.8"
    -summary = "MessagePack serializer"
    -files = [
    -    {file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:04ad6069c86e531682f9e1e71b71c1c3937d6014a7c3e9edd2aa81ad58842862"},
    -    {file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cca1b62fe70d761a282496b96a5e51c44c213e410a964bdffe0928e611368329"},
    -    {file = "msgpack-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e50ebce52f41370707f1e21a59514e3375e3edd6e1832f5e5235237db933c98b"},
    -    {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b4f35de6a304b5533c238bee86b670b75b03d31b7797929caa7a624b5dda6"},
    -    {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28efb066cde83c479dfe5a48141a53bc7e5f13f785b92ddde336c716663039ee"},
    -    {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cb14ce54d9b857be9591ac364cb08dc2d6a5c4318c1182cb1d02274029d590d"},
    -    {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b573a43ef7c368ba4ea06050a957c2a7550f729c31f11dd616d2ac4aba99888d"},
    -    {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ccf9a39706b604d884d2cb1e27fe973bc55f2890c52f38df742bc1d79ab9f5e1"},
    -    {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cb70766519500281815dfd7a87d3a178acf7ce95390544b8c90587d76b227681"},
    -    {file = "msgpack-1.0.7-cp310-cp310-win32.whl", hash = "sha256:b610ff0f24e9f11c9ae653c67ff8cc03c075131401b3e5ef4b82570d1728f8a9"},
    -    {file = "msgpack-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:a40821a89dc373d6427e2b44b572efc36a2778d3f543299e2f24eb1a5de65415"},
    -    {file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:576eb384292b139821c41995523654ad82d1916da6a60cff129c715a6223ea84"},
    -    {file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:730076207cb816138cf1af7f7237b208340a2c5e749707457d70705715c93b93"},
    -    {file = "msgpack-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:85765fdf4b27eb5086f05ac0491090fc76f4f2b28e09d9350c31aac25a5aaff8"},
    -    {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3476fae43db72bd11f29a5147ae2f3cb22e2f1a91d575ef130d2bf49afd21c46"},
    -    {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d4c80667de2e36970ebf74f42d1088cc9ee7ef5f4e8c35eee1b40eafd33ca5b"},
    -    {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b0bf0effb196ed76b7ad883848143427a73c355ae8e569fa538365064188b8e"},
    -    {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f9a7c509542db4eceed3dcf21ee5267ab565a83555c9b88a8109dcecc4709002"},
    -    {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:84b0daf226913133f899ea9b30618722d45feffa67e4fe867b0b5ae83a34060c"},
    -    {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ec79ff6159dffcc30853b2ad612ed572af86c92b5168aa3fc01a67b0fa40665e"},
    -    {file = "msgpack-1.0.7-cp311-cp311-win32.whl", hash = "sha256:3e7bf4442b310ff154b7bb9d81eb2c016b7d597e364f97d72b1acc3817a0fdc1"},
    -    {file = "msgpack-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:3f0c8c6dfa6605ab8ff0611995ee30d4f9fcff89966cf562733b4008a3d60d82"},
    -    {file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f0936e08e0003f66bfd97e74ee530427707297b0d0361247e9b4f59ab78ddc8b"},
    -    {file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:98bbd754a422a0b123c66a4c341de0474cad4a5c10c164ceed6ea090f3563db4"},
    -    {file = "msgpack-1.0.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b291f0ee7961a597cbbcc77709374087fa2a9afe7bdb6a40dbbd9b127e79afee"},
    -    {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebbbba226f0a108a7366bf4b59bf0f30a12fd5e75100c630267d94d7f0ad20e5"},
    -    {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e2d69948e4132813b8d1131f29f9101bc2c915f26089a6d632001a5c1349672"},
    -    {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdf38ba2d393c7911ae989c3bbba510ebbcdf4ecbdbfec36272abe350c454075"},
    -    {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:993584fc821c58d5993521bfdcd31a4adf025c7d745bbd4d12ccfecf695af5ba"},
    -    {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:52700dc63a4676669b341ba33520f4d6e43d3ca58d422e22ba66d1736b0a6e4c"},
    -    {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e45ae4927759289c30ccba8d9fdce62bb414977ba158286b5ddaf8df2cddb5c5"},
    -    {file = "msgpack-1.0.7-cp312-cp312-win32.whl", hash = "sha256:27dcd6f46a21c18fa5e5deed92a43d4554e3df8d8ca5a47bf0615d6a5f39dbc9"},
    -    {file = "msgpack-1.0.7-cp312-cp312-win_amd64.whl", hash = "sha256:7687e22a31e976a0e7fc99c2f4d11ca45eff652a81eb8c8085e9609298916dcf"},
    -    {file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfef2bb6ef068827bbd021017a107194956918ab43ce4d6dc945ffa13efbc25f"},
    -    {file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:484ae3240666ad34cfa31eea7b8c6cd2f1fdaae21d73ce2974211df099a95d81"},
    -    {file = "msgpack-1.0.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3967e4ad1aa9da62fd53e346ed17d7b2e922cba5ab93bdd46febcac39be636fc"},
    -    {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd178c4c80706546702c59529ffc005681bd6dc2ea234c450661b205445a34d"},
    -    {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ffbc252eb0d229aeb2f9ad051200668fc3a9aaa8994e49f0cb2ffe2b7867e7"},
    -    {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:822ea70dc4018c7e6223f13affd1c5c30c0f5c12ac1f96cd8e9949acddb48a61"},
    -    {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:384d779f0d6f1b110eae74cb0659d9aa6ff35aaf547b3955abf2ab4c901c4819"},
    -    {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f64e376cd20d3f030190e8c32e1c64582eba56ac6dc7d5b0b49a9d44021b52fd"},
    -    {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ed82f5a7af3697b1c4786053736f24a0efd0a1b8a130d4c7bfee4b9ded0f08f"},
    -    {file = "msgpack-1.0.7-cp39-cp39-win32.whl", hash = "sha256:f26a07a6e877c76a88e3cecac8531908d980d3d5067ff69213653649ec0f60ad"},
    -    {file = "msgpack-1.0.7-cp39-cp39-win_amd64.whl", hash = "sha256:1dc93e8e4653bdb5910aed79f11e165c85732067614f180f70534f056da97db3"},
    -    {file = "msgpack-1.0.7.tar.gz", hash = "sha256:572efc93db7a4d27e404501975ca6d2d9775705c2d922390d878fcf768d92c87"},
    -]
    -
     [[package]]
     name = "mutagen"
     version = "1.47.0"
    @@ -993,41 +501,6 @@ files = [
         {file = "mutagen-1.47.0.tar.gz", hash = "sha256:719fadef0a978c31b4cf3c956261b3c58b6948b32023078a2117b1de09f0fc99"},
     ]
     
    -[[package]]
    -name = "mypy"
    -version = "1.6.1"
    -requires_python = ">=3.8"
    -summary = "Optional static typing for Python"
    -dependencies = [
    -    "mypy-extensions>=1.0.0",
    -    "tomli>=1.1.0; python_version < \"3.11\"",
    -    "typing-extensions>=4.1.0",
    -]
    -files = [
    -    {file = "mypy-1.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e5012e5cc2ac628177eaac0e83d622b2dd499e28253d4107a08ecc59ede3fc2c"},
    -    {file = "mypy-1.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d8fbb68711905f8912e5af474ca8b78d077447d8f3918997fecbf26943ff3cbb"},
    -    {file = "mypy-1.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a1ad938fee7d2d96ca666c77b7c494c3c5bd88dff792220e1afbebb2925b5e"},
    -    {file = "mypy-1.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b96ae2c1279d1065413965c607712006205a9ac541895004a1e0d4f281f2ff9f"},
    -    {file = "mypy-1.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:40b1844d2e8b232ed92e50a4bd11c48d2daa351f9deee6c194b83bf03e418b0c"},
    -    {file = "mypy-1.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:81af8adaa5e3099469e7623436881eff6b3b06db5ef75e6f5b6d4871263547e5"},
    -    {file = "mypy-1.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8c223fa57cb154c7eab5156856c231c3f5eace1e0bed9b32a24696b7ba3c3245"},
    -    {file = "mypy-1.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8032e00ce71c3ceb93eeba63963b864bf635a18f6c0c12da6c13c450eedb183"},
    -    {file = "mypy-1.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4c46b51de523817a0045b150ed11b56f9fff55f12b9edd0f3ed35b15a2809de0"},
    -    {file = "mypy-1.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:19f905bcfd9e167159b3d63ecd8cb5e696151c3e59a1742e79bc3bcb540c42c7"},
    -    {file = "mypy-1.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:82e469518d3e9a321912955cc702d418773a2fd1e91c651280a1bda10622f02f"},
    -    {file = "mypy-1.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d4473c22cc296425bbbce7e9429588e76e05bc7342da359d6520b6427bf76660"},
    -    {file = "mypy-1.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59a0d7d24dfb26729e0a068639a6ce3500e31d6655df8557156c51c1cb874ce7"},
    -    {file = "mypy-1.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cfd13d47b29ed3bbaafaff7d8b21e90d827631afda134836962011acb5904b71"},
    -    {file = "mypy-1.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:eb4f18589d196a4cbe5290b435d135dee96567e07c2b2d43b5c4621b6501531a"},
    -    {file = "mypy-1.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:49ae115da099dcc0922a7a895c1eec82c1518109ea5c162ed50e3b3594c71208"},
    -    {file = "mypy-1.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8b27958f8c76bed8edaa63da0739d76e4e9ad4ed325c814f9b3851425582a3cd"},
    -    {file = "mypy-1.6.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:925cd6a3b7b55dfba252b7c4561892311c5358c6b5a601847015a1ad4eb7d332"},
    -    {file = "mypy-1.6.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8f57e6b6927a49550da3d122f0cb983d400f843a8a82e65b3b380d3d7259468f"},
    -    {file = "mypy-1.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:a43ef1c8ddfdb9575691720b6352761f3f53d85f1b57d7745701041053deff30"},
    -    {file = "mypy-1.6.1-py3-none-any.whl", hash = "sha256:4cbe68ef919c28ea561165206a2dcb68591c50f3bcf777932323bc208d949cf1"},
    -    {file = "mypy-1.6.1.tar.gz", hash = "sha256:4d01c00d09a0be62a4ca3f933e315455bde83f37f892ba4b08ce92f3cf44bcc1"},
    -]
    -
     [[package]]
     name = "mypy-extensions"
     version = "1.0.0"
    @@ -1038,39 +511,6 @@ files = [
         {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
     ]
     
    -[[package]]
    -name = "nh3"
    -version = "0.2.14"
    -summary = "Ammonia HTML sanitizer Python binding"
    -files = [
    -    {file = "nh3-0.2.14-cp37-abi3-macosx_10_7_x86_64.whl", hash = "sha256:9be2f68fb9a40d8440cbf34cbf40758aa7f6093160bfc7fb018cce8e424f0c3a"},
    -    {file = "nh3-0.2.14-cp37-abi3-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:f99212a81c62b5f22f9e7c3e347aa00491114a5647e1f13bbebd79c3e5f08d75"},
    -    {file = "nh3-0.2.14-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7771d43222b639a4cd9e341f870cee336b9d886de1ad9bec8dddab22fe1de450"},
    -    {file = "nh3-0.2.14-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:525846c56c2bcd376f5eaee76063ebf33cf1e620c1498b2a40107f60cfc6054e"},
    -    {file = "nh3-0.2.14-cp37-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e8986f1dd3221d1e741fda0a12eaa4a273f1d80a35e31a1ffe579e7c621d069e"},
    -    {file = "nh3-0.2.14-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:18415df36db9b001f71a42a3a5395db79cf23d556996090d293764436e98e8ad"},
    -    {file = "nh3-0.2.14-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:377aaf6a9e7c63962f367158d808c6a1344e2b4f83d071c43fbd631b75c4f0b2"},
    -    {file = "nh3-0.2.14-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b0be5c792bd43d0abef8ca39dd8acb3c0611052ce466d0401d51ea0d9aa7525"},
    -    {file = "nh3-0.2.14-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:93a943cfd3e33bd03f77b97baa11990148687877b74193bf777956b67054dcc6"},
    -    {file = "nh3-0.2.14-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ac8056e937f264995a82bf0053ca898a1cb1c9efc7cd68fa07fe0060734df7e4"},
    -    {file = "nh3-0.2.14-cp37-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:203cac86e313cf6486704d0ec620a992c8bc164c86d3a4fd3d761dd552d839b5"},
    -    {file = "nh3-0.2.14-cp37-abi3-musllinux_1_2_i686.whl", hash = "sha256:5529a3bf99402c34056576d80ae5547123f1078da76aa99e8ed79e44fa67282d"},
    -    {file = "nh3-0.2.14-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:aed56a86daa43966dd790ba86d4b810b219f75b4bb737461b6886ce2bde38fd6"},
    -    {file = "nh3-0.2.14-cp37-abi3-win32.whl", hash = "sha256:116c9515937f94f0057ef50ebcbcc10600860065953ba56f14473ff706371873"},
    -    {file = "nh3-0.2.14-cp37-abi3-win_amd64.whl", hash = "sha256:88c753efbcdfc2644a5012938c6b9753f1c64a5723a67f0301ca43e7b85dcf0e"},
    -    {file = "nh3-0.2.14.tar.gz", hash = "sha256:a0c509894fd4dccdff557068e5074999ae3b75f4c5a2d6fb5415e782e25679c4"},
    -]
    -
    -[[package]]
    -name = "packaging"
    -version = "23.2"
    -requires_python = ">=3.7"
    -summary = "Core utilities for Python packages"
    -files = [
    -    {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
    -    {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
    -]
    -
     [[package]]
     name = "parso"
     version = "0.8.3"
    @@ -1081,37 +521,6 @@ files = [
         {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"},
     ]
     
    -[[package]]
    -name = "pdm"
    -version = "2.9.3"
    -requires_python = ">=3.7"
    -summary = "A modern Python package and dependency manager supporting the latest PEP standards"
    -dependencies = [
    -    "blinker",
    -    "cachecontrol[filecache]>=0.13.0",
    -    "certifi",
    -    "findpython<1.0.0a0,>=0.4.0",
    -    "importlib-metadata>=3.6; python_version < \"3.10\"",
    -    "installer<0.8,>=0.7",
    -    "packaging!=22.0,>=20.9",
    -    "platformdirs",
    -    "pyproject-hooks",
    -    "python-dotenv>=0.15",
    -    "requests-toolbelt",
    -    "resolvelib>=1.0.1",
    -    "rich>=12.3.0",
    -    "shellingham>=1.3.2",
    -    "tomli>=1.1.0; python_version < \"3.11\"",
    -    "tomlkit<1,>=0.11.1",
    -    "truststore; python_version >= \"3.10\"",
    -    "unearth>=0.10.0",
    -    "virtualenv>=20",
    -]
    -files = [
    -    {file = "pdm-2.9.3-py3-none-any.whl", hash = "sha256:0b55fcaa61ed70b9dacd03c4a937f15e908c8c031b621523890de9cdf04325fd"},
    -    {file = "pdm-2.9.3.tar.gz", hash = "sha256:0b1195b51e9630b5a0b063f27dfcb0120cb6ea284f1a4cd975a3a26f0856d253"},
    -]
    -
     [[package]]
     name = "pexpect"
     version = "4.8.0"
    @@ -1124,35 +533,6 @@ files = [
         {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"},
     ]
     
    -[[package]]
    -name = "pickleshare"
    -version = "0.7.5"
    -summary = "Tiny 'shelve'-like database with concurrency support"
    -files = [
    -    {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"},
    -    {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"},
    -]
    -
    -[[package]]
    -name = "pkginfo"
    -version = "1.9.6"
    -requires_python = ">=3.6"
    -summary = "Query metadata from sdists / bdists / installed packages."
    -files = [
    -    {file = "pkginfo-1.9.6-py3-none-any.whl", hash = "sha256:4b7a555a6d5a22169fcc9cf7bfd78d296b0361adad412a346c1226849af5e546"},
    -    {file = "pkginfo-1.9.6.tar.gz", hash = "sha256:8fd5896e8718a4372f0ea9cc9d96f6417c9b986e23a4d116dda26b62cc29d046"},
    -]
    -
    -[[package]]
    -name = "platformdirs"
    -version = "3.11.0"
    -requires_python = ">=3.7"
    -summary = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
    -files = [
    -    {file = "platformdirs-3.11.0-py3-none-any.whl", hash = "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"},
    -    {file = "platformdirs-3.11.0.tar.gz", hash = "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3"},
    -]
    -
     [[package]]
     name = "playwright"
     version = "1.39.0"
    @@ -1172,16 +552,6 @@ files = [
         {file = "playwright-1.39.0-py3-none-win_amd64.whl", hash = "sha256:a420d814e21b05e1156747e2a9fae6c3cca2b46bb4a0226fb26ee65538ce09c9"},
     ]
     
    -[[package]]
    -name = "pluggy"
    -version = "1.3.0"
    -requires_python = ">=3.8"
    -summary = "plugin and hook calling mechanisms for python"
    -files = [
    -    {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"},
    -    {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"},
    -]
    -
     [[package]]
     name = "prompt-toolkit"
     version = "3.0.39"
    @@ -1236,16 +606,6 @@ files = [
         {file = "pyasn1_modules-0.3.0.tar.gz", hash = "sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c"},
     ]
     
    -[[package]]
    -name = "pycodestyle"
    -version = "2.11.1"
    -requires_python = ">=3.8"
    -summary = "Python style guide checker"
    -files = [
    -    {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"},
    -    {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"},
    -]
    -
     [[package]]
     name = "pycparser"
     version = "2.21"
    @@ -1298,16 +658,6 @@ files = [
         {file = "pyee-11.0.1.tar.gz", hash = "sha256:a642c51e3885a33ead087286e35212783a4e9b8d6514a10a5db4e57ac57b2b29"},
     ]
     
    -[[package]]
    -name = "pyflakes"
    -version = "3.1.0"
    -requires_python = ">=3.8"
    -summary = "passive checker of Python programs"
    -files = [
    -    {file = "pyflakes-3.1.0-py2.py3-none-any.whl", hash = "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774"},
    -    {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"},
    -]
    -
     [[package]]
     name = "pygments"
     version = "2.16.1"
    @@ -1318,37 +668,6 @@ files = [
         {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"},
     ]
     
    -[[package]]
    -name = "pyproject-hooks"
    -version = "1.0.0"
    -requires_python = ">=3.7"
    -summary = "Wrappers to call pyproject.toml-based build backend hooks."
    -dependencies = [
    -    "tomli>=1.1.0; python_version < \"3.11\"",
    -]
    -files = [
    -    {file = "pyproject_hooks-1.0.0-py3-none-any.whl", hash = "sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8"},
    -    {file = "pyproject_hooks-1.0.0.tar.gz", hash = "sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5"},
    -]
    -
    -[[package]]
    -name = "pytest"
    -version = "7.4.2"
    -requires_python = ">=3.7"
    -summary = "pytest: simple powerful testing with Python"
    -dependencies = [
    -    "colorama; sys_platform == \"win32\"",
    -    "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"",
    -    "iniconfig",
    -    "packaging",
    -    "pluggy<2.0,>=0.12",
    -    "tomli>=1.0.0; python_version < \"3.11\"",
    -]
    -files = [
    -    {file = "pytest-7.4.2-py3-none-any.whl", hash = "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002"},
    -    {file = "pytest-7.4.2.tar.gz", hash = "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069"},
    -]
    -
     [[package]]
     name = "python-crontab"
     version = "3.0.0"
    @@ -1374,16 +693,6 @@ files = [
         {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
     ]
     
    -[[package]]
    -name = "python-dotenv"
    -version = "1.0.0"
    -requires_python = ">=3.8"
    -summary = "Read key-value pairs from a .env file and set them as environment variables"
    -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]]
     name = "python-ldap"
     version = "3.4.3"
    @@ -1406,45 +715,6 @@ files = [
         {file = "pytz-2023.3.post1.tar.gz", hash = "sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b"},
     ]
     
    -[[package]]
    -name = "pywin32-ctypes"
    -version = "0.2.2"
    -requires_python = ">=3.6"
    -summary = "A (partial) reimplementation of pywin32 using ctypes/cffi"
    -files = [
    -    {file = "pywin32-ctypes-0.2.2.tar.gz", hash = "sha256:3426e063bdd5fd4df74a14fa3cf80a0b42845a87e1d1e81f6549f9daec593a60"},
    -    {file = "pywin32_ctypes-0.2.2-py3-none-any.whl", hash = "sha256:bf490a1a709baf35d688fe0ecf980ed4de11d2b3e37b51e5442587a75d9957e7"},
    -]
    -
    -[[package]]
    -name = "readme-renderer"
    -version = "42.0"
    -requires_python = ">=3.8"
    -summary = "readme_renderer is a library for rendering readme descriptions for Warehouse"
    -dependencies = [
    -    "Pygments>=2.5.1",
    -    "docutils>=0.13.1",
    -    "nh3>=0.2.14",
    -]
    -files = [
    -    {file = "readme_renderer-42.0-py3-none-any.whl", hash = "sha256:13d039515c1f24de668e2c93f2e877b9dbe6c6c32328b90a40a49d8b2b85f36d"},
    -    {file = "readme_renderer-42.0.tar.gz", hash = "sha256:2d55489f83be4992fe4454939d1a051c33edbab778e82761d060c9fc6b308cd1"},
    -]
    -
    -[[package]]
    -name = "recommonmark"
    -version = "0.7.1"
    -summary = "A docutils-compatibility bridge to CommonMark, enabling you to write CommonMark inside of Docutils & Sphinx projects."
    -dependencies = [
    -    "commonmark>=0.8.1",
    -    "docutils>=0.11",
    -    "sphinx>=1.3.1",
    -]
    -files = [
    -    {file = "recommonmark-0.7.1-py2.py3-none-any.whl", hash = "sha256:1b1db69af0231efce3fa21b94ff627ea33dee7079a01dd0a7f8482c3da148b3f"},
    -    {file = "recommonmark-0.7.1.tar.gz", hash = "sha256:bdb4db649f2222dcd8d2d844f0006b958d627f732415d399791ee436a3686d67"},
    -]
    -
     [[package]]
     name = "regex"
     version = "2023.10.3"
    @@ -1528,66 +798,6 @@ files = [
         {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
     ]
     
    -[[package]]
    -name = "requests-toolbelt"
    -version = "1.0.0"
    -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
    -summary = "A utility belt for advanced users of python-requests"
    -dependencies = [
    -    "requests<3.0.0,>=2.0.1",
    -]
    -files = [
    -    {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"},
    -    {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"},
    -]
    -
    -[[package]]
    -name = "resolvelib"
    -version = "1.0.1"
    -summary = "Resolve abstract dependencies into concrete ones"
    -files = [
    -    {file = "resolvelib-1.0.1-py2.py3-none-any.whl", hash = "sha256:d2da45d1a8dfee81bdd591647783e340ef3bcb104b54c383f70d422ef5cc7dbf"},
    -    {file = "resolvelib-1.0.1.tar.gz", hash = "sha256:04ce76cbd63fded2078ce224785da6ecd42b9564b1390793f64ddecbe997b309"},
    -]
    -
    -[[package]]
    -name = "rfc3986"
    -version = "2.0.0"
    -requires_python = ">=3.7"
    -summary = "Validating URI References per RFC 3986"
    -files = [
    -    {file = "rfc3986-2.0.0-py2.py3-none-any.whl", hash = "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd"},
    -    {file = "rfc3986-2.0.0.tar.gz", hash = "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c"},
    -]
    -
    -[[package]]
    -name = "rich"
    -version = "13.6.0"
    -requires_python = ">=3.7.0"
    -summary = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
    -dependencies = [
    -    "markdown-it-py>=2.2.0",
    -    "pygments<3.0.0,>=2.13.0",
    -]
    -files = [
    -    {file = "rich-13.6.0-py3-none-any.whl", hash = "sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245"},
    -    {file = "rich-13.6.0.tar.gz", hash = "sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef"},
    -]
    -
    -[[package]]
    -name = "secretstorage"
    -version = "3.3.3"
    -requires_python = ">=3.6"
    -summary = "Python bindings to FreeDesktop.org Secret Service API"
    -dependencies = [
    -    "cryptography>=2.0",
    -    "jeepney>=0.6",
    -]
    -files = [
    -    {file = "SecretStorage-3.3.3-py3-none-any.whl", hash = "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99"},
    -    {file = "SecretStorage-3.3.3.tar.gz", hash = "sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77"},
    -]
    -
     [[package]]
     name = "setuptools"
     version = "68.2.2"
    @@ -1598,16 +808,6 @@ files = [
         {file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"},
     ]
     
    -[[package]]
    -name = "shellingham"
    -version = "1.5.3"
    -requires_python = ">=3.7"
    -summary = "Tool to Detect Surrounding Shell"
    -files = [
    -    {file = "shellingham-1.5.3-py2.py3-none-any.whl", hash = "sha256:419c6a164770c9c7cfcaeddfacb3d31ac7a8db0b0f3e9c1287679359734107e9"},
    -    {file = "shellingham-1.5.3.tar.gz", hash = "sha256:cb4a6fec583535bc6da17b647dd2330cf7ef30239e05d547d99ae3705fd0f7f8"},
    -]
    -
     [[package]]
     name = "six"
     version = "1.16.0"
    @@ -1618,15 +818,6 @@ files = [
         {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
     ]
     
    -[[package]]
    -name = "snowballstemmer"
    -version = "2.2.0"
    -summary = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
    -files = [
    -    {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
    -    {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
    -]
    -
     [[package]]
     name = "sonic-client"
     version = "1.0.0"
    @@ -1636,138 +827,6 @@ files = [
         {file = "sonic_client-1.0.0-py3-none-any.whl", hash = "sha256:291bf292861e97a2dd765ff0c8754ea9631383680d31a63ec3da6f5aa5f4beda"},
     ]
     
    -[[package]]
    -name = "sphinx"
    -version = "7.2.6"
    -requires_python = ">=3.9"
    -summary = "Python documentation generator"
    -dependencies = [
    -    "Jinja2>=3.0",
    -    "Pygments>=2.14",
    -    "alabaster<0.8,>=0.7",
    -    "babel>=2.9",
    -    "colorama>=0.4.5; sys_platform == \"win32\"",
    -    "docutils<0.21,>=0.18.1",
    -    "imagesize>=1.3",
    -    "importlib-metadata>=4.8; python_version < \"3.10\"",
    -    "packaging>=21.0",
    -    "requests>=2.25.0",
    -    "snowballstemmer>=2.0",
    -    "sphinxcontrib-applehelp",
    -    "sphinxcontrib-devhelp",
    -    "sphinxcontrib-htmlhelp>=2.0.0",
    -    "sphinxcontrib-jsmath",
    -    "sphinxcontrib-qthelp",
    -    "sphinxcontrib-serializinghtml>=1.1.9",
    -]
    -files = [
    -    {file = "sphinx-7.2.6-py3-none-any.whl", hash = "sha256:1e09160a40b956dc623c910118fa636da93bd3ca0b9876a7b3df90f07d691560"},
    -    {file = "sphinx-7.2.6.tar.gz", hash = "sha256:9a5160e1ea90688d5963ba09a2dcd8bdd526620edbb65c328728f1b2228d5ab5"},
    -]
    -
    -[[package]]
    -name = "sphinx-rtd-theme"
    -version = "1.3.0"
    -requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
    -summary = "Read the Docs theme for Sphinx"
    -dependencies = [
    -    "docutils<0.19",
    -    "sphinx<8,>=1.6",
    -    "sphinxcontrib-jquery<5,>=4",
    -]
    -files = [
    -    {file = "sphinx_rtd_theme-1.3.0-py2.py3-none-any.whl", hash = "sha256:46ddef89cc2416a81ecfbeaceab1881948c014b1b6e4450b815311a89fb977b0"},
    -    {file = "sphinx_rtd_theme-1.3.0.tar.gz", hash = "sha256:590b030c7abb9cf038ec053b95e5380b5c70d61591eb0b552063fbe7c41f0931"},
    -]
    -
    -[[package]]
    -name = "sphinxcontrib-applehelp"
    -version = "1.0.7"
    -requires_python = ">=3.9"
    -summary = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books"
    -dependencies = [
    -    "Sphinx>=5",
    -]
    -files = [
    -    {file = "sphinxcontrib_applehelp-1.0.7-py3-none-any.whl", hash = "sha256:094c4d56209d1734e7d252f6e0b3ccc090bd52ee56807a5d9315b19c122ab15d"},
    -    {file = "sphinxcontrib_applehelp-1.0.7.tar.gz", hash = "sha256:39fdc8d762d33b01a7d8f026a3b7d71563ea3b72787d5f00ad8465bd9d6dfbfa"},
    -]
    -
    -[[package]]
    -name = "sphinxcontrib-devhelp"
    -version = "1.0.5"
    -requires_python = ">=3.9"
    -summary = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents"
    -dependencies = [
    -    "Sphinx>=5",
    -]
    -files = [
    -    {file = "sphinxcontrib_devhelp-1.0.5-py3-none-any.whl", hash = "sha256:fe8009aed765188f08fcaadbb3ea0d90ce8ae2d76710b7e29ea7d047177dae2f"},
    -    {file = "sphinxcontrib_devhelp-1.0.5.tar.gz", hash = "sha256:63b41e0d38207ca40ebbeabcf4d8e51f76c03e78cd61abe118cf4435c73d4212"},
    -]
    -
    -[[package]]
    -name = "sphinxcontrib-htmlhelp"
    -version = "2.0.4"
    -requires_python = ">=3.9"
    -summary = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
    -dependencies = [
    -    "Sphinx>=5",
    -]
    -files = [
    -    {file = "sphinxcontrib_htmlhelp-2.0.4-py3-none-any.whl", hash = "sha256:8001661c077a73c29beaf4a79968d0726103c5605e27db92b9ebed8bab1359e9"},
    -    {file = "sphinxcontrib_htmlhelp-2.0.4.tar.gz", hash = "sha256:6c26a118a05b76000738429b724a0568dbde5b72391a688577da08f11891092a"},
    -]
    -
    -[[package]]
    -name = "sphinxcontrib-jquery"
    -version = "4.1"
    -requires_python = ">=2.7"
    -summary = "Extension to include jQuery on newer Sphinx releases"
    -dependencies = [
    -    "Sphinx>=1.8",
    -]
    -files = [
    -    {file = "sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a"},
    -    {file = "sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae"},
    -]
    -
    -[[package]]
    -name = "sphinxcontrib-jsmath"
    -version = "1.0.1"
    -requires_python = ">=3.5"
    -summary = "A sphinx extension which renders display math in HTML via JavaScript"
    -files = [
    -    {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"},
    -    {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"},
    -]
    -
    -[[package]]
    -name = "sphinxcontrib-qthelp"
    -version = "1.0.6"
    -requires_python = ">=3.9"
    -summary = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents"
    -dependencies = [
    -    "Sphinx>=5",
    -]
    -files = [
    -    {file = "sphinxcontrib_qthelp-1.0.6-py3-none-any.whl", hash = "sha256:bf76886ee7470b934e363da7a954ea2825650013d367728588732c7350f49ea4"},
    -    {file = "sphinxcontrib_qthelp-1.0.6.tar.gz", hash = "sha256:62b9d1a186ab7f5ee3356d906f648cacb7a6bdb94d201ee7adf26db55092982d"},
    -]
    -
    -[[package]]
    -name = "sphinxcontrib-serializinghtml"
    -version = "1.1.9"
    -requires_python = ">=3.9"
    -summary = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)"
    -dependencies = [
    -    "Sphinx>=5",
    -]
    -files = [
    -    {file = "sphinxcontrib_serializinghtml-1.1.9-py3-none-any.whl", hash = "sha256:9b36e503703ff04f20e9675771df105e58aa029cfcbc23b8ed716019b7416ae1"},
    -    {file = "sphinxcontrib_serializinghtml-1.1.9.tar.gz", hash = "sha256:0c64ff898339e1fac29abd2bf5f11078f3ec413cfe9c046d3120d7ca65530b54"},
    -]
    -
     [[package]]
     name = "sqlparse"
     version = "0.4.4"
    @@ -1792,91 +851,14 @@ files = [
         {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"},
     ]
     
    -[[package]]
    -name = "stdeb"
    -version = "0.10.0"
    -summary = "Python to Debian source package conversion utility"
    -files = [
    -    {file = "stdeb-0.10.0.tar.gz", hash = "sha256:08c22c9c03b28a140fe3ec5064b53a5288279f22e596ca06b0be698d50c93cf2"},
    -]
    -
    -[[package]]
    -name = "tomli"
    -version = "2.0.1"
    -requires_python = ">=3.7"
    -summary = "A lil' TOML parser"
    -files = [
    -    {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
    -    {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
    -]
    -
    -[[package]]
    -name = "tomlkit"
    -version = "0.12.1"
    -requires_python = ">=3.7"
    -summary = "Style preserving TOML library"
    -files = [
    -    {file = "tomlkit-0.12.1-py3-none-any.whl", hash = "sha256:712cbd236609acc6a3e2e97253dfc52d4c2082982a88f61b640ecf0817eab899"},
    -    {file = "tomlkit-0.12.1.tar.gz", hash = "sha256:38e1ff8edb991273ec9f6181244a6a391ac30e9f5098e7535640ea6be97a7c86"},
    -]
    -
     [[package]]
     name = "traitlets"
    -version = "5.11.2"
    +version = "5.13.0"
     requires_python = ">=3.8"
     summary = "Traitlets Python configuration system"
     files = [
    -    {file = "traitlets-5.11.2-py3-none-any.whl", hash = "sha256:98277f247f18b2c5cabaf4af369187754f4fb0e85911d473f72329db8a7f4fae"},
    -    {file = "traitlets-5.11.2.tar.gz", hash = "sha256:7564b5bf8d38c40fa45498072bf4dc5e8346eb087bbf1e2ae2d8774f6a0f078e"},
    -]
    -
    -[[package]]
    -name = "truststore"
    -version = "0.8.0"
    -requires_python = ">= 3.10"
    -summary = "Verify certificates using native system trust stores"
    -files = [
    -    {file = "truststore-0.8.0-py3-none-any.whl", hash = "sha256:e37a5642ae9fc48caa8f120b6283d77225d600d224965a672c9e8ef49ce4bb4c"},
    -    {file = "truststore-0.8.0.tar.gz", hash = "sha256:dc70da89634944a579bfeec70a7a4523c53ffdb3cf52d1bb4a431fda278ddb96"},
    -]
    -
    -[[package]]
    -name = "twine"
    -version = "4.0.2"
    -requires_python = ">=3.7"
    -summary = "Collection of utilities for publishing packages on PyPI"
    -dependencies = [
    -    "importlib-metadata>=3.6",
    -    "keyring>=15.1",
    -    "pkginfo>=1.8.1",
    -    "readme-renderer>=35.0",
    -    "requests-toolbelt!=0.9.0,>=0.8.0",
    -    "requests>=2.20",
    -    "rfc3986>=1.4.0",
    -    "rich>=12.0.0",
    -    "urllib3>=1.26.0",
    -]
    -files = [
    -    {file = "twine-4.0.2-py3-none-any.whl", hash = "sha256:929bc3c280033347a00f847236564d1c52a3e61b1ac2516c97c48f3ceab756d8"},
    -    {file = "twine-4.0.2.tar.gz", hash = "sha256:9e102ef5fdd5a20661eb88fad46338806c3bd32cf1db729603fe3697b1bc83c8"},
    -]
    -
    -[[package]]
    -name = "types-pytz"
    -version = "2023.3.1.1"
    -summary = "Typing stubs for pytz"
    -files = [
    -    {file = "types-pytz-2023.3.1.1.tar.gz", hash = "sha256:cc23d0192cd49c8f6bba44ee0c81e4586a8f30204970fc0894d209a6b08dab9a"},
    -    {file = "types_pytz-2023.3.1.1-py3-none-any.whl", hash = "sha256:1999a123a3dc0e39a2ef6d19f3f8584211de9e6a77fe7a0259f04a524e90a5cf"},
    -]
    -
    -[[package]]
    -name = "types-pyyaml"
    -version = "6.0.12.12"
    -summary = "Typing stubs for PyYAML"
    -files = [
    -    {file = "types-PyYAML-6.0.12.12.tar.gz", hash = "sha256:334373d392fde0fdf95af5c3f1661885fa10c52167b14593eb856289e1855062"},
    -    {file = "types_PyYAML-6.0.12.12-py3-none-any.whl", hash = "sha256:c05bc6c158facb0676674b7f11fe3960db4f389718e19e62bd2b84d6205cfd24"},
    +    {file = "traitlets-5.13.0-py3-none-any.whl", hash = "sha256:baf991e61542da48fe8aef8b779a9ea0aa38d8a54166ee250d5af5ecf4486619"},
    +    {file = "traitlets-5.13.0.tar.gz", hash = "sha256:9b232b9430c8f57288c1024b34a8f0251ddcc47268927367a0dd3eeaca40deb5"},
     ]
     
     [[package]]
    @@ -1901,29 +883,15 @@ files = [
     
     [[package]]
     name = "tzlocal"
    -version = "5.1"
    -requires_python = ">=3.7"
    +version = "5.2"
    +requires_python = ">=3.8"
     summary = "tzinfo object for the local timezone"
     dependencies = [
         "tzdata; platform_system == \"Windows\"",
     ]
     files = [
    -    {file = "tzlocal-5.1-py3-none-any.whl", hash = "sha256:2938498395d5f6a898ab8009555cb37a4d360913ad375d4747ef16826b03ef23"},
    -    {file = "tzlocal-5.1.tar.gz", hash = "sha256:a5ccb2365b295ed964e0a98ad076fe10c495591e75505d34f154d60a7f1ed722"},
    -]
    -
    -[[package]]
    -name = "unearth"
    -version = "0.11.2"
    -requires_python = ">=3.7"
    -summary = "A utility to fetch and download python packages"
    -dependencies = [
    -    "packaging>=20",
    -    "requests>=2.25",
    -]
    -files = [
    -    {file = "unearth-0.11.2-py3-none-any.whl", hash = "sha256:046a996466de40a16e257fc883ae08157e7ab78a85bcec00313f3fdf9131bd37"},
    -    {file = "unearth-0.11.2.tar.gz", hash = "sha256:0eb5a8800fda0610e095fef768b48d47c858c9b8417a785af647046c2df5ed2b"},
    +    {file = "tzlocal-5.2-py3-none-any.whl", hash = "sha256:49816ef2fe65ea8ac19d19aa7a1ae0551c834303d5014c6d5a62e4cbda8047b8"},
    +    {file = "tzlocal-5.2.tar.gz", hash = "sha256:8d399205578f1a9342816409cc1e46a93ebd5755e39ea2d85334bea911bf0e6e"},
     ]
     
     [[package]]
    @@ -1936,21 +904,6 @@ files = [
         {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"},
     ]
     
    -[[package]]
    -name = "virtualenv"
    -version = "20.24.5"
    -requires_python = ">=3.7"
    -summary = "Virtual Python Environment builder"
    -dependencies = [
    -    "distlib<1,>=0.3.7",
    -    "filelock<4,>=3.12.2",
    -    "platformdirs<4,>=3.9.1",
    -]
    -files = [
    -    {file = "virtualenv-20.24.5-py3-none-any.whl", hash = "sha256:b80039f280f4919c77b30f1c23294ae357c4c8701042086e3fc005963e4e537b"},
    -    {file = "virtualenv-20.24.5.tar.gz", hash = "sha256:e8361967f6da6fbdf1426483bfe9fca8287c242ac0bc30429905721cefbff752"},
    -]
    -
     [[package]]
     name = "w3lib"
     version = "2.1.2"
    @@ -1963,79 +916,80 @@ files = [
     
     [[package]]
     name = "wcwidth"
    -version = "0.2.8"
    +version = "0.2.9"
     summary = "Measures the displayed width of unicode strings in a terminal"
     files = [
    -    {file = "wcwidth-0.2.8-py2.py3-none-any.whl", hash = "sha256:77f719e01648ed600dfa5402c347481c0992263b81a027344f3e1ba25493a704"},
    -    {file = "wcwidth-0.2.8.tar.gz", hash = "sha256:8705c569999ffbb4f6a87c6d1b80f324bd6db952f5eb0b95bc07517f4c1813d4"},
    +    {file = "wcwidth-0.2.9-py2.py3-none-any.whl", hash = "sha256:9a929bd8380f6cd9571a968a9c8f4353ca58d7cd812a4822bba831f8d685b223"},
    +    {file = "wcwidth-0.2.9.tar.gz", hash = "sha256:a675d1a4a2d24ef67096a04b85b02deeecd8e226f57b5e3a72dbb9ed99d27da8"},
     ]
     
     [[package]]
     name = "websockets"
    -version = "11.0.3"
    -requires_python = ">=3.7"
    +version = "12.0"
    +requires_python = ">=3.8"
     summary = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
     files = [
    -    {file = "websockets-11.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3ccc8a0c387629aec40f2fc9fdcb4b9d5431954f934da3eaf16cdc94f67dbfac"},
    -    {file = "websockets-11.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d67ac60a307f760c6e65dad586f556dde58e683fab03323221a4e530ead6f74d"},
    -    {file = "websockets-11.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:84d27a4832cc1a0ee07cdcf2b0629a8a72db73f4cf6de6f0904f6661227f256f"},
    -    {file = "websockets-11.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffd7dcaf744f25f82190856bc26ed81721508fc5cbf2a330751e135ff1283564"},
    -    {file = "websockets-11.0.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7622a89d696fc87af8e8d280d9b421db5133ef5b29d3f7a1ce9f1a7bf7fcfa11"},
    -    {file = "websockets-11.0.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bceab846bac555aff6427d060f2fcfff71042dba6f5fca7dc4f75cac815e57ca"},
    -    {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:54c6e5b3d3a8936a4ab6870d46bdd6ec500ad62bde9e44462c32d18f1e9a8e54"},
    -    {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:41f696ba95cd92dc047e46b41b26dd24518384749ed0d99bea0a941ca87404c4"},
    -    {file = "websockets-11.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:86d2a77fd490ae3ff6fae1c6ceaecad063d3cc2320b44377efdde79880e11526"},
    -    {file = "websockets-11.0.3-cp310-cp310-win32.whl", hash = "sha256:2d903ad4419f5b472de90cd2d40384573b25da71e33519a67797de17ef849b69"},
    -    {file = "websockets-11.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:1d2256283fa4b7f4c7d7d3e84dc2ece74d341bce57d5b9bf385df109c2a1a82f"},
    -    {file = "websockets-11.0.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e848f46a58b9fcf3d06061d17be388caf70ea5b8cc3466251963c8345e13f7eb"},
    -    {file = "websockets-11.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:aa5003845cdd21ac0dc6c9bf661c5beddd01116f6eb9eb3c8e272353d45b3288"},
    -    {file = "websockets-11.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b58cbf0697721120866820b89f93659abc31c1e876bf20d0b3d03cef14faf84d"},
    -    {file = "websockets-11.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:660e2d9068d2bedc0912af508f30bbeb505bbbf9774d98def45f68278cea20d3"},
    -    {file = "websockets-11.0.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c1f0524f203e3bd35149f12157438f406eff2e4fb30f71221c8a5eceb3617b6b"},
    -    {file = "websockets-11.0.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:def07915168ac8f7853812cc593c71185a16216e9e4fa886358a17ed0fd9fcf6"},
    -    {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b30c6590146e53149f04e85a6e4fcae068df4289e31e4aee1fdf56a0dead8f97"},
    -    {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:619d9f06372b3a42bc29d0cd0354c9bb9fb39c2cbc1a9c5025b4538738dbffaf"},
    -    {file = "websockets-11.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:01f5567d9cf6f502d655151645d4e8b72b453413d3819d2b6f1185abc23e82dd"},
    -    {file = "websockets-11.0.3-cp311-cp311-win32.whl", hash = "sha256:e1459677e5d12be8bbc7584c35b992eea142911a6236a3278b9b5ce3326f282c"},
    -    {file = "websockets-11.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:e7837cb169eca3b3ae94cc5787c4fed99eef74c0ab9506756eea335e0d6f3ed8"},
    -    {file = "websockets-11.0.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:777354ee16f02f643a4c7f2b3eff8027a33c9861edc691a2003531f5da4f6bc8"},
    -    {file = "websockets-11.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8c82f11964f010053e13daafdc7154ce7385ecc538989a354ccc7067fd7028fd"},
    -    {file = "websockets-11.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3580dd9c1ad0701169e4d6fc41e878ffe05e6bdcaf3c412f9d559389d0c9e016"},
    -    {file = "websockets-11.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f1a3f10f836fab6ca6efa97bb952300b20ae56b409414ca85bff2ad241d2a61"},
    -    {file = "websockets-11.0.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df41b9bc27c2c25b486bae7cf42fccdc52ff181c8c387bfd026624a491c2671b"},
    -    {file = "websockets-11.0.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:279e5de4671e79a9ac877427f4ac4ce93751b8823f276b681d04b2156713b9dd"},
    -    {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1fdf26fa8a6a592f8f9235285b8affa72748dc12e964a5518c6c5e8f916716f7"},
    -    {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:69269f3a0b472e91125b503d3c0b3566bda26da0a3261c49f0027eb6075086d1"},
    -    {file = "websockets-11.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:97b52894d948d2f6ea480171a27122d77af14ced35f62e5c892ca2fae9344311"},
    -    {file = "websockets-11.0.3-cp39-cp39-win32.whl", hash = "sha256:c7f3cb904cce8e1be667c7e6fef4516b98d1a6a0635a58a57528d577ac18a128"},
    -    {file = "websockets-11.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c792ea4eabc0159535608fc5658a74d1a81020eb35195dd63214dcf07556f67e"},
    -    {file = "websockets-11.0.3-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f2e58f2c36cc52d41f2659e4c0cbf7353e28c8c9e63e30d8c6d3494dc9fdedcf"},
    -    {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de36fe9c02995c7e6ae6efe2e205816f5f00c22fd1fbf343d4d18c3d5ceac2f5"},
    -    {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0ac56b661e60edd453585f4bd68eb6a29ae25b5184fd5ba51e97652580458998"},
    -    {file = "websockets-11.0.3-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e052b8467dd07d4943936009f46ae5ce7b908ddcac3fda581656b1b19c083d9b"},
    -    {file = "websockets-11.0.3-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:42cc5452a54a8e46a032521d7365da775823e21bfba2895fb7b77633cce031bb"},
    -    {file = "websockets-11.0.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e6316827e3e79b7b8e7d8e3b08f4e331af91a48e794d5d8b099928b6f0b85f20"},
    -    {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8531fdcad636d82c517b26a448dcfe62f720e1922b33c81ce695d0edb91eb931"},
    -    {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c114e8da9b475739dde229fd3bc6b05a6537a88a578358bc8eb29b4030fac9c9"},
    -    {file = "websockets-11.0.3-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e063b1865974611313a3849d43f2c3f5368093691349cf3c7c8f8f75ad7cb280"},
    -    {file = "websockets-11.0.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:92b2065d642bf8c0a82d59e59053dd2fdde64d4ed44efe4870fa816c1232647b"},
    -    {file = "websockets-11.0.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0ee68fe502f9031f19d495dae2c268830df2760c0524cbac5d759921ba8c8e82"},
    -    {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcacf2c7a6c3a84e720d1bb2b543c675bf6c40e460300b628bab1b1efc7c034c"},
    -    {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b67c6f5e5a401fc56394f191f00f9b3811fe843ee93f4a70df3c389d1adf857d"},
    -    {file = "websockets-11.0.3-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d5023a4b6a5b183dc838808087033ec5df77580485fc533e7dab2567851b0a4"},
    -    {file = "websockets-11.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ed058398f55163a79bb9f06a90ef9ccc063b204bb346c4de78efc5d15abfe602"},
    -    {file = "websockets-11.0.3-py3-none-any.whl", hash = "sha256:6681ba9e7f8f3b19440921e99efbb40fc89f26cd71bf539e45d8c8a25c976dc6"},
    -    {file = "websockets-11.0.3.tar.gz", hash = "sha256:88fc51d9a26b10fc331be344f1781224a375b78488fc343620184e95a4b27016"},
    -]
    -
    -[[package]]
    -name = "wheel"
    -version = "0.41.2"
    -requires_python = ">=3.7"
    -summary = "A built-package format for Python"
    -files = [
    -    {file = "wheel-0.41.2-py3-none-any.whl", hash = "sha256:75909db2664838d015e3d9139004ee16711748a52c8f336b52882266540215d8"},
    -    {file = "wheel-0.41.2.tar.gz", hash = "sha256:0c5ac5ff2afb79ac23ab82bab027a0be7b5dbcf2e54dc50efe4bf507de1f7985"},
    +    {file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"},
    +    {file = "websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"},
    +    {file = "websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547"},
    +    {file = "websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2"},
    +    {file = "websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558"},
    +    {file = "websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480"},
    +    {file = "websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c"},
    +    {file = "websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8"},
    +    {file = "websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603"},
    +    {file = "websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f"},
    +    {file = "websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf"},
    +    {file = "websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4"},
    +    {file = "websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f"},
    +    {file = "websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3"},
    +    {file = "websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c"},
    +    {file = "websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45"},
    +    {file = "websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04"},
    +    {file = "websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447"},
    +    {file = "websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca"},
    +    {file = "websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53"},
    +    {file = "websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402"},
    +    {file = "websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b"},
    +    {file = "websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df"},
    +    {file = "websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc"},
    +    {file = "websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b"},
    +    {file = "websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb"},
    +    {file = "websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92"},
    +    {file = "websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed"},
    +    {file = "websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5"},
    +    {file = "websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2"},
    +    {file = "websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113"},
    +    {file = "websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d"},
    +    {file = "websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f"},
    +    {file = "websockets-12.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d"},
    +    {file = "websockets-12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28"},
    +    {file = "websockets-12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53"},
    +    {file = "websockets-12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c"},
    +    {file = "websockets-12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec"},
    +    {file = "websockets-12.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9"},
    +    {file = "websockets-12.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae"},
    +    {file = "websockets-12.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b"},
    +    {file = "websockets-12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9"},
    +    {file = "websockets-12.0-cp39-cp39-win32.whl", hash = "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6"},
    +    {file = "websockets-12.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8"},
    +    {file = "websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd"},
    +    {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870"},
    +    {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077"},
    +    {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b"},
    +    {file = "websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30"},
    +    {file = "websockets-12.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6"},
    +    {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123"},
    +    {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931"},
    +    {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2"},
    +    {file = "websockets-12.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468"},
    +    {file = "websockets-12.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b"},
    +    {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399"},
    +    {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7"},
    +    {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611"},
    +    {file = "websockets-12.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370"},
    +    {file = "websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e"},
    +    {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"},
     ]
     
     [[package]]
    @@ -2055,13 +1009,3 @@ files = [
         {file = "yt-dlp-2023.10.13.tar.gz", hash = "sha256:e026ea1c435ff36eef1215bc4c5bb8c479938b90054997ba99f63a4541fe63b4"},
         {file = "yt_dlp-2023.10.13-py2.py3-none-any.whl", hash = "sha256:2b069f22675532eebacdfd6372b1825651a751fef848de9ae6efe6491b2dc38a"},
     ]
    -
    -[[package]]
    -name = "zipp"
    -version = "3.17.0"
    -requires_python = ">=3.8"
    -summary = "Backport of pathlib-compatible object wrapper for zip files"
    -files = [
    -    {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"},
    -    {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"},
    -]
    diff --git a/pyproject.toml b/pyproject.toml
    index acd8571a..af7f89ad 100644
    --- a/pyproject.toml
    +++ b/pyproject.toml
    @@ -57,12 +57,12 @@ classifiers = [
     # pdm install -G:all
     [tool.pdm.dev-dependencies]
     build = [
    -    "pdm",
    -    "bottle",
         "setuptools",
    -    "stdeb",
    -    "twine",
         "wheel",
    +    "pdm",
    +    # "bottle",
    +    # "stdeb",
    +    # "twine",
     ]
     lint = [
         "flake8",
    diff --git a/requirements.txt b/requirements.txt
    index 793e32e0..0270635f 100644
    --- a/requirements.txt
    +++ b/requirements.txt
    @@ -1,752 +1,53 @@
     # This file is @generated by PDM.
     # Please do not edit it manually.
     
    -alabaster==0.7.13 \
    -    --hash=sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3 \
    -    --hash=sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2
    -appnope==0.1.3 \
    -    --hash=sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24 \
    -    --hash=sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e
    -asgiref==3.7.2 \
    -    --hash=sha256:89b2ef2247e3b562a16eef663bc0e2e703ec6468e2fa8a5cd61cd449786d4f6e \
    -    --hash=sha256:9e0ce3aa93a819ba5b45120216b23878cf6e8525eb3848653452b4192b92afed
    -asttokens==2.4.0 \
    -    --hash=sha256:2e0171b991b2c959acc6c49318049236844a5da1d65ba2672c4880c1c894834e \
    -    --hash=sha256:cf8fc9e61a86461aa9fb161a14a0841a03c405fa829ac6b202670b3495d2ce69
    -babel==2.13.0 \
    -    --hash=sha256:04c3e2d28d2b7681644508f836be388ae49e0cfe91465095340395b60d00f210 \
    -    --hash=sha256:fbfcae1575ff78e26c7449136f1abbefc3c13ce542eeb13d43d50d8b047216ec
    -backcall==0.2.0 \
    -    --hash=sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e \
    -    --hash=sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255
    -blinker==1.6.3 \
    -    --hash=sha256:152090d27c1c5c722ee7e48504b02d76502811ce02e1523553b4cf8c8b3d3a8d \
    -    --hash=sha256:296320d6c28b006eb5e32d4712202dbcdcbf5dc482da298c2f44881c43884aaa
    -bottle==0.12.25 \
    -    --hash=sha256:d6f15f9d422670b7c073d63bd8d287b135388da187a0f3e3c19293626ce034ea \
    -    --hash=sha256:e1a9c94970ae6d710b3fb4526294dfeb86f2cb4a81eff3a4b98dc40fb0e5e021
    -brotli==1.1.0 \
    -    --hash=sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128 \
    -    --hash=sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9 \
    -    --hash=sha256:1ae56aca0402a0f9a3431cddda62ad71666ca9d4dc3a10a142b9dce2e3c0cda3 \
    -    --hash=sha256:22fc2a8549ffe699bfba2256ab2ed0421a7b8fadff114a3d201794e45a9ff578 \
    -    --hash=sha256:30924eb4c57903d5a7526b08ef4a584acc22ab1ffa085faceb521521d2de32dd \
    -    --hash=sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409 \
    -    --hash=sha256:38025d9f30cf4634f8309c6874ef871b841eb3c347e90b0851f63d1ded5212da \
    -    --hash=sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50 \
    -    --hash=sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180 \
    -    --hash=sha256:43ce1b9935bfa1ede40028054d7f48b5469cd02733a365eec8a329ffd342915d \
    -    --hash=sha256:4ed11165dd45ce798d99a136808a794a748d5dc38511303239d4e2363c0695dc \
    -    --hash=sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265 \
    -    --hash=sha256:524f35912131cc2cabb00edfd8d573b07f2d9f21fa824bd3fb19725a9cf06327 \
    -    --hash=sha256:5b3cc074004d968722f51e550b41a27be656ec48f8afaeeb45ebf65b561481dd \
    -    --hash=sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0 \
    -    --hash=sha256:5fb2ce4b8045c78ebbc7b8f3c15062e435d47e7393cc57c25115cfd49883747a \
    -    --hash=sha256:6c3020404e0b5eefd7c9485ccf8393cfb75ec38ce75586e046573c9dc29967a0 \
    -    --hash=sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451 \
    -    --hash=sha256:7905193081db9bfa73b1219140b3d315831cbff0d8941f22da695832f0dd188f \
    -    --hash=sha256:7c4855522edb2e6ae7fdb58e07c3ba9111e7621a8956f481c68d5d979c93032e \
    -    --hash=sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248 \
    -    --hash=sha256:7f4bf76817c14aa98cc6697ac02f3972cb8c3da93e9ef16b9c66573a68014f91 \
    -    --hash=sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724 \
    -    --hash=sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966 \
    -    --hash=sha256:89f4988c7203739d48c6f806f1e87a1d96e0806d44f0fba61dba81392c9e474d \
    -    --hash=sha256:8dadd1314583ec0bf2d1379f7008ad627cd6336625d6679cf2f8e67081b83acf \
    -    --hash=sha256:901032ff242d479a0efa956d853d16875d42157f98951c0230f69e69f9c09bac \
    -    --hash=sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951 \
    -    --hash=sha256:949f3b7c29912693cee0afcf09acd6ebc04c57af949d9bf77d6101ebb61e388c \
    -    --hash=sha256:a1fd8a29719ccce974d523580987b7f8229aeace506952fa9ce1d53a033873c8 \
    -    --hash=sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d \
    -    --hash=sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc \
    -    --hash=sha256:a469274ad18dc0e4d316eefa616d1d0c2ff9da369af19fa6f3daa4f09671fd61 \
    -    --hash=sha256:a77def80806c421b4b0af06f45d65a136e7ac0bdca3c09d9e2ea4e515367c7e9 \
    -    --hash=sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1 \
    -    --hash=sha256:ae15b066e5ad21366600ebec29a7ccbc86812ed267e4b28e860b8ca16a2bc474 \
    -    --hash=sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2 \
    -    --hash=sha256:c8146669223164fc87a7e3de9f81e9423c67a79d6b3447994dfb9c95da16e2d6 \
    -    --hash=sha256:c8fd5270e906eef71d4a8d19b7c6a43760c6abcfcc10c9101d14eb2357418de9 \
    -    --hash=sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2 \
    -    --hash=sha256:cdad5b9014d83ca68c25d2e9444e28e967ef16e80f6b436918c700c117a85467 \
    -    --hash=sha256:ceb64bbc6eac5a140ca649003756940f8d6a7c444a68af170b3187623b43bebf \
    -    --hash=sha256:d0c5516f0aed654134a2fc936325cc2e642f8a0e096d075209672eb321cff408 \
    -    --hash=sha256:de6551e370ef19f8de1807d0a9aa2cdfdce2e85ce88b122fe9f6b2b076837e59 \
    -    --hash=sha256:e1140c64812cb9b06c922e77f1c26a75ec5e3f0fb2bf92cc8c58720dec276752 \
    -    --hash=sha256:e6a904cb26bfefc2f0a6f240bdf5233be78cd2488900a2f846f3c3ac8489ab80 \
    -    --hash=sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0 \
    -    --hash=sha256:f0d8a7a6b5983c2496e364b969f0e526647a06b075d034f3297dc66f3b360c64 \
    -    --hash=sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e
    -cachecontrol==0.13.1 \
    -    --hash=sha256:95dedbec849f46dda3137866dc28b9d133fc9af55f5b805ab1291833e4457aa4 \
    -    --hash=sha256:f012366b79d2243a6118309ce73151bf52a38d4a5dac8ea57f09bd29087e506b
    -certifi==2023.7.22 \
    -    --hash=sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082 \
    -    --hash=sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9
    -charset-normalizer==3.3.0 \
    -    --hash=sha256:02673e456dc5ab13659f85196c534dc596d4ef260e4d86e856c3b2773ce09843 \
    -    --hash=sha256:02af06682e3590ab952599fbadac535ede5d60d78848e555aa58d0c0abbde786 \
    -    --hash=sha256:03680bb39035fbcffe828eae9c3f8afc0428c91d38e7d61aa992ef7a59fb120e \
    -    --hash=sha256:0570d21da019941634a531444364f2482e8db0b3425fcd5ac0c36565a64142c8 \
    -    --hash=sha256:09c77f964f351a7369cc343911e0df63e762e42bac24cd7d18525961c81754f4 \
    -    --hash=sha256:0d3d5b7db9ed8a2b11a774db2bbea7ba1884430a205dbd54a32d61d7c2a190fa \
    -    --hash=sha256:12ebea541c44fdc88ccb794a13fe861cc5e35d64ed689513a5c03d05b53b7c82 \
    -    --hash=sha256:153e7b6e724761741e0974fc4dcd406d35ba70b92bfe3fedcb497226c93b9da7 \
    -    --hash=sha256:1872d01ac8c618a8da634e232f24793883d6e456a66593135aeafe3784b0848d \
    -    --hash=sha256:1b2919306936ac6efb3aed1fbf81039f7087ddadb3160882a57ee2ff74fd2382 \
    -    --hash=sha256:232ac332403e37e4a03d209a3f92ed9071f7d3dbda70e2a5e9cff1c4ba9f0678 \
    -    --hash=sha256:23e8565ab7ff33218530bc817922fae827420f143479b753104ab801145b1d5b \
    -    --hash=sha256:24817cb02cbef7cd499f7c9a2735286b4782bd47a5b3516a0e84c50eab44b98e \
    -    --hash=sha256:2502dd2a736c879c0f0d3e2161e74d9907231e25d35794584b1ca5284e43f596 \
    -    --hash=sha256:278c296c6f96fa686d74eb449ea1697f3c03dc28b75f873b65b5201806346a69 \
    -    --hash=sha256:2935ffc78db9645cb2086c2f8f4cfd23d9b73cc0dc80334bc30aac6f03f68f8c \
    -    --hash=sha256:380c4bde80bce25c6e4f77b19386f5ec9db230df9f2f2ac1e5ad7af2caa70459 \
    -    --hash=sha256:3b447982ad46348c02cb90d230b75ac34e9886273df3a93eec0539308a6296d7 \
    -    --hash=sha256:3debd1150027933210c2fc321527c2299118aa929c2f5a0a80ab6953e3bd1908 \
    -    --hash=sha256:4162918ef3098851fcd8a628bf9b6a98d10c380725df9e04caf5ca6dd48c847a \
    -    --hash=sha256:4cc152c5dd831641e995764f9f0b6589519f6f5123258ccaca8c6d34572fefa8 \
    -    --hash=sha256:557b21a44ceac6c6b9773bc65aa1b4cc3e248a5ad2f5b914b91579a32e22204d \
    -    --hash=sha256:5707a746c6083a3a74b46b3a631d78d129edab06195a92a8ece755aac25a3f3d \
    -    --hash=sha256:5adf257bd58c1b8632046bbe43ee38c04e1038e9d37de9c57a94d6bd6ce5da34 \
    -    --hash=sha256:619d1c96099be5823db34fe89e2582b336b5b074a7f47f819d6b3a57ff7bdb86 \
    -    --hash=sha256:63563193aec44bce707e0c5ca64ff69fa72ed7cf34ce6e11d5127555756fd2f6 \
    -    --hash=sha256:6a685067d05e46641d5d1623d7c7fdf15a357546cbb2f71b0ebde91b175ffc3e \
    -    --hash=sha256:7966951325782121e67c81299a031f4c115615e68046f79b85856b86ebffc4cd \
    -    --hash=sha256:7b8b8bf1189b3ba9b8de5c8db4d541b406611a71a955bbbd7385bbc45fcb786c \
    -    --hash=sha256:805dfea4ca10411a5296bcc75638017215a93ffb584c9e344731eef0dcfb026a \
    -    --hash=sha256:82eb849f085624f6a607538ee7b83a6d8126df6d2f7d3b319cb837b289123078 \
    -    --hash=sha256:86d1f65ac145e2c9ed71d8ffb1905e9bba3a91ae29ba55b4c46ae6fc31d7c0d4 \
    -    --hash=sha256:86f63face3a527284f7bb8a9d4f78988e3c06823f7bea2bd6f0e0e9298ca0403 \
    -    --hash=sha256:8eaf82f0eccd1505cf39a45a6bd0a8cf1c70dcfc30dba338207a969d91b965c0 \
    -    --hash=sha256:93aa7eef6ee71c629b51ef873991d6911b906d7312c6e8e99790c0f33c576f89 \
    -    --hash=sha256:96c2b49eb6a72c0e4991d62406e365d87067ca14c1a729a870d22354e6f68115 \
    -    --hash=sha256:9cf3126b85822c4e53aa28c7ec9869b924d6fcfb76e77a45c44b83d91afd74f9 \
    -    --hash=sha256:9fe359b2e3a7729010060fbca442ca225280c16e923b37db0e955ac2a2b72a05 \
    -    --hash=sha256:a0ac5e7015a5920cfce654c06618ec40c33e12801711da6b4258af59a8eff00a \
    -    --hash=sha256:a3f93dab657839dfa61025056606600a11d0b696d79386f974e459a3fbc568ec \
    -    --hash=sha256:a4b71f4d1765639372a3b32d2638197f5cd5221b19531f9245fcc9ee62d38f56 \
    -    --hash=sha256:aaf7b34c5bc56b38c931a54f7952f1ff0ae77a2e82496583b247f7c969eb1479 \
    -    --hash=sha256:abf0d9f45ea5fb95051c8bfe43cb40cda383772f7e5023a83cc481ca2604d74e \
    -    --hash=sha256:b09719a17a2301178fac4470d54b1680b18a5048b481cb8890e1ef820cb80455 \
    -    --hash=sha256:b3b2316b25644b23b54a6f6401074cebcecd1244c0b8e80111c9a3f1c8e83d65 \
    -    --hash=sha256:b3d9b48ee6e3967b7901c052b670c7dda6deb812c309439adaffdec55c6d7b78 \
    -    --hash=sha256:b8f3307af845803fb0b060ab76cf6dd3a13adc15b6b451f54281d25911eb92df \
    -    --hash=sha256:c2af80fb58f0f24b3f3adcb9148e6203fa67dd3f61c4af146ecad033024dde43 \
    -    --hash=sha256:c350354efb159b8767a6244c166f66e67506e06c8924ed74669b2c70bc8735b1 \
    -    --hash=sha256:c71f16da1ed8949774ef79f4a0260d28b83b3a50c6576f8f4f0288d109777989 \
    -    --hash=sha256:d47ecf253780c90ee181d4d871cd655a789da937454045b17b5798da9393901a \
    -    --hash=sha256:d7eff0f27edc5afa9e405f7165f85a6d782d308f3b6b9d96016c010597958e63 \
    -    --hash=sha256:d97d85fa63f315a8bdaba2af9a6a686e0eceab77b3089af45133252618e70884 \
    -    --hash=sha256:db756e48f9c5c607b5e33dd36b1d5872d0422e960145b08ab0ec7fd420e9d649 \
    -    --hash=sha256:e0fc42822278451bc13a2e8626cf2218ba570f27856b536e00cfa53099724828 \
    -    --hash=sha256:e46cd37076971c1040fc8c41273a8b3e2c624ce4f2be3f5dfcb7a430c1d3acc2 \
    -    --hash=sha256:e5c1502d4ace69a179305abb3f0bb6141cbe4714bc9b31d427329a95acfc8bdd \
    -    --hash=sha256:edfe077ab09442d4ef3c52cb1f9dab89bff02f4524afc0acf2d46be17dc479f5 \
    -    --hash=sha256:effe5406c9bd748a871dbcaf3ac69167c38d72db8c9baf3ff954c344f31c4cbe \
    -    --hash=sha256:f0d1e3732768fecb052d90d62b220af62ead5748ac51ef61e7b32c266cac9293 \
    -    --hash=sha256:f5969baeaea61c97efa706b9b107dcba02784b1601c74ac84f2a532ea079403e \
    -    --hash=sha256:f8888e31e3a85943743f8fc15e71536bda1c81d5aa36d014a3c0c44481d7db6e
    -commonmark==0.9.1 \
    -    --hash=sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60 \
    -    --hash=sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9
    -croniter==2.0.1 \
    -    --hash=sha256:4cb064ce2d8f695b3b078be36ff50115cf8ac306c10a7e8653ee2a5b534673d7 \
    -    --hash=sha256:d199b2ec3ea5e82988d1f72022433c5f9302b3b3ea9e6bfd6a1518f6ea5e700a
    -dateparser==1.1.8 \
    -    --hash=sha256:070b29b5bbf4b1ec2cd51c96ea040dc68a614de703910a91ad1abba18f9f379f \
    -    --hash=sha256:86b8b7517efcc558f085a142cdb7620f0921543fcabdb538c8a4c4001d8178e3
    -decorator==5.1.1 \
    -    --hash=sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330 \
    -    --hash=sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186
    -distlib==0.3.7 \
    -    --hash=sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057 \
    -    --hash=sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8
    -django==3.1.14 \
    -    --hash=sha256:0fabc786489af16ad87a8c170ba9d42bfd23f7b699bd5ef05675864e8d012859 \
    -    --hash=sha256:72a4a5a136a214c39cf016ccdd6b69e2aa08c7479c66d93f3a9b5e4bb9d8a347
    -django-auth-ldap==4.1.0 \
    -    --hash=sha256:68870e7921e84b1a9867e268a9c8a3e573e8a0d95ea08bcf31be178f5826ff36 \
    -    --hash=sha256:77f749d3b17807ce8eb56a9c9c8e5746ff316567f81d5ba613495d9c7495a949
    -django-debug-toolbar==3.2.4 \
    -    --hash=sha256:644bbd5c428d3283aa9115722471769cac1bec189edf3a0c855fd8ff870375a9 \
    -    --hash=sha256:6b633b6cfee24f232d73569870f19aa86c819d750e7f3e833f2344a9eb4b4409
    -django-extensions==3.1.5 \
    -    --hash=sha256:28e1e1bf49f0e00307ba574d645b0af3564c981a6dfc87209d48cb98f77d0b1a \
    -    --hash=sha256:9238b9e016bb0009d621e05cf56ea8ce5cce9b32e91ad2026996a7377ca28069
    -django-stubs==4.2.5 \
    -    --hash=sha256:5a23cf622f1426a0b0c48bd6e2ef709a66275d72073baf6fdf5ac36fc4cce736 \
    -    --hash=sha256:706b2456bd0e56c468dfd8f27b0e7dde001c5c7cd3010d67fcbda9d95467e050
    -django-stubs-ext==4.2.5 \
    -    --hash=sha256:8c4d1fb5f68419b3b2474c659681a189803e27d6a5e5abf5aa0da57601b58633 \
    -    --hash=sha256:921cd7ae4614e74c234bc0fe86ee75537d163addfe1fc6f134bf03e29d86c01e
    -djdt-flamegraph==0.2.13 \
    -    --hash=sha256:b3252b8cc9b586829166cc158b26952626cd6f41a3ffa92dceef2f5dbe5b99a0 \
    -    --hash=sha256:c07a71be58484636e021d4c49b129fd819f24c9128849cb59558e5141192dbf3
    -docutils==0.18.1 \
    -    --hash=sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c \
    -    --hash=sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06
    -executing==2.0.0 \
    -    --hash=sha256:06df6183df67389625f4e763921c6cf978944721abf3e714000200aab95b0657 \
    -    --hash=sha256:0ff053696fdeef426cda5bd18eacd94f82c91f49823a2e9090124212ceea9b08
    -filelock==3.12.4 \
    -    --hash=sha256:08c21d87ded6e2b9da6728c3dff51baf1dcecf973b768ef35bcbc3447edb9ad4 \
    -    --hash=sha256:2e6f249f1f3654291606e046b09f1fd5eac39b360664c27f5aad072012f8bcbd
    -findpython==0.4.0 \
    -    --hash=sha256:087148ac5935f9be458f36a05f3fa479efdf2c629f5d386c73ea481cfecff15e \
    -    --hash=sha256:18b14d115678da18ae92ee22d7001cc30915ea531053f77010ee05a39680f438
    -flake8==6.1.0 \
    -    --hash=sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23 \
    -    --hash=sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5
    -greenlet==3.0.0 \
    -    --hash=sha256:02a807b2a58d5cdebb07050efe3d7deaf915468d112dfcf5e426d0564aa3aa4a \
    -    --hash=sha256:0b72b802496cccbd9b31acea72b6f87e7771ccfd7f7927437d592e5c92ed703c \
    -    --hash=sha256:0d3f83ffb18dc57243e0151331e3c383b05e5b6c5029ac29f754745c800f8ed9 \
    -    --hash=sha256:123910c58234a8d40eaab595bc56a5ae49bdd90122dde5bdc012c20595a94c14 \
    -    --hash=sha256:1482fba7fbed96ea7842b5a7fc11d61727e8be75a077e603e8ab49d24e234383 \
    -    --hash=sha256:19834e3f91f485442adc1ee440171ec5d9a4840a1f7bd5ed97833544719ce10b \
    -    --hash=sha256:1d363666acc21d2c204dd8705c0e0457d7b2ee7a76cb16ffc099d6799744ac99 \
    -    --hash=sha256:211ef8d174601b80e01436f4e6905aca341b15a566f35a10dd8d1e93f5dbb3b7 \
    -    --hash=sha256:269d06fa0f9624455ce08ae0179430eea61085e3cf6457f05982b37fd2cefe17 \
    -    --hash=sha256:2e7dcdfad252f2ca83c685b0fa9fba00e4d8f243b73839229d56ee3d9d219314 \
    -    --hash=sha256:334ef6ed8337bd0b58bb0ae4f7f2dcc84c9f116e474bb4ec250a8bb9bd797a66 \
    -    --hash=sha256:37f60b3a42d8b5499be910d1267b24355c495064f271cfe74bf28b17b099133c \
    -    --hash=sha256:38ad562a104cd41e9d4644f46ea37167b93190c6d5e4048fcc4b80d34ecb278f \
    -    --hash=sha256:4cd83fb8d8e17633ad534d9ac93719ef8937568d730ef07ac3a98cb520fd93e4 \
    -    --hash=sha256:527cd90ba3d8d7ae7dceb06fda619895768a46a1b4e423bdb24c1969823b8362 \
    -    --hash=sha256:56867a3b3cf26dc8a0beecdb4459c59f4c47cdd5424618c08515f682e1d46692 \
    -    --hash=sha256:6512592cc49b2c6d9b19fbaa0312124cd4c4c8a90d28473f86f92685cc5fef8e \
    -    --hash=sha256:6672fdde0fd1a60b44fb1751a7779c6db487e42b0cc65e7caa6aa686874e79fb \
    -    --hash=sha256:6a5b2d4cdaf1c71057ff823a19d850ed5c6c2d3686cb71f73ae4d6382aaa7a06 \
    -    --hash=sha256:6a68d670c8f89ff65c82b936275369e532772eebc027c3be68c6b87ad05ca695 \
    -    --hash=sha256:73b2f1922a39d5d59cc0e597987300df3396b148a9bd10b76a058a2f2772fc04 \
    -    --hash=sha256:7709fd7bb02b31908dc8fd35bfd0a29fc24681d5cc9ac1d64ad07f8d2b7db62f \
    -    --hash=sha256:813720bd57e193391dfe26f4871186cf460848b83df7e23e6bef698a7624b4c9 \
    -    --hash=sha256:831d6f35037cf18ca5e80a737a27d822d87cd922521d18ed3dbc8a6967be50ce \
    -    --hash=sha256:871b0a8835f9e9d461b7fdaa1b57e3492dd45398e87324c047469ce2fc9f516c \
    -    --hash=sha256:952256c2bc5b4ee8df8dfc54fc4de330970bf5d79253c863fb5e6761f00dda35 \
    -    --hash=sha256:96d9ea57292f636ec851a9bb961a5cc0f9976900e16e5d5647f19aa36ba6366b \
    -    --hash=sha256:9a812224a5fb17a538207e8cf8e86f517df2080c8ee0f8c1ed2bdaccd18f38f4 \
    -    --hash=sha256:9adbd8ecf097e34ada8efde9b6fec4dd2a903b1e98037adf72d12993a1c80b51 \
    -    --hash=sha256:a048293392d4e058298710a54dfaefcefdf49d287cd33fb1f7d63d55426e4355 \
    -    --hash=sha256:aa15a2ec737cb609ed48902b45c5e4ff6044feb5dcdfcf6fa8482379190330d7 \
    -    --hash=sha256:ad6fb737e46b8bd63156b8f59ba6cdef46fe2b7db0c5804388a2d0519b8ddb99 \
    -    --hash=sha256:b1660a15a446206c8545edc292ab5c48b91ff732f91b3d3b30d9a915d5ec4779 \
    -    --hash=sha256:b505fcfc26f4148551826a96f7317e02c400665fa0883fe505d4fcaab1dabfdd \
    -    --hash=sha256:bdfaeecf8cc705d35d8e6de324bf58427d7eafb55f67050d8f28053a3d57118c \
    -    --hash=sha256:be557119bf467d37a8099d91fbf11b2de5eb1fd5fc5b91598407574848dc910f \
    -    --hash=sha256:c94e4e924d09b5a3e37b853fe5924a95eac058cb6f6fb437ebb588b7eda79870 \
    -    --hash=sha256:d1e22c22f7826096ad503e9bb681b05b8c1f5a8138469b255eb91f26a76634f2 \
    -    --hash=sha256:d55db1db455c59b46f794346efce896e754b8942817f46a1bada2d29446e305a \
    -    --hash=sha256:e09dea87cc91aea5500262993cbd484b41edf8af74f976719dd83fe724644cd6 \
    -    --hash=sha256:f47932c434a3c8d3c86d865443fadc1fbf574e9b11d6650b656e602b1797908a
    -idna==3.4 \
    -    --hash=sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4 \
    -    --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2
    -imagesize==1.4.1 \
    -    --hash=sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b \
    -    --hash=sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a
    -importlib-metadata==6.8.0 \
    -    --hash=sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb \
    -    --hash=sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743
    -iniconfig==2.0.0 \
    -    --hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \
    -    --hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374
    -installer==0.7.0 \
    -    --hash=sha256:05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53 \
    -    --hash=sha256:a26d3e3116289bb08216e0d0f7d925fcef0b0194eedfa0c944bcaaa106c4b631
    -ipdb==0.13.13 \
    -    --hash=sha256:45529994741c4ab6d2388bfa5d7b725c2cf7fe9deffabdb8a6113aa5ed449ed4 \
    -    --hash=sha256:e3ac6018ef05126d442af680aad863006ec19d02290561ac88b8b1c0b0cfc726
    -ipython==8.16.1 \
    -    --hash=sha256:0852469d4d579d9cd613c220af7bf0c9cc251813e12be647cb9d463939db9b1e \
    -    --hash=sha256:ad52f58fca8f9f848e256c629eff888efc0528c12fe0f8ec14f33205f23ef938
    -jaraco-classes==3.3.0 \
    -    --hash=sha256:10afa92b6743f25c0cf5f37c6bb6e18e2c5bb84a16527ccfc0040ea377e7aaeb \
    -    --hash=sha256:c063dd08e89217cee02c8d5e5ec560f2c8ce6cdc2fcdc2e68f7b2e5547ed3621
    -jedi==0.19.1 \
    -    --hash=sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd \
    -    --hash=sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0
    -Jinja2==3.1.2 \
    -    --hash=sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852 \
    -    --hash=sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61
    -keyring==24.2.0 \
    -    --hash=sha256:4901caaf597bfd3bbd78c9a0c7c4c29fcd8310dab2cffefe749e916b6527acd6 \
    -    --hash=sha256:ca0746a19ec421219f4d713f848fa297a661a8a8c1504867e55bfb5e09091509
    -markdown-it-py==3.0.0 \
    -    --hash=sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 \
    -    --hash=sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb
    -MarkupSafe==2.1.3 \
    -    --hash=sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e \
    -    --hash=sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e \
    -    --hash=sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431 \
    -    --hash=sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686 \
    -    --hash=sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c \
    -    --hash=sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559 \
    -    --hash=sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb \
    -    --hash=sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939 \
    -    --hash=sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c \
    -    --hash=sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9 \
    -    --hash=sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575 \
    -    --hash=sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba \
    -    --hash=sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd \
    -    --hash=sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00 \
    -    --hash=sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac \
    -    --hash=sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52 \
    -    --hash=sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f \
    -    --hash=sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b \
    -    --hash=sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007 \
    -    --hash=sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea \
    -    --hash=sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198 \
    -    --hash=sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1 \
    -    --hash=sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6 \
    -    --hash=sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c \
    -    --hash=sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58 \
    -    --hash=sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823 \
    -    --hash=sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779 \
    -    --hash=sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636 \
    -    --hash=sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c \
    -    --hash=sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad \
    -    --hash=sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee \
    -    --hash=sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2 \
    -    --hash=sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7 \
    -    --hash=sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa \
    -    --hash=sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb \
    -    --hash=sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9 \
    -    --hash=sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57 \
    -    --hash=sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc \
    -    --hash=sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc \
    -    --hash=sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2 \
    -    --hash=sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11
    -matplotlib-inline==0.1.6 \
    -    --hash=sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311 \
    -    --hash=sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304
    -mccabe==0.7.0 \
    -    --hash=sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325 \
    -    --hash=sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e
    -mdurl==0.1.2 \
    -    --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \
    -    --hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba
    -more-itertools==10.1.0 \
    -    --hash=sha256:626c369fa0eb37bac0291bce8259b332fd59ac792fa5497b59837309cd5b114a \
    -    --hash=sha256:64e0735fcfdc6f3464ea133afe8ea4483b1c5fe3a3d69852e6503b43a0b222e6
    -msgpack==1.0.7 \
    -    --hash=sha256:04ad6069c86e531682f9e1e71b71c1c3937d6014a7c3e9edd2aa81ad58842862 \
    -    --hash=sha256:1dc93e8e4653bdb5910aed79f11e165c85732067614f180f70534f056da97db3 \
    -    --hash=sha256:1e2d69948e4132813b8d1131f29f9101bc2c915f26089a6d632001a5c1349672 \
    -    --hash=sha256:27dcd6f46a21c18fa5e5deed92a43d4554e3df8d8ca5a47bf0615d6a5f39dbc9 \
    -    --hash=sha256:28efb066cde83c479dfe5a48141a53bc7e5f13f785b92ddde336c716663039ee \
    -    --hash=sha256:3476fae43db72bd11f29a5147ae2f3cb22e2f1a91d575ef130d2bf49afd21c46 \
    -    --hash=sha256:384d779f0d6f1b110eae74cb0659d9aa6ff35aaf547b3955abf2ab4c901c4819 \
    -    --hash=sha256:3967e4ad1aa9da62fd53e346ed17d7b2e922cba5ab93bdd46febcac39be636fc \
    -    --hash=sha256:3e7bf4442b310ff154b7bb9d81eb2c016b7d597e364f97d72b1acc3817a0fdc1 \
    -    --hash=sha256:3f0c8c6dfa6605ab8ff0611995ee30d4f9fcff89966cf562733b4008a3d60d82 \
    -    --hash=sha256:484ae3240666ad34cfa31eea7b8c6cd2f1fdaae21d73ce2974211df099a95d81 \
    -    --hash=sha256:4a7b4f35de6a304b5533c238bee86b670b75b03d31b7797929caa7a624b5dda6 \
    -    --hash=sha256:4cb14ce54d9b857be9591ac364cb08dc2d6a5c4318c1182cb1d02274029d590d \
    -    --hash=sha256:52700dc63a4676669b341ba33520f4d6e43d3ca58d422e22ba66d1736b0a6e4c \
    -    --hash=sha256:572efc93db7a4d27e404501975ca6d2d9775705c2d922390d878fcf768d92c87 \
    -    --hash=sha256:576eb384292b139821c41995523654ad82d1916da6a60cff129c715a6223ea84 \
    -    --hash=sha256:5b0bf0effb196ed76b7ad883848143427a73c355ae8e569fa538365064188b8e \
    -    --hash=sha256:5ed82f5a7af3697b1c4786053736f24a0efd0a1b8a130d4c7bfee4b9ded0f08f \
    -    --hash=sha256:6d4c80667de2e36970ebf74f42d1088cc9ee7ef5f4e8c35eee1b40eafd33ca5b \
    -    --hash=sha256:730076207cb816138cf1af7f7237b208340a2c5e749707457d70705715c93b93 \
    -    --hash=sha256:7687e22a31e976a0e7fc99c2f4d11ca45eff652a81eb8c8085e9609298916dcf \
    -    --hash=sha256:822ea70dc4018c7e6223f13affd1c5c30c0f5c12ac1f96cd8e9949acddb48a61 \
    -    --hash=sha256:84b0daf226913133f899ea9b30618722d45feffa67e4fe867b0b5ae83a34060c \
    -    --hash=sha256:85765fdf4b27eb5086f05ac0491090fc76f4f2b28e09d9350c31aac25a5aaff8 \
    -    --hash=sha256:8dd178c4c80706546702c59529ffc005681bd6dc2ea234c450661b205445a34d \
    -    --hash=sha256:98bbd754a422a0b123c66a4c341de0474cad4a5c10c164ceed6ea090f3563db4 \
    -    --hash=sha256:993584fc821c58d5993521bfdcd31a4adf025c7d745bbd4d12ccfecf695af5ba \
    -    --hash=sha256:a40821a89dc373d6427e2b44b572efc36a2778d3f543299e2f24eb1a5de65415 \
    -    --hash=sha256:b291f0ee7961a597cbbcc77709374087fa2a9afe7bdb6a40dbbd9b127e79afee \
    -    --hash=sha256:b573a43ef7c368ba4ea06050a957c2a7550f729c31f11dd616d2ac4aba99888d \
    -    --hash=sha256:b610ff0f24e9f11c9ae653c67ff8cc03c075131401b3e5ef4b82570d1728f8a9 \
    -    --hash=sha256:bdf38ba2d393c7911ae989c3bbba510ebbcdf4ecbdbfec36272abe350c454075 \
    -    --hash=sha256:bfef2bb6ef068827bbd021017a107194956918ab43ce4d6dc945ffa13efbc25f \
    -    --hash=sha256:cb70766519500281815dfd7a87d3a178acf7ce95390544b8c90587d76b227681 \
    -    --hash=sha256:cca1b62fe70d761a282496b96a5e51c44c213e410a964bdffe0928e611368329 \
    -    --hash=sha256:ccf9a39706b604d884d2cb1e27fe973bc55f2890c52f38df742bc1d79ab9f5e1 \
    -    --hash=sha256:e45ae4927759289c30ccba8d9fdce62bb414977ba158286b5ddaf8df2cddb5c5 \
    -    --hash=sha256:e50ebce52f41370707f1e21a59514e3375e3edd6e1832f5e5235237db933c98b \
    -    --hash=sha256:ebbbba226f0a108a7366bf4b59bf0f30a12fd5e75100c630267d94d7f0ad20e5 \
    -    --hash=sha256:ec79ff6159dffcc30853b2ad612ed572af86c92b5168aa3fc01a67b0fa40665e \
    -    --hash=sha256:f0936e08e0003f66bfd97e74ee530427707297b0d0361247e9b4f59ab78ddc8b \
    -    --hash=sha256:f26a07a6e877c76a88e3cecac8531908d980d3d5067ff69213653649ec0f60ad \
    -    --hash=sha256:f64e376cd20d3f030190e8c32e1c64582eba56ac6dc7d5b0b49a9d44021b52fd \
    -    --hash=sha256:f6ffbc252eb0d229aeb2f9ad051200668fc3a9aaa8994e49f0cb2ffe2b7867e7 \
    -    --hash=sha256:f9a7c509542db4eceed3dcf21ee5267ab565a83555c9b88a8109dcecc4709002
    -mutagen==1.47.0 \
    -    --hash=sha256:719fadef0a978c31b4cf3c956261b3c58b6948b32023078a2117b1de09f0fc99 \
    -    --hash=sha256:edd96f50c5907a9539d8e5bba7245f62c9f520aef333d13392a79a4f70aca719
    -mypy==1.6.1 \
    -    --hash=sha256:19f905bcfd9e167159b3d63ecd8cb5e696151c3e59a1742e79bc3bcb540c42c7 \
    -    --hash=sha256:21a1ad938fee7d2d96ca666c77b7c494c3c5bd88dff792220e1afbebb2925b5e \
    -    --hash=sha256:40b1844d2e8b232ed92e50a4bd11c48d2daa351f9deee6c194b83bf03e418b0c \
    -    --hash=sha256:49ae115da099dcc0922a7a895c1eec82c1518109ea5c162ed50e3b3594c71208 \
    -    --hash=sha256:4c46b51de523817a0045b150ed11b56f9fff55f12b9edd0f3ed35b15a2809de0 \
    -    --hash=sha256:4cbe68ef919c28ea561165206a2dcb68591c50f3bcf777932323bc208d949cf1 \
    -    --hash=sha256:4d01c00d09a0be62a4ca3f933e315455bde83f37f892ba4b08ce92f3cf44bcc1 \
    -    --hash=sha256:59a0d7d24dfb26729e0a068639a6ce3500e31d6655df8557156c51c1cb874ce7 \
    -    --hash=sha256:81af8adaa5e3099469e7623436881eff6b3b06db5ef75e6f5b6d4871263547e5 \
    -    --hash=sha256:82e469518d3e9a321912955cc702d418773a2fd1e91c651280a1bda10622f02f \
    -    --hash=sha256:8b27958f8c76bed8edaa63da0739d76e4e9ad4ed325c814f9b3851425582a3cd \
    -    --hash=sha256:8c223fa57cb154c7eab5156856c231c3f5eace1e0bed9b32a24696b7ba3c3245 \
    -    --hash=sha256:8f57e6b6927a49550da3d122f0cb983d400f843a8a82e65b3b380d3d7259468f \
    -    --hash=sha256:925cd6a3b7b55dfba252b7c4561892311c5358c6b5a601847015a1ad4eb7d332 \
    -    --hash=sha256:a43ef1c8ddfdb9575691720b6352761f3f53d85f1b57d7745701041053deff30 \
    -    --hash=sha256:a8032e00ce71c3ceb93eeba63963b864bf635a18f6c0c12da6c13c450eedb183 \
    -    --hash=sha256:b96ae2c1279d1065413965c607712006205a9ac541895004a1e0d4f281f2ff9f \
    -    --hash=sha256:cfd13d47b29ed3bbaafaff7d8b21e90d827631afda134836962011acb5904b71 \
    -    --hash=sha256:d4473c22cc296425bbbce7e9429588e76e05bc7342da359d6520b6427bf76660 \
    -    --hash=sha256:d8fbb68711905f8912e5af474ca8b78d077447d8f3918997fecbf26943ff3cbb \
    -    --hash=sha256:e5012e5cc2ac628177eaac0e83d622b2dd499e28253d4107a08ecc59ede3fc2c \
    -    --hash=sha256:eb4f18589d196a4cbe5290b435d135dee96567e07c2b2d43b5c4621b6501531a
    -mypy-extensions==1.0.0 \
    -    --hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \
    -    --hash=sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782
    -nh3==0.2.14 \
    -    --hash=sha256:116c9515937f94f0057ef50ebcbcc10600860065953ba56f14473ff706371873 \
    -    --hash=sha256:18415df36db9b001f71a42a3a5395db79cf23d556996090d293764436e98e8ad \
    -    --hash=sha256:203cac86e313cf6486704d0ec620a992c8bc164c86d3a4fd3d761dd552d839b5 \
    -    --hash=sha256:2b0be5c792bd43d0abef8ca39dd8acb3c0611052ce466d0401d51ea0d9aa7525 \
    -    --hash=sha256:377aaf6a9e7c63962f367158d808c6a1344e2b4f83d071c43fbd631b75c4f0b2 \
    -    --hash=sha256:525846c56c2bcd376f5eaee76063ebf33cf1e620c1498b2a40107f60cfc6054e \
    -    --hash=sha256:5529a3bf99402c34056576d80ae5547123f1078da76aa99e8ed79e44fa67282d \
    -    --hash=sha256:7771d43222b639a4cd9e341f870cee336b9d886de1ad9bec8dddab22fe1de450 \
    -    --hash=sha256:88c753efbcdfc2644a5012938c6b9753f1c64a5723a67f0301ca43e7b85dcf0e \
    -    --hash=sha256:93a943cfd3e33bd03f77b97baa11990148687877b74193bf777956b67054dcc6 \
    -    --hash=sha256:9be2f68fb9a40d8440cbf34cbf40758aa7f6093160bfc7fb018cce8e424f0c3a \
    -    --hash=sha256:a0c509894fd4dccdff557068e5074999ae3b75f4c5a2d6fb5415e782e25679c4 \
    -    --hash=sha256:ac8056e937f264995a82bf0053ca898a1cb1c9efc7cd68fa07fe0060734df7e4 \
    -    --hash=sha256:aed56a86daa43966dd790ba86d4b810b219f75b4bb737461b6886ce2bde38fd6 \
    -    --hash=sha256:e8986f1dd3221d1e741fda0a12eaa4a273f1d80a35e31a1ffe579e7c621d069e \
    -    --hash=sha256:f99212a81c62b5f22f9e7c3e347aa00491114a5647e1f13bbebd79c3e5f08d75
    -packaging==23.2 \
    -    --hash=sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5 \
    -    --hash=sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7
    -parso==0.8.3 \
    -    --hash=sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0 \
    -    --hash=sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75
    -pdm==2.9.3 \
    -    --hash=sha256:0b1195b51e9630b5a0b063f27dfcb0120cb6ea284f1a4cd975a3a26f0856d253 \
    -    --hash=sha256:0b55fcaa61ed70b9dacd03c4a937f15e908c8c031b621523890de9cdf04325fd
    -pexpect==4.8.0 \
    -    --hash=sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937 \
    -    --hash=sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c
    -pickleshare==0.7.5 \
    -    --hash=sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca \
    -    --hash=sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56
    -pkginfo==1.9.6 \
    -    --hash=sha256:4b7a555a6d5a22169fcc9cf7bfd78d296b0361adad412a346c1226849af5e546 \
    -    --hash=sha256:8fd5896e8718a4372f0ea9cc9d96f6417c9b986e23a4d116dda26b62cc29d046
    -platformdirs==3.11.0 \
    -    --hash=sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3 \
    -    --hash=sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e
    -playwright==1.39.0 \
    -    --hash=sha256:384e195a6d09343f319031cf552e9cd601ede78fe9c082b9fa197537c5cbfe7a \
    -    --hash=sha256:40ed7f2546c64f1bb3d22b2295b4d43ed5a2f0b7ea7599d93a72f723a1883e1e \
    -    --hash=sha256:654bb3ae0dc3c69ffddc0c38c127c3b8e93032d8cf3928e2c4f21890cb39514b \
    -    --hash=sha256:699a8e707ca5f3567aa28223ee1be7e42d2bf25eda7d3d86babda71e36e5f16f \
    -    --hash=sha256:a420d814e21b05e1156747e2a9fae6c3cca2b46bb4a0226fb26ee65538ce09c9 \
    -    --hash=sha256:d2c3634411828d9273196ed6f69f2fa7645c89732b3c982dcf09ab03ed4c5d2b \
    -    --hash=sha256:d2fd90f370599cf9a2c6a041bd79a5eeec62baf0e943c7c5c2079b29be476d2a
    -pluggy==1.3.0 \
    -    --hash=sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12 \
    -    --hash=sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7
    -prompt-toolkit==3.0.39 \
    -    --hash=sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac \
    -    --hash=sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88
    -ptyprocess==0.7.0 \
    -    --hash=sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35 \
    -    --hash=sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220
    -pure-eval==0.2.2 \
    -    --hash=sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350 \
    -    --hash=sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3
    -pyasn1==0.5.0 \
    -    --hash=sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57 \
    -    --hash=sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde
    -pyasn1-modules==0.3.0 \
    -    --hash=sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c \
    -    --hash=sha256:d3ccd6ed470d9ffbc716be08bd90efbd44d0734bc9303818f7336070984a162d
    -pycodestyle==2.11.1 \
    -    --hash=sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f \
    -    --hash=sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67
    -pycryptodomex==3.19.0 \
    -    --hash=sha256:09c9401dc06fb3d94cb1ec23b4ea067a25d1f4c6b7b118ff5631d0b5daaab3cc \
    -    --hash=sha256:0b2f1982c5bc311f0aab8c293524b861b485d76f7c9ab2c3ac9a25b6f7655975 \
    -    --hash=sha256:136b284e9246b4ccf4f752d435c80f2c44fc2321c198505de1d43a95a3453b3c \
    -    --hash=sha256:2126bc54beccbede6eade00e647106b4f4c21e5201d2b0a73e9e816a01c50905 \
    -    --hash=sha256:263de9a96d2fcbc9f5bd3a279f14ea0d5f072adb68ebd324987576ec25da084d \
    -    --hash=sha256:50cb18d4dd87571006fd2447ccec85e6cec0136632a550aa29226ba075c80644 \
    -    --hash=sha256:5b883e1439ab63af976656446fb4839d566bb096f15fc3c06b5a99cde4927188 \
    -    --hash=sha256:5d73e9fa3fe830e7b6b42afc49d8329b07a049a47d12e0ef9225f2fd220f19b2 \
    -    --hash=sha256:67c8eb79ab33d0fbcb56842992298ddb56eb6505a72369c20f60bc1d2b6fb002 \
    -    --hash=sha256:7cb51096a6a8d400724104db8a7e4f2206041a1f23e58924aa3d8d96bcb48338 \
    -    --hash=sha256:800a2b05cfb83654df80266692f7092eeefe2a314fa7901dcefab255934faeec \
    -    --hash=sha256:a3866d68e2fc345162b1b9b83ef80686acfe5cec0d134337f3b03950a0a8bf56 \
    -    --hash=sha256:a588a1cb7781da9d5e1c84affd98c32aff9c89771eac8eaa659d2760666f7139 \
    -    --hash=sha256:a77b79852175064c822b047fee7cf5a1f434f06ad075cc9986aa1c19a0c53eb0 \
    -    --hash=sha256:af83a554b3f077564229865c45af0791be008ac6469ef0098152139e6bd4b5b6 \
    -    --hash=sha256:b801216c48c0886742abf286a9a6b117e248ca144d8ceec1f931ce2dd0c9cb40 \
    -    --hash=sha256:bfb040b5dda1dff1e197d2ef71927bd6b8bfcb9793bc4dfe0bb6df1e691eaacb \
    -    --hash=sha256:c01678aee8ac0c1a461cbc38ad496f953f9efcb1fa19f5637cbeba7544792a53 \
    -    --hash=sha256:c74eb1f73f788facece7979ce91594dc177e1a9b5d5e3e64697dd58299e5cb4d \
    -    --hash=sha256:d4dd3b381ff5a5907a3eb98f5f6d32c64d319a840278ceea1dcfcc65063856f3 \
    -    --hash=sha256:edbe083c299835de7e02c8aa0885cb904a75087d35e7bab75ebe5ed336e8c3e2
    -pyee==11.0.1 \
    -    --hash=sha256:9bcc9647822234f42c228d88de63d0f9ffa881e87a87f9d36ddf5211f6ac977d \
    -    --hash=sha256:a642c51e3885a33ead087286e35212783a4e9b8d6514a10a5db4e57ac57b2b29
    -pyflakes==3.1.0 \
    -    --hash=sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774 \
    -    --hash=sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc
    -pygments==2.16.1 \
    -    --hash=sha256:13fc09fa63bc8d8671a6d247e1eb303c4b343eaee81d861f3404db2935653692 \
    -    --hash=sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29
    -pyproject-hooks==1.0.0 \
    -    --hash=sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8 \
    -    --hash=sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5
    -pytest==7.4.2 \
    -    --hash=sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002 \
    -    --hash=sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069
    -python-crontab==3.0.0 \
    -    --hash=sha256:6d5ba3c190ec76e4d252989a1644fcb233dbf53fbc8fceeb9febe1657b9fb1d4 \
    -    --hash=sha256:79fb7465039ddfd4fb93d072d6ee0d45c1ac8bf1597f0686ea14fd4361dba379
    -python-dateutil==2.8.2 \
    -    --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \
    -    --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9
    -python-dotenv==1.0.0 \
    -    --hash=sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba \
    -    --hash=sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a
    -python-ldap==3.4.3 \
    -    --hash=sha256:ab26c519a0ef2a443a2a10391fa3c5cb52d7871323399db949ebfaa9f25ee2a0
    -pytz==2023.3.post1 \
    -    --hash=sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b \
    -    --hash=sha256:ce42d816b81b68506614c11e8937d3aa9e41007ceb50bfdcb0749b921bf646c7
    -readme-renderer==42.0 \
    -    --hash=sha256:13d039515c1f24de668e2c93f2e877b9dbe6c6c32328b90a40a49d8b2b85f36d \
    -    --hash=sha256:2d55489f83be4992fe4454939d1a051c33edbab778e82761d060c9fc6b308cd1
    -recommonmark==0.7.1 \
    -    --hash=sha256:1b1db69af0231efce3fa21b94ff627ea33dee7079a01dd0a7f8482c3da148b3f \
    -    --hash=sha256:bdb4db649f2222dcd8d2d844f0006b958d627f732415d399791ee436a3686d67
    -regex==2023.10.3 \
    -    --hash=sha256:00ba3c9818e33f1fa974693fb55d24cdc8ebafcb2e4207680669d8f8d7cca79a \
    -    --hash=sha256:06e9abc0e4c9ab4779c74ad99c3fc10d3967d03114449acc2c2762ad4472b8ca \
    -    --hash=sha256:0b9ac09853b2a3e0d0082104036579809679e7715671cfbf89d83c1cb2a30f58 \
    -    --hash=sha256:0d47840dc05e0ba04fe2e26f15126de7c755496d5a8aae4a08bda4dd8d646c54 \
    -    --hash=sha256:107ac60d1bfdc3edb53be75e2a52aff7481b92817cfdddd9b4519ccf0e54a6ff \
    -    --hash=sha256:11175910f62b2b8c055f2b089e0fedd694fe2be3941b3e2633653bc51064c528 \
    -    --hash=sha256:12bd4bc2c632742c7ce20db48e0d99afdc05e03f0b4c1af90542e05b809a03d9 \
    -    --hash=sha256:1c0e8fae5b27caa34177bdfa5a960c46ff2f78ee2d45c6db15ae3f64ecadde14 \
    -    --hash=sha256:2c54e23836650bdf2c18222c87f6f840d4943944146ca479858404fedeb9f9af \
    -    --hash=sha256:36362386b813fa6c9146da6149a001b7bd063dabc4d49522a1f7aa65b725c7ec \
    -    --hash=sha256:39cdf8d141d6d44e8d5a12a8569d5a227f645c87df4f92179bd06e2e2705e76b \
    -    --hash=sha256:3b2c3502603fab52d7619b882c25a6850b766ebd1b18de3df23b2f939360e1bd \
    -    --hash=sha256:3ccf2716add72f80714b9a63899b67fa711b654be3fcdd34fa391d2d274ce767 \
    -    --hash=sha256:3fef4f844d2290ee0ba57addcec17eec9e3df73f10a2748485dfd6a3a188cc0f \
    -    --hash=sha256:4023e2efc35a30e66e938de5aef42b520c20e7eda7bb5fb12c35e5d09a4c43f6 \
    -    --hash=sha256:4a8bf76e3182797c6b1afa5b822d1d5802ff30284abe4599e1247be4fd6b03be \
    -    --hash=sha256:4a992f702c9be9c72fa46f01ca6e18d131906a7180950958f766c2aa294d4b41 \
    -    --hash=sha256:4c34d4f73ea738223a094d8e0ffd6d2c1a1b4c175da34d6b0de3d8d69bee6bcc \
    -    --hash=sha256:4cd1bccf99d3ef1ab6ba835308ad85be040e6a11b0977ef7ea8c8005f01a3c29 \
    -    --hash=sha256:4ef80829117a8061f974b2fda8ec799717242353bff55f8a29411794d635d964 \
    -    --hash=sha256:5a8f91c64f390ecee09ff793319f30a0f32492e99f5dc1c72bc361f23ccd0a9a \
    -    --hash=sha256:5addc9d0209a9afca5fc070f93b726bf7003bd63a427f65ef797a931782e7edc \
    -    --hash=sha256:6239d4e2e0b52c8bd38c51b760cd870069f0bdf99700a62cd509d7a031749a55 \
    -    --hash=sha256:66e2fe786ef28da2b28e222c89502b2af984858091675044d93cb50e6f46d7af \
    -    --hash=sha256:69c0771ca5653c7d4b65203cbfc5e66db9375f1078689459fe196fe08b7b4930 \
    -    --hash=sha256:6ac965a998e1388e6ff2e9781f499ad1eaa41e962a40d11c7823c9952c77123e \
    -    --hash=sha256:6c56c3d47da04f921b73ff9415fbaa939f684d47293f071aa9cbb13c94afc17d \
    -    --hash=sha256:7434a61b158be563c1362d9071358f8ab91b8d928728cd2882af060481244c9e \
    -    --hash=sha256:7ef1e014eed78ab650bef9a6a9cbe50b052c0aebe553fb2881e0453717573f52 \
    -    --hash=sha256:81dce2ddc9f6e8f543d94b05d56e70d03a0774d32f6cca53e978dc01e4fc75b8 \
    -    --hash=sha256:8d1f21af4c1539051049796a0f50aa342f9a27cde57318f2fc41ed50b0dbc4ac \
    -    --hash=sha256:90a79bce019c442604662d17bf69df99090e24cdc6ad95b18b6725c2988a490e \
    -    --hash=sha256:9145f092b5d1977ec8c0ab46e7b3381b2fd069957b9862a43bd383e5c01d18c2 \
    -    --hash=sha256:994645a46c6a740ee8ce8df7911d4aee458d9b1bc5639bc968226763d07f00fa \
    -    --hash=sha256:9c6b4d23c04831e3ab61717a707a5d763b300213db49ca680edf8bf13ab5d91b \
    -    --hash=sha256:9c6d0ced3c06d0f183b73d3c5920727268d2201aa0fe6d55c60d68c792ff3588 \
    -    --hash=sha256:a8f4e49fc3ce020f65411432183e6775f24e02dff617281094ba6ab079ef0915 \
    -    --hash=sha256:a9e908ef5889cda4de038892b9accc36d33d72fb3e12c747e2799a0e806ec841 \
    -    --hash=sha256:ad08a69728ff3c79866d729b095872afe1e0557251da4abb2c5faff15a91d19a \
    -    --hash=sha256:adbccd17dcaff65704c856bd29951c58a1bd4b2b0f8ad6b826dbd543fe740988 \
    -    --hash=sha256:b0c7d2f698e83f15228ba41c135501cfe7d5740181d5903e250e47f617eb4292 \
    -    --hash=sha256:b6104f9a46bd8743e4f738afef69b153c4b8b592d35ae46db07fc28ae3d5fb7c \
    -    --hash=sha256:ba7cd6dc4d585ea544c1412019921570ebd8a597fabf475acc4528210d7c4a6f \
    -    --hash=sha256:bc72c231f5449d86d6c7d9cc7cd819b6eb30134bb770b8cfdc0765e48ef9c420 \
    -    --hash=sha256:bce8814b076f0ce5766dc87d5a056b0e9437b8e0cd351b9a6c4e1134a7dfbda9 \
    -    --hash=sha256:be5e22bbb67924dea15039c3282fa4cc6cdfbe0cbbd1c0515f9223186fc2ec5f \
    -    --hash=sha256:be6b7b8d42d3090b6c80793524fa66c57ad7ee3fe9722b258aec6d0672543fd0 \
    -    --hash=sha256:bff507ae210371d4b1fe316d03433ac099f184d570a1a611e541923f78f05037 \
    -    --hash=sha256:c148bec483cc4b421562b4bcedb8e28a3b84fcc8f0aa4418e10898f3c2c0eb9b \
    -    --hash=sha256:c15ad0aee158a15e17e0495e1e18741573d04eb6da06d8b84af726cfc1ed02ee \
    -    --hash=sha256:c2169b2dcabf4e608416f7f9468737583ce5f0a6e8677c4efbf795ce81109d7c \
    -    --hash=sha256:c65a3b5330b54103e7d21cac3f6bf3900d46f6d50138d73343d9e5b2900b2353 \
    -    --hash=sha256:c7964c2183c3e6cce3f497e3a9f49d182e969f2dc3aeeadfa18945ff7bdd7051 \
    -    --hash=sha256:d29338556a59423d9ff7b6eb0cb89ead2b0875e08fe522f3e068b955c3e7b59b \
    -    --hash=sha256:d8a993c0a0ffd5f2d3bda23d0cd75e7086736f8f8268de8a82fbc4bd0ac6791e \
    -    --hash=sha256:d9c727bbcf0065cbb20f39d2b4f932f8fa1631c3e01fcedc979bd4f51fe051c5 \
    -    --hash=sha256:ebedc192abbc7fd13c5ee800e83a6df252bec691eb2c4bedc9f8b2e2903f5e2a \
    -    --hash=sha256:f0a47efb1dbef13af9c9a54a94a0b814902e547b7f21acb29434504d18f36e3a \
    -    --hash=sha256:fb02e4257376ae25c6dd95a5aec377f9b18c09be6ebdefa7ad209b9137b73d48
    -requests==2.31.0 \
    -    --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \
    -    --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1
    -requests-toolbelt==1.0.0 \
    -    --hash=sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6 \
    -    --hash=sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06
    -resolvelib==1.0.1 \
    -    --hash=sha256:04ce76cbd63fded2078ce224785da6ecd42b9564b1390793f64ddecbe997b309 \
    -    --hash=sha256:d2da45d1a8dfee81bdd591647783e340ef3bcb104b54c383f70d422ef5cc7dbf
    -rfc3986==2.0.0 \
    -    --hash=sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd \
    -    --hash=sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c
    -rich==13.6.0 \
    -    --hash=sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245 \
    -    --hash=sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef
    -setuptools==68.2.2 \
    -    --hash=sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87 \
    -    --hash=sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a
    -shellingham==1.5.3 \
    -    --hash=sha256:419c6a164770c9c7cfcaeddfacb3d31ac7a8db0b0f3e9c1287679359734107e9 \
    -    --hash=sha256:cb4a6fec583535bc6da17b647dd2330cf7ef30239e05d547d99ae3705fd0f7f8
    -six==1.16.0 \
    -    --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
    -    --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
    -snowballstemmer==2.2.0 \
    -    --hash=sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1 \
    -    --hash=sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a
    -sonic-client==1.0.0 \
    -    --hash=sha256:291bf292861e97a2dd765ff0c8754ea9631383680d31a63ec3da6f5aa5f4beda \
    -    --hash=sha256:fe324c7354670488ed84847f6a6727d3cb5fb3675cb9b61396dcf5720e5aca66
    -sphinx==7.2.6 \
    -    --hash=sha256:1e09160a40b956dc623c910118fa636da93bd3ca0b9876a7b3df90f07d691560 \
    -    --hash=sha256:9a5160e1ea90688d5963ba09a2dcd8bdd526620edbb65c328728f1b2228d5ab5
    -sphinx-rtd-theme==1.3.0 \
    -    --hash=sha256:46ddef89cc2416a81ecfbeaceab1881948c014b1b6e4450b815311a89fb977b0 \
    -    --hash=sha256:590b030c7abb9cf038ec053b95e5380b5c70d61591eb0b552063fbe7c41f0931
    -sphinxcontrib-applehelp==1.0.7 \
    -    --hash=sha256:094c4d56209d1734e7d252f6e0b3ccc090bd52ee56807a5d9315b19c122ab15d \
    -    --hash=sha256:39fdc8d762d33b01a7d8f026a3b7d71563ea3b72787d5f00ad8465bd9d6dfbfa
    -sphinxcontrib-devhelp==1.0.5 \
    -    --hash=sha256:63b41e0d38207ca40ebbeabcf4d8e51f76c03e78cd61abe118cf4435c73d4212 \
    -    --hash=sha256:fe8009aed765188f08fcaadbb3ea0d90ce8ae2d76710b7e29ea7d047177dae2f
    -sphinxcontrib-htmlhelp==2.0.4 \
    -    --hash=sha256:6c26a118a05b76000738429b724a0568dbde5b72391a688577da08f11891092a \
    -    --hash=sha256:8001661c077a73c29beaf4a79968d0726103c5605e27db92b9ebed8bab1359e9
    -sphinxcontrib-jquery==4.1 \
    -    --hash=sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a \
    -    --hash=sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae
    -sphinxcontrib-jsmath==1.0.1 \
    -    --hash=sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178 \
    -    --hash=sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8
    -sphinxcontrib-qthelp==1.0.6 \
    -    --hash=sha256:62b9d1a186ab7f5ee3356d906f648cacb7a6bdb94d201ee7adf26db55092982d \
    -    --hash=sha256:bf76886ee7470b934e363da7a954ea2825650013d367728588732c7350f49ea4
    -sphinxcontrib-serializinghtml==1.1.9 \
    -    --hash=sha256:0c64ff898339e1fac29abd2bf5f11078f3ec413cfe9c046d3120d7ca65530b54 \
    -    --hash=sha256:9b36e503703ff04f20e9675771df105e58aa029cfcbc23b8ed716019b7416ae1
    -sqlparse==0.4.4 \
    -    --hash=sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3 \
    -    --hash=sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c
    -stack-data==0.6.3 \
    -    --hash=sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9 \
    -    --hash=sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695
    -stdeb==0.10.0 \
    -    --hash=sha256:08c22c9c03b28a140fe3ec5064b53a5288279f22e596ca06b0be698d50c93cf2
    -tomlkit==0.12.1 \
    -    --hash=sha256:38e1ff8edb991273ec9f6181244a6a391ac30e9f5098e7535640ea6be97a7c86 \
    -    --hash=sha256:712cbd236609acc6a3e2e97253dfc52d4c2082982a88f61b640ecf0817eab899
    -traitlets==5.11.2 \
    -    --hash=sha256:7564b5bf8d38c40fa45498072bf4dc5e8346eb087bbf1e2ae2d8774f6a0f078e \
    -    --hash=sha256:98277f247f18b2c5cabaf4af369187754f4fb0e85911d473f72329db8a7f4fae
    -truststore==0.8.0 \
    -    --hash=sha256:dc70da89634944a579bfeec70a7a4523c53ffdb3cf52d1bb4a431fda278ddb96 \
    -    --hash=sha256:e37a5642ae9fc48caa8f120b6283d77225d600d224965a672c9e8ef49ce4bb4c
    -twine==4.0.2 \
    -    --hash=sha256:929bc3c280033347a00f847236564d1c52a3e61b1ac2516c97c48f3ceab756d8 \
    -    --hash=sha256:9e102ef5fdd5a20661eb88fad46338806c3bd32cf1db729603fe3697b1bc83c8
    -types-pytz==2023.3.1.1 \
    -    --hash=sha256:1999a123a3dc0e39a2ef6d19f3f8584211de9e6a77fe7a0259f04a524e90a5cf \
    -    --hash=sha256:cc23d0192cd49c8f6bba44ee0c81e4586a8f30204970fc0894d209a6b08dab9a
    -types-PyYAML==6.0.12.12 \
    -    --hash=sha256:334373d392fde0fdf95af5c3f1661885fa10c52167b14593eb856289e1855062 \
    -    --hash=sha256:c05bc6c158facb0676674b7f11fe3960db4f389718e19e62bd2b84d6205cfd24
    -typing-extensions==4.8.0 \
    -    --hash=sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0 \
    -    --hash=sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef
    -tzlocal==5.1 \
    -    --hash=sha256:2938498395d5f6a898ab8009555cb37a4d360913ad375d4747ef16826b03ef23 \
    -    --hash=sha256:a5ccb2365b295ed964e0a98ad076fe10c495591e75505d34f154d60a7f1ed722
    -unearth==0.11.2 \
    -    --hash=sha256:046a996466de40a16e257fc883ae08157e7ab78a85bcec00313f3fdf9131bd37 \
    -    --hash=sha256:0eb5a8800fda0610e095fef768b48d47c858c9b8417a785af647046c2df5ed2b
    -urllib3==2.0.7 \
    -    --hash=sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84 \
    -    --hash=sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e
    -virtualenv==20.24.5 \
    -    --hash=sha256:b80039f280f4919c77b30f1c23294ae357c4c8701042086e3fc005963e4e537b \
    -    --hash=sha256:e8361967f6da6fbdf1426483bfe9fca8287c242ac0bc30429905721cefbff752
    -w3lib==2.1.2 \
    -    --hash=sha256:c4432926e739caa8e3f49f5de783f336df563d9490416aebd5d39fb896d264e7 \
    -    --hash=sha256:ed5b74e997eea2abe3c1321f916e344144ee8e9072a6f33463ee8e57f858a4b1
    -wcwidth==0.2.8 \
    -    --hash=sha256:77f719e01648ed600dfa5402c347481c0992263b81a027344f3e1ba25493a704 \
    -    --hash=sha256:8705c569999ffbb4f6a87c6d1b80f324bd6db952f5eb0b95bc07517f4c1813d4
    -websockets==11.0.3 \
    -    --hash=sha256:01f5567d9cf6f502d655151645d4e8b72b453413d3819d2b6f1185abc23e82dd \
    -    --hash=sha256:0ac56b661e60edd453585f4bd68eb6a29ae25b5184fd5ba51e97652580458998 \
    -    --hash=sha256:0ee68fe502f9031f19d495dae2c268830df2760c0524cbac5d759921ba8c8e82 \
    -    --hash=sha256:1d2256283fa4b7f4c7d7d3e84dc2ece74d341bce57d5b9bf385df109c2a1a82f \
    -    --hash=sha256:1d5023a4b6a5b183dc838808087033ec5df77580485fc533e7dab2567851b0a4 \
    -    --hash=sha256:1fdf26fa8a6a592f8f9235285b8affa72748dc12e964a5518c6c5e8f916716f7 \
    -    --hash=sha256:279e5de4671e79a9ac877427f4ac4ce93751b8823f276b681d04b2156713b9dd \
    -    --hash=sha256:2d903ad4419f5b472de90cd2d40384573b25da71e33519a67797de17ef849b69 \
    -    --hash=sha256:3580dd9c1ad0701169e4d6fc41e878ffe05e6bdcaf3c412f9d559389d0c9e016 \
    -    --hash=sha256:3ccc8a0c387629aec40f2fc9fdcb4b9d5431954f934da3eaf16cdc94f67dbfac \
    -    --hash=sha256:41f696ba95cd92dc047e46b41b26dd24518384749ed0d99bea0a941ca87404c4 \
    -    --hash=sha256:42cc5452a54a8e46a032521d7365da775823e21bfba2895fb7b77633cce031bb \
    -    --hash=sha256:54c6e5b3d3a8936a4ab6870d46bdd6ec500ad62bde9e44462c32d18f1e9a8e54 \
    -    --hash=sha256:619d9f06372b3a42bc29d0cd0354c9bb9fb39c2cbc1a9c5025b4538738dbffaf \
    -    --hash=sha256:660e2d9068d2bedc0912af508f30bbeb505bbbf9774d98def45f68278cea20d3 \
    -    --hash=sha256:6681ba9e7f8f3b19440921e99efbb40fc89f26cd71bf539e45d8c8a25c976dc6 \
    -    --hash=sha256:69269f3a0b472e91125b503d3c0b3566bda26da0a3261c49f0027eb6075086d1 \
    -    --hash=sha256:6f1a3f10f836fab6ca6efa97bb952300b20ae56b409414ca85bff2ad241d2a61 \
    -    --hash=sha256:7622a89d696fc87af8e8d280d9b421db5133ef5b29d3f7a1ce9f1a7bf7fcfa11 \
    -    --hash=sha256:777354ee16f02f643a4c7f2b3eff8027a33c9861edc691a2003531f5da4f6bc8 \
    -    --hash=sha256:84d27a4832cc1a0ee07cdcf2b0629a8a72db73f4cf6de6f0904f6661227f256f \
    -    --hash=sha256:8531fdcad636d82c517b26a448dcfe62f720e1922b33c81ce695d0edb91eb931 \
    -    --hash=sha256:86d2a77fd490ae3ff6fae1c6ceaecad063d3cc2320b44377efdde79880e11526 \
    -    --hash=sha256:88fc51d9a26b10fc331be344f1781224a375b78488fc343620184e95a4b27016 \
    -    --hash=sha256:8c82f11964f010053e13daafdc7154ce7385ecc538989a354ccc7067fd7028fd \
    -    --hash=sha256:92b2065d642bf8c0a82d59e59053dd2fdde64d4ed44efe4870fa816c1232647b \
    -    --hash=sha256:97b52894d948d2f6ea480171a27122d77af14ced35f62e5c892ca2fae9344311 \
    -    --hash=sha256:aa5003845cdd21ac0dc6c9bf661c5beddd01116f6eb9eb3c8e272353d45b3288 \
    -    --hash=sha256:b30c6590146e53149f04e85a6e4fcae068df4289e31e4aee1fdf56a0dead8f97 \
    -    --hash=sha256:b58cbf0697721120866820b89f93659abc31c1e876bf20d0b3d03cef14faf84d \
    -    --hash=sha256:b67c6f5e5a401fc56394f191f00f9b3811fe843ee93f4a70df3c389d1adf857d \
    -    --hash=sha256:bceab846bac555aff6427d060f2fcfff71042dba6f5fca7dc4f75cac815e57ca \
    -    --hash=sha256:c114e8da9b475739dde229fd3bc6b05a6537a88a578358bc8eb29b4030fac9c9 \
    -    --hash=sha256:c1f0524f203e3bd35149f12157438f406eff2e4fb30f71221c8a5eceb3617b6b \
    -    --hash=sha256:c792ea4eabc0159535608fc5658a74d1a81020eb35195dd63214dcf07556f67e \
    -    --hash=sha256:c7f3cb904cce8e1be667c7e6fef4516b98d1a6a0635a58a57528d577ac18a128 \
    -    --hash=sha256:d67ac60a307f760c6e65dad586f556dde58e683fab03323221a4e530ead6f74d \
    -    --hash=sha256:dcacf2c7a6c3a84e720d1bb2b543c675bf6c40e460300b628bab1b1efc7c034c \
    -    --hash=sha256:de36fe9c02995c7e6ae6efe2e205816f5f00c22fd1fbf343d4d18c3d5ceac2f5 \
    -    --hash=sha256:def07915168ac8f7853812cc593c71185a16216e9e4fa886358a17ed0fd9fcf6 \
    -    --hash=sha256:df41b9bc27c2c25b486bae7cf42fccdc52ff181c8c387bfd026624a491c2671b \
    -    --hash=sha256:e052b8467dd07d4943936009f46ae5ce7b908ddcac3fda581656b1b19c083d9b \
    -    --hash=sha256:e063b1865974611313a3849d43f2c3f5368093691349cf3c7c8f8f75ad7cb280 \
    -    --hash=sha256:e1459677e5d12be8bbc7584c35b992eea142911a6236a3278b9b5ce3326f282c \
    -    --hash=sha256:e6316827e3e79b7b8e7d8e3b08f4e331af91a48e794d5d8b099928b6f0b85f20 \
    -    --hash=sha256:e7837cb169eca3b3ae94cc5787c4fed99eef74c0ab9506756eea335e0d6f3ed8 \
    -    --hash=sha256:e848f46a58b9fcf3d06061d17be388caf70ea5b8cc3466251963c8345e13f7eb \
    -    --hash=sha256:ed058398f55163a79bb9f06a90ef9ccc063b204bb346c4de78efc5d15abfe602 \
    -    --hash=sha256:f2e58f2c36cc52d41f2659e4c0cbf7353e28c8c9e63e30d8c6d3494dc9fdedcf \
    -    --hash=sha256:ffd7dcaf744f25f82190856bc26ed81721508fc5cbf2a330751e135ff1283564
    -wheel==0.41.2 \
    -    --hash=sha256:0c5ac5ff2afb79ac23ab82bab027a0be7b5dbcf2e54dc50efe4bf507de1f7985 \
    -    --hash=sha256:75909db2664838d015e3d9139004ee16711748a52c8f336b52882266540215d8
    -yt-dlp==2023.10.13 \
    -    --hash=sha256:2b069f22675532eebacdfd6372b1825651a751fef848de9ae6efe6491b2dc38a \
    -    --hash=sha256:e026ea1c435ff36eef1215bc4c5bb8c479938b90054997ba99f63a4541fe63b4
    -zipp==3.17.0 \
    -    --hash=sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31 \
    -    --hash=sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0
    +appnope==0.1.3
    +asgiref==3.7.2
    +asttokens==2.4.1
    +brotli==1.1.0
    +certifi==2023.7.22
    +charset-normalizer==3.3.1
    +croniter==2.0.1
    +dateparser==1.1.8
    +decorator==5.1.1
    +django==3.1.14
    +django-auth-ldap==4.1.0
    +django-extensions==3.1.5
    +executing==2.0.1
    +greenlet==3.0.0
    +idna==3.4
    +ipython==8.17.1
    +jedi==0.19.1
    +matplotlib-inline==0.1.6
    +mutagen==1.47.0
    +mypy-extensions==1.0.0
    +parso==0.8.3
    +pexpect==4.8.0
    +playwright==1.39.0
    +prompt-toolkit==3.0.39
    +ptyprocess==0.7.0
    +pure-eval==0.2.2
    +pyasn1==0.5.0
    +pyasn1-modules==0.3.0
    +pycryptodomex==3.19.0
    +pyee==11.0.1
    +pygments==2.16.1
    +python-crontab==3.0.0
    +python-dateutil==2.8.2
    +python-ldap==3.4.3
    +pytz==2023.3.post1
    +regex==2023.10.3
    +requests==2.31.0
    +setuptools==68.2.2
    +six==1.16.0
    +sonic-client==1.0.0
    +sqlparse==0.4.4
    +stack-data==0.6.3
    +traitlets==5.13.0
    +typing-extensions==4.8.0
    +tzlocal==5.2
    +urllib3==2.0.7
    +w3lib==2.1.2
    +wcwidth==0.2.9
    +websockets==12.0
    +yt-dlp==2023.10.13
    
    From da80a41afb75d4c4d9188ed1b096509f2bd65af3 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 03:10:48 -0700
    Subject: [PATCH 76/89] use bookworm-backports for everything
    
    ---
     Dockerfile | 8 +++++---
     1 file changed, 5 insertions(+), 3 deletions(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index 76bc3360..c2a865cb 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -102,7 +102,7 @@ RUN echo "[+] Installing APT base system dependencies for $TARGETPLATFORM..." \
         # && echo 'deb https://deb.debian.org/debian bookworm-backports main contrib non-free' >> /etc/apt/sources.list.d/backports.list \
         && mkdir -p /etc/apt/keyrings \
         && apt-get update -qq \
    -    && apt-get install -qq -y --no-install-recommends \
    +    && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
             # 1. packaging dependencies
             apt-transport-https ca-certificates gnupg2 curl wget \
             # 2. docker and init system dependencies
    @@ -234,9 +234,11 @@ RUN echo "[*] Installing PIP ArchiveBox package from $CODE_DIR..." \
         && apt-get update -qq \
         # install C compiler to build deps on platforms that dont have 32-bit wheels available on pypi
         && if [[ "$TARGETPLATFORM" == "linux/arm/v7" ]]; then \
    -        apt-get install -qq -y --no-install-recommends build-essential python3-regex procps; \
    +        apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    +            build-essential python3-regex procps; \
         else \
    -        apt-get install -qq -y --no-install-recommends procps; \
    +        apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    +            procps; \
         fi \
         # INSTALL ARCHIVEBOX python package globally from CODE_DIR, with all optional dependencies
         && $GLOBAL_VENV/bin/pip3 install --break-system-packages -e "$CODE_DIR"[sonic,ldap] \
    
    From ce4df6d965831f835cacd46646025dfe7d009501 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 03:19:35 -0700
    Subject: [PATCH 77/89] use global pip cache
    
    ---
     Dockerfile | 8 +++++---
     1 file changed, 5 insertions(+), 3 deletions(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index c2a865cb..553bf4c4 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -15,8 +15,8 @@
     # Read more about [developing Archivebox](https://github.com/ArchiveBox/ArchiveBox#archivebox-development).
     
     
    +# Use Debian 12 w/ faster package updates: https://packages.debian.org/bookworm-backports/
     FROM debian:bookworm-backports
    -# Debian 12 w/ faster package updates: https://packages.debian.org/bookworm-backports/
     
     LABEL name="archivebox" \
         maintainer="Nick Sweeting <dockerfile@archivebox.io>" \
    @@ -212,7 +212,8 @@ RUN echo "[+] Installing NPM extractor dependencies from package.json into $NODE
     # Install ArchiveBox Python dependencies
     WORKDIR "$CODE_DIR"
     COPY --chown=root:root --chmod=755 "./pyproject.toml" "./pdm.lock" "requirements.txt" "$CODE_DIR/"
    -RUN echo "[+] Installing PIP ArchiveBox dependencies from requirements.txt into $GLOBAL_VENV..." \
    +RUN --mount=type=cache,target=/root/.cache/pip \
    +    && echo "[+] Installing PIP ArchiveBox dependencies from requirements.txt into $GLOBAL_VENV..." \
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
             build-essential libssl-dev libldap2-dev libsasl2-dev \
    @@ -221,7 +222,8 @@ RUN echo "[+] Installing PIP ArchiveBox dependencies from requirements.txt into
         # && pdm run python -m ensurepip \
         # && pdm sync --fail-fast --no-editable --group :all --no-self \
         # && pdm export -o requirements.txt --without-hashes \
    -    && $GLOBAL_VENV/bin/pip install -r requirements.txt \
    +    && source $GLOBAL_VENV/bin/activate \
    +    && pip install -r requirements.txt \
         && apt-get purge -y \
             build-essential libssl-dev libldap2-dev libsasl2-dev \
             # these are only needed to build CPython libs, we discard after build phase to shrink layer size
    
    From 562fd5a3bb9b29a2d93347a17eeb56f61f621a69 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 03:58:24 -0700
    Subject: [PATCH 78/89] revert back to python-3.11 base image and add cache
     dirs for massive build speed increase
    
    ---
     Dockerfile       | 55 ++++++++++++++++++++++++++++--------------------
     pdm.lock         |  6 +++---
     requirements.txt |  2 +-
     3 files changed, 36 insertions(+), 27 deletions(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index 553bf4c4..1213a7cc 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -16,7 +16,7 @@
     
     
     # Use Debian 12 w/ faster package updates: https://packages.debian.org/bookworm-backports/
    -FROM debian:bookworm-backports
    +FROM python:3.11-slim-bookworm
     
     LABEL name="archivebox" \
         maintainer="Nick Sweeting <dockerfile@archivebox.io>" \
    @@ -98,8 +98,9 @@ RUN echo "[*] Setting up $ARCHIVEBOX_USER user uid=${DEFAULT_PUID}..." \
         # https://docs.linuxserver.io/general/understanding-puid-and-pgid
     
     # Install system apt dependencies (adding backports to access more recent apt updates)
    -RUN echo "[+] Installing APT base system dependencies for $TARGETPLATFORM..." \
    -    # && echo 'deb https://deb.debian.org/debian bookworm-backports main contrib non-free' >> /etc/apt/sources.list.d/backports.list \
    +RUN --mount=type=cache,target=/var/cache/apt \
    +    echo "[+] Installing APT base system dependencies for $TARGETPLATFORM..." \
    +    && echo 'deb https://deb.debian.org/debian bookworm-backports main contrib non-free' >> /etc/apt/sources.list.d/backports.list \
         && mkdir -p /etc/apt/keyrings \
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    @@ -114,7 +115,8 @@ RUN echo "[+] Installing APT base system dependencies for $TARGETPLATFORM..." \
     ######### Language Environments ####################################
     
     # Install Node environment
    -RUN echo "[+] Installing Node $NODE_VERSION environment in $NODE_MODULES..." \
    +RUN --mount=type=cache,target=/var/cache/apt \
    +    echo "[+] Installing Node $NODE_VERSION environment in $NODE_MODULES..." \
         && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_VERSION}.x nodistro main" >> /etc/apt/sources.list.d/nodejs.list \
         && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
         && apt-get update -qq \
    @@ -131,30 +133,34 @@ RUN echo "[+] Installing Node $NODE_VERSION environment in $NODE_MODULES..." \
         ) | tee -a /VERSION.txt
     
     # Install Python environment
    -RUN echo "[+] Installing Python $PYTHON_VERSION environment in $GLOBAL_VENV and $APP_VENV..." \
    +RUN --mount=type=cache,target=/root/.cache/pip --mount=type=cache,target=/var/cache/apt \
    +    echo "[+] Installing Python $PYTHON_VERSION environment in $GLOBAL_VENV and $APP_VENV..." \
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    -        python3 python3-pip python3-setuptools python3-wheel python3-venv python3-pdm python-dev-is-python3 \
    +        python3 python3-pip python3-setuptools python3-wheel python3-venv python-dev-is-python3 \
             #python3-ldap libldap2-dev libsasl2-dev libssl-dev python3-msgpack \
         && rm -rf /var/lib/apt/lists/* \
         # tell PDM to allow using global system python site packages
    -    && rm /usr/lib/python3*/EXTERNALLY-MANAGED \
    +    # && rm /usr/lib/python3*/EXTERNALLY-MANAGED \
         # create global virtual environment GLOBAL_VENV to use (better than using pip install --global)
    -    && python3 -m venv --system-site-packages --symlinks $GLOBAL_VENV \
    +    # && python3 -m venv --system-site-packages --symlinks $GLOBAL_VENV \
    +    # && python3 -m venv --system-site-packages $GLOBAL_VENV \
    +    # && python3 -m venv $GLOBAL_VENV \
         # install global dependencies / python build dependencies in GLOBAL_VENV
    -    && $GLOBAL_VENV/bin/pip install --break-system-packages --upgrade pip pdm setuptools wheel \
    +    && pip install --upgrade pip setuptools wheel \
         # Save version info
         && ( \
             which python3 && python3 --version | grep " $PYTHON_VERSION" \
    -        && which pip3 && pip3 --version \
    -        && which pdm && pdm --version \
    +        && which pip && pip --version \
    +        # && which pdm && pdm --version \
             && echo -e '\n\n' \
         ) | tee -a /VERSION.txt
     
     ######### Extractor Dependencies ##################################
     
     # Install apt dependencies
    -RUN echo "[+] Installing APT extractor dependencies globally using apt..." \
    +RUN --mount=type=cache,target=/var/cache/apt \
    +    echo "[+] Installing APT extractor dependencies globally using apt..." \
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
             curl wget git yt-dlp ffmpeg ripgrep \
    @@ -173,11 +179,12 @@ RUN echo "[+] Installing APT extractor dependencies globally using apt..." \
         ) | tee -a /VERSION.txt
     
     # Install chromium browser using playwright
    -RUN echo "[+] Installing Browser binary dependencies to $PLAYWRIGHT_BROWSERS_PATH..." \
    +RUN --mount=type=cache,target=/var/cache/apt \
    +    echo "[+] Installing Browser binary dependencies to $PLAYWRIGHT_BROWSERS_PATH..." \
         && apt-get update -qq \
         && if [[ "$TARGETPLATFORM" == "linux/amd64" || "$TARGETPLATFORM" == "linux/arm64" ]]; then \
             # install Chromium using playwright
    -        $GLOBAL_VENV/bin/pip install playwright \
    +        pip install playwright \
             && $GLOBAL_VENV/bin/playwright install --with-deps chromium \
             && export CHROME_BINARY="$($GLOBAL_VENV/bin/python -c 'from playwright.sync_api import sync_playwright; print(sync_playwright().start().chromium.executable_path)')"; \
         else \
    @@ -199,8 +206,9 @@ RUN echo "[+] Installing Browser binary dependencies to $PLAYWRIGHT_BROWSERS_PAT
     # Install Node dependencies
     WORKDIR "$CODE_DIR"
     COPY --chown=root:root --chmod=755 "package.json" "package-lock.json" "$CODE_DIR/"
    -RUN echo "[+] Installing NPM extractor dependencies from package.json into $NODE_MODULES..." \
    -    && npm ci --prefer-offline --no-audit \
    +RUN --mount=type=cache,target=/root/.npm \
    +    echo "[+] Installing NPM extractor dependencies from package.json into $NODE_MODULES..." \
    +    && npm ci --prefer-offline --no-audit --cache /root/.npm \
         && ( \
             which node && node --version \
             && which npm && npm version \
    @@ -211,18 +219,18 @@ RUN echo "[+] Installing NPM extractor dependencies from package.json into $NODE
     
     # Install ArchiveBox Python dependencies
     WORKDIR "$CODE_DIR"
    -COPY --chown=root:root --chmod=755 "./pyproject.toml" "./pdm.lock" "requirements.txt" "$CODE_DIR/"
    -RUN --mount=type=cache,target=/root/.cache/pip \
    -    && echo "[+] Installing PIP ArchiveBox dependencies from requirements.txt into $GLOBAL_VENV..." \
    +COPY --chown=root:root --chmod=755 "./pyproject.toml" "requirements.txt" "$CODE_DIR/"
    +RUN --mount=type=cache,target=/root/.cache/pip --mount=type=cache,target=/var/cache/apt \
    +    echo "[+] Installing PIP ArchiveBox dependencies from requirements.txt into $GLOBAL_VENV..." \
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
             build-essential libssl-dev libldap2-dev libsasl2-dev \
    -    && ln -s "$GLOBAL_VENV" "$APP_VENV" \
    +    # && ln -s "$GLOBAL_VENV" "$APP_VENV" \
         # && pdm use --venv in-project \
         # && pdm run python -m ensurepip \
         # && pdm sync --fail-fast --no-editable --group :all --no-self \
         # && pdm export -o requirements.txt --without-hashes \
    -    && source $GLOBAL_VENV/bin/activate \
    +    # && source $GLOBAL_VENV/bin/activate \
         && pip install -r requirements.txt \
         && apt-get purge -y \
             build-essential libssl-dev libldap2-dev libsasl2-dev \
    @@ -232,7 +240,8 @@ RUN --mount=type=cache,target=/root/.cache/pip \
     
     # Install ArchiveBox Python package from source
     COPY --chown=root:root --chmod=755 "." "$CODE_DIR/"
    -RUN echo "[*] Installing PIP ArchiveBox package from $CODE_DIR..." \
    +RUN --mount=type=cache,target=/root/.cache/pip --mount=type=cache,target=/var/cache/apt \
    +    echo "[*] Installing PIP ArchiveBox package from $CODE_DIR..." \
         && apt-get update -qq \
         # install C compiler to build deps on platforms that dont have 32-bit wheels available on pypi
         && if [[ "$TARGETPLATFORM" == "linux/arm/v7" ]]; then \
    @@ -243,7 +252,7 @@ RUN echo "[*] Installing PIP ArchiveBox package from $CODE_DIR..." \
                 procps; \
         fi \
         # INSTALL ARCHIVEBOX python package globally from CODE_DIR, with all optional dependencies
    -    && $GLOBAL_VENV/bin/pip3 install --break-system-packages -e "$CODE_DIR"[sonic,ldap] \
    +    && pip install --break-system-packages -e "$CODE_DIR"[sonic,ldap] \
         # save docker image size and always remove compilers / build tools after building is complete
         && apt-get purge -y build-essential \
         && apt-get autoremove -y \
    diff --git a/pdm.lock b/pdm.lock
    index 2a8610fa..503c9133 100644
    --- a/pdm.lock
    +++ b/pdm.lock
    @@ -443,7 +443,7 @@ files = [
     
     [[package]]
     name = "ipython"
    -version = "8.17.1"
    +version = "8.17.2"
     requires_python = ">=3.9"
     summary = "IPython: Productive Interactive Computing"
     dependencies = [
    @@ -461,8 +461,8 @@ dependencies = [
         "typing-extensions; python_version < \"3.10\"",
     ]
     files = [
    -    {file = "ipython-8.17.1-py3-none-any.whl", hash = "sha256:b4510d0a163c89c78cf81be68acc841dde4a8290b6ee3f3c9578ccdd2574553c"},
    -    {file = "ipython-8.17.1.tar.gz", hash = "sha256:9e12020f4bf74f08631c0f033bb580e074fbe36c64903195f3e63b9c0a986cbe"},
    +    {file = "ipython-8.17.2-py3-none-any.whl", hash = "sha256:1e4d1d666a023e3c93585ba0d8e962867f7a111af322efff6b9c58062b3e5444"},
    +    {file = "ipython-8.17.2.tar.gz", hash = "sha256:126bb57e1895594bb0d91ea3090bbd39384f6fe87c3d57fd558d0670f50339bb"},
     ]
     
     [[package]]
    diff --git a/requirements.txt b/requirements.txt
    index 0270635f..c935bdd7 100644
    --- a/requirements.txt
    +++ b/requirements.txt
    @@ -16,7 +16,7 @@ django-extensions==3.1.5
     executing==2.0.1
     greenlet==3.0.0
     idna==3.4
    -ipython==8.17.1
    +ipython==8.17.2
     jedi==0.19.1
     matplotlib-inline==0.1.6
     mutagen==1.47.0
    
    From 211ca363b5c442b80a4c4166271619b0e776765c Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 05:31:19 -0700
    Subject: [PATCH 79/89] better dockerfiles caching
    
    ---
     Dockerfile            |  48 ++-
     bin/release_docker.sh |   5 +-
     pdm.lock              | 850 +++++++++++++++++++++++++++++++++++++++++-
     pyproject.toml        |   3 +-
     requirements.txt      |   1 -
     5 files changed, 874 insertions(+), 33 deletions(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index 1213a7cc..8ce55ce2 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -39,6 +39,7 @@ ENV TZ=UTC \
         APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 \
         PYTHONIOENCODING=UTF-8 \
         PYTHONUNBUFFERED=1 \
    +    PIP_DISABLE_PIP_VERSION_CHECK=1 \
         npm_config_loglevel=error
     
     # Version config
    @@ -115,7 +116,7 @@ RUN --mount=type=cache,target=/var/cache/apt \
     ######### Language Environments ####################################
     
     # Install Node environment
    -RUN --mount=type=cache,target=/var/cache/apt \
    +RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.npm \
         echo "[+] Installing Node $NODE_VERSION environment in $NODE_MODULES..." \
         && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_VERSION}.x nodistro main" >> /etc/apt/sources.list.d/nodejs.list \
         && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
    @@ -124,7 +125,7 @@ RUN --mount=type=cache,target=/var/cache/apt \
             nodejs libatomic1 \
         && rm -rf /var/lib/apt/lists/* \
         # Update NPM to latest version
    -    && npm i -g npm \
    +    && npm i -g npm --cache /root/.npm \
         # Save version info
         && ( \
             which node && node --version \
    @@ -133,13 +134,8 @@ RUN --mount=type=cache,target=/var/cache/apt \
         ) | tee -a /VERSION.txt
     
     # Install Python environment
    -RUN --mount=type=cache,target=/root/.cache/pip --mount=type=cache,target=/var/cache/apt \
    -    echo "[+] Installing Python $PYTHON_VERSION environment in $GLOBAL_VENV and $APP_VENV..." \
    -    && apt-get update -qq \
    -    && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    -        python3 python3-pip python3-setuptools python3-wheel python3-venv python-dev-is-python3 \
    -        #python3-ldap libldap2-dev libsasl2-dev libssl-dev python3-msgpack \
    -    && rm -rf /var/lib/apt/lists/* \
    +RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.cache/pip \
    +    echo "[+] Setting up Python $PYTHON_VERSION runtime..." \
         # tell PDM to allow using global system python site packages
         # && rm /usr/lib/python3*/EXTERNALLY-MANAGED \
         # create global virtual environment GLOBAL_VENV to use (better than using pip install --global)
    @@ -159,7 +155,7 @@ RUN --mount=type=cache,target=/root/.cache/pip --mount=type=cache,target=/var/ca
     ######### Extractor Dependencies ##################################
     
     # Install apt dependencies
    -RUN --mount=type=cache,target=/var/cache/apt \
    +RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.cache/pip \
         echo "[+] Installing APT extractor dependencies globally using apt..." \
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    @@ -179,14 +175,15 @@ RUN --mount=type=cache,target=/var/cache/apt \
         ) | tee -a /VERSION.txt
     
     # Install chromium browser using playwright
    -RUN --mount=type=cache,target=/var/cache/apt \
    +RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.cache/pip --mount=type=cache,target=/root/.cache/ms-playwright \
         echo "[+] Installing Browser binary dependencies to $PLAYWRIGHT_BROWSERS_PATH..." \
         && apt-get update -qq \
    -    && if [[ "$TARGETPLATFORM" == "linux/amd64" || "$TARGETPLATFORM" == "linux/arm64" ]]; then \
    +    && if [[ "$TARGETPLATFORM" == "linux/amd64"* || "$TARGETPLATFORM" == "linux/arm64"* ]]; then \
             # install Chromium using playwright
             pip install playwright \
    -        && $GLOBAL_VENV/bin/playwright install --with-deps chromium \
    -        && export CHROME_BINARY="$($GLOBAL_VENV/bin/python -c 'from playwright.sync_api import sync_playwright; print(sync_playwright().start().chromium.executable_path)')"; \
    +        && cp -r /root/.cache/ms-playwright "$PLAYWRIGHT_BROWSERS_PATH" \
    +        && playwright install --with-deps chromium \
    +        && export CHROME_BINARY="$(python -c 'from playwright.sync_api import sync_playwright; print(sync_playwright().start().chromium.executable_path)')"; \
         else \
             # fall back to installing Chromium via apt-get on platforms not supported by playwright (e.g. risc, ARMv7, etc.) 
             apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    @@ -220,11 +217,13 @@ RUN --mount=type=cache,target=/root/.npm \
     # Install ArchiveBox Python dependencies
     WORKDIR "$CODE_DIR"
     COPY --chown=root:root --chmod=755 "./pyproject.toml" "requirements.txt" "$CODE_DIR/"
    -RUN --mount=type=cache,target=/root/.cache/pip --mount=type=cache,target=/var/cache/apt \
    -    echo "[+] Installing PIP ArchiveBox dependencies from requirements.txt into $GLOBAL_VENV..." \
    +RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.cache/pip \
    +    echo "[+] Installing PIP ArchiveBox dependencies from requirements.txt for ${TARGETPLATFORM}..." \ 
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    -        build-essential libssl-dev libldap2-dev libsasl2-dev \
    +        build-essential \
    +        libssl-dev libldap2-dev libsasl2-dev \
    +        python3-ldap python3-msgpack python3-mutagen python3-regex procps \
         # && ln -s "$GLOBAL_VENV" "$APP_VENV" \
         # && pdm use --venv in-project \
         # && pdm run python -m ensurepip \
    @@ -233,26 +232,21 @@ RUN --mount=type=cache,target=/root/.cache/pip --mount=type=cache,target=/var/ca
         # && source $GLOBAL_VENV/bin/activate \
         && pip install -r requirements.txt \
         && apt-get purge -y \
    -        build-essential libssl-dev libldap2-dev libsasl2-dev \
    +        build-essential \
             # these are only needed to build CPython libs, we discard after build phase to shrink layer size
         && apt-get autoremove -y \
         && rm -rf /var/lib/apt/lists/*
     
     # Install ArchiveBox Python package from source
     COPY --chown=root:root --chmod=755 "." "$CODE_DIR/"
    -RUN --mount=type=cache,target=/root/.cache/pip --mount=type=cache,target=/var/cache/apt \
    +RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.cache/pip \
         echo "[*] Installing PIP ArchiveBox package from $CODE_DIR..." \
         && apt-get update -qq \
         # install C compiler to build deps on platforms that dont have 32-bit wheels available on pypi
    -    && if [[ "$TARGETPLATFORM" == "linux/arm/v7" ]]; then \
    -        apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    -            build-essential python3-regex procps; \
    -    else \
    -        apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    -            procps; \
    -    fi \
    +    && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    +        build-essential  \
         # INSTALL ARCHIVEBOX python package globally from CODE_DIR, with all optional dependencies
    -    && pip install --break-system-packages -e "$CODE_DIR"[sonic,ldap] \
    +    && pip install -e "$CODE_DIR"[sonic,ldap] \
         # save docker image size and always remove compilers / build tools after building is complete
         && apt-get purge -y build-essential \
         && apt-get autoremove -y \
    diff --git a/bin/release_docker.sh b/bin/release_docker.sh
    index 80353808..7855cb1c 100755
    --- a/bin/release_docker.sh
    +++ b/bin/release_docker.sh
    @@ -15,10 +15,11 @@ VERSION="$(jq -r '.version' < "$REPO_DIR/package.json")"
     SHORT_VERSION="$(echo "$VERSION" | perl -pe 's/(\d+)\.(\d+)\.(\d+)/$1.$2/g')"
     cd "$REPO_DIR"
     
    +echo "[*] Logging in to Docker Hub & Github Container Registry"
    +docker login --username=nikisweeting
    +docker login docker.pkg.github.com --username=pirate
     
     echo "[^] Uploading docker image"
    -# docker login --username=nikisweeting
    -# docker login docker.pkg.github.com --username=pirate
     docker push archivebox/archivebox:$VERSION archivebox/archivebox:$SHORT_VERSION archivebox/archivebox:latest
     docker push docker.io/nikisweeting/archivebox
     docker push docker.io/archivebox/archivebox
    diff --git a/pdm.lock b/pdm.lock
    index 503c9133..76e3e747 100644
    --- a/pdm.lock
    +++ b/pdm.lock
    @@ -2,10 +2,20 @@
     # It is not intended for manual editing.
     
     [metadata]
    -groups = ["default", "ldap", "sonic"]
    +groups = ["default", "build", "debug", "doc", "ldap", "lint", "sonic", "test"]
     strategy = ["cross_platform"]
     lock_version = "4.4"
    -content_hash = "sha256:dc6df5fe3c05dc53c4a12a47dc11fa88863c819d0487e21770fd5fed1b57ec5d"
    +content_hash = "sha256:ce27205ae21629182620f0420e7141e46a2746d074a295566f6df11fba19eaac"
    +
    +[[package]]
    +name = "alabaster"
    +version = "0.7.13"
    +requires_python = ">=3.6"
    +summary = "A configurable sidebar-enabled Sphinx theme"
    +files = [
    +    {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"},
    +    {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"},
    +]
     
     [[package]]
     name = "appnope"
    @@ -41,6 +51,29 @@ files = [
         {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"},
     ]
     
    +[[package]]
    +name = "babel"
    +version = "2.13.1"
    +requires_python = ">=3.7"
    +summary = "Internationalization utilities"
    +dependencies = [
    +    "setuptools; python_version >= \"3.12\"",
    +]
    +files = [
    +    {file = "Babel-2.13.1-py3-none-any.whl", hash = "sha256:7077a4984b02b6727ac10f1f7294484f737443d7e2e66c5e4380e41a3ae0b4ed"},
    +    {file = "Babel-2.13.1.tar.gz", hash = "sha256:33e0952d7dd6374af8dbf6768cc4ddf3ccfefc244f9986d4074704f2fbd18900"},
    +]
    +
    +[[package]]
    +name = "blinker"
    +version = "1.6.3"
    +requires_python = ">=3.7"
    +summary = "Fast, simple object-to-object and broadcast signaling"
    +files = [
    +    {file = "blinker-1.6.3-py3-none-any.whl", hash = "sha256:296320d6c28b006eb5e32d4712202dbcdcbf5dc482da298c2f44881c43884aaa"},
    +    {file = "blinker-1.6.3.tar.gz", hash = "sha256:152090d27c1c5c722ee7e48504b02d76502811ce02e1523553b4cf8c8b3d3a8d"},
    +]
    +
     [[package]]
     name = "brotli"
     version = "1.1.0"
    @@ -135,6 +168,35 @@ files = [
         {file = "brotlicffi-1.1.0.0.tar.gz", hash = "sha256:b77827a689905143f87915310b93b273ab17888fd43ef350d4832c4a71083c13"},
     ]
     
    +[[package]]
    +name = "cachecontrol"
    +version = "0.13.1"
    +requires_python = ">=3.7"
    +summary = "httplib2 caching for requests"
    +dependencies = [
    +    "msgpack>=0.5.2",
    +    "requests>=2.16.0",
    +]
    +files = [
    +    {file = "cachecontrol-0.13.1-py3-none-any.whl", hash = "sha256:95dedbec849f46dda3137866dc28b9d133fc9af55f5b805ab1291833e4457aa4"},
    +    {file = "cachecontrol-0.13.1.tar.gz", hash = "sha256:f012366b79d2243a6118309ce73151bf52a38d4a5dac8ea57f09bd29087e506b"},
    +]
    +
    +[[package]]
    +name = "cachecontrol"
    +version = "0.13.1"
    +extras = ["filecache"]
    +requires_python = ">=3.7"
    +summary = "httplib2 caching for requests"
    +dependencies = [
    +    "cachecontrol==0.13.1",
    +    "filelock>=3.8.0",
    +]
    +files = [
    +    {file = "cachecontrol-0.13.1-py3-none-any.whl", hash = "sha256:95dedbec849f46dda3137866dc28b9d133fc9af55f5b805ab1291833e4457aa4"},
    +    {file = "cachecontrol-0.13.1.tar.gz", hash = "sha256:f012366b79d2243a6118309ce73151bf52a38d4a5dac8ea57f09bd29087e506b"},
    +]
    +
     [[package]]
     name = "certifi"
     version = "2023.7.22"
    @@ -280,6 +342,15 @@ files = [
         {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
     ]
     
    +[[package]]
    +name = "commonmark"
    +version = "0.9.1"
    +summary = "Python parser for the CommonMark Markdown spec"
    +files = [
    +    {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"},
    +    {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"},
    +]
    +
     [[package]]
     name = "croniter"
     version = "2.0.1"
    @@ -320,6 +391,15 @@ files = [
         {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"},
     ]
     
    +[[package]]
    +name = "distlib"
    +version = "0.3.7"
    +summary = "Distribution utilities"
    +files = [
    +    {file = "distlib-0.3.7-py2.py3-none-any.whl", hash = "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057"},
    +    {file = "distlib-0.3.7.tar.gz", hash = "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8"},
    +]
    +
     [[package]]
     name = "django"
     version = "3.1.14"
    @@ -349,6 +429,20 @@ files = [
         {file = "django_auth_ldap-4.1.0-py3-none-any.whl", hash = "sha256:68870e7921e84b1a9867e268a9c8a3e573e8a0d95ea08bcf31be178f5826ff36"},
     ]
     
    +[[package]]
    +name = "django-debug-toolbar"
    +version = "3.2.4"
    +requires_python = ">=3.6"
    +summary = "A configurable set of panels that display various debug information about the current request/response."
    +dependencies = [
    +    "Django>=2.2",
    +    "sqlparse>=0.2.0",
    +]
    +files = [
    +    {file = "django-debug-toolbar-3.2.4.tar.gz", hash = "sha256:644bbd5c428d3283aa9115722471769cac1bec189edf3a0c855fd8ff870375a9"},
    +    {file = "django_debug_toolbar-3.2.4-py3-none-any.whl", hash = "sha256:6b633b6cfee24f232d73569870f19aa86c819d750e7f3e833f2344a9eb4b4409"},
    +]
    +
     [[package]]
     name = "django-extensions"
     version = "3.1.5"
    @@ -362,6 +456,57 @@ files = [
         {file = "django_extensions-3.1.5-py3-none-any.whl", hash = "sha256:9238b9e016bb0009d621e05cf56ea8ce5cce9b32e91ad2026996a7377ca28069"},
     ]
     
    +[[package]]
    +name = "django-stubs"
    +version = "4.2.6"
    +requires_python = ">=3.8"
    +summary = "Mypy stubs for Django"
    +dependencies = [
    +    "django",
    +    "django-stubs-ext>=4.2.5",
    +    "tomli; python_version < \"3.11\"",
    +    "types-PyYAML",
    +    "types-pytz",
    +    "typing-extensions",
    +]
    +files = [
    +    {file = "django-stubs-4.2.6.tar.gz", hash = "sha256:e60b43de662a199db4b15c803c06669e0ac5035614af291cbd3b91591f7dcc94"},
    +    {file = "django_stubs-4.2.6-py3-none-any.whl", hash = "sha256:2fcd257884a68dfa02de41ee5410ec805264d9b07d9b5b119e4dea82c7b8345e"},
    +]
    +
    +[[package]]
    +name = "django-stubs-ext"
    +version = "4.2.5"
    +requires_python = ">=3.8"
    +summary = "Monkey-patching and extensions for django-stubs"
    +dependencies = [
    +    "django",
    +    "typing-extensions",
    +]
    +files = [
    +    {file = "django-stubs-ext-4.2.5.tar.gz", hash = "sha256:8c4d1fb5f68419b3b2474c659681a189803e27d6a5e5abf5aa0da57601b58633"},
    +    {file = "django_stubs_ext-4.2.5-py3-none-any.whl", hash = "sha256:921cd7ae4614e74c234bc0fe86ee75537d163addfe1fc6f134bf03e29d86c01e"},
    +]
    +
    +[[package]]
    +name = "djdt-flamegraph"
    +version = "0.2.13"
    +summary = "Flamegraphs for Django Debug Toolbar"
    +files = [
    +    {file = "djdt_flamegraph-0.2.13-py2.py3-none-any.whl", hash = "sha256:b3252b8cc9b586829166cc158b26952626cd6f41a3ffa92dceef2f5dbe5b99a0"},
    +    {file = "djdt_flamegraph-0.2.13.tar.gz", hash = "sha256:c07a71be58484636e021d4c49b129fd819f24c9128849cb59558e5141192dbf3"},
    +]
    +
    +[[package]]
    +name = "docutils"
    +version = "0.18.1"
    +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
    +summary = "Docutils -- Python Documentation Utilities"
    +files = [
    +    {file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"},
    +    {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"},
    +]
    +
     [[package]]
     name = "exceptiongroup"
     version = "1.1.3"
    @@ -382,6 +527,44 @@ files = [
         {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"},
     ]
     
    +[[package]]
    +name = "filelock"
    +version = "3.13.1"
    +requires_python = ">=3.8"
    +summary = "A platform independent file lock."
    +files = [
    +    {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"},
    +    {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"},
    +]
    +
    +[[package]]
    +name = "findpython"
    +version = "0.4.0"
    +requires_python = ">=3.7"
    +summary = "A utility to find python versions on your system"
    +dependencies = [
    +    "packaging>=20",
    +]
    +files = [
    +    {file = "findpython-0.4.0-py3-none-any.whl", hash = "sha256:087148ac5935f9be458f36a05f3fa479efdf2c629f5d386c73ea481cfecff15e"},
    +    {file = "findpython-0.4.0.tar.gz", hash = "sha256:18b14d115678da18ae92ee22d7001cc30915ea531053f77010ee05a39680f438"},
    +]
    +
    +[[package]]
    +name = "flake8"
    +version = "6.1.0"
    +requires_python = ">=3.8.1"
    +summary = "the modular source code checker: pep8 pyflakes and co"
    +dependencies = [
    +    "mccabe<0.8.0,>=0.7.0",
    +    "pycodestyle<2.12.0,>=2.11.0",
    +    "pyflakes<3.2.0,>=3.1.0",
    +]
    +files = [
    +    {file = "flake8-6.1.0-py2.py3-none-any.whl", hash = "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"},
    +    {file = "flake8-6.1.0.tar.gz", hash = "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23"},
    +]
    +
     [[package]]
     name = "greenlet"
     version = "3.0.0"
    @@ -441,6 +624,66 @@ files = [
         {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
     ]
     
    +[[package]]
    +name = "imagesize"
    +version = "1.4.1"
    +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
    +summary = "Getting image size from png/jpeg/jpeg2000/gif file"
    +files = [
    +    {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"},
    +    {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"},
    +]
    +
    +[[package]]
    +name = "importlib-metadata"
    +version = "6.8.0"
    +requires_python = ">=3.8"
    +summary = "Read metadata from Python packages"
    +dependencies = [
    +    "zipp>=0.5",
    +]
    +files = [
    +    {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"},
    +    {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"},
    +]
    +
    +[[package]]
    +name = "iniconfig"
    +version = "2.0.0"
    +requires_python = ">=3.7"
    +summary = "brain-dead simple config-ini parsing"
    +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 = "installer"
    +version = "0.7.0"
    +requires_python = ">=3.7"
    +summary = "A library for installing Python wheels."
    +files = [
    +    {file = "installer-0.7.0-py3-none-any.whl", hash = "sha256:05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53"},
    +    {file = "installer-0.7.0.tar.gz", hash = "sha256:a26d3e3116289bb08216e0d0f7d925fcef0b0194eedfa0c944bcaaa106c4b631"},
    +]
    +
    +[[package]]
    +name = "ipdb"
    +version = "0.13.13"
    +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
    +summary = "IPython-enabled pdb"
    +dependencies = [
    +    "decorator; python_version > \"3.6\" and python_version < \"3.11\"",
    +    "decorator; python_version >= \"3.11\"",
    +    "ipython>=7.31.1; python_version > \"3.6\" and python_version < \"3.11\"",
    +    "ipython>=7.31.1; python_version >= \"3.11\"",
    +    "tomli; python_version > \"3.6\" and python_version < \"3.11\"",
    +]
    +files = [
    +    {file = "ipdb-0.13.13-py3-none-any.whl", hash = "sha256:45529994741c4ab6d2388bfa5d7b725c2cf7fe9deffabdb8a6113aa5ed449ed4"},
    +    {file = "ipdb-0.13.13.tar.gz", hash = "sha256:e3ac6018ef05126d442af680aad863006ec19d02290561ac88b8b1c0b0cfc726"},
    +]
    +
     [[package]]
     name = "ipython"
     version = "8.17.2"
    @@ -478,6 +721,81 @@ files = [
         {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"},
     ]
     
    +[[package]]
    +name = "jinja2"
    +version = "3.1.2"
    +requires_python = ">=3.7"
    +summary = "A very fast and expressive template engine."
    +dependencies = [
    +    "MarkupSafe>=2.0",
    +]
    +files = [
    +    {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
    +    {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
    +]
    +
    +[[package]]
    +name = "markdown-it-py"
    +version = "3.0.0"
    +requires_python = ">=3.8"
    +summary = "Python port of markdown-it. Markdown parsing, done right!"
    +dependencies = [
    +    "mdurl~=0.1",
    +]
    +files = [
    +    {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"},
    +    {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"},
    +]
    +
    +[[package]]
    +name = "markupsafe"
    +version = "2.1.3"
    +requires_python = ">=3.7"
    +summary = "Safely add untrusted strings to HTML/XML markup."
    +files = [
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"},
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"},
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"},
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"},
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"},
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"},
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"},
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"},
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"},
    +    {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"},
    +    {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"},
    +    {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"},
    +    {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"},
    +    {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"},
    +]
    +
     [[package]]
     name = "matplotlib-inline"
     version = "0.1.6"
    @@ -491,6 +809,79 @@ files = [
         {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"},
     ]
     
    +[[package]]
    +name = "mccabe"
    +version = "0.7.0"
    +requires_python = ">=3.6"
    +summary = "McCabe checker, plugin for flake8"
    +files = [
    +    {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
    +    {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
    +]
    +
    +[[package]]
    +name = "mdurl"
    +version = "0.1.2"
    +requires_python = ">=3.7"
    +summary = "Markdown URL utilities"
    +files = [
    +    {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"},
    +    {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
    +]
    +
    +[[package]]
    +name = "msgpack"
    +version = "1.0.7"
    +requires_python = ">=3.8"
    +summary = "MessagePack serializer"
    +files = [
    +    {file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:04ad6069c86e531682f9e1e71b71c1c3937d6014a7c3e9edd2aa81ad58842862"},
    +    {file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cca1b62fe70d761a282496b96a5e51c44c213e410a964bdffe0928e611368329"},
    +    {file = "msgpack-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e50ebce52f41370707f1e21a59514e3375e3edd6e1832f5e5235237db933c98b"},
    +    {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b4f35de6a304b5533c238bee86b670b75b03d31b7797929caa7a624b5dda6"},
    +    {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28efb066cde83c479dfe5a48141a53bc7e5f13f785b92ddde336c716663039ee"},
    +    {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cb14ce54d9b857be9591ac364cb08dc2d6a5c4318c1182cb1d02274029d590d"},
    +    {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b573a43ef7c368ba4ea06050a957c2a7550f729c31f11dd616d2ac4aba99888d"},
    +    {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ccf9a39706b604d884d2cb1e27fe973bc55f2890c52f38df742bc1d79ab9f5e1"},
    +    {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cb70766519500281815dfd7a87d3a178acf7ce95390544b8c90587d76b227681"},
    +    {file = "msgpack-1.0.7-cp310-cp310-win32.whl", hash = "sha256:b610ff0f24e9f11c9ae653c67ff8cc03c075131401b3e5ef4b82570d1728f8a9"},
    +    {file = "msgpack-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:a40821a89dc373d6427e2b44b572efc36a2778d3f543299e2f24eb1a5de65415"},
    +    {file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:576eb384292b139821c41995523654ad82d1916da6a60cff129c715a6223ea84"},
    +    {file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:730076207cb816138cf1af7f7237b208340a2c5e749707457d70705715c93b93"},
    +    {file = "msgpack-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:85765fdf4b27eb5086f05ac0491090fc76f4f2b28e09d9350c31aac25a5aaff8"},
    +    {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3476fae43db72bd11f29a5147ae2f3cb22e2f1a91d575ef130d2bf49afd21c46"},
    +    {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d4c80667de2e36970ebf74f42d1088cc9ee7ef5f4e8c35eee1b40eafd33ca5b"},
    +    {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b0bf0effb196ed76b7ad883848143427a73c355ae8e569fa538365064188b8e"},
    +    {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f9a7c509542db4eceed3dcf21ee5267ab565a83555c9b88a8109dcecc4709002"},
    +    {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:84b0daf226913133f899ea9b30618722d45feffa67e4fe867b0b5ae83a34060c"},
    +    {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ec79ff6159dffcc30853b2ad612ed572af86c92b5168aa3fc01a67b0fa40665e"},
    +    {file = "msgpack-1.0.7-cp311-cp311-win32.whl", hash = "sha256:3e7bf4442b310ff154b7bb9d81eb2c016b7d597e364f97d72b1acc3817a0fdc1"},
    +    {file = "msgpack-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:3f0c8c6dfa6605ab8ff0611995ee30d4f9fcff89966cf562733b4008a3d60d82"},
    +    {file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f0936e08e0003f66bfd97e74ee530427707297b0d0361247e9b4f59ab78ddc8b"},
    +    {file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:98bbd754a422a0b123c66a4c341de0474cad4a5c10c164ceed6ea090f3563db4"},
    +    {file = "msgpack-1.0.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b291f0ee7961a597cbbcc77709374087fa2a9afe7bdb6a40dbbd9b127e79afee"},
    +    {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebbbba226f0a108a7366bf4b59bf0f30a12fd5e75100c630267d94d7f0ad20e5"},
    +    {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e2d69948e4132813b8d1131f29f9101bc2c915f26089a6d632001a5c1349672"},
    +    {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdf38ba2d393c7911ae989c3bbba510ebbcdf4ecbdbfec36272abe350c454075"},
    +    {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:993584fc821c58d5993521bfdcd31a4adf025c7d745bbd4d12ccfecf695af5ba"},
    +    {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:52700dc63a4676669b341ba33520f4d6e43d3ca58d422e22ba66d1736b0a6e4c"},
    +    {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e45ae4927759289c30ccba8d9fdce62bb414977ba158286b5ddaf8df2cddb5c5"},
    +    {file = "msgpack-1.0.7-cp312-cp312-win32.whl", hash = "sha256:27dcd6f46a21c18fa5e5deed92a43d4554e3df8d8ca5a47bf0615d6a5f39dbc9"},
    +    {file = "msgpack-1.0.7-cp312-cp312-win_amd64.whl", hash = "sha256:7687e22a31e976a0e7fc99c2f4d11ca45eff652a81eb8c8085e9609298916dcf"},
    +    {file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfef2bb6ef068827bbd021017a107194956918ab43ce4d6dc945ffa13efbc25f"},
    +    {file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:484ae3240666ad34cfa31eea7b8c6cd2f1fdaae21d73ce2974211df099a95d81"},
    +    {file = "msgpack-1.0.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3967e4ad1aa9da62fd53e346ed17d7b2e922cba5ab93bdd46febcac39be636fc"},
    +    {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd178c4c80706546702c59529ffc005681bd6dc2ea234c450661b205445a34d"},
    +    {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ffbc252eb0d229aeb2f9ad051200668fc3a9aaa8994e49f0cb2ffe2b7867e7"},
    +    {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:822ea70dc4018c7e6223f13affd1c5c30c0f5c12ac1f96cd8e9949acddb48a61"},
    +    {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:384d779f0d6f1b110eae74cb0659d9aa6ff35aaf547b3955abf2ab4c901c4819"},
    +    {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f64e376cd20d3f030190e8c32e1c64582eba56ac6dc7d5b0b49a9d44021b52fd"},
    +    {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ed82f5a7af3697b1c4786053736f24a0efd0a1b8a130d4c7bfee4b9ded0f08f"},
    +    {file = "msgpack-1.0.7-cp39-cp39-win32.whl", hash = "sha256:f26a07a6e877c76a88e3cecac8531908d980d3d5067ff69213653649ec0f60ad"},
    +    {file = "msgpack-1.0.7-cp39-cp39-win_amd64.whl", hash = "sha256:1dc93e8e4653bdb5910aed79f11e165c85732067614f180f70534f056da97db3"},
    +    {file = "msgpack-1.0.7.tar.gz", hash = "sha256:572efc93db7a4d27e404501975ca6d2d9775705c2d922390d878fcf768d92c87"},
    +]
    +
     [[package]]
     name = "mutagen"
     version = "1.47.0"
    @@ -501,6 +892,41 @@ files = [
         {file = "mutagen-1.47.0.tar.gz", hash = "sha256:719fadef0a978c31b4cf3c956261b3c58b6948b32023078a2117b1de09f0fc99"},
     ]
     
    +[[package]]
    +name = "mypy"
    +version = "1.6.1"
    +requires_python = ">=3.8"
    +summary = "Optional static typing for Python"
    +dependencies = [
    +    "mypy-extensions>=1.0.0",
    +    "tomli>=1.1.0; python_version < \"3.11\"",
    +    "typing-extensions>=4.1.0",
    +]
    +files = [
    +    {file = "mypy-1.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e5012e5cc2ac628177eaac0e83d622b2dd499e28253d4107a08ecc59ede3fc2c"},
    +    {file = "mypy-1.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d8fbb68711905f8912e5af474ca8b78d077447d8f3918997fecbf26943ff3cbb"},
    +    {file = "mypy-1.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a1ad938fee7d2d96ca666c77b7c494c3c5bd88dff792220e1afbebb2925b5e"},
    +    {file = "mypy-1.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b96ae2c1279d1065413965c607712006205a9ac541895004a1e0d4f281f2ff9f"},
    +    {file = "mypy-1.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:40b1844d2e8b232ed92e50a4bd11c48d2daa351f9deee6c194b83bf03e418b0c"},
    +    {file = "mypy-1.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:81af8adaa5e3099469e7623436881eff6b3b06db5ef75e6f5b6d4871263547e5"},
    +    {file = "mypy-1.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8c223fa57cb154c7eab5156856c231c3f5eace1e0bed9b32a24696b7ba3c3245"},
    +    {file = "mypy-1.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8032e00ce71c3ceb93eeba63963b864bf635a18f6c0c12da6c13c450eedb183"},
    +    {file = "mypy-1.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4c46b51de523817a0045b150ed11b56f9fff55f12b9edd0f3ed35b15a2809de0"},
    +    {file = "mypy-1.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:19f905bcfd9e167159b3d63ecd8cb5e696151c3e59a1742e79bc3bcb540c42c7"},
    +    {file = "mypy-1.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:82e469518d3e9a321912955cc702d418773a2fd1e91c651280a1bda10622f02f"},
    +    {file = "mypy-1.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d4473c22cc296425bbbce7e9429588e76e05bc7342da359d6520b6427bf76660"},
    +    {file = "mypy-1.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59a0d7d24dfb26729e0a068639a6ce3500e31d6655df8557156c51c1cb874ce7"},
    +    {file = "mypy-1.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cfd13d47b29ed3bbaafaff7d8b21e90d827631afda134836962011acb5904b71"},
    +    {file = "mypy-1.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:eb4f18589d196a4cbe5290b435d135dee96567e07c2b2d43b5c4621b6501531a"},
    +    {file = "mypy-1.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:49ae115da099dcc0922a7a895c1eec82c1518109ea5c162ed50e3b3594c71208"},
    +    {file = "mypy-1.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8b27958f8c76bed8edaa63da0739d76e4e9ad4ed325c814f9b3851425582a3cd"},
    +    {file = "mypy-1.6.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:925cd6a3b7b55dfba252b7c4561892311c5358c6b5a601847015a1ad4eb7d332"},
    +    {file = "mypy-1.6.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8f57e6b6927a49550da3d122f0cb983d400f843a8a82e65b3b380d3d7259468f"},
    +    {file = "mypy-1.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:a43ef1c8ddfdb9575691720b6352761f3f53d85f1b57d7745701041053deff30"},
    +    {file = "mypy-1.6.1-py3-none-any.whl", hash = "sha256:4cbe68ef919c28ea561165206a2dcb68591c50f3bcf777932323bc208d949cf1"},
    +    {file = "mypy-1.6.1.tar.gz", hash = "sha256:4d01c00d09a0be62a4ca3f933e315455bde83f37f892ba4b08ce92f3cf44bcc1"},
    +]
    +
     [[package]]
     name = "mypy-extensions"
     version = "1.0.0"
    @@ -511,6 +937,16 @@ files = [
         {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
     ]
     
    +[[package]]
    +name = "packaging"
    +version = "23.2"
    +requires_python = ">=3.7"
    +summary = "Core utilities for Python packages"
    +files = [
    +    {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
    +    {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
    +]
    +
     [[package]]
     name = "parso"
     version = "0.8.3"
    @@ -521,6 +957,37 @@ files = [
         {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"},
     ]
     
    +[[package]]
    +name = "pdm"
    +version = "2.10.0"
    +requires_python = ">=3.7"
    +summary = "A modern Python package and dependency manager supporting the latest PEP standards"
    +dependencies = [
    +    "blinker",
    +    "cachecontrol[filecache]>=0.13.0",
    +    "certifi",
    +    "findpython<1.0.0a0,>=0.4.0",
    +    "importlib-metadata>=3.6; python_version < \"3.10\"",
    +    "installer<0.8,>=0.7",
    +    "packaging!=22.0,>=20.9",
    +    "platformdirs",
    +    "pyproject-hooks",
    +    "python-dotenv>=0.15",
    +    "requests-toolbelt",
    +    "resolvelib>=1.0.1",
    +    "rich>=12.3.0",
    +    "shellingham>=1.3.2",
    +    "tomli>=1.1.0; python_version < \"3.11\"",
    +    "tomlkit<1,>=0.11.1",
    +    "truststore; python_version >= \"3.10\"",
    +    "unearth>=0.12.1",
    +    "virtualenv>=20",
    +]
    +files = [
    +    {file = "pdm-2.10.0-py3-none-any.whl", hash = "sha256:2486cb9e66d4a3e3723fd5a8178ebb285d50f8448ecc165e1a2e80124ff066a9"},
    +    {file = "pdm-2.10.0.tar.gz", hash = "sha256:ce2249595af9f61b0926a0899632df49b1c711261e8056a4fae14b53f93d9193"},
    +]
    +
     [[package]]
     name = "pexpect"
     version = "4.8.0"
    @@ -533,6 +1000,16 @@ files = [
         {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"},
     ]
     
    +[[package]]
    +name = "platformdirs"
    +version = "3.11.0"
    +requires_python = ">=3.7"
    +summary = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
    +files = [
    +    {file = "platformdirs-3.11.0-py3-none-any.whl", hash = "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"},
    +    {file = "platformdirs-3.11.0.tar.gz", hash = "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3"},
    +]
    +
     [[package]]
     name = "playwright"
     version = "1.39.0"
    @@ -552,6 +1029,16 @@ files = [
         {file = "playwright-1.39.0-py3-none-win_amd64.whl", hash = "sha256:a420d814e21b05e1156747e2a9fae6c3cca2b46bb4a0226fb26ee65538ce09c9"},
     ]
     
    +[[package]]
    +name = "pluggy"
    +version = "1.3.0"
    +requires_python = ">=3.8"
    +summary = "plugin and hook calling mechanisms for python"
    +files = [
    +    {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"},
    +    {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"},
    +]
    +
     [[package]]
     name = "prompt-toolkit"
     version = "3.0.39"
    @@ -606,6 +1093,16 @@ files = [
         {file = "pyasn1_modules-0.3.0.tar.gz", hash = "sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c"},
     ]
     
    +[[package]]
    +name = "pycodestyle"
    +version = "2.11.1"
    +requires_python = ">=3.8"
    +summary = "Python style guide checker"
    +files = [
    +    {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"},
    +    {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"},
    +]
    +
     [[package]]
     name = "pycparser"
     version = "2.21"
    @@ -658,6 +1155,16 @@ files = [
         {file = "pyee-11.0.1.tar.gz", hash = "sha256:a642c51e3885a33ead087286e35212783a4e9b8d6514a10a5db4e57ac57b2b29"},
     ]
     
    +[[package]]
    +name = "pyflakes"
    +version = "3.1.0"
    +requires_python = ">=3.8"
    +summary = "passive checker of Python programs"
    +files = [
    +    {file = "pyflakes-3.1.0-py2.py3-none-any.whl", hash = "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774"},
    +    {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"},
    +]
    +
     [[package]]
     name = "pygments"
     version = "2.16.1"
    @@ -668,6 +1175,37 @@ files = [
         {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"},
     ]
     
    +[[package]]
    +name = "pyproject-hooks"
    +version = "1.0.0"
    +requires_python = ">=3.7"
    +summary = "Wrappers to call pyproject.toml-based build backend hooks."
    +dependencies = [
    +    "tomli>=1.1.0; python_version < \"3.11\"",
    +]
    +files = [
    +    {file = "pyproject_hooks-1.0.0-py3-none-any.whl", hash = "sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8"},
    +    {file = "pyproject_hooks-1.0.0.tar.gz", hash = "sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5"},
    +]
    +
    +[[package]]
    +name = "pytest"
    +version = "7.4.3"
    +requires_python = ">=3.7"
    +summary = "pytest: simple powerful testing with Python"
    +dependencies = [
    +    "colorama; sys_platform == \"win32\"",
    +    "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"",
    +    "iniconfig",
    +    "packaging",
    +    "pluggy<2.0,>=0.12",
    +    "tomli>=1.0.0; python_version < \"3.11\"",
    +]
    +files = [
    +    {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"},
    +    {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"},
    +]
    +
     [[package]]
     name = "python-crontab"
     version = "3.0.0"
    @@ -693,6 +1231,16 @@ files = [
         {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
     ]
     
    +[[package]]
    +name = "python-dotenv"
    +version = "1.0.0"
    +requires_python = ">=3.8"
    +summary = "Read key-value pairs from a .env file and set them as environment variables"
    +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]]
     name = "python-ldap"
     version = "3.4.3"
    @@ -715,6 +1263,20 @@ files = [
         {file = "pytz-2023.3.post1.tar.gz", hash = "sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b"},
     ]
     
    +[[package]]
    +name = "recommonmark"
    +version = "0.7.1"
    +summary = "A docutils-compatibility bridge to CommonMark, enabling you to write CommonMark inside of Docutils & Sphinx projects."
    +dependencies = [
    +    "commonmark>=0.8.1",
    +    "docutils>=0.11",
    +    "sphinx>=1.3.1",
    +]
    +files = [
    +    {file = "recommonmark-0.7.1-py2.py3-none-any.whl", hash = "sha256:1b1db69af0231efce3fa21b94ff627ea33dee7079a01dd0a7f8482c3da148b3f"},
    +    {file = "recommonmark-0.7.1.tar.gz", hash = "sha256:bdb4db649f2222dcd8d2d844f0006b958d627f732415d399791ee436a3686d67"},
    +]
    +
     [[package]]
     name = "regex"
     version = "2023.10.3"
    @@ -798,6 +1360,42 @@ files = [
         {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
     ]
     
    +[[package]]
    +name = "requests-toolbelt"
    +version = "1.0.0"
    +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
    +summary = "A utility belt for advanced users of python-requests"
    +dependencies = [
    +    "requests<3.0.0,>=2.0.1",
    +]
    +files = [
    +    {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"},
    +    {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"},
    +]
    +
    +[[package]]
    +name = "resolvelib"
    +version = "1.0.1"
    +summary = "Resolve abstract dependencies into concrete ones"
    +files = [
    +    {file = "resolvelib-1.0.1-py2.py3-none-any.whl", hash = "sha256:d2da45d1a8dfee81bdd591647783e340ef3bcb104b54c383f70d422ef5cc7dbf"},
    +    {file = "resolvelib-1.0.1.tar.gz", hash = "sha256:04ce76cbd63fded2078ce224785da6ecd42b9564b1390793f64ddecbe997b309"},
    +]
    +
    +[[package]]
    +name = "rich"
    +version = "13.6.0"
    +requires_python = ">=3.7.0"
    +summary = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
    +dependencies = [
    +    "markdown-it-py>=2.2.0",
    +    "pygments<3.0.0,>=2.13.0",
    +]
    +files = [
    +    {file = "rich-13.6.0-py3-none-any.whl", hash = "sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245"},
    +    {file = "rich-13.6.0.tar.gz", hash = "sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef"},
    +]
    +
     [[package]]
     name = "setuptools"
     version = "68.2.2"
    @@ -808,6 +1406,16 @@ files = [
         {file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"},
     ]
     
    +[[package]]
    +name = "shellingham"
    +version = "1.5.4"
    +requires_python = ">=3.7"
    +summary = "Tool to Detect Surrounding Shell"
    +files = [
    +    {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"},
    +    {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"},
    +]
    +
     [[package]]
     name = "six"
     version = "1.16.0"
    @@ -818,6 +1426,15 @@ files = [
         {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
     ]
     
    +[[package]]
    +name = "snowballstemmer"
    +version = "2.2.0"
    +summary = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
    +files = [
    +    {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
    +    {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
    +]
    +
     [[package]]
     name = "sonic-client"
     version = "1.0.0"
    @@ -827,6 +1444,138 @@ files = [
         {file = "sonic_client-1.0.0-py3-none-any.whl", hash = "sha256:291bf292861e97a2dd765ff0c8754ea9631383680d31a63ec3da6f5aa5f4beda"},
     ]
     
    +[[package]]
    +name = "sphinx"
    +version = "7.2.6"
    +requires_python = ">=3.9"
    +summary = "Python documentation generator"
    +dependencies = [
    +    "Jinja2>=3.0",
    +    "Pygments>=2.14",
    +    "alabaster<0.8,>=0.7",
    +    "babel>=2.9",
    +    "colorama>=0.4.5; sys_platform == \"win32\"",
    +    "docutils<0.21,>=0.18.1",
    +    "imagesize>=1.3",
    +    "importlib-metadata>=4.8; python_version < \"3.10\"",
    +    "packaging>=21.0",
    +    "requests>=2.25.0",
    +    "snowballstemmer>=2.0",
    +    "sphinxcontrib-applehelp",
    +    "sphinxcontrib-devhelp",
    +    "sphinxcontrib-htmlhelp>=2.0.0",
    +    "sphinxcontrib-jsmath",
    +    "sphinxcontrib-qthelp",
    +    "sphinxcontrib-serializinghtml>=1.1.9",
    +]
    +files = [
    +    {file = "sphinx-7.2.6-py3-none-any.whl", hash = "sha256:1e09160a40b956dc623c910118fa636da93bd3ca0b9876a7b3df90f07d691560"},
    +    {file = "sphinx-7.2.6.tar.gz", hash = "sha256:9a5160e1ea90688d5963ba09a2dcd8bdd526620edbb65c328728f1b2228d5ab5"},
    +]
    +
    +[[package]]
    +name = "sphinx-rtd-theme"
    +version = "1.3.0"
    +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
    +summary = "Read the Docs theme for Sphinx"
    +dependencies = [
    +    "docutils<0.19",
    +    "sphinx<8,>=1.6",
    +    "sphinxcontrib-jquery<5,>=4",
    +]
    +files = [
    +    {file = "sphinx_rtd_theme-1.3.0-py2.py3-none-any.whl", hash = "sha256:46ddef89cc2416a81ecfbeaceab1881948c014b1b6e4450b815311a89fb977b0"},
    +    {file = "sphinx_rtd_theme-1.3.0.tar.gz", hash = "sha256:590b030c7abb9cf038ec053b95e5380b5c70d61591eb0b552063fbe7c41f0931"},
    +]
    +
    +[[package]]
    +name = "sphinxcontrib-applehelp"
    +version = "1.0.7"
    +requires_python = ">=3.9"
    +summary = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books"
    +dependencies = [
    +    "Sphinx>=5",
    +]
    +files = [
    +    {file = "sphinxcontrib_applehelp-1.0.7-py3-none-any.whl", hash = "sha256:094c4d56209d1734e7d252f6e0b3ccc090bd52ee56807a5d9315b19c122ab15d"},
    +    {file = "sphinxcontrib_applehelp-1.0.7.tar.gz", hash = "sha256:39fdc8d762d33b01a7d8f026a3b7d71563ea3b72787d5f00ad8465bd9d6dfbfa"},
    +]
    +
    +[[package]]
    +name = "sphinxcontrib-devhelp"
    +version = "1.0.5"
    +requires_python = ">=3.9"
    +summary = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents"
    +dependencies = [
    +    "Sphinx>=5",
    +]
    +files = [
    +    {file = "sphinxcontrib_devhelp-1.0.5-py3-none-any.whl", hash = "sha256:fe8009aed765188f08fcaadbb3ea0d90ce8ae2d76710b7e29ea7d047177dae2f"},
    +    {file = "sphinxcontrib_devhelp-1.0.5.tar.gz", hash = "sha256:63b41e0d38207ca40ebbeabcf4d8e51f76c03e78cd61abe118cf4435c73d4212"},
    +]
    +
    +[[package]]
    +name = "sphinxcontrib-htmlhelp"
    +version = "2.0.4"
    +requires_python = ">=3.9"
    +summary = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
    +dependencies = [
    +    "Sphinx>=5",
    +]
    +files = [
    +    {file = "sphinxcontrib_htmlhelp-2.0.4-py3-none-any.whl", hash = "sha256:8001661c077a73c29beaf4a79968d0726103c5605e27db92b9ebed8bab1359e9"},
    +    {file = "sphinxcontrib_htmlhelp-2.0.4.tar.gz", hash = "sha256:6c26a118a05b76000738429b724a0568dbde5b72391a688577da08f11891092a"},
    +]
    +
    +[[package]]
    +name = "sphinxcontrib-jquery"
    +version = "4.1"
    +requires_python = ">=2.7"
    +summary = "Extension to include jQuery on newer Sphinx releases"
    +dependencies = [
    +    "Sphinx>=1.8",
    +]
    +files = [
    +    {file = "sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a"},
    +    {file = "sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae"},
    +]
    +
    +[[package]]
    +name = "sphinxcontrib-jsmath"
    +version = "1.0.1"
    +requires_python = ">=3.5"
    +summary = "A sphinx extension which renders display math in HTML via JavaScript"
    +files = [
    +    {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"},
    +    {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"},
    +]
    +
    +[[package]]
    +name = "sphinxcontrib-qthelp"
    +version = "1.0.6"
    +requires_python = ">=3.9"
    +summary = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents"
    +dependencies = [
    +    "Sphinx>=5",
    +]
    +files = [
    +    {file = "sphinxcontrib_qthelp-1.0.6-py3-none-any.whl", hash = "sha256:bf76886ee7470b934e363da7a954ea2825650013d367728588732c7350f49ea4"},
    +    {file = "sphinxcontrib_qthelp-1.0.6.tar.gz", hash = "sha256:62b9d1a186ab7f5ee3356d906f648cacb7a6bdb94d201ee7adf26db55092982d"},
    +]
    +
    +[[package]]
    +name = "sphinxcontrib-serializinghtml"
    +version = "1.1.9"
    +requires_python = ">=3.9"
    +summary = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)"
    +dependencies = [
    +    "Sphinx>=5",
    +]
    +files = [
    +    {file = "sphinxcontrib_serializinghtml-1.1.9-py3-none-any.whl", hash = "sha256:9b36e503703ff04f20e9675771df105e58aa029cfcbc23b8ed716019b7416ae1"},
    +    {file = "sphinxcontrib_serializinghtml-1.1.9.tar.gz", hash = "sha256:0c64ff898339e1fac29abd2bf5f11078f3ec413cfe9c046d3120d7ca65530b54"},
    +]
    +
     [[package]]
     name = "sqlparse"
     version = "0.4.4"
    @@ -851,6 +1600,26 @@ files = [
         {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"},
     ]
     
    +[[package]]
    +name = "tomli"
    +version = "2.0.1"
    +requires_python = ">=3.7"
    +summary = "A lil' TOML parser"
    +files = [
    +    {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
    +    {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
    +]
    +
    +[[package]]
    +name = "tomlkit"
    +version = "0.12.1"
    +requires_python = ">=3.7"
    +summary = "Style preserving TOML library"
    +files = [
    +    {file = "tomlkit-0.12.1-py3-none-any.whl", hash = "sha256:712cbd236609acc6a3e2e97253dfc52d4c2082982a88f61b640ecf0817eab899"},
    +    {file = "tomlkit-0.12.1.tar.gz", hash = "sha256:38e1ff8edb991273ec9f6181244a6a391ac30e9f5098e7535640ea6be97a7c86"},
    +]
    +
     [[package]]
     name = "traitlets"
     version = "5.13.0"
    @@ -861,6 +1630,34 @@ files = [
         {file = "traitlets-5.13.0.tar.gz", hash = "sha256:9b232b9430c8f57288c1024b34a8f0251ddcc47268927367a0dd3eeaca40deb5"},
     ]
     
    +[[package]]
    +name = "truststore"
    +version = "0.8.0"
    +requires_python = ">= 3.10"
    +summary = "Verify certificates using native system trust stores"
    +files = [
    +    {file = "truststore-0.8.0-py3-none-any.whl", hash = "sha256:e37a5642ae9fc48caa8f120b6283d77225d600d224965a672c9e8ef49ce4bb4c"},
    +    {file = "truststore-0.8.0.tar.gz", hash = "sha256:dc70da89634944a579bfeec70a7a4523c53ffdb3cf52d1bb4a431fda278ddb96"},
    +]
    +
    +[[package]]
    +name = "types-pytz"
    +version = "2023.3.1.1"
    +summary = "Typing stubs for pytz"
    +files = [
    +    {file = "types-pytz-2023.3.1.1.tar.gz", hash = "sha256:cc23d0192cd49c8f6bba44ee0c81e4586a8f30204970fc0894d209a6b08dab9a"},
    +    {file = "types_pytz-2023.3.1.1-py3-none-any.whl", hash = "sha256:1999a123a3dc0e39a2ef6d19f3f8584211de9e6a77fe7a0259f04a524e90a5cf"},
    +]
    +
    +[[package]]
    +name = "types-pyyaml"
    +version = "6.0.12.12"
    +summary = "Typing stubs for PyYAML"
    +files = [
    +    {file = "types-PyYAML-6.0.12.12.tar.gz", hash = "sha256:334373d392fde0fdf95af5c3f1661885fa10c52167b14593eb856289e1855062"},
    +    {file = "types_PyYAML-6.0.12.12-py3-none-any.whl", hash = "sha256:c05bc6c158facb0676674b7f11fe3960db4f389718e19e62bd2b84d6205cfd24"},
    +]
    +
     [[package]]
     name = "typing-extensions"
     version = "4.8.0"
    @@ -894,6 +1691,20 @@ files = [
         {file = "tzlocal-5.2.tar.gz", hash = "sha256:8d399205578f1a9342816409cc1e46a93ebd5755e39ea2d85334bea911bf0e6e"},
     ]
     
    +[[package]]
    +name = "unearth"
    +version = "0.12.1"
    +requires_python = ">=3.7"
    +summary = "A utility to fetch and download python packages"
    +dependencies = [
    +    "packaging>=20",
    +    "requests>=2.25",
    +]
    +files = [
    +    {file = "unearth-0.12.1-py3-none-any.whl", hash = "sha256:a5a5c51ca44965cbe3618116bd592bb0bbe3705af5fe14e5792660d904aad7c8"},
    +    {file = "unearth-0.12.1.tar.gz", hash = "sha256:4caad941b60f51e50fdc109866234d407910aef77f1233aa1b6b5d168c7427ee"},
    +]
    +
     [[package]]
     name = "urllib3"
     version = "2.0.7"
    @@ -904,6 +1715,21 @@ files = [
         {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"},
     ]
     
    +[[package]]
    +name = "virtualenv"
    +version = "20.24.6"
    +requires_python = ">=3.7"
    +summary = "Virtual Python Environment builder"
    +dependencies = [
    +    "distlib<1,>=0.3.7",
    +    "filelock<4,>=3.12.2",
    +    "platformdirs<4,>=3.9.1",
    +]
    +files = [
    +    {file = "virtualenv-20.24.6-py3-none-any.whl", hash = "sha256:520d056652454c5098a00c0f073611ccbea4c79089331f60bf9d7ba247bb7381"},
    +    {file = "virtualenv-20.24.6.tar.gz", hash = "sha256:02ece4f56fbf939dbbc33c0715159951d6bf14aaf5457b092e4548e1382455af"},
    +]
    +
     [[package]]
     name = "w3lib"
     version = "2.1.2"
    @@ -992,6 +1818,16 @@ files = [
         {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"},
     ]
     
    +[[package]]
    +name = "wheel"
    +version = "0.41.3"
    +requires_python = ">=3.7"
    +summary = "A built-package format for Python"
    +files = [
    +    {file = "wheel-0.41.3-py3-none-any.whl", hash = "sha256:488609bc63a29322326e05560731bf7bfea8e48ad646e1f5e40d366607de0942"},
    +    {file = "wheel-0.41.3.tar.gz", hash = "sha256:4d4987ce51a49370ea65c0bfd2234e8ce80a12780820d9dc462597a6e60d0841"},
    +]
    +
     [[package]]
     name = "yt-dlp"
     version = "2023.10.13"
    @@ -1009,3 +1845,13 @@ files = [
         {file = "yt-dlp-2023.10.13.tar.gz", hash = "sha256:e026ea1c435ff36eef1215bc4c5bb8c479938b90054997ba99f63a4541fe63b4"},
         {file = "yt_dlp-2023.10.13-py2.py3-none-any.whl", hash = "sha256:2b069f22675532eebacdfd6372b1825651a751fef848de9ae6efe6491b2dc38a"},
     ]
    +
    +[[package]]
    +name = "zipp"
    +version = "3.17.0"
    +requires_python = ">=3.8"
    +summary = "Backport of pathlib-compatible object wrapper for zip files"
    +files = [
    +    {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"},
    +    {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"},
    +]
    diff --git a/pyproject.toml b/pyproject.toml
    index af7f89ad..99fb7571 100644
    --- a/pyproject.toml
    +++ b/pyproject.toml
    @@ -6,7 +6,7 @@ authors = [
         {name = "Nick Sweeting", email = "setup.py@archivebox.io"},
     ]
     dependencies = [
    -    "setuptools>=68.2.2",
    +    # "setuptools>=68.2.2",
         "croniter>=0.3.34",
         "dateparser>=1.0.0",
         "django-extensions>=3.0.3",
    @@ -91,6 +91,7 @@ sonic = [
     ]
     ldap = [
         # apt install libldap2-dev libsasl2-dev
    +    "python-ldap>=3.4.3",
         "django-auth-ldap>=4.1.0",
     ]
     
    diff --git a/requirements.txt b/requirements.txt
    index c935bdd7..70cd153a 100644
    --- a/requirements.txt
    +++ b/requirements.txt
    @@ -38,7 +38,6 @@ python-ldap==3.4.3
     pytz==2023.3.post1
     regex==2023.10.3
     requests==2.31.0
    -setuptools==68.2.2
     six==1.16.0
     sonic-client==1.0.0
     sqlparse==0.4.4
    
    From 43a020c534ac80ac017d5195a15569846f971ed3 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 05:33:30 -0700
    Subject: [PATCH 80/89] fewer packages
    
    ---
     dist     |   1 -
     pdm.lock | 858 +------------------------------------------------------
     2 files changed, 1 insertion(+), 858 deletions(-)
     delete mode 120000 dist
    
    diff --git a/dist b/dist
    deleted file mode 120000
    index 7bc6c67a..00000000
    --- a/dist
    +++ /dev/null
    @@ -1 +0,0 @@
    -./pip_dist
    \ No newline at end of file
    diff --git a/pdm.lock b/pdm.lock
    index 76e3e747..05da1d7a 100644
    --- a/pdm.lock
    +++ b/pdm.lock
    @@ -2,21 +2,11 @@
     # It is not intended for manual editing.
     
     [metadata]
    -groups = ["default", "build", "debug", "doc", "ldap", "lint", "sonic", "test"]
    +groups = ["default", "ldap", "sonic"]
     strategy = ["cross_platform"]
     lock_version = "4.4"
     content_hash = "sha256:ce27205ae21629182620f0420e7141e46a2746d074a295566f6df11fba19eaac"
     
    -[[package]]
    -name = "alabaster"
    -version = "0.7.13"
    -requires_python = ">=3.6"
    -summary = "A configurable sidebar-enabled Sphinx theme"
    -files = [
    -    {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"},
    -    {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"},
    -]
    -
     [[package]]
     name = "appnope"
     version = "0.1.3"
    @@ -51,29 +41,6 @@ files = [
         {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"},
     ]
     
    -[[package]]
    -name = "babel"
    -version = "2.13.1"
    -requires_python = ">=3.7"
    -summary = "Internationalization utilities"
    -dependencies = [
    -    "setuptools; python_version >= \"3.12\"",
    -]
    -files = [
    -    {file = "Babel-2.13.1-py3-none-any.whl", hash = "sha256:7077a4984b02b6727ac10f1f7294484f737443d7e2e66c5e4380e41a3ae0b4ed"},
    -    {file = "Babel-2.13.1.tar.gz", hash = "sha256:33e0952d7dd6374af8dbf6768cc4ddf3ccfefc244f9986d4074704f2fbd18900"},
    -]
    -
    -[[package]]
    -name = "blinker"
    -version = "1.6.3"
    -requires_python = ">=3.7"
    -summary = "Fast, simple object-to-object and broadcast signaling"
    -files = [
    -    {file = "blinker-1.6.3-py3-none-any.whl", hash = "sha256:296320d6c28b006eb5e32d4712202dbcdcbf5dc482da298c2f44881c43884aaa"},
    -    {file = "blinker-1.6.3.tar.gz", hash = "sha256:152090d27c1c5c722ee7e48504b02d76502811ce02e1523553b4cf8c8b3d3a8d"},
    -]
    -
     [[package]]
     name = "brotli"
     version = "1.1.0"
    @@ -168,35 +135,6 @@ files = [
         {file = "brotlicffi-1.1.0.0.tar.gz", hash = "sha256:b77827a689905143f87915310b93b273ab17888fd43ef350d4832c4a71083c13"},
     ]
     
    -[[package]]
    -name = "cachecontrol"
    -version = "0.13.1"
    -requires_python = ">=3.7"
    -summary = "httplib2 caching for requests"
    -dependencies = [
    -    "msgpack>=0.5.2",
    -    "requests>=2.16.0",
    -]
    -files = [
    -    {file = "cachecontrol-0.13.1-py3-none-any.whl", hash = "sha256:95dedbec849f46dda3137866dc28b9d133fc9af55f5b805ab1291833e4457aa4"},
    -    {file = "cachecontrol-0.13.1.tar.gz", hash = "sha256:f012366b79d2243a6118309ce73151bf52a38d4a5dac8ea57f09bd29087e506b"},
    -]
    -
    -[[package]]
    -name = "cachecontrol"
    -version = "0.13.1"
    -extras = ["filecache"]
    -requires_python = ">=3.7"
    -summary = "httplib2 caching for requests"
    -dependencies = [
    -    "cachecontrol==0.13.1",
    -    "filelock>=3.8.0",
    -]
    -files = [
    -    {file = "cachecontrol-0.13.1-py3-none-any.whl", hash = "sha256:95dedbec849f46dda3137866dc28b9d133fc9af55f5b805ab1291833e4457aa4"},
    -    {file = "cachecontrol-0.13.1.tar.gz", hash = "sha256:f012366b79d2243a6118309ce73151bf52a38d4a5dac8ea57f09bd29087e506b"},
    -]
    -
     [[package]]
     name = "certifi"
     version = "2023.7.22"
    @@ -342,15 +280,6 @@ files = [
         {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
     ]
     
    -[[package]]
    -name = "commonmark"
    -version = "0.9.1"
    -summary = "Python parser for the CommonMark Markdown spec"
    -files = [
    -    {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"},
    -    {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"},
    -]
    -
     [[package]]
     name = "croniter"
     version = "2.0.1"
    @@ -391,15 +320,6 @@ files = [
         {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"},
     ]
     
    -[[package]]
    -name = "distlib"
    -version = "0.3.7"
    -summary = "Distribution utilities"
    -files = [
    -    {file = "distlib-0.3.7-py2.py3-none-any.whl", hash = "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057"},
    -    {file = "distlib-0.3.7.tar.gz", hash = "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8"},
    -]
    -
     [[package]]
     name = "django"
     version = "3.1.14"
    @@ -429,20 +349,6 @@ files = [
         {file = "django_auth_ldap-4.1.0-py3-none-any.whl", hash = "sha256:68870e7921e84b1a9867e268a9c8a3e573e8a0d95ea08bcf31be178f5826ff36"},
     ]
     
    -[[package]]
    -name = "django-debug-toolbar"
    -version = "3.2.4"
    -requires_python = ">=3.6"
    -summary = "A configurable set of panels that display various debug information about the current request/response."
    -dependencies = [
    -    "Django>=2.2",
    -    "sqlparse>=0.2.0",
    -]
    -files = [
    -    {file = "django-debug-toolbar-3.2.4.tar.gz", hash = "sha256:644bbd5c428d3283aa9115722471769cac1bec189edf3a0c855fd8ff870375a9"},
    -    {file = "django_debug_toolbar-3.2.4-py3-none-any.whl", hash = "sha256:6b633b6cfee24f232d73569870f19aa86c819d750e7f3e833f2344a9eb4b4409"},
    -]
    -
     [[package]]
     name = "django-extensions"
     version = "3.1.5"
    @@ -456,57 +362,6 @@ files = [
         {file = "django_extensions-3.1.5-py3-none-any.whl", hash = "sha256:9238b9e016bb0009d621e05cf56ea8ce5cce9b32e91ad2026996a7377ca28069"},
     ]
     
    -[[package]]
    -name = "django-stubs"
    -version = "4.2.6"
    -requires_python = ">=3.8"
    -summary = "Mypy stubs for Django"
    -dependencies = [
    -    "django",
    -    "django-stubs-ext>=4.2.5",
    -    "tomli; python_version < \"3.11\"",
    -    "types-PyYAML",
    -    "types-pytz",
    -    "typing-extensions",
    -]
    -files = [
    -    {file = "django-stubs-4.2.6.tar.gz", hash = "sha256:e60b43de662a199db4b15c803c06669e0ac5035614af291cbd3b91591f7dcc94"},
    -    {file = "django_stubs-4.2.6-py3-none-any.whl", hash = "sha256:2fcd257884a68dfa02de41ee5410ec805264d9b07d9b5b119e4dea82c7b8345e"},
    -]
    -
    -[[package]]
    -name = "django-stubs-ext"
    -version = "4.2.5"
    -requires_python = ">=3.8"
    -summary = "Monkey-patching and extensions for django-stubs"
    -dependencies = [
    -    "django",
    -    "typing-extensions",
    -]
    -files = [
    -    {file = "django-stubs-ext-4.2.5.tar.gz", hash = "sha256:8c4d1fb5f68419b3b2474c659681a189803e27d6a5e5abf5aa0da57601b58633"},
    -    {file = "django_stubs_ext-4.2.5-py3-none-any.whl", hash = "sha256:921cd7ae4614e74c234bc0fe86ee75537d163addfe1fc6f134bf03e29d86c01e"},
    -]
    -
    -[[package]]
    -name = "djdt-flamegraph"
    -version = "0.2.13"
    -summary = "Flamegraphs for Django Debug Toolbar"
    -files = [
    -    {file = "djdt_flamegraph-0.2.13-py2.py3-none-any.whl", hash = "sha256:b3252b8cc9b586829166cc158b26952626cd6f41a3ffa92dceef2f5dbe5b99a0"},
    -    {file = "djdt_flamegraph-0.2.13.tar.gz", hash = "sha256:c07a71be58484636e021d4c49b129fd819f24c9128849cb59558e5141192dbf3"},
    -]
    -
    -[[package]]
    -name = "docutils"
    -version = "0.18.1"
    -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
    -summary = "Docutils -- Python Documentation Utilities"
    -files = [
    -    {file = "docutils-0.18.1-py2.py3-none-any.whl", hash = "sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c"},
    -    {file = "docutils-0.18.1.tar.gz", hash = "sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06"},
    -]
    -
     [[package]]
     name = "exceptiongroup"
     version = "1.1.3"
    @@ -527,44 +382,6 @@ files = [
         {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"},
     ]
     
    -[[package]]
    -name = "filelock"
    -version = "3.13.1"
    -requires_python = ">=3.8"
    -summary = "A platform independent file lock."
    -files = [
    -    {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"},
    -    {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"},
    -]
    -
    -[[package]]
    -name = "findpython"
    -version = "0.4.0"
    -requires_python = ">=3.7"
    -summary = "A utility to find python versions on your system"
    -dependencies = [
    -    "packaging>=20",
    -]
    -files = [
    -    {file = "findpython-0.4.0-py3-none-any.whl", hash = "sha256:087148ac5935f9be458f36a05f3fa479efdf2c629f5d386c73ea481cfecff15e"},
    -    {file = "findpython-0.4.0.tar.gz", hash = "sha256:18b14d115678da18ae92ee22d7001cc30915ea531053f77010ee05a39680f438"},
    -]
    -
    -[[package]]
    -name = "flake8"
    -version = "6.1.0"
    -requires_python = ">=3.8.1"
    -summary = "the modular source code checker: pep8 pyflakes and co"
    -dependencies = [
    -    "mccabe<0.8.0,>=0.7.0",
    -    "pycodestyle<2.12.0,>=2.11.0",
    -    "pyflakes<3.2.0,>=3.1.0",
    -]
    -files = [
    -    {file = "flake8-6.1.0-py2.py3-none-any.whl", hash = "sha256:ffdfce58ea94c6580c77888a86506937f9a1a227dfcd15f245d694ae20a6b6e5"},
    -    {file = "flake8-6.1.0.tar.gz", hash = "sha256:d5b3857f07c030bdb5bf41c7f53799571d75c4491748a3adcd47de929e34cd23"},
    -]
    -
     [[package]]
     name = "greenlet"
     version = "3.0.0"
    @@ -624,66 +441,6 @@ files = [
         {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
     ]
     
    -[[package]]
    -name = "imagesize"
    -version = "1.4.1"
    -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
    -summary = "Getting image size from png/jpeg/jpeg2000/gif file"
    -files = [
    -    {file = "imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b"},
    -    {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"},
    -]
    -
    -[[package]]
    -name = "importlib-metadata"
    -version = "6.8.0"
    -requires_python = ">=3.8"
    -summary = "Read metadata from Python packages"
    -dependencies = [
    -    "zipp>=0.5",
    -]
    -files = [
    -    {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"},
    -    {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"},
    -]
    -
    -[[package]]
    -name = "iniconfig"
    -version = "2.0.0"
    -requires_python = ">=3.7"
    -summary = "brain-dead simple config-ini parsing"
    -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 = "installer"
    -version = "0.7.0"
    -requires_python = ">=3.7"
    -summary = "A library for installing Python wheels."
    -files = [
    -    {file = "installer-0.7.0-py3-none-any.whl", hash = "sha256:05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53"},
    -    {file = "installer-0.7.0.tar.gz", hash = "sha256:a26d3e3116289bb08216e0d0f7d925fcef0b0194eedfa0c944bcaaa106c4b631"},
    -]
    -
    -[[package]]
    -name = "ipdb"
    -version = "0.13.13"
    -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
    -summary = "IPython-enabled pdb"
    -dependencies = [
    -    "decorator; python_version > \"3.6\" and python_version < \"3.11\"",
    -    "decorator; python_version >= \"3.11\"",
    -    "ipython>=7.31.1; python_version > \"3.6\" and python_version < \"3.11\"",
    -    "ipython>=7.31.1; python_version >= \"3.11\"",
    -    "tomli; python_version > \"3.6\" and python_version < \"3.11\"",
    -]
    -files = [
    -    {file = "ipdb-0.13.13-py3-none-any.whl", hash = "sha256:45529994741c4ab6d2388bfa5d7b725c2cf7fe9deffabdb8a6113aa5ed449ed4"},
    -    {file = "ipdb-0.13.13.tar.gz", hash = "sha256:e3ac6018ef05126d442af680aad863006ec19d02290561ac88b8b1c0b0cfc726"},
    -]
    -
     [[package]]
     name = "ipython"
     version = "8.17.2"
    @@ -721,81 +478,6 @@ files = [
         {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"},
     ]
     
    -[[package]]
    -name = "jinja2"
    -version = "3.1.2"
    -requires_python = ">=3.7"
    -summary = "A very fast and expressive template engine."
    -dependencies = [
    -    "MarkupSafe>=2.0",
    -]
    -files = [
    -    {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
    -    {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
    -]
    -
    -[[package]]
    -name = "markdown-it-py"
    -version = "3.0.0"
    -requires_python = ">=3.8"
    -summary = "Python port of markdown-it. Markdown parsing, done right!"
    -dependencies = [
    -    "mdurl~=0.1",
    -]
    -files = [
    -    {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"},
    -    {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"},
    -]
    -
    -[[package]]
    -name = "markupsafe"
    -version = "2.1.3"
    -requires_python = ">=3.7"
    -summary = "Safely add untrusted strings to HTML/XML markup."
    -files = [
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"},
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"},
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"},
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"},
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"},
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"},
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"},
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"},
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"},
    -    {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"},
    -    {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"},
    -    {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"},
    -    {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"},
    -    {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"},
    -]
    -
     [[package]]
     name = "matplotlib-inline"
     version = "0.1.6"
    @@ -809,79 +491,6 @@ files = [
         {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"},
     ]
     
    -[[package]]
    -name = "mccabe"
    -version = "0.7.0"
    -requires_python = ">=3.6"
    -summary = "McCabe checker, plugin for flake8"
    -files = [
    -    {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
    -    {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
    -]
    -
    -[[package]]
    -name = "mdurl"
    -version = "0.1.2"
    -requires_python = ">=3.7"
    -summary = "Markdown URL utilities"
    -files = [
    -    {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"},
    -    {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
    -]
    -
    -[[package]]
    -name = "msgpack"
    -version = "1.0.7"
    -requires_python = ">=3.8"
    -summary = "MessagePack serializer"
    -files = [
    -    {file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:04ad6069c86e531682f9e1e71b71c1c3937d6014a7c3e9edd2aa81ad58842862"},
    -    {file = "msgpack-1.0.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cca1b62fe70d761a282496b96a5e51c44c213e410a964bdffe0928e611368329"},
    -    {file = "msgpack-1.0.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e50ebce52f41370707f1e21a59514e3375e3edd6e1832f5e5235237db933c98b"},
    -    {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b4f35de6a304b5533c238bee86b670b75b03d31b7797929caa7a624b5dda6"},
    -    {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28efb066cde83c479dfe5a48141a53bc7e5f13f785b92ddde336c716663039ee"},
    -    {file = "msgpack-1.0.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cb14ce54d9b857be9591ac364cb08dc2d6a5c4318c1182cb1d02274029d590d"},
    -    {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b573a43ef7c368ba4ea06050a957c2a7550f729c31f11dd616d2ac4aba99888d"},
    -    {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ccf9a39706b604d884d2cb1e27fe973bc55f2890c52f38df742bc1d79ab9f5e1"},
    -    {file = "msgpack-1.0.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cb70766519500281815dfd7a87d3a178acf7ce95390544b8c90587d76b227681"},
    -    {file = "msgpack-1.0.7-cp310-cp310-win32.whl", hash = "sha256:b610ff0f24e9f11c9ae653c67ff8cc03c075131401b3e5ef4b82570d1728f8a9"},
    -    {file = "msgpack-1.0.7-cp310-cp310-win_amd64.whl", hash = "sha256:a40821a89dc373d6427e2b44b572efc36a2778d3f543299e2f24eb1a5de65415"},
    -    {file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:576eb384292b139821c41995523654ad82d1916da6a60cff129c715a6223ea84"},
    -    {file = "msgpack-1.0.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:730076207cb816138cf1af7f7237b208340a2c5e749707457d70705715c93b93"},
    -    {file = "msgpack-1.0.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:85765fdf4b27eb5086f05ac0491090fc76f4f2b28e09d9350c31aac25a5aaff8"},
    -    {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3476fae43db72bd11f29a5147ae2f3cb22e2f1a91d575ef130d2bf49afd21c46"},
    -    {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d4c80667de2e36970ebf74f42d1088cc9ee7ef5f4e8c35eee1b40eafd33ca5b"},
    -    {file = "msgpack-1.0.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b0bf0effb196ed76b7ad883848143427a73c355ae8e569fa538365064188b8e"},
    -    {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f9a7c509542db4eceed3dcf21ee5267ab565a83555c9b88a8109dcecc4709002"},
    -    {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:84b0daf226913133f899ea9b30618722d45feffa67e4fe867b0b5ae83a34060c"},
    -    {file = "msgpack-1.0.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ec79ff6159dffcc30853b2ad612ed572af86c92b5168aa3fc01a67b0fa40665e"},
    -    {file = "msgpack-1.0.7-cp311-cp311-win32.whl", hash = "sha256:3e7bf4442b310ff154b7bb9d81eb2c016b7d597e364f97d72b1acc3817a0fdc1"},
    -    {file = "msgpack-1.0.7-cp311-cp311-win_amd64.whl", hash = "sha256:3f0c8c6dfa6605ab8ff0611995ee30d4f9fcff89966cf562733b4008a3d60d82"},
    -    {file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f0936e08e0003f66bfd97e74ee530427707297b0d0361247e9b4f59ab78ddc8b"},
    -    {file = "msgpack-1.0.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:98bbd754a422a0b123c66a4c341de0474cad4a5c10c164ceed6ea090f3563db4"},
    -    {file = "msgpack-1.0.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b291f0ee7961a597cbbcc77709374087fa2a9afe7bdb6a40dbbd9b127e79afee"},
    -    {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebbbba226f0a108a7366bf4b59bf0f30a12fd5e75100c630267d94d7f0ad20e5"},
    -    {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e2d69948e4132813b8d1131f29f9101bc2c915f26089a6d632001a5c1349672"},
    -    {file = "msgpack-1.0.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bdf38ba2d393c7911ae989c3bbba510ebbcdf4ecbdbfec36272abe350c454075"},
    -    {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:993584fc821c58d5993521bfdcd31a4adf025c7d745bbd4d12ccfecf695af5ba"},
    -    {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:52700dc63a4676669b341ba33520f4d6e43d3ca58d422e22ba66d1736b0a6e4c"},
    -    {file = "msgpack-1.0.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e45ae4927759289c30ccba8d9fdce62bb414977ba158286b5ddaf8df2cddb5c5"},
    -    {file = "msgpack-1.0.7-cp312-cp312-win32.whl", hash = "sha256:27dcd6f46a21c18fa5e5deed92a43d4554e3df8d8ca5a47bf0615d6a5f39dbc9"},
    -    {file = "msgpack-1.0.7-cp312-cp312-win_amd64.whl", hash = "sha256:7687e22a31e976a0e7fc99c2f4d11ca45eff652a81eb8c8085e9609298916dcf"},
    -    {file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfef2bb6ef068827bbd021017a107194956918ab43ce4d6dc945ffa13efbc25f"},
    -    {file = "msgpack-1.0.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:484ae3240666ad34cfa31eea7b8c6cd2f1fdaae21d73ce2974211df099a95d81"},
    -    {file = "msgpack-1.0.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3967e4ad1aa9da62fd53e346ed17d7b2e922cba5ab93bdd46febcac39be636fc"},
    -    {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dd178c4c80706546702c59529ffc005681bd6dc2ea234c450661b205445a34d"},
    -    {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ffbc252eb0d229aeb2f9ad051200668fc3a9aaa8994e49f0cb2ffe2b7867e7"},
    -    {file = "msgpack-1.0.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:822ea70dc4018c7e6223f13affd1c5c30c0f5c12ac1f96cd8e9949acddb48a61"},
    -    {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:384d779f0d6f1b110eae74cb0659d9aa6ff35aaf547b3955abf2ab4c901c4819"},
    -    {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f64e376cd20d3f030190e8c32e1c64582eba56ac6dc7d5b0b49a9d44021b52fd"},
    -    {file = "msgpack-1.0.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ed82f5a7af3697b1c4786053736f24a0efd0a1b8a130d4c7bfee4b9ded0f08f"},
    -    {file = "msgpack-1.0.7-cp39-cp39-win32.whl", hash = "sha256:f26a07a6e877c76a88e3cecac8531908d980d3d5067ff69213653649ec0f60ad"},
    -    {file = "msgpack-1.0.7-cp39-cp39-win_amd64.whl", hash = "sha256:1dc93e8e4653bdb5910aed79f11e165c85732067614f180f70534f056da97db3"},
    -    {file = "msgpack-1.0.7.tar.gz", hash = "sha256:572efc93db7a4d27e404501975ca6d2d9775705c2d922390d878fcf768d92c87"},
    -]
    -
     [[package]]
     name = "mutagen"
     version = "1.47.0"
    @@ -892,41 +501,6 @@ files = [
         {file = "mutagen-1.47.0.tar.gz", hash = "sha256:719fadef0a978c31b4cf3c956261b3c58b6948b32023078a2117b1de09f0fc99"},
     ]
     
    -[[package]]
    -name = "mypy"
    -version = "1.6.1"
    -requires_python = ">=3.8"
    -summary = "Optional static typing for Python"
    -dependencies = [
    -    "mypy-extensions>=1.0.0",
    -    "tomli>=1.1.0; python_version < \"3.11\"",
    -    "typing-extensions>=4.1.0",
    -]
    -files = [
    -    {file = "mypy-1.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e5012e5cc2ac628177eaac0e83d622b2dd499e28253d4107a08ecc59ede3fc2c"},
    -    {file = "mypy-1.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d8fbb68711905f8912e5af474ca8b78d077447d8f3918997fecbf26943ff3cbb"},
    -    {file = "mypy-1.6.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21a1ad938fee7d2d96ca666c77b7c494c3c5bd88dff792220e1afbebb2925b5e"},
    -    {file = "mypy-1.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b96ae2c1279d1065413965c607712006205a9ac541895004a1e0d4f281f2ff9f"},
    -    {file = "mypy-1.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:40b1844d2e8b232ed92e50a4bd11c48d2daa351f9deee6c194b83bf03e418b0c"},
    -    {file = "mypy-1.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:81af8adaa5e3099469e7623436881eff6b3b06db5ef75e6f5b6d4871263547e5"},
    -    {file = "mypy-1.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8c223fa57cb154c7eab5156856c231c3f5eace1e0bed9b32a24696b7ba3c3245"},
    -    {file = "mypy-1.6.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8032e00ce71c3ceb93eeba63963b864bf635a18f6c0c12da6c13c450eedb183"},
    -    {file = "mypy-1.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4c46b51de523817a0045b150ed11b56f9fff55f12b9edd0f3ed35b15a2809de0"},
    -    {file = "mypy-1.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:19f905bcfd9e167159b3d63ecd8cb5e696151c3e59a1742e79bc3bcb540c42c7"},
    -    {file = "mypy-1.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:82e469518d3e9a321912955cc702d418773a2fd1e91c651280a1bda10622f02f"},
    -    {file = "mypy-1.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d4473c22cc296425bbbce7e9429588e76e05bc7342da359d6520b6427bf76660"},
    -    {file = "mypy-1.6.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59a0d7d24dfb26729e0a068639a6ce3500e31d6655df8557156c51c1cb874ce7"},
    -    {file = "mypy-1.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:cfd13d47b29ed3bbaafaff7d8b21e90d827631afda134836962011acb5904b71"},
    -    {file = "mypy-1.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:eb4f18589d196a4cbe5290b435d135dee96567e07c2b2d43b5c4621b6501531a"},
    -    {file = "mypy-1.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:49ae115da099dcc0922a7a895c1eec82c1518109ea5c162ed50e3b3594c71208"},
    -    {file = "mypy-1.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8b27958f8c76bed8edaa63da0739d76e4e9ad4ed325c814f9b3851425582a3cd"},
    -    {file = "mypy-1.6.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:925cd6a3b7b55dfba252b7c4561892311c5358c6b5a601847015a1ad4eb7d332"},
    -    {file = "mypy-1.6.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8f57e6b6927a49550da3d122f0cb983d400f843a8a82e65b3b380d3d7259468f"},
    -    {file = "mypy-1.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:a43ef1c8ddfdb9575691720b6352761f3f53d85f1b57d7745701041053deff30"},
    -    {file = "mypy-1.6.1-py3-none-any.whl", hash = "sha256:4cbe68ef919c28ea561165206a2dcb68591c50f3bcf777932323bc208d949cf1"},
    -    {file = "mypy-1.6.1.tar.gz", hash = "sha256:4d01c00d09a0be62a4ca3f933e315455bde83f37f892ba4b08ce92f3cf44bcc1"},
    -]
    -
     [[package]]
     name = "mypy-extensions"
     version = "1.0.0"
    @@ -937,16 +511,6 @@ files = [
         {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
     ]
     
    -[[package]]
    -name = "packaging"
    -version = "23.2"
    -requires_python = ">=3.7"
    -summary = "Core utilities for Python packages"
    -files = [
    -    {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
    -    {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
    -]
    -
     [[package]]
     name = "parso"
     version = "0.8.3"
    @@ -957,37 +521,6 @@ files = [
         {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"},
     ]
     
    -[[package]]
    -name = "pdm"
    -version = "2.10.0"
    -requires_python = ">=3.7"
    -summary = "A modern Python package and dependency manager supporting the latest PEP standards"
    -dependencies = [
    -    "blinker",
    -    "cachecontrol[filecache]>=0.13.0",
    -    "certifi",
    -    "findpython<1.0.0a0,>=0.4.0",
    -    "importlib-metadata>=3.6; python_version < \"3.10\"",
    -    "installer<0.8,>=0.7",
    -    "packaging!=22.0,>=20.9",
    -    "platformdirs",
    -    "pyproject-hooks",
    -    "python-dotenv>=0.15",
    -    "requests-toolbelt",
    -    "resolvelib>=1.0.1",
    -    "rich>=12.3.0",
    -    "shellingham>=1.3.2",
    -    "tomli>=1.1.0; python_version < \"3.11\"",
    -    "tomlkit<1,>=0.11.1",
    -    "truststore; python_version >= \"3.10\"",
    -    "unearth>=0.12.1",
    -    "virtualenv>=20",
    -]
    -files = [
    -    {file = "pdm-2.10.0-py3-none-any.whl", hash = "sha256:2486cb9e66d4a3e3723fd5a8178ebb285d50f8448ecc165e1a2e80124ff066a9"},
    -    {file = "pdm-2.10.0.tar.gz", hash = "sha256:ce2249595af9f61b0926a0899632df49b1c711261e8056a4fae14b53f93d9193"},
    -]
    -
     [[package]]
     name = "pexpect"
     version = "4.8.0"
    @@ -1000,16 +533,6 @@ files = [
         {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"},
     ]
     
    -[[package]]
    -name = "platformdirs"
    -version = "3.11.0"
    -requires_python = ">=3.7"
    -summary = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
    -files = [
    -    {file = "platformdirs-3.11.0-py3-none-any.whl", hash = "sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e"},
    -    {file = "platformdirs-3.11.0.tar.gz", hash = "sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3"},
    -]
    -
     [[package]]
     name = "playwright"
     version = "1.39.0"
    @@ -1029,16 +552,6 @@ files = [
         {file = "playwright-1.39.0-py3-none-win_amd64.whl", hash = "sha256:a420d814e21b05e1156747e2a9fae6c3cca2b46bb4a0226fb26ee65538ce09c9"},
     ]
     
    -[[package]]
    -name = "pluggy"
    -version = "1.3.0"
    -requires_python = ">=3.8"
    -summary = "plugin and hook calling mechanisms for python"
    -files = [
    -    {file = "pluggy-1.3.0-py3-none-any.whl", hash = "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7"},
    -    {file = "pluggy-1.3.0.tar.gz", hash = "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12"},
    -]
    -
     [[package]]
     name = "prompt-toolkit"
     version = "3.0.39"
    @@ -1093,16 +606,6 @@ files = [
         {file = "pyasn1_modules-0.3.0.tar.gz", hash = "sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c"},
     ]
     
    -[[package]]
    -name = "pycodestyle"
    -version = "2.11.1"
    -requires_python = ">=3.8"
    -summary = "Python style guide checker"
    -files = [
    -    {file = "pycodestyle-2.11.1-py2.py3-none-any.whl", hash = "sha256:44fe31000b2d866f2e41841b18528a505fbd7fef9017b04eff4e2648a0fadc67"},
    -    {file = "pycodestyle-2.11.1.tar.gz", hash = "sha256:41ba0e7afc9752dfb53ced5489e89f8186be00e599e712660695b7a75ff2663f"},
    -]
    -
     [[package]]
     name = "pycparser"
     version = "2.21"
    @@ -1155,16 +658,6 @@ files = [
         {file = "pyee-11.0.1.tar.gz", hash = "sha256:a642c51e3885a33ead087286e35212783a4e9b8d6514a10a5db4e57ac57b2b29"},
     ]
     
    -[[package]]
    -name = "pyflakes"
    -version = "3.1.0"
    -requires_python = ">=3.8"
    -summary = "passive checker of Python programs"
    -files = [
    -    {file = "pyflakes-3.1.0-py2.py3-none-any.whl", hash = "sha256:4132f6d49cb4dae6819e5379898f2b8cce3c5f23994194c24b77d5da2e36f774"},
    -    {file = "pyflakes-3.1.0.tar.gz", hash = "sha256:a0aae034c444db0071aa077972ba4768d40c830d9539fd45bf4cd3f8f6992efc"},
    -]
    -
     [[package]]
     name = "pygments"
     version = "2.16.1"
    @@ -1175,37 +668,6 @@ files = [
         {file = "Pygments-2.16.1.tar.gz", hash = "sha256:1daff0494820c69bc8941e407aa20f577374ee88364ee10a98fdbe0aece96e29"},
     ]
     
    -[[package]]
    -name = "pyproject-hooks"
    -version = "1.0.0"
    -requires_python = ">=3.7"
    -summary = "Wrappers to call pyproject.toml-based build backend hooks."
    -dependencies = [
    -    "tomli>=1.1.0; python_version < \"3.11\"",
    -]
    -files = [
    -    {file = "pyproject_hooks-1.0.0-py3-none-any.whl", hash = "sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8"},
    -    {file = "pyproject_hooks-1.0.0.tar.gz", hash = "sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5"},
    -]
    -
    -[[package]]
    -name = "pytest"
    -version = "7.4.3"
    -requires_python = ">=3.7"
    -summary = "pytest: simple powerful testing with Python"
    -dependencies = [
    -    "colorama; sys_platform == \"win32\"",
    -    "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"",
    -    "iniconfig",
    -    "packaging",
    -    "pluggy<2.0,>=0.12",
    -    "tomli>=1.0.0; python_version < \"3.11\"",
    -]
    -files = [
    -    {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"},
    -    {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"},
    -]
    -
     [[package]]
     name = "python-crontab"
     version = "3.0.0"
    @@ -1231,16 +693,6 @@ files = [
         {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
     ]
     
    -[[package]]
    -name = "python-dotenv"
    -version = "1.0.0"
    -requires_python = ">=3.8"
    -summary = "Read key-value pairs from a .env file and set them as environment variables"
    -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]]
     name = "python-ldap"
     version = "3.4.3"
    @@ -1263,20 +715,6 @@ files = [
         {file = "pytz-2023.3.post1.tar.gz", hash = "sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b"},
     ]
     
    -[[package]]
    -name = "recommonmark"
    -version = "0.7.1"
    -summary = "A docutils-compatibility bridge to CommonMark, enabling you to write CommonMark inside of Docutils & Sphinx projects."
    -dependencies = [
    -    "commonmark>=0.8.1",
    -    "docutils>=0.11",
    -    "sphinx>=1.3.1",
    -]
    -files = [
    -    {file = "recommonmark-0.7.1-py2.py3-none-any.whl", hash = "sha256:1b1db69af0231efce3fa21b94ff627ea33dee7079a01dd0a7f8482c3da148b3f"},
    -    {file = "recommonmark-0.7.1.tar.gz", hash = "sha256:bdb4db649f2222dcd8d2d844f0006b958d627f732415d399791ee436a3686d67"},
    -]
    -
     [[package]]
     name = "regex"
     version = "2023.10.3"
    @@ -1360,62 +798,6 @@ files = [
         {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"},
     ]
     
    -[[package]]
    -name = "requests-toolbelt"
    -version = "1.0.0"
    -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
    -summary = "A utility belt for advanced users of python-requests"
    -dependencies = [
    -    "requests<3.0.0,>=2.0.1",
    -]
    -files = [
    -    {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"},
    -    {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"},
    -]
    -
    -[[package]]
    -name = "resolvelib"
    -version = "1.0.1"
    -summary = "Resolve abstract dependencies into concrete ones"
    -files = [
    -    {file = "resolvelib-1.0.1-py2.py3-none-any.whl", hash = "sha256:d2da45d1a8dfee81bdd591647783e340ef3bcb104b54c383f70d422ef5cc7dbf"},
    -    {file = "resolvelib-1.0.1.tar.gz", hash = "sha256:04ce76cbd63fded2078ce224785da6ecd42b9564b1390793f64ddecbe997b309"},
    -]
    -
    -[[package]]
    -name = "rich"
    -version = "13.6.0"
    -requires_python = ">=3.7.0"
    -summary = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
    -dependencies = [
    -    "markdown-it-py>=2.2.0",
    -    "pygments<3.0.0,>=2.13.0",
    -]
    -files = [
    -    {file = "rich-13.6.0-py3-none-any.whl", hash = "sha256:2b38e2fe9ca72c9a00170a1a2d20c63c790d0e10ef1fe35eba76e1e7b1d7d245"},
    -    {file = "rich-13.6.0.tar.gz", hash = "sha256:5c14d22737e6d5084ef4771b62d5d4363165b403455a30a1c8ca39dc7b644bef"},
    -]
    -
    -[[package]]
    -name = "setuptools"
    -version = "68.2.2"
    -requires_python = ">=3.8"
    -summary = "Easily download, build, install, upgrade, and uninstall Python packages"
    -files = [
    -    {file = "setuptools-68.2.2-py3-none-any.whl", hash = "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"},
    -    {file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"},
    -]
    -
    -[[package]]
    -name = "shellingham"
    -version = "1.5.4"
    -requires_python = ">=3.7"
    -summary = "Tool to Detect Surrounding Shell"
    -files = [
    -    {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"},
    -    {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"},
    -]
    -
     [[package]]
     name = "six"
     version = "1.16.0"
    @@ -1426,15 +808,6 @@ files = [
         {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
     ]
     
    -[[package]]
    -name = "snowballstemmer"
    -version = "2.2.0"
    -summary = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms."
    -files = [
    -    {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"},
    -    {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"},
    -]
    -
     [[package]]
     name = "sonic-client"
     version = "1.0.0"
    @@ -1444,138 +817,6 @@ files = [
         {file = "sonic_client-1.0.0-py3-none-any.whl", hash = "sha256:291bf292861e97a2dd765ff0c8754ea9631383680d31a63ec3da6f5aa5f4beda"},
     ]
     
    -[[package]]
    -name = "sphinx"
    -version = "7.2.6"
    -requires_python = ">=3.9"
    -summary = "Python documentation generator"
    -dependencies = [
    -    "Jinja2>=3.0",
    -    "Pygments>=2.14",
    -    "alabaster<0.8,>=0.7",
    -    "babel>=2.9",
    -    "colorama>=0.4.5; sys_platform == \"win32\"",
    -    "docutils<0.21,>=0.18.1",
    -    "imagesize>=1.3",
    -    "importlib-metadata>=4.8; python_version < \"3.10\"",
    -    "packaging>=21.0",
    -    "requests>=2.25.0",
    -    "snowballstemmer>=2.0",
    -    "sphinxcontrib-applehelp",
    -    "sphinxcontrib-devhelp",
    -    "sphinxcontrib-htmlhelp>=2.0.0",
    -    "sphinxcontrib-jsmath",
    -    "sphinxcontrib-qthelp",
    -    "sphinxcontrib-serializinghtml>=1.1.9",
    -]
    -files = [
    -    {file = "sphinx-7.2.6-py3-none-any.whl", hash = "sha256:1e09160a40b956dc623c910118fa636da93bd3ca0b9876a7b3df90f07d691560"},
    -    {file = "sphinx-7.2.6.tar.gz", hash = "sha256:9a5160e1ea90688d5963ba09a2dcd8bdd526620edbb65c328728f1b2228d5ab5"},
    -]
    -
    -[[package]]
    -name = "sphinx-rtd-theme"
    -version = "1.3.0"
    -requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
    -summary = "Read the Docs theme for Sphinx"
    -dependencies = [
    -    "docutils<0.19",
    -    "sphinx<8,>=1.6",
    -    "sphinxcontrib-jquery<5,>=4",
    -]
    -files = [
    -    {file = "sphinx_rtd_theme-1.3.0-py2.py3-none-any.whl", hash = "sha256:46ddef89cc2416a81ecfbeaceab1881948c014b1b6e4450b815311a89fb977b0"},
    -    {file = "sphinx_rtd_theme-1.3.0.tar.gz", hash = "sha256:590b030c7abb9cf038ec053b95e5380b5c70d61591eb0b552063fbe7c41f0931"},
    -]
    -
    -[[package]]
    -name = "sphinxcontrib-applehelp"
    -version = "1.0.7"
    -requires_python = ">=3.9"
    -summary = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books"
    -dependencies = [
    -    "Sphinx>=5",
    -]
    -files = [
    -    {file = "sphinxcontrib_applehelp-1.0.7-py3-none-any.whl", hash = "sha256:094c4d56209d1734e7d252f6e0b3ccc090bd52ee56807a5d9315b19c122ab15d"},
    -    {file = "sphinxcontrib_applehelp-1.0.7.tar.gz", hash = "sha256:39fdc8d762d33b01a7d8f026a3b7d71563ea3b72787d5f00ad8465bd9d6dfbfa"},
    -]
    -
    -[[package]]
    -name = "sphinxcontrib-devhelp"
    -version = "1.0.5"
    -requires_python = ">=3.9"
    -summary = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents"
    -dependencies = [
    -    "Sphinx>=5",
    -]
    -files = [
    -    {file = "sphinxcontrib_devhelp-1.0.5-py3-none-any.whl", hash = "sha256:fe8009aed765188f08fcaadbb3ea0d90ce8ae2d76710b7e29ea7d047177dae2f"},
    -    {file = "sphinxcontrib_devhelp-1.0.5.tar.gz", hash = "sha256:63b41e0d38207ca40ebbeabcf4d8e51f76c03e78cd61abe118cf4435c73d4212"},
    -]
    -
    -[[package]]
    -name = "sphinxcontrib-htmlhelp"
    -version = "2.0.4"
    -requires_python = ">=3.9"
    -summary = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files"
    -dependencies = [
    -    "Sphinx>=5",
    -]
    -files = [
    -    {file = "sphinxcontrib_htmlhelp-2.0.4-py3-none-any.whl", hash = "sha256:8001661c077a73c29beaf4a79968d0726103c5605e27db92b9ebed8bab1359e9"},
    -    {file = "sphinxcontrib_htmlhelp-2.0.4.tar.gz", hash = "sha256:6c26a118a05b76000738429b724a0568dbde5b72391a688577da08f11891092a"},
    -]
    -
    -[[package]]
    -name = "sphinxcontrib-jquery"
    -version = "4.1"
    -requires_python = ">=2.7"
    -summary = "Extension to include jQuery on newer Sphinx releases"
    -dependencies = [
    -    "Sphinx>=1.8",
    -]
    -files = [
    -    {file = "sphinxcontrib-jquery-4.1.tar.gz", hash = "sha256:1620739f04e36a2c779f1a131a2dfd49b2fd07351bf1968ced074365933abc7a"},
    -    {file = "sphinxcontrib_jquery-4.1-py2.py3-none-any.whl", hash = "sha256:f936030d7d0147dd026a4f2b5a57343d233f1fc7b363f68b3d4f1cb0993878ae"},
    -]
    -
    -[[package]]
    -name = "sphinxcontrib-jsmath"
    -version = "1.0.1"
    -requires_python = ">=3.5"
    -summary = "A sphinx extension which renders display math in HTML via JavaScript"
    -files = [
    -    {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"},
    -    {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"},
    -]
    -
    -[[package]]
    -name = "sphinxcontrib-qthelp"
    -version = "1.0.6"
    -requires_python = ">=3.9"
    -summary = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents"
    -dependencies = [
    -    "Sphinx>=5",
    -]
    -files = [
    -    {file = "sphinxcontrib_qthelp-1.0.6-py3-none-any.whl", hash = "sha256:bf76886ee7470b934e363da7a954ea2825650013d367728588732c7350f49ea4"},
    -    {file = "sphinxcontrib_qthelp-1.0.6.tar.gz", hash = "sha256:62b9d1a186ab7f5ee3356d906f648cacb7a6bdb94d201ee7adf26db55092982d"},
    -]
    -
    -[[package]]
    -name = "sphinxcontrib-serializinghtml"
    -version = "1.1.9"
    -requires_python = ">=3.9"
    -summary = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)"
    -dependencies = [
    -    "Sphinx>=5",
    -]
    -files = [
    -    {file = "sphinxcontrib_serializinghtml-1.1.9-py3-none-any.whl", hash = "sha256:9b36e503703ff04f20e9675771df105e58aa029cfcbc23b8ed716019b7416ae1"},
    -    {file = "sphinxcontrib_serializinghtml-1.1.9.tar.gz", hash = "sha256:0c64ff898339e1fac29abd2bf5f11078f3ec413cfe9c046d3120d7ca65530b54"},
    -]
    -
     [[package]]
     name = "sqlparse"
     version = "0.4.4"
    @@ -1600,26 +841,6 @@ files = [
         {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"},
     ]
     
    -[[package]]
    -name = "tomli"
    -version = "2.0.1"
    -requires_python = ">=3.7"
    -summary = "A lil' TOML parser"
    -files = [
    -    {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
    -    {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
    -]
    -
    -[[package]]
    -name = "tomlkit"
    -version = "0.12.1"
    -requires_python = ">=3.7"
    -summary = "Style preserving TOML library"
    -files = [
    -    {file = "tomlkit-0.12.1-py3-none-any.whl", hash = "sha256:712cbd236609acc6a3e2e97253dfc52d4c2082982a88f61b640ecf0817eab899"},
    -    {file = "tomlkit-0.12.1.tar.gz", hash = "sha256:38e1ff8edb991273ec9f6181244a6a391ac30e9f5098e7535640ea6be97a7c86"},
    -]
    -
     [[package]]
     name = "traitlets"
     version = "5.13.0"
    @@ -1630,34 +851,6 @@ files = [
         {file = "traitlets-5.13.0.tar.gz", hash = "sha256:9b232b9430c8f57288c1024b34a8f0251ddcc47268927367a0dd3eeaca40deb5"},
     ]
     
    -[[package]]
    -name = "truststore"
    -version = "0.8.0"
    -requires_python = ">= 3.10"
    -summary = "Verify certificates using native system trust stores"
    -files = [
    -    {file = "truststore-0.8.0-py3-none-any.whl", hash = "sha256:e37a5642ae9fc48caa8f120b6283d77225d600d224965a672c9e8ef49ce4bb4c"},
    -    {file = "truststore-0.8.0.tar.gz", hash = "sha256:dc70da89634944a579bfeec70a7a4523c53ffdb3cf52d1bb4a431fda278ddb96"},
    -]
    -
    -[[package]]
    -name = "types-pytz"
    -version = "2023.3.1.1"
    -summary = "Typing stubs for pytz"
    -files = [
    -    {file = "types-pytz-2023.3.1.1.tar.gz", hash = "sha256:cc23d0192cd49c8f6bba44ee0c81e4586a8f30204970fc0894d209a6b08dab9a"},
    -    {file = "types_pytz-2023.3.1.1-py3-none-any.whl", hash = "sha256:1999a123a3dc0e39a2ef6d19f3f8584211de9e6a77fe7a0259f04a524e90a5cf"},
    -]
    -
    -[[package]]
    -name = "types-pyyaml"
    -version = "6.0.12.12"
    -summary = "Typing stubs for PyYAML"
    -files = [
    -    {file = "types-PyYAML-6.0.12.12.tar.gz", hash = "sha256:334373d392fde0fdf95af5c3f1661885fa10c52167b14593eb856289e1855062"},
    -    {file = "types_PyYAML-6.0.12.12-py3-none-any.whl", hash = "sha256:c05bc6c158facb0676674b7f11fe3960db4f389718e19e62bd2b84d6205cfd24"},
    -]
    -
     [[package]]
     name = "typing-extensions"
     version = "4.8.0"
    @@ -1691,20 +884,6 @@ files = [
         {file = "tzlocal-5.2.tar.gz", hash = "sha256:8d399205578f1a9342816409cc1e46a93ebd5755e39ea2d85334bea911bf0e6e"},
     ]
     
    -[[package]]
    -name = "unearth"
    -version = "0.12.1"
    -requires_python = ">=3.7"
    -summary = "A utility to fetch and download python packages"
    -dependencies = [
    -    "packaging>=20",
    -    "requests>=2.25",
    -]
    -files = [
    -    {file = "unearth-0.12.1-py3-none-any.whl", hash = "sha256:a5a5c51ca44965cbe3618116bd592bb0bbe3705af5fe14e5792660d904aad7c8"},
    -    {file = "unearth-0.12.1.tar.gz", hash = "sha256:4caad941b60f51e50fdc109866234d407910aef77f1233aa1b6b5d168c7427ee"},
    -]
    -
     [[package]]
     name = "urllib3"
     version = "2.0.7"
    @@ -1715,21 +894,6 @@ files = [
         {file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"},
     ]
     
    -[[package]]
    -name = "virtualenv"
    -version = "20.24.6"
    -requires_python = ">=3.7"
    -summary = "Virtual Python Environment builder"
    -dependencies = [
    -    "distlib<1,>=0.3.7",
    -    "filelock<4,>=3.12.2",
    -    "platformdirs<4,>=3.9.1",
    -]
    -files = [
    -    {file = "virtualenv-20.24.6-py3-none-any.whl", hash = "sha256:520d056652454c5098a00c0f073611ccbea4c79089331f60bf9d7ba247bb7381"},
    -    {file = "virtualenv-20.24.6.tar.gz", hash = "sha256:02ece4f56fbf939dbbc33c0715159951d6bf14aaf5457b092e4548e1382455af"},
    -]
    -
     [[package]]
     name = "w3lib"
     version = "2.1.2"
    @@ -1818,16 +982,6 @@ files = [
         {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"},
     ]
     
    -[[package]]
    -name = "wheel"
    -version = "0.41.3"
    -requires_python = ">=3.7"
    -summary = "A built-package format for Python"
    -files = [
    -    {file = "wheel-0.41.3-py3-none-any.whl", hash = "sha256:488609bc63a29322326e05560731bf7bfea8e48ad646e1f5e40d366607de0942"},
    -    {file = "wheel-0.41.3.tar.gz", hash = "sha256:4d4987ce51a49370ea65c0bfd2234e8ce80a12780820d9dc462597a6e60d0841"},
    -]
    -
     [[package]]
     name = "yt-dlp"
     version = "2023.10.13"
    @@ -1845,13 +999,3 @@ files = [
         {file = "yt-dlp-2023.10.13.tar.gz", hash = "sha256:e026ea1c435ff36eef1215bc4c5bb8c479938b90054997ba99f63a4541fe63b4"},
         {file = "yt_dlp-2023.10.13-py2.py3-none-any.whl", hash = "sha256:2b069f22675532eebacdfd6372b1825651a751fef848de9ae6efe6491b2dc38a"},
     ]
    -
    -[[package]]
    -name = "zipp"
    -version = "3.17.0"
    -requires_python = ">=3.8"
    -summary = "Backport of pathlib-compatible object wrapper for zip files"
    -files = [
    -    {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"},
    -    {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"},
    -]
    
    From 12c966477f97a15c05ea9877918e95df2ea3c3fb Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 05:37:26 -0700
    Subject: [PATCH 81/89] bump docker build action ci versions
    
    ---
     .github/workflows/docker.yml | 14 +++++++-------
     1 file changed, 7 insertions(+), 7 deletions(-)
    
    diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
    index ac080b4f..ce174b27 100644
    --- a/.github/workflows/docker.yml
    +++ b/.github/workflows/docker.yml
    @@ -18,17 +18,17 @@ jobs:
         runs-on: ubuntu-latest
         steps:
           - name: Checkout
    -        uses: actions/checkout@v2
    +        uses: actions/checkout@v4
             with:
               submodules: true
               fetch-depth: 1
     
           - name: Set up QEMU
    -        uses: docker/setup-qemu-action@v1
    +        uses: docker/setup-qemu-action@v3
           
           - name: Set up Docker Buildx
             id: buildx
    -        uses: docker/setup-buildx-action@v1
    +        uses: docker/setup-buildx-action@v3
             with:
               version: latest
               install: true
    @@ -40,7 +40,7 @@ jobs:
             run: echo ${{ steps.buildx.outputs.platforms }}
           
           - name: Cache Docker layers
    -        uses: actions/cache@v2
    +        uses: actions/cache@v3
             with:
               path: /tmp/.buildx-cache
               key: ${{ runner.os }}-buildx-${{ github.sha }}
    @@ -48,7 +48,7 @@ jobs:
                 ${{ runner.os }}-buildx-
     
           - name: Docker Login
    -        uses: docker/login-action@v1
    +        uses: docker/login-action@v3
             if: github.event_name != 'pull_request'
             with:
                username: ${{ secrets.DOCKER_USERNAME }}
    @@ -56,7 +56,7 @@ jobs:
           
           - name: Collect Docker tags
             id: docker_meta
    -        uses: crazy-max/ghaction-docker-meta@v2
    +        uses: docker/metadata-action@v5
             with:
               images: archivebox/archivebox,nikisweeting/archivebox
               flavor: |
    @@ -69,7 +69,7 @@ jobs:
           
           - name: Build and push
             id: docker_build
    -        uses: docker/build-push-action@v2
    +        uses: docker/build-push-action@v5
             with:
               context: ./
               file: ./Dockerfile
    
    From bc555cca96e201403b81d882e36c70d597be5603 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 06:28:11 -0700
    Subject: [PATCH 82/89] working arm v7 build
    
    ---
     Dockerfile          |  7 ++--
     bin/build_docker.sh |  4 +--
     pdm.lock            | 83 +--------------------------------------------
     pyproject.toml      |  6 +++-
     requirements.txt    |  4 ---
     5 files changed, 11 insertions(+), 93 deletions(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index 8ce55ce2..ed9838c5 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -71,6 +71,7 @@ SHELL ["/bin/bash", "-o", "pipefail", "-o", "errexit", "-o", "errtrace", "-o", "
     COPY --chown=root:root --chmod=755 package.json "$CODE_DIR/"
     RUN grep '"version": ' "${CODE_DIR}/package.json" | awk -F'"' '{print $4}' > /VERSION.txt
     
    +
     # Print debug info about build and save it to disk
     RUN (echo "[i] Docker build for ArchiveBox $(cat /VERSION.txt) starting..." \
         && echo "PLATFORM=${TARGETPLATFORM} ARCH=$(uname -m) ($(uname -s) ${TARGETARCH} ${TARGETVARIANT})" \
    @@ -106,7 +107,7 @@ RUN --mount=type=cache,target=/var/cache/apt \
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
             # 1. packaging dependencies
    -        apt-transport-https ca-certificates gnupg2 curl wget \
    +        apt-transport-https ca-certificates apt-utils gnupg2 curl wget \
             # 2. docker and init system dependencies
             zlib1g-dev dumb-init gosu cron unzip grep \
             # 3. frivolous CLI helpers to make debugging failed archiving easier
    @@ -122,7 +123,7 @@ RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.np
         && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    -        nodejs libatomic1 \
    +        nodejs libatomic1 python3-minimal \
         && rm -rf /var/lib/apt/lists/* \
         # Update NPM to latest version
         && npm i -g npm --cache /root/.npm \
    @@ -178,7 +179,7 @@ RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.ca
     RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.cache/pip --mount=type=cache,target=/root/.cache/ms-playwright \
         echo "[+] Installing Browser binary dependencies to $PLAYWRIGHT_BROWSERS_PATH..." \
         && apt-get update -qq \
    -    && if [[ "$TARGETPLATFORM" == "linux/amd64"* || "$TARGETPLATFORM" == "linux/arm64"* ]]; then \
    +    && if [[ "$TARGETPLATFORM" == *amd64* || "$TARGETPLATFORM" == *arm64* ]]; then \
             # install Chromium using playwright
             pip install playwright \
             && cp -r /root/.cache/ms-playwright "$PLAYWRIGHT_BROWSERS_PATH" \
    diff --git a/bin/build_docker.sh b/bin/build_docker.sh
    index 4fd4fa5a..bcaacbb8 100755
    --- a/bin/build_docker.sh
    +++ b/bin/build_docker.sh
    @@ -18,9 +18,7 @@ which docker > /dev/null || exit 1
     which jq > /dev/null || exit 1
     # which pdm > /dev/null || exit 1
     
    -SUPPORTED_PLATFORMS="linux/arm64,linux/amd64,linux/arm/v7"
    -
    -
    +SUPPORTED_PLATFORMS="linux/amd64,linux/arm64,linux/arm/v7"
     
     TAG_NAME="${1:-$(git rev-parse --abbrev-ref HEAD)}"
     VERSION="$(jq -r '.version' < "$REPO_DIR/package.json")"
    diff --git a/pdm.lock b/pdm.lock
    index 05da1d7a..270f9a5a 100644
    --- a/pdm.lock
    +++ b/pdm.lock
    @@ -5,7 +5,7 @@
     groups = ["default", "ldap", "sonic"]
     strategy = ["cross_platform"]
     lock_version = "4.4"
    -content_hash = "sha256:ce27205ae21629182620f0420e7141e46a2746d074a295566f6df11fba19eaac"
    +content_hash = "sha256:94ce8e464cde936eeb187affb454ff96c68663bd354c808620a0650ff78d5630"
     
     [[package]]
     name = "appnope"
    @@ -382,55 +382,6 @@ files = [
         {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"},
     ]
     
    -[[package]]
    -name = "greenlet"
    -version = "3.0.0"
    -requires_python = ">=3.7"
    -summary = "Lightweight in-process concurrent programming"
    -files = [
    -    {file = "greenlet-3.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e09dea87cc91aea5500262993cbd484b41edf8af74f976719dd83fe724644cd6"},
    -    {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f47932c434a3c8d3c86d865443fadc1fbf574e9b11d6650b656e602b1797908a"},
    -    {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bdfaeecf8cc705d35d8e6de324bf58427d7eafb55f67050d8f28053a3d57118c"},
    -    {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a68d670c8f89ff65c82b936275369e532772eebc027c3be68c6b87ad05ca695"},
    -    {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:38ad562a104cd41e9d4644f46ea37167b93190c6d5e4048fcc4b80d34ecb278f"},
    -    {file = "greenlet-3.0.0-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02a807b2a58d5cdebb07050efe3d7deaf915468d112dfcf5e426d0564aa3aa4a"},
    -    {file = "greenlet-3.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b1660a15a446206c8545edc292ab5c48b91ff732f91b3d3b30d9a915d5ec4779"},
    -    {file = "greenlet-3.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:813720bd57e193391dfe26f4871186cf460848b83df7e23e6bef698a7624b4c9"},
    -    {file = "greenlet-3.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:aa15a2ec737cb609ed48902b45c5e4ff6044feb5dcdfcf6fa8482379190330d7"},
    -    {file = "greenlet-3.0.0-cp310-universal2-macosx_11_0_x86_64.whl", hash = "sha256:7709fd7bb02b31908dc8fd35bfd0a29fc24681d5cc9ac1d64ad07f8d2b7db62f"},
    -    {file = "greenlet-3.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:211ef8d174601b80e01436f4e6905aca341b15a566f35a10dd8d1e93f5dbb3b7"},
    -    {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6512592cc49b2c6d9b19fbaa0312124cd4c4c8a90d28473f86f92685cc5fef8e"},
    -    {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:871b0a8835f9e9d461b7fdaa1b57e3492dd45398e87324c047469ce2fc9f516c"},
    -    {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b505fcfc26f4148551826a96f7317e02c400665fa0883fe505d4fcaab1dabfdd"},
    -    {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:123910c58234a8d40eaab595bc56a5ae49bdd90122dde5bdc012c20595a94c14"},
    -    {file = "greenlet-3.0.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:96d9ea57292f636ec851a9bb961a5cc0f9976900e16e5d5647f19aa36ba6366b"},
    -    {file = "greenlet-3.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0b72b802496cccbd9b31acea72b6f87e7771ccfd7f7927437d592e5c92ed703c"},
    -    {file = "greenlet-3.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:527cd90ba3d8d7ae7dceb06fda619895768a46a1b4e423bdb24c1969823b8362"},
    -    {file = "greenlet-3.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:37f60b3a42d8b5499be910d1267b24355c495064f271cfe74bf28b17b099133c"},
    -    {file = "greenlet-3.0.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1482fba7fbed96ea7842b5a7fc11d61727e8be75a077e603e8ab49d24e234383"},
    -    {file = "greenlet-3.0.0-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:be557119bf467d37a8099d91fbf11b2de5eb1fd5fc5b91598407574848dc910f"},
    -    {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:73b2f1922a39d5d59cc0e597987300df3396b148a9bd10b76a058a2f2772fc04"},
    -    {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1e22c22f7826096ad503e9bb681b05b8c1f5a8138469b255eb91f26a76634f2"},
    -    {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d363666acc21d2c204dd8705c0e0457d7b2ee7a76cb16ffc099d6799744ac99"},
    -    {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:334ef6ed8337bd0b58bb0ae4f7f2dcc84c9f116e474bb4ec250a8bb9bd797a66"},
    -    {file = "greenlet-3.0.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6672fdde0fd1a60b44fb1751a7779c6db487e42b0cc65e7caa6aa686874e79fb"},
    -    {file = "greenlet-3.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:952256c2bc5b4ee8df8dfc54fc4de330970bf5d79253c863fb5e6761f00dda35"},
    -    {file = "greenlet-3.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:269d06fa0f9624455ce08ae0179430eea61085e3cf6457f05982b37fd2cefe17"},
    -    {file = "greenlet-3.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:9adbd8ecf097e34ada8efde9b6fec4dd2a903b1e98037adf72d12993a1c80b51"},
    -    {file = "greenlet-3.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4cd83fb8d8e17633ad534d9ac93719ef8937568d730ef07ac3a98cb520fd93e4"},
    -    {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a5b2d4cdaf1c71057ff823a19d850ed5c6c2d3686cb71f73ae4d6382aaa7a06"},
    -    {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e7dcdfad252f2ca83c685b0fa9fba00e4d8f243b73839229d56ee3d9d219314"},
    -    {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c94e4e924d09b5a3e37b853fe5924a95eac058cb6f6fb437ebb588b7eda79870"},
    -    {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad6fb737e46b8bd63156b8f59ba6cdef46fe2b7db0c5804388a2d0519b8ddb99"},
    -    {file = "greenlet-3.0.0-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d55db1db455c59b46f794346efce896e754b8942817f46a1bada2d29446e305a"},
    -    {file = "greenlet-3.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:56867a3b3cf26dc8a0beecdb4459c59f4c47cdd5424618c08515f682e1d46692"},
    -    {file = "greenlet-3.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a812224a5fb17a538207e8cf8e86f517df2080c8ee0f8c1ed2bdaccd18f38f4"},
    -    {file = "greenlet-3.0.0-cp39-cp39-win32.whl", hash = "sha256:0d3f83ffb18dc57243e0151331e3c383b05e5b6c5029ac29f754745c800f8ed9"},
    -    {file = "greenlet-3.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:831d6f35037cf18ca5e80a737a27d822d87cd922521d18ed3dbc8a6967be50ce"},
    -    {file = "greenlet-3.0.0-cp39-universal2-macosx_11_0_x86_64.whl", hash = "sha256:a048293392d4e058298710a54dfaefcefdf49d287cd33fb1f7d63d55426e4355"},
    -    {file = "greenlet-3.0.0.tar.gz", hash = "sha256:19834e3f91f485442adc1ee440171ec5d9a4840a1f7bd5ed97833544719ce10b"},
    -]
    -
     [[package]]
     name = "idna"
     version = "3.4"
    @@ -533,25 +484,6 @@ files = [
         {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"},
     ]
     
    -[[package]]
    -name = "playwright"
    -version = "1.39.0"
    -requires_python = ">=3.8"
    -summary = "A high-level API to automate web browsers"
    -dependencies = [
    -    "greenlet==3.0.0",
    -    "pyee==11.0.1",
    -]
    -files = [
    -    {file = "playwright-1.39.0-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:384e195a6d09343f319031cf552e9cd601ede78fe9c082b9fa197537c5cbfe7a"},
    -    {file = "playwright-1.39.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d2c3634411828d9273196ed6f69f2fa7645c89732b3c982dcf09ab03ed4c5d2b"},
    -    {file = "playwright-1.39.0-py3-none-macosx_11_0_universal2.whl", hash = "sha256:d2fd90f370599cf9a2c6a041bd79a5eeec62baf0e943c7c5c2079b29be476d2a"},
    -    {file = "playwright-1.39.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:699a8e707ca5f3567aa28223ee1be7e42d2bf25eda7d3d86babda71e36e5f16f"},
    -    {file = "playwright-1.39.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:654bb3ae0dc3c69ffddc0c38c127c3b8e93032d8cf3928e2c4f21890cb39514b"},
    -    {file = "playwright-1.39.0-py3-none-win32.whl", hash = "sha256:40ed7f2546c64f1bb3d22b2295b4d43ed5a2f0b7ea7599d93a72f723a1883e1e"},
    -    {file = "playwright-1.39.0-py3-none-win_amd64.whl", hash = "sha256:a420d814e21b05e1156747e2a9fae6c3cca2b46bb4a0226fb26ee65538ce09c9"},
    -]
    -
     [[package]]
     name = "prompt-toolkit"
     version = "3.0.39"
    @@ -645,19 +577,6 @@ files = [
         {file = "pycryptodomex-3.19.0.tar.gz", hash = "sha256:af83a554b3f077564229865c45af0791be008ac6469ef0098152139e6bd4b5b6"},
     ]
     
    -[[package]]
    -name = "pyee"
    -version = "11.0.1"
    -requires_python = ">=3.8"
    -summary = "A rough port of Node.js's EventEmitter to Python with a few tricks of its own"
    -dependencies = [
    -    "typing-extensions",
    -]
    -files = [
    -    {file = "pyee-11.0.1-py3-none-any.whl", hash = "sha256:9bcc9647822234f42c228d88de63d0f9ffa881e87a87f9d36ddf5211f6ac977d"},
    -    {file = "pyee-11.0.1.tar.gz", hash = "sha256:a642c51e3885a33ead087286e35212783a4e9b8d6514a10a5db4e57ac57b2b29"},
    -]
    -
     [[package]]
     name = "pygments"
     version = "2.16.1"
    diff --git a/pyproject.toml b/pyproject.toml
    index 99fb7571..5d175e9e 100644
    --- a/pyproject.toml
    +++ b/pyproject.toml
    @@ -18,7 +18,7 @@ dependencies = [
         "w3lib>=1.22.0",
         # "youtube-dl>=2021.04.17",
         "yt-dlp>=2021.4.11",
    -    "playwright>=1.39.0; platform_machine != 'armv7l'",
    +    # "playwright>=1.39.0; platform_machine != 'armv7l'",
     ]
     requires-python = ">=3.9"
     readme = "README.md"
    @@ -94,6 +94,10 @@ ldap = [
         "python-ldap>=3.4.3",
         "django-auth-ldap>=4.1.0",
     ]
    +# playwright = [
    +#     platform_machine isnt respected by pdm export -o requirements.txt, this breaks arm/v7
    +#     "playwright>=1.39.0; platform_machine != 'armv7l'",
    +# ]
     
     [project.scripts]
     archivebox = "archivebox.cli:main"
    diff --git a/requirements.txt b/requirements.txt
    index 70cd153a..f1dacefa 100644
    --- a/requirements.txt
    +++ b/requirements.txt
    @@ -14,7 +14,6 @@ django==3.1.14
     django-auth-ldap==4.1.0
     django-extensions==3.1.5
     executing==2.0.1
    -greenlet==3.0.0
     idna==3.4
     ipython==8.17.2
     jedi==0.19.1
    @@ -23,14 +22,12 @@ mutagen==1.47.0
     mypy-extensions==1.0.0
     parso==0.8.3
     pexpect==4.8.0
    -playwright==1.39.0
     prompt-toolkit==3.0.39
     ptyprocess==0.7.0
     pure-eval==0.2.2
     pyasn1==0.5.0
     pyasn1-modules==0.3.0
     pycryptodomex==3.19.0
    -pyee==11.0.1
     pygments==2.16.1
     python-crontab==3.0.0
     python-dateutil==2.8.2
    @@ -43,7 +40,6 @@ sonic-client==1.0.0
     sqlparse==0.4.4
     stack-data==0.6.3
     traitlets==5.13.0
    -typing-extensions==4.8.0
     tzlocal==5.2
     urllib3==2.0.7
     w3lib==2.1.2
    
    From 2c692191ef71eefaa5d159a281a5c5b8e6c0bf9c Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 06:48:55 -0700
    Subject: [PATCH 83/89] fixes for ci
    
    ---
     .github/workflows/docker.yml | 4 ++++
     1 file changed, 4 insertions(+)
    
    diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
    index ce174b27..9078a9b8 100644
    --- a/.github/workflows/docker.yml
    +++ b/.github/workflows/docker.yml
    @@ -32,6 +32,10 @@ jobs:
             with:
               version: latest
               install: true
    +          platforms: linux/amd64,linux/arm64,linux/arm/v7
    +          config-inline: |
    +            [worker.oci]
    +            max-parallelism = 1
           
           - name: Builder instance name
             run: echo ${{ steps.buildx.outputs.name }}
    
    From 41bd7c648019031212f343a371439d2c6fbad019 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 14:59:17 -0700
    Subject: [PATCH 84/89] fix cache locking errors during parallel builds
    
    ---
     .github/workflows/docker.yml |  3 ---
     Dockerfile                   | 16 ++++++++--------
     requirements.txt             |  2 ++
     3 files changed, 10 insertions(+), 11 deletions(-)
    
    diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
    index 9078a9b8..9840f7ae 100644
    --- a/.github/workflows/docker.yml
    +++ b/.github/workflows/docker.yml
    @@ -33,9 +33,6 @@ jobs:
               version: latest
               install: true
               platforms: linux/amd64,linux/arm64,linux/arm/v7
    -          config-inline: |
    -            [worker.oci]
    -            max-parallelism = 1
           
           - name: Builder instance name
             run: echo ${{ steps.buildx.outputs.name }}
    diff --git a/Dockerfile b/Dockerfile
    index ed9838c5..b032a350 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -100,7 +100,7 @@ RUN echo "[*] Setting up $ARCHIVEBOX_USER user uid=${DEFAULT_PUID}..." \
         # https://docs.linuxserver.io/general/understanding-puid-and-pgid
     
     # Install system apt dependencies (adding backports to access more recent apt updates)
    -RUN --mount=type=cache,target=/var/cache/apt \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
         echo "[+] Installing APT base system dependencies for $TARGETPLATFORM..." \
         && echo 'deb https://deb.debian.org/debian bookworm-backports main contrib non-free' >> /etc/apt/sources.list.d/backports.list \
         && mkdir -p /etc/apt/keyrings \
    @@ -117,7 +117,7 @@ RUN --mount=type=cache,target=/var/cache/apt \
     ######### Language Environments ####################################
     
     # Install Node environment
    -RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.npm \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,target=/root/.npm,sharing=locked \
         echo "[+] Installing Node $NODE_VERSION environment in $NODE_MODULES..." \
         && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_VERSION}.x nodistro main" >> /etc/apt/sources.list.d/nodejs.list \
         && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
    @@ -135,7 +135,7 @@ RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.np
         ) | tee -a /VERSION.txt
     
     # Install Python environment
    -RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.cache/pip \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,target=/root/.cache/pip,sharing=locked \
         echo "[+] Setting up Python $PYTHON_VERSION runtime..." \
         # tell PDM to allow using global system python site packages
         # && rm /usr/lib/python3*/EXTERNALLY-MANAGED \
    @@ -156,7 +156,7 @@ RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.ca
     ######### Extractor Dependencies ##################################
     
     # Install apt dependencies
    -RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.cache/pip \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,target=/root/.cache/pip,sharing=locked \
         echo "[+] Installing APT extractor dependencies globally using apt..." \
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    @@ -176,7 +176,7 @@ RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.ca
         ) | tee -a /VERSION.txt
     
     # Install chromium browser using playwright
    -RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.cache/pip --mount=type=cache,target=/root/.cache/ms-playwright \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,target=/root/.cache/pip,sharing=locked --mount=type=cache,target=/root/.cache/ms-playwright \
         echo "[+] Installing Browser binary dependencies to $PLAYWRIGHT_BROWSERS_PATH..." \
         && apt-get update -qq \
         && if [[ "$TARGETPLATFORM" == *amd64* || "$TARGETPLATFORM" == *arm64* ]]; then \
    @@ -204,7 +204,7 @@ RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.ca
     # Install Node dependencies
     WORKDIR "$CODE_DIR"
     COPY --chown=root:root --chmod=755 "package.json" "package-lock.json" "$CODE_DIR/"
    -RUN --mount=type=cache,target=/root/.npm \
    +RUN --mount=type=cache,target=/root/.npm,sharing=locked \
         echo "[+] Installing NPM extractor dependencies from package.json into $NODE_MODULES..." \
         && npm ci --prefer-offline --no-audit --cache /root/.npm \
         && ( \
    @@ -218,7 +218,7 @@ RUN --mount=type=cache,target=/root/.npm \
     # Install ArchiveBox Python dependencies
     WORKDIR "$CODE_DIR"
     COPY --chown=root:root --chmod=755 "./pyproject.toml" "requirements.txt" "$CODE_DIR/"
    -RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.cache/pip \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,target=/root/.cache/pip,sharing=locked \
         echo "[+] Installing PIP ArchiveBox dependencies from requirements.txt for ${TARGETPLATFORM}..." \ 
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    @@ -240,7 +240,7 @@ RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.ca
     
     # Install ArchiveBox Python package from source
     COPY --chown=root:root --chmod=755 "." "$CODE_DIR/"
    -RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/root/.cache/pip \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,target=/root/.cache/pip,sharing=locked \
         echo "[*] Installing PIP ArchiveBox package from $CODE_DIR..." \
         && apt-get update -qq \
         # install C compiler to build deps on platforms that dont have 32-bit wheels available on pypi
    diff --git a/requirements.txt b/requirements.txt
    index f1dacefa..4447c0a5 100644
    --- a/requirements.txt
    +++ b/requirements.txt
    @@ -13,6 +13,7 @@ decorator==5.1.1
     django==3.1.14
     django-auth-ldap==4.1.0
     django-extensions==3.1.5
    +exceptiongroup==1.1.3
     executing==2.0.1
     idna==3.4
     ipython==8.17.2
    @@ -40,6 +41,7 @@ sonic-client==1.0.0
     sqlparse==0.4.4
     stack-data==0.6.3
     traitlets==5.13.0
    +typing-extensions==4.8.0
     tzlocal==5.2
     urllib3==2.0.7
     w3lib==2.1.2
    
    From 00d671240ebe9596c6a2f0e9c5159da9a96e9a1a Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 16:06:19 -0700
    Subject: [PATCH 85/89] use private caches for each architecture build so as
     not to pollute caches with bad binaries
    
    ---
     Dockerfile | 20 ++++++++++----------
     1 file changed, 10 insertions(+), 10 deletions(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index b032a350..68b6158c 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -70,7 +70,7 @@ SHELL ["/bin/bash", "-o", "pipefail", "-o", "errexit", "-o", "errtrace", "-o", "
     # Detect ArchiveBox version number by reading package.json
     COPY --chown=root:root --chmod=755 package.json "$CODE_DIR/"
     RUN grep '"version": ' "${CODE_DIR}/package.json" | awk -F'"' '{print $4}' > /VERSION.txt
    -
    +RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
     
     # Print debug info about build and save it to disk
     RUN (echo "[i] Docker build for ArchiveBox $(cat /VERSION.txt) starting..." \
    @@ -100,7 +100,7 @@ RUN echo "[*] Setting up $ARCHIVEBOX_USER user uid=${DEFAULT_PUID}..." \
         # https://docs.linuxserver.io/general/understanding-puid-and-pgid
     
     # Install system apt dependencies (adding backports to access more recent apt updates)
    -RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=private \
         echo "[+] Installing APT base system dependencies for $TARGETPLATFORM..." \
         && echo 'deb https://deb.debian.org/debian bookworm-backports main contrib non-free' >> /etc/apt/sources.list.d/backports.list \
         && mkdir -p /etc/apt/keyrings \
    @@ -117,7 +117,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
     ######### Language Environments ####################################
     
     # Install Node environment
    -RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,target=/root/.npm,sharing=locked \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=private --mount=type=cache,target=/root/.npm,sharing=private \
         echo "[+] Installing Node $NODE_VERSION environment in $NODE_MODULES..." \
         && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_VERSION}.x nodistro main" >> /etc/apt/sources.list.d/nodejs.list \
         && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
    @@ -135,7 +135,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,t
         ) | tee -a /VERSION.txt
     
     # Install Python environment
    -RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,target=/root/.cache/pip,sharing=locked \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=private --mount=type=cache,target=/root/.cache/pip,sharing=private \
         echo "[+] Setting up Python $PYTHON_VERSION runtime..." \
         # tell PDM to allow using global system python site packages
         # && rm /usr/lib/python3*/EXTERNALLY-MANAGED \
    @@ -156,7 +156,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,t
     ######### Extractor Dependencies ##################################
     
     # Install apt dependencies
    -RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,target=/root/.cache/pip,sharing=locked \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=private --mount=type=cache,target=/root/.cache/pip,sharing=private \
         echo "[+] Installing APT extractor dependencies globally using apt..." \
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    @@ -176,7 +176,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,t
         ) | tee -a /VERSION.txt
     
     # Install chromium browser using playwright
    -RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,target=/root/.cache/pip,sharing=locked --mount=type=cache,target=/root/.cache/ms-playwright \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=private --mount=type=cache,target=/root/.cache/pip,sharing=private --mount=type=cache,target=/root/.cache/ms-playwright \
         echo "[+] Installing Browser binary dependencies to $PLAYWRIGHT_BROWSERS_PATH..." \
         && apt-get update -qq \
         && if [[ "$TARGETPLATFORM" == *amd64* || "$TARGETPLATFORM" == *arm64* ]]; then \
    @@ -204,7 +204,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,t
     # Install Node dependencies
     WORKDIR "$CODE_DIR"
     COPY --chown=root:root --chmod=755 "package.json" "package-lock.json" "$CODE_DIR/"
    -RUN --mount=type=cache,target=/root/.npm,sharing=locked \
    +RUN --mount=type=cache,target=/root/.npm,sharing=private \
         echo "[+] Installing NPM extractor dependencies from package.json into $NODE_MODULES..." \
         && npm ci --prefer-offline --no-audit --cache /root/.npm \
         && ( \
    @@ -218,13 +218,13 @@ RUN --mount=type=cache,target=/root/.npm,sharing=locked \
     # Install ArchiveBox Python dependencies
     WORKDIR "$CODE_DIR"
     COPY --chown=root:root --chmod=755 "./pyproject.toml" "requirements.txt" "$CODE_DIR/"
    -RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,target=/root/.cache/pip,sharing=locked \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=private --mount=type=cache,target=/root/.cache/pip,sharing=private \
         echo "[+] Installing PIP ArchiveBox dependencies from requirements.txt for ${TARGETPLATFORM}..." \ 
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
             build-essential \
             libssl-dev libldap2-dev libsasl2-dev \
    -        python3-ldap python3-msgpack python3-mutagen python3-regex procps \
    +        python3-ldap python3-msgpack python3-mutagen python3-regex python3-pycryptodome procps \
         # && ln -s "$GLOBAL_VENV" "$APP_VENV" \
         # && pdm use --venv in-project \
         # && pdm run python -m ensurepip \
    @@ -240,7 +240,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,t
     
     # Install ArchiveBox Python package from source
     COPY --chown=root:root --chmod=755 "." "$CODE_DIR/"
    -RUN --mount=type=cache,target=/var/cache/apt,sharing=locked --mount=type=cache,target=/root/.cache/pip,sharing=locked \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=private --mount=type=cache,target=/root/.cache/pip,sharing=private \
         echo "[*] Installing PIP ArchiveBox package from $CODE_DIR..." \
         && apt-get update -qq \
         # install C compiler to build deps on platforms that dont have 32-bit wheels available on pypi
    
    From 7283e9b91d553ad66b88fc942124ec4a93756917 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 19:11:14 -0700
    Subject: [PATCH 86/89] fix docker build tags
    
    ---
     bin/build_docker.sh | 40 ++++++++++++++++----------------
     package-lock.json   | 56 ++++++++++++++++++++++-----------------------
     requirements.txt    |  2 --
     3 files changed, 48 insertions(+), 50 deletions(-)
    
    diff --git a/bin/build_docker.sh b/bin/build_docker.sh
    index bcaacbb8..c88ed54c 100755
    --- a/bin/build_docker.sh
    +++ b/bin/build_docker.sh
    @@ -23,14 +23,14 @@ SUPPORTED_PLATFORMS="linux/amd64,linux/arm64,linux/arm/v7"
     TAG_NAME="${1:-$(git rev-parse --abbrev-ref HEAD)}"
     VERSION="$(jq -r '.version' < "$REPO_DIR/package.json")"
     SHORT_VERSION="$(echo "$VERSION" | perl -pe 's/(\d+)\.(\d+)\.(\d+)/$1.$2/g')"
    -REQUIRED_PLATFORMS="${2:-$SUPPORTED_PLATFORMS}"
    +SELECTED_PLATFORMS="${2:-$SUPPORTED_PLATFORMS}"
     
    -echo "[+] Building Docker image: tag=$TAG_NAME version=$SHORT_VERSION arch=$REQUIRED_PLATFORMS"
    +echo "[+] Building Docker image: tag=$TAG_NAME version=$SHORT_VERSION arch=$SELECTED_PLATFORMS"
     
     function check_platforms() {
         INSTALLED_PLATFORMS="$(docker buildx inspect | grep 'Platforms:' )"
     
    -    for REQUIRED_PLATFORM in ${REQUIRED_PLATFORMS//,/$IFS}; do
    +    for REQUIRED_PLATFORM in ${SELECTED_PLATFORMS//,/$IFS}; do
             echo "[+] Checking for: $REQUIRED_PLATFORM..."
             if ! (echo "$INSTALLED_PLATFORMS" | grep -q "$REQUIRED_PLATFORM"); then
                 return 1
    @@ -48,11 +48,11 @@ function remove_builder() {
     
     function create_builder() {
         docker buildx use xbuilder && return 0
    -    echo "[+] Creating new xbuilder for: $REQUIRED_PLATFORMS"
    +    echo "[+] Creating new xbuilder for: $SELECTED_PLATFORMS"
         echo
     
         # Switch to buildx builder if already present / previously created
    -    docker buildx create --name xbuilder --driver docker-container --bootstrap --use --platform "$REQUIRED_PLATFORMS" || true
    +    docker buildx create --name xbuilder --driver docker-container --bootstrap --use --platform "$SELECTED_PLATFORMS" || true
         docker buildx inspect --bootstrap || true
     }
     
    @@ -77,18 +77,18 @@ pdm export --group=':all' --production --without-hashes -o requirements.txt
     echo "[+] Building archivebox:$VERSION docker image..."
     # docker builder prune
     # docker build . --no-cache -t archivebox-dev \
    -docker buildx build --platform "$REQUIRED_PLATFORMS" --load . \
    -               -t archivebox \
    -               -t archivebox:$TAG_NAME \
    -               -t archivebox:$VERSION \
    -               -t archivebox:$SHORT_VERSION \
    -               -t archivebox:latest \
    -               -t docker.io/nikisweeting/archivebox:$TAG_NAME \
    -               -t docker.io/nikisweeting/archivebox:$VERSION \
    -               -t docker.io/nikisweeting/archivebox:$SHORT_VERSION \
    -               -t docker.io/archivebox/archivebox:$TAG_NAME \
    -               -t docker.io/archivebox/archivebox:$VERSION \
    -               -t docker.io/archivebox/archivebox:$SHORT_VERSION \
    -               -t docker.pkg.github.com/archivebox/archivebox/archivebox:$TAG_NAME \
    -               -t docker.pkg.github.com/archivebox/archivebox/archivebox:$VERSION \
    -               -t docker.pkg.github.com/archivebox/archivebox/archivebox:$SHORT_VERSION
    +# replace --load with --push to deploy
    +docker buildx build --platform "$SELECTED_PLATFORMS" --load . \
    +               -t archivebox/archivebox \
    +               -t archivebox/archivebox:$TAG_NAME \
    +               -t archivebox/archivebox:$VERSION \
    +               -t archivebox/archivebox:$SHORT_VERSION \
    +               -t archivebox/archivebox:latest \
    +               -t nikisweeting/archivebox \
    +               -t nikisweeting/archivebox:$TAG_NAME \
    +               -t nikisweeting/archivebox:$VERSION \
    +               -t nikisweeting/archivebox:$SHORT_VERSION \
    +               -t nikisweeting/archivebox:latest \
    +               -t ghcr.io/archivebox/archivebox/archivebox:$TAG_NAME \
    +               -t ghcr.io/archivebox/archivebox/archivebox:$VERSION \
    +               -t ghcr.io/archivebox/archivebox/archivebox:$SHORT_VERSION
    diff --git a/package-lock.json b/package-lock.json
    index 484fc4e7..a4d3dc21 100644
    --- a/package-lock.json
    +++ b/package-lock.json
    @@ -226,12 +226,12 @@
           "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="
         },
         "node_modules/@types/node": {
    -      "version": "20.8.7",
    -      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.7.tgz",
    -      "integrity": "sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==",
    +      "version": "20.8.10",
    +      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.10.tgz",
    +      "integrity": "sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w==",
           "optional": true,
           "dependencies": {
    -        "undici-types": "~5.25.1"
    +        "undici-types": "~5.26.4"
           }
         },
         "node_modules/@types/yauzl": {
    @@ -249,9 +249,9 @@
           "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA=="
         },
         "node_modules/acorn": {
    -      "version": "8.10.0",
    -      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
    -      "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
    +      "version": "8.11.2",
    +      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz",
    +      "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==",
           "bin": {
             "acorn": "bin/acorn"
           },
    @@ -269,9 +269,9 @@
           }
         },
         "node_modules/acorn-walk": {
    -      "version": "8.2.0",
    -      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
    -      "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
    +      "version": "8.3.0",
    +      "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.0.tgz",
    +      "integrity": "sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==",
           "engines": {
             "node": ">=0.4.0"
           }
    @@ -1793,9 +1793,9 @@
           }
         },
         "node_modules/punycode": {
    -      "version": "2.3.0",
    -      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
    -      "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
    +      "version": "2.3.1",
    +      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
    +      "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
           "engines": {
             "node": ">=6"
           }
    @@ -1855,8 +1855,8 @@
           "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag=="
         },
         "node_modules/readability-extractor": {
    -      "version": "0.0.8",
    -      "resolved": "git+ssh://git@github.com/ArchiveBox/readability-extractor.git#fd0c971ea15c69338aad38871b5246fc474f6152",
    +      "version": "0.0.9",
    +      "resolved": "git+ssh://git@github.com/ArchiveBox/readability-extractor.git#e614ba08c4e024db75f8c746b8f4634f16ae2f50",
           "license": "MIT",
           "dependencies": {
             "@mozilla/readability": "^0.4.4",
    @@ -1971,16 +1971,16 @@
           "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
         },
         "node_modules/single-file-cli": {
    -      "version": "1.1.12",
    -      "resolved": "https://registry.npmjs.org/single-file-cli/-/single-file-cli-1.1.12.tgz",
    -      "integrity": "sha512-CTMqoCnHgB/duMU10SwA6v9uqG511GItVghLDTv1lTVa4JRwJ4qpsiz7KWXYQh5QyefQJHFVVxzSNWDVpNJC4w==",
    +      "version": "1.1.18",
    +      "resolved": "https://registry.npmjs.org/single-file-cli/-/single-file-cli-1.1.18.tgz",
    +      "integrity": "sha512-M60Mm385w2dvESNdGrFlrJoK3Cln011y8n3g3myRH7XQcuiuBQB2hVP1DDlpqOGRePDpayVFgDflSnRMMf0klQ==",
           "dependencies": {
             "file-url": "3.0.0",
             "iconv-lite": "0.6.3",
             "jsdom": "22.1.0",
             "puppeteer-core": "21.2.1",
             "selenium-webdriver": "4.12.0",
    -        "single-file-core": "1.2.13",
    +        "single-file-core": "1.2.22",
             "strong-data-uri": "1.0.6",
             "yargs": "17.7.2"
           },
    @@ -2064,9 +2064,9 @@
           }
         },
         "node_modules/single-file-core": {
    -      "version": "1.2.13",
    -      "resolved": "https://registry.npmjs.org/single-file-core/-/single-file-core-1.2.13.tgz",
    -      "integrity": "sha512-QO9wfaajBii670m5mmjslrpCxmK9gkiGUg3XSTLtG4YN9k7t6EAhSORpjg5N/DwZk0seEZqXTorPp6aN9c6lYA=="
    +      "version": "1.2.22",
    +      "resolved": "https://registry.npmjs.org/single-file-core/-/single-file-core-1.2.22.tgz",
    +      "integrity": "sha512-2XDxfZFWkUf391vx4R6FwIJcwTJKCBg+g8EKzp9a9ef8JZgomWeO4WwPhE7N9+aYBE15pzR9gcHRvVieI8/2FA=="
         },
         "node_modules/smart-buffer": {
           "version": "4.2.0",
    @@ -2161,9 +2161,9 @@
           }
         },
         "node_modules/streamx": {
    -      "version": "2.15.1",
    -      "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.1.tgz",
    -      "integrity": "sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==",
    +      "version": "2.15.2",
    +      "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.15.2.tgz",
    +      "integrity": "sha512-b62pAV/aeMjUoRN2C/9F0n+G8AfcJjNC0zw/ZmOHeFsIe4m4GzjVW9m6VHXVjk536NbdU9JRwKMJRfkc+zUFTg==",
           "dependencies": {
             "fast-fifo": "^1.1.0",
             "queue-tick": "^1.0.1"
    @@ -2313,9 +2313,9 @@
           }
         },
         "node_modules/undici-types": {
    -      "version": "5.25.3",
    -      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
    -      "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==",
    +      "version": "5.26.5",
    +      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
    +      "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
           "optional": true
         },
         "node_modules/universalify": {
    diff --git a/requirements.txt b/requirements.txt
    index 4447c0a5..f1dacefa 100644
    --- a/requirements.txt
    +++ b/requirements.txt
    @@ -13,7 +13,6 @@ decorator==5.1.1
     django==3.1.14
     django-auth-ldap==4.1.0
     django-extensions==3.1.5
    -exceptiongroup==1.1.3
     executing==2.0.1
     idna==3.4
     ipython==8.17.2
    @@ -41,7 +40,6 @@ sonic-client==1.0.0
     sqlparse==0.4.4
     stack-data==0.6.3
     traitlets==5.13.0
    -typing-extensions==4.8.0
     tzlocal==5.2
     urllib3==2.0.7
     w3lib==2.1.2
    
    From db733151f71da03e7994b96583549ae32f2f6748 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 19:16:15 -0700
    Subject: [PATCH 87/89] bump user agent browser version
    
    ---
     archivebox/config.py | 6 +++---
     1 file changed, 3 insertions(+), 3 deletions(-)
    
    diff --git a/archivebox/config.py b/archivebox/config.py
    index 67d84d93..18e06f1f 100644
    --- a/archivebox/config.py
    +++ b/archivebox/config.py
    @@ -158,9 +158,9 @@ CONFIG_SCHEMA: Dict[str, ConfigDefaultDict] = {
             'CHECK_SSL_VALIDITY':       {'type': bool,  'default': True},
             'MEDIA_MAX_SIZE':           {'type': str,   'default': '750m'},
     
    -        'CURL_USER_AGENT':          {'type': str,   'default': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/605.1.15 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/) curl/{CURL_VERSION}'},
    -        'WGET_USER_AGENT':          {'type': str,   'default': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/605.1.15 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/) wget/{WGET_VERSION}'},
    -        'CHROME_USER_AGENT':        {'type': str,   'default': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/605.1.15 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)'},
    +        'CURL_USER_AGENT':          {'type': str,   'default': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/) curl/{CURL_VERSION}'},
    +        'WGET_USER_AGENT':          {'type': str,   'default': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/) wget/{WGET_VERSION}'},
    +        'CHROME_USER_AGENT':        {'type': str,   'default': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36 ArchiveBox/{VERSION} (+https://github.com/ArchiveBox/ArchiveBox/)'},
     
             'COOKIES_FILE':             {'type': str,   'default': None},
             'CHROME_USER_DATA_DIR':     {'type': str,   'default': None},
    
    From 57f033be60463f54fdd4874dd2329002c9489061 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 19:43:01 -0700
    Subject: [PATCH 88/89] add targetos to build args
    
    ---
     Dockerfile | 3 +++
     1 file changed, 3 insertions(+)
    
    diff --git a/Dockerfile b/Dockerfile
    index 68b6158c..533113a3 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -25,6 +25,7 @@ LABEL name="archivebox" \
         documentation="https://github.com/ArchiveBox/ArchiveBox/wiki/Docker#docker"
     
     ARG TARGETPLATFORM
    +ARG TARGETOS
     ARG TARGETARCH
     ARG TARGETVARIANT
     
    @@ -70,6 +71,8 @@ SHELL ["/bin/bash", "-o", "pipefail", "-o", "errexit", "-o", "errtrace", "-o", "
     # Detect ArchiveBox version number by reading package.json
     COPY --chown=root:root --chmod=755 package.json "$CODE_DIR/"
     RUN grep '"version": ' "${CODE_DIR}/package.json" | awk -F'"' '{print $4}' > /VERSION.txt
    +
    +# Force apt to leave downloaded binaries in /var/cache/apt (massively speeds up Docker builds)
     RUN rm -f /etc/apt/apt.conf.d/docker-clean; echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
     
     # Print debug info about build and save it to disk
    
    From c6e5a565c0b040358ab326d59f329c549e7f6ce0 Mon Sep 17 00:00:00 2001
    From: Nick Sweeting <git@sweeting.me>
    Date: Tue, 31 Oct 2023 19:43:41 -0700
    Subject: [PATCH 89/89] switch back to locked cache instead of private but put
     targetarch in cache id to separate them
    
    ---
     Dockerfile            | 18 +++++++++---------
     bin/release_docker.sh | 37 ++++++++++++++++++++++++++++---------
     2 files changed, 37 insertions(+), 18 deletions(-)
    
    diff --git a/Dockerfile b/Dockerfile
    index 533113a3..10ea86cb 100644
    --- a/Dockerfile
    +++ b/Dockerfile
    @@ -103,7 +103,7 @@ RUN echo "[*] Setting up $ARCHIVEBOX_USER user uid=${DEFAULT_PUID}..." \
         # https://docs.linuxserver.io/general/understanding-puid-and-pgid
     
     # Install system apt dependencies (adding backports to access more recent apt updates)
    -RUN --mount=type=cache,target=/var/cache/apt,sharing=private \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=apt-$TARGETARCH$TARGETVARIANT \
         echo "[+] Installing APT base system dependencies for $TARGETPLATFORM..." \
         && echo 'deb https://deb.debian.org/debian bookworm-backports main contrib non-free' >> /etc/apt/sources.list.d/backports.list \
         && mkdir -p /etc/apt/keyrings \
    @@ -120,7 +120,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=private \
     ######### Language Environments ####################################
     
     # Install Node environment
    -RUN --mount=type=cache,target=/var/cache/apt,sharing=private --mount=type=cache,target=/root/.npm,sharing=private \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=apt-$TARGETARCH$TARGETVARIANT --mount=type=cache,target=/root/.npm,sharing=locked,id=npm-$TARGETARCH$TARGETVARIANT \
         echo "[+] Installing Node $NODE_VERSION environment in $NODE_MODULES..." \
         && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_${NODE_VERSION}.x nodistro main" >> /etc/apt/sources.list.d/nodejs.list \
         && curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \
    @@ -138,7 +138,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=private --mount=type=cache,
         ) | tee -a /VERSION.txt
     
     # Install Python environment
    -RUN --mount=type=cache,target=/var/cache/apt,sharing=private --mount=type=cache,target=/root/.cache/pip,sharing=private \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=apt-$TARGETARCH$TARGETVARIANT --mount=type=cache,target=/root/.cache/pip,sharing=locked,id=pip-$TARGETARCH$TARGETVARIANT \
         echo "[+] Setting up Python $PYTHON_VERSION runtime..." \
         # tell PDM to allow using global system python site packages
         # && rm /usr/lib/python3*/EXTERNALLY-MANAGED \
    @@ -147,7 +147,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=private --mount=type=cache,
         # && python3 -m venv --system-site-packages $GLOBAL_VENV \
         # && python3 -m venv $GLOBAL_VENV \
         # install global dependencies / python build dependencies in GLOBAL_VENV
    -    && pip install --upgrade pip setuptools wheel \
    +    # && pip install --upgrade pip setuptools wheel \
         # Save version info
         && ( \
             which python3 && python3 --version | grep " $PYTHON_VERSION" \
    @@ -159,7 +159,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=private --mount=type=cache,
     ######### Extractor Dependencies ##################################
     
     # Install apt dependencies
    -RUN --mount=type=cache,target=/var/cache/apt,sharing=private --mount=type=cache,target=/root/.cache/pip,sharing=private \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=apt-$TARGETARCH$TARGETVARIANT --mount=type=cache,target=/root/.cache/pip,sharing=locked,id=pip-$TARGETARCH$TARGETVARIANT \
         echo "[+] Installing APT extractor dependencies globally using apt..." \
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    @@ -179,7 +179,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=private --mount=type=cache,
         ) | tee -a /VERSION.txt
     
     # Install chromium browser using playwright
    -RUN --mount=type=cache,target=/var/cache/apt,sharing=private --mount=type=cache,target=/root/.cache/pip,sharing=private --mount=type=cache,target=/root/.cache/ms-playwright \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=apt-$TARGETARCH$TARGETVARIANT --mount=type=cache,target=/root/.cache/pip,sharing=locked,id=pip-$TARGETARCH$TARGETVARIANT --mount=type=cache,target=/root/.cache/ms-playwright,sharing=locked,id=browsers-$TARGETARCH$TARGETVARIANT \
         echo "[+] Installing Browser binary dependencies to $PLAYWRIGHT_BROWSERS_PATH..." \
         && apt-get update -qq \
         && if [[ "$TARGETPLATFORM" == *amd64* || "$TARGETPLATFORM" == *arm64* ]]; then \
    @@ -207,7 +207,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=private --mount=type=cache,
     # Install Node dependencies
     WORKDIR "$CODE_DIR"
     COPY --chown=root:root --chmod=755 "package.json" "package-lock.json" "$CODE_DIR/"
    -RUN --mount=type=cache,target=/root/.npm,sharing=private \
    +RUN --mount=type=cache,target=/root/.npm,sharing=locked,id=npm-$TARGETARCH$TARGETVARIANT \
         echo "[+] Installing NPM extractor dependencies from package.json into $NODE_MODULES..." \
         && npm ci --prefer-offline --no-audit --cache /root/.npm \
         && ( \
    @@ -221,7 +221,7 @@ RUN --mount=type=cache,target=/root/.npm,sharing=private \
     # Install ArchiveBox Python dependencies
     WORKDIR "$CODE_DIR"
     COPY --chown=root:root --chmod=755 "./pyproject.toml" "requirements.txt" "$CODE_DIR/"
    -RUN --mount=type=cache,target=/var/cache/apt,sharing=private --mount=type=cache,target=/root/.cache/pip,sharing=private \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=apt-$TARGETARCH$TARGETVARIANT --mount=type=cache,target=/root/.cache/pip,sharing=locked,id=pip-$TARGETARCH$TARGETVARIANT \
         echo "[+] Installing PIP ArchiveBox dependencies from requirements.txt for ${TARGETPLATFORM}..." \ 
         && apt-get update -qq \
         && apt-get install -qq -y -t bookworm-backports --no-install-recommends \
    @@ -243,7 +243,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=private --mount=type=cache,
     
     # Install ArchiveBox Python package from source
     COPY --chown=root:root --chmod=755 "." "$CODE_DIR/"
    -RUN --mount=type=cache,target=/var/cache/apt,sharing=private --mount=type=cache,target=/root/.cache/pip,sharing=private \
    +RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=apt-$TARGETARCH$TARGETVARIANT --mount=type=cache,target=/root/.cache/pip,sharing=locked,id=pip-$TARGETARCH$TARGETVARIANT \
         echo "[*] Installing PIP ArchiveBox package from $CODE_DIR..." \
         && apt-get update -qq \
         # install C compiler to build deps on platforms that dont have 32-bit wheels available on pypi
    diff --git a/bin/release_docker.sh b/bin/release_docker.sh
    index 7855cb1c..15e1b666 100755
    --- a/bin/release_docker.sh
    +++ b/bin/release_docker.sh
    @@ -11,16 +11,35 @@ set -o pipefail
     IFS=$'\n'
     
     REPO_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd .. && pwd )"
    -VERSION="$(jq -r '.version' < "$REPO_DIR/package.json")"
    -SHORT_VERSION="$(echo "$VERSION" | perl -pe 's/(\d+)\.(\d+)\.(\d+)/$1.$2/g')"
     cd "$REPO_DIR"
     
    -echo "[*] Logging in to Docker Hub & Github Container Registry"
    -docker login --username=nikisweeting
    -docker login docker.pkg.github.com --username=pirate
    +SUPPORTED_PLATFORMS="linux/amd64,linux/arm64,linux/arm/v7"
    +
    +TAG_NAME="${1:-$(git rev-parse --abbrev-ref HEAD)}"
    +VERSION="$(jq -r '.version' < "$REPO_DIR/package.json")"
    +SHORT_VERSION="$(echo "$VERSION" | perl -pe 's/(\d+)\.(\d+)\.(\d+)/$1.$2/g')"
    +SELECTED_PLATFORMS="${2:-$SUPPORTED_PLATFORMS}"
    +
    +
    +# echo "[*] Logging in to Docker Hub & Github Container Registry"
    +# docker login --username=nikisweeting
    +# docker login ghcr.io --username=pirate
    +
    +echo "[^] Building docker image"
    +./bin/build_docker.sh "$TAG_NAME" "$SELECTED_PLATFORMS"
     
     echo "[^] Uploading docker image"
    -docker push archivebox/archivebox:$VERSION archivebox/archivebox:$SHORT_VERSION archivebox/archivebox:latest
    -docker push docker.io/nikisweeting/archivebox
    -docker push docker.io/archivebox/archivebox
    -docker push docker.pkg.github.com/archivebox/archivebox/archivebox
    +docker buildx build --platform "$SELECTED_PLATFORMS" --push . \
    +               -t archivebox/archivebox \
    +               -t archivebox/archivebox:$TAG_NAME \
    +               -t archivebox/archivebox:$VERSION \
    +               -t archivebox/archivebox:$SHORT_VERSION \
    +               -t archivebox/archivebox:latest \
    +               -t nikisweeting/archivebox \
    +               -t nikisweeting/archivebox:$TAG_NAME \
    +               -t nikisweeting/archivebox:$VERSION \
    +               -t nikisweeting/archivebox:$SHORT_VERSION \
    +               -t nikisweeting/archivebox:latest \
    +               -t ghcr.io/archivebox/archivebox/archivebox:$TAG_NAME \
    +               -t ghcr.io/archivebox/archivebox/archivebox:$VERSION \
    +               -t ghcr.io/archivebox/archivebox/archivebox:$SHORT_VERSION
    \ No newline at end of file