From 5be033d2f87de551d739a2f85ce05f7cfd6f6311 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Mon, 29 Apr 2024 16:47:04 -0700 Subject: [PATCH 01/43] Nick: init --- .../rag/extractor/entity/datasource_type.py | 1 + .../rag/extractor/entity/extract_setting.py | 19 +++ api/core/rag/extractor/extract_processor.py | 8 ++ .../rag/extractor/firecrawl/firecrawl_app.py | 136 ++++++++++++++++++ .../rag/extractor/firecrawl/web_extractor.py | 54 +++++++ api/libs/bearer_data_source.py | 53 +++++++ 6 files changed, 271 insertions(+) create mode 100644 api/core/rag/extractor/firecrawl/firecrawl_app.py create mode 100644 api/core/rag/extractor/firecrawl/web_extractor.py create mode 100644 api/libs/bearer_data_source.py diff --git a/api/core/rag/extractor/entity/datasource_type.py b/api/core/rag/extractor/entity/datasource_type.py index 2c79e7b97b18d8..902835571d94f4 100644 --- a/api/core/rag/extractor/entity/datasource_type.py +++ b/api/core/rag/extractor/entity/datasource_type.py @@ -4,3 +4,4 @@ class DatasourceType(Enum): FILE = "upload_file" NOTION = "notion_import" + URL = "url" diff --git a/api/core/rag/extractor/entity/extract_setting.py b/api/core/rag/extractor/entity/extract_setting.py index 49cd4d0c033143..688bf7250c0927 100644 --- a/api/core/rag/extractor/entity/extract_setting.py +++ b/api/core/rag/extractor/entity/extract_setting.py @@ -20,6 +20,24 @@ class Config: def __init__(self, **data) -> None: super().__init__(**data) +class FirecrawlInfo(BaseModel): + """ + Firecrawl import info. + """ + url: str + mode: str + # [Review] Not sure if api key and base url belong here. + firecrawl_api_key: str # should this even be here? + firecrawl_base_url: str = 'https://api.firecrawl.dev' # should this even be here? + document: Document = None + tenant_id: str + + class Config: + arbitrary_types_allowed = True + + def __init__(self, **data) -> None: + super().__init__(**data) + class ExtractSetting(BaseModel): """ @@ -28,6 +46,7 @@ class ExtractSetting(BaseModel): datasource_type: str upload_file: UploadFile = None notion_info: NotionInfo = None + firecrawl_info: FirecrawlInfo = None document_model: str = None class Config: diff --git a/api/core/rag/extractor/extract_processor.py b/api/core/rag/extractor/extract_processor.py index 1136e11f765246..b11232f727eb6e 100644 --- a/api/core/rag/extractor/extract_processor.py +++ b/api/core/rag/extractor/extract_processor.py @@ -9,6 +9,7 @@ from core.rag.extractor.entity.datasource_type import DatasourceType from core.rag.extractor.entity.extract_setting import ExtractSetting from core.rag.extractor.excel_extractor import ExcelExtractor +from core.rag.extractor.firecrawl.web_extractor import FirecrawlWebExtractor from core.rag.extractor.html_extractor import HtmlExtractor from core.rag.extractor.markdown_extractor import MarkdownExtractor from core.rag.extractor.notion_extractor import NotionExtractor @@ -141,5 +142,12 @@ def extract(cls, extract_setting: ExtractSetting, is_automatic: bool = False, tenant_id=extract_setting.notion_info.tenant_id, ) return extractor.extract() + elif extract_setting.datasource_type == DatasourceType.URL.value: + # [Review] Not sure if api key and base url belong here. + extractor = FirecrawlWebExtractor( + api_key=extract_setting.firecrawl_info.firecrawl_api_key, + base_url=extract_setting.firecrawl_info.firecrawl_base_url, + url=extract_setting.firecrawl_info.url, mode=extract_setting.firecrawl_info.mode) + return extractor.extract() else: raise ValueError(f"Unsupported datasource type: {extract_setting.datasource_type}") diff --git a/api/core/rag/extractor/firecrawl/firecrawl_app.py b/api/core/rag/extractor/firecrawl/firecrawl_app.py new file mode 100644 index 00000000000000..1af8778353764d --- /dev/null +++ b/api/core/rag/extractor/firecrawl/firecrawl_app.py @@ -0,0 +1,136 @@ +import os +import requests +import time + +class FirecrawlApp: + def __init__(self, api_key=None, base_url='https://api.firecrawl.dev'): + self.api_key = api_key or os.getenv('FIRECRAWL_API_KEY') + self.base_url = base_url + if self.api_key is None: + raise ValueError('No API key provided') + + def scrape_url(self, url, params=None): + headers = { + 'Content-Type': 'application/json', + 'Authorization': f'Bearer {self.api_key}' + } + json_data = {'url': url} + if params: + json_data.update(params) + response = requests.post( + f'{self.base_url}/v0/scrape', + headers=headers, + json=json_data + ) + if response.status_code == 200: + response = response.json() + if response['success'] == True: + return response['data'] + else: + raise Exception(f'Failed to scrape URL. Error: {response["error"]}') + + elif response.status_code in [402, 409, 500]: + error_message = response.json().get('error', 'Unknown error occurred') + raise Exception(f'Failed to scrape URL. Status code: {response.status_code}. Error: {error_message}') + else: + raise Exception(f'Failed to scrape URL. Status code: {response.status_code}') + + def search(self, query, params=None): + headers = { + 'Content-Type': 'application/json', + 'Authorization': f'Bearer {self.api_key}' + } + json_data = {'query': query} + if params: + json_data.update(params) + response = requests.post( + f'{self.base_url}/v0/search', + headers=headers, + json=json_data + ) + if response.status_code == 200: + response = response.json() + if response['success'] == True: + return response['data'] + else: + raise Exception(f'Failed to search. Error: {response["error"]}') + + elif response.status_code in [402, 409, 500]: + error_message = response.json().get('error', 'Unknown error occurred') + raise Exception(f'Failed to search. Status code: {response.status_code}. Error: {error_message}') + else: + raise Exception(f'Failed to search. Status code: {response.status_code}') + + def crawl_url(self, url, params=None, wait_until_done=True, timeout=2): + headers = self._prepare_headers() + json_data = {'url': url} + if params: + json_data.update(params) + response = self._post_request(f'{self.base_url}/v0/crawl', json_data, headers) + if response.status_code == 200: + job_id = response.json().get('jobId') + if wait_until_done: + return self._monitor_job_status(job_id, headers, timeout) + else: + return {'jobId': job_id} + else: + self._handle_error(response, 'start crawl job') + + def check_crawl_status(self, job_id): + headers = self._prepare_headers() + response = self._get_request(f'{self.base_url}/v0/crawl/status/{job_id}', headers) + if response.status_code == 200: + return response.json() + else: + self._handle_error(response, 'check crawl status') + + def _prepare_headers(self): + return { + 'Content-Type': 'application/json', + 'Authorization': f'Bearer {self.api_key}' + } + + def _post_request(self, url, data, headers, retries=3, backoff_factor=0.5): + for attempt in range(retries): + response = requests.post(url, headers=headers, json=data) + if response.status_code == 502: + time.sleep(backoff_factor * (2 ** attempt)) + else: + return response + return response + + def _get_request(self, url, headers, retries=3, backoff_factor=0.5): + for attempt in range(retries): + response = requests.get(url, headers=headers) + if response.status_code == 502: + time.sleep(backoff_factor * (2 ** attempt)) + else: + return response + return response + + def _monitor_job_status(self, job_id, headers, timeout): + import time + while True: + status_response = self._get_request(f'{self.base_url}/v0/crawl/status/{job_id}', headers) + if status_response.status_code == 200: + status_data = status_response.json() + if status_data['status'] == 'completed': + if 'data' in status_data: + return status_data['data'] + else: + raise Exception('Crawl job completed but no data was returned') + elif status_data['status'] in ['active', 'paused', 'pending', 'queued']: + if timeout < 2: + timeout = 2 + time.sleep(timeout) # Wait for the specified timeout before checking again + else: + raise Exception(f'Crawl job failed or was stopped. Status: {status_data["status"]}') + else: + self._handle_error(status_response, 'check crawl status') + + def _handle_error(self, response, action): + if response.status_code in [402, 409, 500]: + error_message = response.json().get('error', 'Unknown error occurred') + raise Exception(f'Failed to {action}. Status code: {response.status_code}. Error: {error_message}') + else: + raise Exception(f'Unexpected error occurred while trying to {action}. Status code: {response.status_code}') diff --git a/api/core/rag/extractor/firecrawl/web_extractor.py b/api/core/rag/extractor/firecrawl/web_extractor.py new file mode 100644 index 00000000000000..5b822c0d337745 --- /dev/null +++ b/api/core/rag/extractor/firecrawl/web_extractor.py @@ -0,0 +1,54 @@ +"""Abstract interface for document loader implementations.""" +from core.rag.extractor.extractor_base import BaseExtractor +from core.rag.models.document import Document +from api.core.rag.extractor.firecrawl.firecrawl_app import FirecrawlApp + + +class FirecrawlWebExtractor(BaseExtractor): + + """ + Load html files. + + + Args: + url: The URL to scrape. + api_key: The API key for Firecrawl. + base_url: The base URL for the Firecrawl API. Defaults to 'https://api.firecrawl.dev'. + mode: The mode of operation. Defaults to 'scrape'. Options are 'crawl', 'scrape' and 'crawl_return_urls'. + """ + + + def __init__( + self, + url: str, + api_key: str, + base_url: str = 'https://api.firecrawl.dev', + mode: str = 'scrape', + ): + """Initialize with url, api_key, base_url and mode.""" + self._url = url + self._api_key = api_key + self._base_url = base_url + self._mode = mode + self._firecrawl_app = FirecrawlApp(api_key=self._api_key, base_url=self._base_url) + + def extract(self) -> list[Document]: + if self._mode == 'scrape': + content = self._scrape_url() + return [Document(page_content=content.get('markdown', ''))] + elif self._mode == 'crawl': + pages = self._crawl_url() + return [Document(page_content=page.get('markdown', '')) for page in pages] + elif self._mode == 'crawl_return_urls': + urls = self._crawl_url(return_only_urls=True) + return [Document(page_content=url) for url in urls] + + def _scrape_url(self): + return self._firecrawl_app.scrape_url(self._url) + + def _crawl_url(self, return_only_urls=False): + return self._firecrawl_app.crawl_url(self._url, { + "crawlerOptions": { + "returnOnlyUrls": return_only_urls + } + }) diff --git a/api/libs/bearer_data_source.py b/api/libs/bearer_data_source.py new file mode 100644 index 00000000000000..22da5bf10ab833 --- /dev/null +++ b/api/libs/bearer_data_source.py @@ -0,0 +1,53 @@ +import requests +import time +from typing import Iterator, Literal, Optional + +class BearerDataSource: + def __init__(self, api_key: str): + self.api_key = api_key + + def access_token(self) -> str: + raise NotImplementedError() + + +class FireCrawlDataSource(BearerDataSource): + _FIRECRAWL_API_URL = 'https://api.firecrawl.dev/v0' + + def __init__(self, api_key: str, mode: Literal["crawl", "scrape"] = "crawl"): + super().__init__(api_key) + self.mode = mode + + def access_token(self) -> str: + return self.api_key + + def get_page_content(self, url: str): + if self.mode not in ("crawl", "scrape"): + raise ValueError( + f"Unrecognized mode '{self.mode}'. Expected one of 'crawl', 'scrape'." + ) + headers = { + 'Content-Type': 'application/json', + 'Authorization': f'Bearer {self.api_key}' + } + if self.mode == "scrape": + response = requests.post(f'{self._FIRECRAWL_API_URL}/scrape', headers=headers, json={"url": url}) + data = response.json().get('data', {}) + return { + 'page_content': data.get('markdown', ''), + 'metadata': data.get('metadata', {}) + } + elif self.mode == "crawl": + response = requests.post(f'{self._FIRECRAWL_API_URL}/crawl', headers=headers, json={"url": url}) + job_id = response.json().get('jobId') + while True: + response = requests.get(f'{self._FIRECRAWL_API_URL}/crawl/status/{job_id}', headers=headers) + data = response.json() + if data.get('status') == 'completed': + break + time.sleep(5) # wait for 5 seconds before checking the status again + return [ + { + 'page_content': doc.get('markdown', ''), + 'metadata': doc.get('metadata', {}) + } for doc in data.get('data', []) + ] From bd2fbbe87dcf6f8b84fea8f134f101fbb5c28e41 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Mon, 29 Apr 2024 16:48:09 -0700 Subject: [PATCH 02/43] Nick: more readable --- api/core/rag/extractor/extract_processor.py | 2 +- .../firecrawl/{web_extractor.py => firecrawl_web_extractor.py} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename api/core/rag/extractor/firecrawl/{web_extractor.py => firecrawl_web_extractor.py} (100%) diff --git a/api/core/rag/extractor/extract_processor.py b/api/core/rag/extractor/extract_processor.py index b11232f727eb6e..85bb3bef853ba2 100644 --- a/api/core/rag/extractor/extract_processor.py +++ b/api/core/rag/extractor/extract_processor.py @@ -9,7 +9,7 @@ from core.rag.extractor.entity.datasource_type import DatasourceType from core.rag.extractor.entity.extract_setting import ExtractSetting from core.rag.extractor.excel_extractor import ExcelExtractor -from core.rag.extractor.firecrawl.web_extractor import FirecrawlWebExtractor +from api.core.rag.extractor.firecrawl.firecrawl_web_extractor import FirecrawlWebExtractor from core.rag.extractor.html_extractor import HtmlExtractor from core.rag.extractor.markdown_extractor import MarkdownExtractor from core.rag.extractor.notion_extractor import NotionExtractor diff --git a/api/core/rag/extractor/firecrawl/web_extractor.py b/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py similarity index 100% rename from api/core/rag/extractor/firecrawl/web_extractor.py rename to api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py From b318b5e171b7f3ba0da59eed047c68d64d3bd051 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Mon, 29 Apr 2024 17:19:55 -0700 Subject: [PATCH 03/43] Nick: added tests and envs --- api/.env.example | 6 ++- .../rag/extractor/entity/extract_setting.py | 9 ++-- .../firecrawl/firecrawl_web_extractor.py | 25 +++++++---- api/libs/bearer_data_source.py | 45 ++----------------- api/pyproject.toml | 4 +- .../unit_tests/core/rag/extractor/__init__.py | 0 .../core/rag/extractor/firecrawl/__init__.py | 0 .../rag/extractor/firecrawl/test_firecrawl.py | 35 +++++++++++++++ 8 files changed, 69 insertions(+), 55 deletions(-) create mode 100644 api/tests/unit_tests/core/rag/extractor/__init__.py create mode 100644 api/tests/unit_tests/core/rag/extractor/firecrawl/__init__.py create mode 100644 api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py diff --git a/api/.env.example b/api/.env.example index c61cb60d3ebff9..6e3cb581c53385 100644 --- a/api/.env.example +++ b/api/.env.example @@ -145,4 +145,8 @@ API_TOOL_DEFAULT_CONNECT_TIMEOUT=10 API_TOOL_DEFAULT_READ_TIMEOUT=60 # Log file path -LOG_FILE= \ No newline at end of file +LOG_FILE= + +# Firecrawl Web Extractor +FIRECRAWL_API_KEY= + diff --git a/api/core/rag/extractor/entity/extract_setting.py b/api/core/rag/extractor/entity/extract_setting.py index 688bf7250c0927..02ae80b27aeffc 100644 --- a/api/core/rag/extractor/entity/extract_setting.py +++ b/api/core/rag/extractor/entity/extract_setting.py @@ -20,15 +20,18 @@ class Config: def __init__(self, **data) -> None: super().__init__(**data) +import os + class FirecrawlInfo(BaseModel): """ Firecrawl import info. """ url: str mode: str - # [Review] Not sure if api key and base url belong here. - firecrawl_api_key: str # should this even be here? - firecrawl_base_url: str = 'https://api.firecrawl.dev' # should this even be here? + ## [Review] Not sure if these belong here + firecrawl_api_key: str + firecrawl_base_url: str + ## --- document: Document = None tenant_id: str diff --git a/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py b/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py index 5b822c0d337745..05088cb48db942 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py @@ -1,7 +1,8 @@ """Abstract interface for document loader implementations.""" +import os from core.rag.extractor.extractor_base import BaseExtractor from core.rag.models.document import Document -from api.core.rag.extractor.firecrawl.firecrawl_app import FirecrawlApp +from core.rag.extractor.firecrawl.firecrawl_app import FirecrawlApp class FirecrawlWebExtractor(BaseExtractor): @@ -33,15 +34,23 @@ def __init__( self._firecrawl_app = FirecrawlApp(api_key=self._api_key, base_url=self._base_url) def extract(self) -> list[Document]: + documents = [] if self._mode == 'scrape': content = self._scrape_url() - return [Document(page_content=content.get('markdown', ''))] - elif self._mode == 'crawl': - pages = self._crawl_url() - return [Document(page_content=page.get('markdown', '')) for page in pages] - elif self._mode == 'crawl_return_urls': - urls = self._crawl_url(return_only_urls=True) - return [Document(page_content=url) for url in urls] + if content: + documents.append(self._create_document(content)) + elif self._mode in ['crawl', 'crawl_return_urls']: + items = self._crawl_url(return_only_urls=(self._mode == 'crawl_return_urls')) + for item in items: + if item: + documents.append(self._create_document(item, is_url=(self._mode == 'crawl_return_urls'))) + return documents + + def _create_document(self, content, is_url=False): + if is_url: + return Document(page_content=content.get('url', '')) + else: + return Document(page_content=content.get('markdown', '')) def _scrape_url(self): return self._firecrawl_app.scrape_url(self._url) diff --git a/api/libs/bearer_data_source.py b/api/libs/bearer_data_source.py index 22da5bf10ab833..002f2de914edd5 100644 --- a/api/libs/bearer_data_source.py +++ b/api/libs/bearer_data_source.py @@ -1,7 +1,6 @@ -import requests -import time from typing import Iterator, Literal, Optional +# [REVIEW] Implement if Needed? Do we need a new type of data source class BearerDataSource: def __init__(self, api_key: str): self.api_key = api_key @@ -11,43 +10,5 @@ def access_token(self) -> str: class FireCrawlDataSource(BearerDataSource): - _FIRECRAWL_API_URL = 'https://api.firecrawl.dev/v0' - - def __init__(self, api_key: str, mode: Literal["crawl", "scrape"] = "crawl"): - super().__init__(api_key) - self.mode = mode - - def access_token(self) -> str: - return self.api_key - - def get_page_content(self, url: str): - if self.mode not in ("crawl", "scrape"): - raise ValueError( - f"Unrecognized mode '{self.mode}'. Expected one of 'crawl', 'scrape'." - ) - headers = { - 'Content-Type': 'application/json', - 'Authorization': f'Bearer {self.api_key}' - } - if self.mode == "scrape": - response = requests.post(f'{self._FIRECRAWL_API_URL}/scrape', headers=headers, json={"url": url}) - data = response.json().get('data', {}) - return { - 'page_content': data.get('markdown', ''), - 'metadata': data.get('metadata', {}) - } - elif self.mode == "crawl": - response = requests.post(f'{self._FIRECRAWL_API_URL}/crawl', headers=headers, json={"url": url}) - job_id = response.json().get('jobId') - while True: - response = requests.get(f'{self._FIRECRAWL_API_URL}/crawl/status/{job_id}', headers=headers) - data = response.json() - if data.get('status') == 'completed': - break - time.sleep(5) # wait for 5 seconds before checking the status again - return [ - { - 'page_content': doc.get('markdown', ''), - 'metadata': doc.get('metadata', {}) - } for doc in data.get('data', []) - ] + # [REVIEW] Implement if Needed? Do we need a new type of data source + pass \ No newline at end of file diff --git a/api/pyproject.toml b/api/pyproject.toml index 0002c6143647a8..5ec91aee38ef08 100644 --- a/api/pyproject.toml +++ b/api/pyproject.toml @@ -55,4 +55,6 @@ HUGGINGFACE_TEXT_GEN_ENDPOINT_URL = "a" HUGGINGFACE_TEXT2TEXT_GEN_ENDPOINT_URL = "b" HUGGINGFACE_EMBEDDINGS_ENDPOINT_URL = "c" MOCK_SWITCH = "true" -CODE_MAX_STRING_LENGTH = "80000" \ No newline at end of file +CODE_MAX_STRING_LENGTH = "80000" +FIRECRAWL_API_KEY = "fc-" + diff --git a/api/tests/unit_tests/core/rag/extractor/__init__.py b/api/tests/unit_tests/core/rag/extractor/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/api/tests/unit_tests/core/rag/extractor/firecrawl/__init__.py b/api/tests/unit_tests/core/rag/extractor/firecrawl/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py b/api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py new file mode 100644 index 00000000000000..5500104a58b84b --- /dev/null +++ b/api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py @@ -0,0 +1,35 @@ +import os +from core.rag.models.document import Document +from core.rag.extractor.firecrawl.firecrawl_web_extractor import FirecrawlWebExtractor + +def test_firecrawl_web_extractor_scrape_mode(): + url = "https://dify.ai" + api_key = os.getenv('FIRECRAWL_API_KEY') or 'fc-' + base_url = 'https://api.firecrawl.dev' + mode = 'scrape' + firecrawl_web_extractor = FirecrawlWebExtractor(url, api_key, base_url, mode) + documents = firecrawl_web_extractor.extract() + print(documents) + assert isinstance(documents, list) + assert all(isinstance(doc, Document) for doc in documents) + +def test_firecrawl_web_extractor_crawl_mode(): + url = "https://firecrawl.dev" + api_key = os.getenv('FIRECRAWL_API_KEY') or 'fc-' + base_url = 'https://api.firecrawl.dev' + mode = 'crawl' + firecrawl_web_extractor = FirecrawlWebExtractor(url, api_key, base_url, mode) + documents = firecrawl_web_extractor.extract() + print(documents) + assert isinstance(documents, list) + assert all(isinstance(doc, Document) for doc in documents) + +def test_firecrawl_web_extractor_crawl_return_urls_mode(): + url = "https://mendable.ai" + api_key = os.getenv('FIRECRAWL_API_KEY') or 'fc-' + base_url = 'https://api.firecrawl.dev' + mode = 'crawl_return_urls' + firecrawl_web_extractor = FirecrawlWebExtractor(url, api_key, base_url, mode) + documents = firecrawl_web_extractor.extract() + assert isinstance(documents, list) + assert all(isinstance(doc, Document) for doc in documents) From 21cfd5e801b814e6e26c559be98cb03569ddb681 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Mon, 29 Apr 2024 17:25:34 -0700 Subject: [PATCH 04/43] Nick: --- api/.env.example | 1 + api/config.py | 4 ++++ api/core/rag/extractor/firecrawl/firecrawl_app.py | 2 +- api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py | 4 +--- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/api/.env.example b/api/.env.example index 6e3cb581c53385..ab36d704425b7d 100644 --- a/api/.env.example +++ b/api/.env.example @@ -149,4 +149,5 @@ LOG_FILE= # Firecrawl Web Extractor FIRECRAWL_API_KEY= +FIRECRAWL_BASE_URL= diff --git a/api/config.py b/api/config.py index 8fb6b83cb3cc60..9c53477f5a1fac 100644 --- a/api/config.py +++ b/api/config.py @@ -297,6 +297,10 @@ def __init__(self): self.NOTION_INTERNAL_SECRET = get_env('NOTION_INTERNAL_SECRET') self.NOTION_INTEGRATION_TOKEN = get_env('NOTION_INTEGRATION_TOKEN') + # Firecrawl integration setting + self.FIRECRAWL_API_KEY = get_env('FIRECRAWL_API_KEY') + self.FIRECRAWL_BASE_URL = get_env('FIRECRAWL_BASE_URL') + # ------------------------ # Platform Configurations. # ------------------------ diff --git a/api/core/rag/extractor/firecrawl/firecrawl_app.py b/api/core/rag/extractor/firecrawl/firecrawl_app.py index 1af8778353764d..eeac19a01acd9c 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_app.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_app.py @@ -5,7 +5,7 @@ class FirecrawlApp: def __init__(self, api_key=None, base_url='https://api.firecrawl.dev'): self.api_key = api_key or os.getenv('FIRECRAWL_API_KEY') - self.base_url = base_url + self.base_url = base_url or os.getenv('FIRECRAWL_BASE_URL') if self.api_key is None: raise ValueError('No API key provided') diff --git a/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py b/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py index 05088cb48db942..c410eebd1f112c 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py @@ -1,5 +1,3 @@ -"""Abstract interface for document loader implementations.""" -import os from core.rag.extractor.extractor_base import BaseExtractor from core.rag.models.document import Document from core.rag.extractor.firecrawl.firecrawl_app import FirecrawlApp @@ -8,7 +6,7 @@ class FirecrawlWebExtractor(BaseExtractor): """ - Load html files. + Crawl and scrape websites and return content in clean llm-ready markdown. Args: From 0cb6bed148014b9475f51dd174fc0a989c20a3e7 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Mon, 29 Apr 2024 17:36:36 -0700 Subject: [PATCH 05/43] Update extract_setting.py --- api/core/rag/extractor/entity/extract_setting.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/api/core/rag/extractor/entity/extract_setting.py b/api/core/rag/extractor/entity/extract_setting.py index 02ae80b27aeffc..69b17039fbf200 100644 --- a/api/core/rag/extractor/entity/extract_setting.py +++ b/api/core/rag/extractor/entity/extract_setting.py @@ -20,8 +20,6 @@ class Config: def __init__(self, **data) -> None: super().__init__(**data) -import os - class FirecrawlInfo(BaseModel): """ Firecrawl import info. From 01b0baccd54ff6a0b8a50572dabca5d61ace47e2 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Wed, 1 May 2024 12:38:01 -0700 Subject: [PATCH 06/43] Update firecrawl_app.py --- .../rag/extractor/firecrawl/firecrawl_app.py | 44 ++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/api/core/rag/extractor/firecrawl/firecrawl_app.py b/api/core/rag/extractor/firecrawl/firecrawl_app.py index eeac19a01acd9c..e10ef60834fea8 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_app.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_app.py @@ -61,7 +61,8 @@ def search(self, query, params=None): else: raise Exception(f'Failed to search. Status code: {response.status_code}') - def crawl_url(self, url, params=None, wait_until_done=True, timeout=2): + def crawl_url(self, url, params=None, wait_until_done=True, polling_interval=2, timeout=500): + start_time = time.time() headers = self._prepare_headers() json_data = {'url': url} if params: @@ -70,12 +71,19 @@ def crawl_url(self, url, params=None, wait_until_done=True, timeout=2): if response.status_code == 200: job_id = response.json().get('jobId') if wait_until_done: - return self._monitor_job_status(job_id, headers, timeout) + while True: + elapsed_time = time.time() - start_time + if elapsed_time > timeout: + raise Exception('Firecrawl: Crawl job timed out.') + result = self._monitor_job_status(job_id, headers, polling_interval) + if result is not None: + return result else: return {'jobId': job_id} else: self._handle_error(response, 'start crawl job') + def check_crawl_status(self, job_id): headers = self._prepare_headers() response = self._get_request(f'{self.base_url}/v0/crawl/status/{job_id}', headers) @@ -107,26 +115,22 @@ def _get_request(self, url, headers, retries=3, backoff_factor=0.5): else: return response return response - - def _monitor_job_status(self, job_id, headers, timeout): - import time - while True: - status_response = self._get_request(f'{self.base_url}/v0/crawl/status/{job_id}', headers) - if status_response.status_code == 200: - status_data = status_response.json() - if status_data['status'] == 'completed': - if 'data' in status_data: - return status_data['data'] - else: - raise Exception('Crawl job completed but no data was returned') - elif status_data['status'] in ['active', 'paused', 'pending', 'queued']: - if timeout < 2: - timeout = 2 - time.sleep(timeout) # Wait for the specified timeout before checking again + + def _monitor_job_status(self, job_id, headers, polling_interval): + status_response = self._get_request(f'{self.base_url}/v0/crawl/status/{job_id}', headers) + if status_response.status_code == 200: + status_data = status_response.json() + if status_data['status'] == 'completed': + if 'data' in status_data: + return status_data['data'] else: - raise Exception(f'Crawl job failed or was stopped. Status: {status_data["status"]}') + raise Exception('Crawl job completed but no data was returned') + elif status_data['status'] in ['active', 'paused', 'pending', 'queued']: + time.sleep(max(polling_interval, 2)) # Wait for the specified polling_interval before checking again else: - self._handle_error(status_response, 'check crawl status') + raise Exception(f'Crawl job failed or was stopped. Status: {status_data["status"]}') + else: + self._handle_error(status_response, 'check crawl status') def _handle_error(self, response, action): if response.status_code in [402, 409, 500]: From 59d1ae9a905dd5518cf3027b503d59719c26b408 Mon Sep 17 00:00:00 2001 From: chenhe Date: Tue, 7 May 2024 15:30:18 +0800 Subject: [PATCH 07/43] init --- api/core/rag/extractor/extract_processor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/core/rag/extractor/extract_processor.py b/api/core/rag/extractor/extract_processor.py index 85bb3bef853ba2..dc416d5d376b3e 100644 --- a/api/core/rag/extractor/extract_processor.py +++ b/api/core/rag/extractor/extract_processor.py @@ -9,7 +9,7 @@ from core.rag.extractor.entity.datasource_type import DatasourceType from core.rag.extractor.entity.extract_setting import ExtractSetting from core.rag.extractor.excel_extractor import ExcelExtractor -from api.core.rag.extractor.firecrawl.firecrawl_web_extractor import FirecrawlWebExtractor +from core.rag.extractor.firecrawl.firecrawl_web_extractor import FirecrawlWebExtractor from core.rag.extractor.html_extractor import HtmlExtractor from core.rag.extractor.markdown_extractor import MarkdownExtractor from core.rag.extractor.notion_extractor import NotionExtractor From c0ddb786b1072be75564d701ae169e30e23a56c1 Mon Sep 17 00:00:00 2001 From: chenhe Date: Tue, 7 May 2024 15:35:40 +0800 Subject: [PATCH 08/43] lint fixes --- .../rag/extractor/firecrawl/firecrawl_app.py | 4 +++- .../firecrawl/firecrawl_web_extractor.py | 2 +- api/libs/bearer_data_source.py | 1 - .../rag/extractor/firecrawl/test_firecrawl.py | 4 +++- web/bun.lockb | Bin 0 -> 394413 bytes 5 files changed, 7 insertions(+), 4 deletions(-) create mode 100755 web/bun.lockb diff --git a/api/core/rag/extractor/firecrawl/firecrawl_app.py b/api/core/rag/extractor/firecrawl/firecrawl_app.py index e10ef60834fea8..e9cce18ffa7606 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_app.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_app.py @@ -1,7 +1,9 @@ import os -import requests import time +import requests + + class FirecrawlApp: def __init__(self, api_key=None, base_url='https://api.firecrawl.dev'): self.api_key = api_key or os.getenv('FIRECRAWL_API_KEY') diff --git a/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py b/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py index c410eebd1f112c..4d70ff74d4d20b 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py @@ -1,6 +1,6 @@ from core.rag.extractor.extractor_base import BaseExtractor -from core.rag.models.document import Document from core.rag.extractor.firecrawl.firecrawl_app import FirecrawlApp +from core.rag.models.document import Document class FirecrawlWebExtractor(BaseExtractor): diff --git a/api/libs/bearer_data_source.py b/api/libs/bearer_data_source.py index 002f2de914edd5..e94f291246c16c 100644 --- a/api/libs/bearer_data_source.py +++ b/api/libs/bearer_data_source.py @@ -1,4 +1,3 @@ -from typing import Iterator, Literal, Optional # [REVIEW] Implement if Needed? Do we need a new type of data source class BearerDataSource: diff --git a/api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py b/api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py index 5500104a58b84b..19b372649911b1 100644 --- a/api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py +++ b/api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py @@ -1,6 +1,8 @@ import os -from core.rag.models.document import Document + from core.rag.extractor.firecrawl.firecrawl_web_extractor import FirecrawlWebExtractor +from core.rag.models.document import Document + def test_firecrawl_web_extractor_scrape_mode(): url = "https://dify.ai" diff --git a/web/bun.lockb b/web/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..b30ced5c52268ea6570fec3c05751af617b795a5 GIT binary patch literal 394413 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%0DqQesb@BYrwmJXWMe0pI?J-0-kNl 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

Gwcz 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 E0LrBH9smFU literal 0 HcmV?d00001 From 898b67583919f02e71ed97ab22288b47063c3494 Mon Sep 17 00:00:00 2001 From: chenhe Date: Wed, 8 May 2024 01:17:22 +0800 Subject: [PATCH 09/43] t --- .../model_providers/togetherai/llm/llm.py | 3 ++- .../firecrawl/firecrawl_web_extractor.py | 2 +- api/libs/bearer_data_source.py | 18 +++++++++++++----- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/api/core/model_runtime/model_providers/togetherai/llm/llm.py b/api/core/model_runtime/model_providers/togetherai/llm/llm.py index 64b7341e9ff7c9..f38e4089426701 100644 --- a/api/core/model_runtime/model_providers/togetherai/llm/llm.py +++ b/api/core/model_runtime/model_providers/togetherai/llm/llm.py @@ -124,7 +124,8 @@ def get_customizable_model_schema(self, model: str, credentials: dict) -> AIMode default=float(credentials.get('presence_penalty', 0)), min=-2, max=2 - ) + ), + ParameterRule ], pricing=PriceConfig( input=Decimal(cred_with_endpoint.get('input_price', 0)), diff --git a/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py b/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py index 4d70ff74d4d20b..f0d03956e7461c 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py @@ -22,7 +22,7 @@ def __init__( url: str, api_key: str, base_url: str = 'https://api.firecrawl.dev', - mode: str = 'scrape', + mode: str = 'crawl', ): """Initialize with url, api_key, base_url and mode.""" self._url = url diff --git a/api/libs/bearer_data_source.py b/api/libs/bearer_data_source.py index e94f291246c16c..7108cad4f39afd 100644 --- a/api/libs/bearer_data_source.py +++ b/api/libs/bearer_data_source.py @@ -1,13 +1,21 @@ # [REVIEW] Implement if Needed? Do we need a new type of data source +from abc import abstractmethod + + class BearerDataSource: - def __init__(self, api_key: str): + def __init__(self, api_key: str, api_base_url: str): self.api_key = api_key + self.api_base_url = api_base_url - def access_token(self) -> str: - raise NotImplementedError() + @abstractmethod + def validate_bearer_data_source(self): + """ + Validate the data source + """ + class FireCrawlDataSource(BearerDataSource): - # [REVIEW] Implement if Needed? Do we need a new type of data source - pass \ No newline at end of file + + \ No newline at end of file From de558efaf11009b104774c4ad929ae373854023e Mon Sep 17 00:00:00 2001 From: chenhe Date: Wed, 8 May 2024 01:17:41 +0800 Subject: [PATCH 10/43] t --- api/libs/bearer_data_source.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/api/libs/bearer_data_source.py b/api/libs/bearer_data_source.py index 7108cad4f39afd..95b890f0cca8b7 100644 --- a/api/libs/bearer_data_source.py +++ b/api/libs/bearer_data_source.py @@ -17,5 +17,6 @@ def validate_bearer_data_source(self): class FireCrawlDataSource(BearerDataSource): - - \ No newline at end of file + def validate_bearer_data_source(self): + + pass \ No newline at end of file From 77cc39f162d8d45cebbe07374d1770fe842dbad2 Mon Sep 17 00:00:00 2001 From: chenhe Date: Fri, 10 May 2024 14:04:14 +0800 Subject: [PATCH 11/43] c --- .../console/auth/data_source_bearer.py | 116 + .../rag/extractor/firecrawl/firecrawl_app.py | 2 +- api/libs/bearer_data_source.py | 21 +- api/models/source.py | 2 + web/yarn.lock | 7378 ----------------- 5 files changed, 139 insertions(+), 7380 deletions(-) create mode 100644 api/controllers/console/auth/data_source_bearer.py delete mode 100644 web/yarn.lock diff --git a/api/controllers/console/auth/data_source_bearer.py b/api/controllers/console/auth/data_source_bearer.py new file mode 100644 index 00000000000000..293ec1c4d341c3 --- /dev/null +++ b/api/controllers/console/auth/data_source_bearer.py @@ -0,0 +1,116 @@ +import logging + +import requests +from flask import current_app, redirect, request +from flask_login import current_user +from flask_restful import Resource +from werkzeug.exceptions import Forbidden + +from controllers.console import api +from libs.login import login_required +from libs.oauth_data_source import NotionOAuth + +from ..setup import setup_required +from ..wraps import account_initialization_required + + +def get_oauth_providers(): + with current_app.app_context(): + notion_oauth = NotionOAuth(client_id=current_app.config.get('NOTION_CLIENT_ID'), + client_secret=current_app.config.get( + 'NOTION_CLIENT_SECRET'), + redirect_uri=current_app.config.get( + 'CONSOLE_API_URL') + '/console/api/oauth/data-source/callback/notion') + + OAUTH_PROVIDERS = { + 'notion': notion_oauth + } + return OAUTH_PROVIDERS + + +class OAuthDataSource(Resource): + def get(self, provider: str): + # The role of the current user in the table must be admin or owner + if not current_user.is_admin_or_owner: + raise Forbidden() + OAUTH_DATASOURCE_PROVIDERS = get_oauth_providers() + with current_app.app_context(): + oauth_provider = OAUTH_DATASOURCE_PROVIDERS.get(provider) + print(vars(oauth_provider)) + if not oauth_provider: + return {'error': 'Invalid provider'}, 400 + if current_app.config.get('NOTION_INTEGRATION_TYPE') == 'internal': + internal_secret = current_app.config.get('NOTION_INTERNAL_SECRET') + oauth_provider.save_internal_access_token(internal_secret) + return { 'data': '' } + else: + auth_url = oauth_provider.get_authorization_url() + return { 'data': auth_url }, 200 + + + + +class OAuthDataSourceCallback(Resource): + def get(self, provider: str): + OAUTH_DATASOURCE_PROVIDERS = get_oauth_providers() + with current_app.app_context(): + oauth_provider = OAUTH_DATASOURCE_PROVIDERS.get(provider) + if not oauth_provider: + return {'error': 'Invalid provider'}, 400 + if 'code' in request.args: + code = request.args.get('code') + + return redirect(f'{current_app.config.get("CONSOLE_WEB_URL")}?type=notion&code={code}') + elif 'error' in request.args: + error = request.args.get('error') + + return redirect(f'{current_app.config.get("CONSOLE_WEB_URL")}?type=notion&error={error}') + else: + return redirect(f'{current_app.config.get("CONSOLE_WEB_URL")}?type=notion&error=Access denied') + + +class OAuthDataSourceBinding(Resource): + def get(self, provider: str): + OAUTH_DATASOURCE_PROVIDERS = get_oauth_providers() + with current_app.app_context(): + oauth_provider = OAUTH_DATASOURCE_PROVIDERS.get(provider) + if not oauth_provider: + return {'error': 'Invalid provider'}, 400 + if 'code' in request.args: + code = request.args.get('code') + try: + oauth_provider.get_access_token(code) + except requests.exceptions.HTTPError as e: + logging.exception( + f"An error occurred during the OAuthCallback process with {provider}: {e.response.text}") + return {'error': 'OAuth data source process failed'}, 400 + + return {'result': 'success'}, 200 + + +class OAuthDataSourceSync(Resource): + @setup_required + @login_required + @account_initialization_required + def get(self, provider, binding_id): + provider = str(provider) + binding_id = str(binding_id) + OAUTH_DATASOURCE_PROVIDERS = get_oauth_providers() + with current_app.app_context(): + oauth_provider = OAUTH_DATASOURCE_PROVIDERS.get(provider) + if not oauth_provider: + return {'error': 'Invalid provider'}, 400 + try: + oauth_provider.sync_data_source(binding_id) + except requests.exceptions.HTTPError as e: + logging.exception( + f"An error occurred during the OAuthCallback process with {provider}: {e.response.text}") + return {'error': 'OAuth data source process failed'}, 400 + + return {'result': 'success'}, 200 + + +api.add_resource(OAuthDataSource, '/oauth/data-source/') +api.add_resource(OAuthDataSourceCallback, '/oauth/data-source/callback/') +api.add_resource(OAuthDataSourceBinding, '/oauth/data-source/binding/') +api.add_resource(OAuthDataSourceSync, '/oauth/data-source///sync') diff --git a/api/core/rag/extractor/firecrawl/firecrawl_app.py b/api/core/rag/extractor/firecrawl/firecrawl_app.py index e9cce18ffa7606..bdb7c8e247aa7d 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_app.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_app.py @@ -8,7 +8,7 @@ class FirecrawlApp: def __init__(self, api_key=None, base_url='https://api.firecrawl.dev'): self.api_key = api_key or os.getenv('FIRECRAWL_API_KEY') self.base_url = base_url or os.getenv('FIRECRAWL_BASE_URL') - if self.api_key is None: + if self.api_key is None and self.base_url == 'https://api.firecrawl.dev': raise ValueError('No API key provided') def scrape_url(self, url, params=None): diff --git a/api/libs/bearer_data_source.py b/api/libs/bearer_data_source.py index 95b890f0cca8b7..9c14e8e2ff41cf 100644 --- a/api/libs/bearer_data_source.py +++ b/api/libs/bearer_data_source.py @@ -2,6 +2,8 @@ # [REVIEW] Implement if Needed? Do we need a new type of data source from abc import abstractmethod +import requests + class BearerDataSource: def __init__(self, api_key: str, api_base_url: str): @@ -18,5 +20,22 @@ def validate_bearer_data_source(self): class FireCrawlDataSource(BearerDataSource): def validate_bearer_data_source(self): + TEST_CRAWL_SITE_URL = "https://www.google.com" + FIRECRAWL_API_VERSION = "v0" - pass \ No newline at end of file + test_api_endpoint = self.api_base_url.rstrip('/') + f"/{FIRECRAWL_API_VERSION}/scrape" + + headers = { + "Authorization": f"Bearer {self.api_key}", + "Content-Type": "application/json", + } + + data = { + "url": TEST_CRAWL_SITE_URL, + } + + response = requests.get(test_api_endpoint, headers=headers, json=data) + + return response.json().get("status") == "success" + + diff --git a/api/models/source.py b/api/models/source.py index 97ba23a5bddbfa..70b139ed25d280 100644 --- a/api/models/source.py +++ b/api/models/source.py @@ -15,6 +15,8 @@ class DataSourceBinding(db.Model): id = db.Column(StringUUID, server_default=db.text('uuid_generate_v4()')) tenant_id = db.Column(StringUUID, nullable=False) access_token = db.Column(db.String(255), nullable=False) + endpoint_url = db.Column(db.String(512), nullable=True) # For validation with endpoint + bearer key + bearer_key = db.Column(db.String(512), nullable=True) # For validation with endpoint + bearer key provider = db.Column(db.String(255), nullable=False) source_info = db.Column(JSONB, nullable=False) created_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) diff --git a/web/yarn.lock b/web/yarn.lock deleted file mode 100644 index 50e5ac1ee36e33..00000000000000 --- a/web/yarn.lock +++ /dev/null @@ -1,7378 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@alloc/quick-lru@^5.2.0": - version "5.2.0" - resolved "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz" - integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== - -"@antfu/eslint-config-basic@0.36.0": - version "0.36.0" - resolved "https://registry.npmjs.org/@antfu/eslint-config-basic/-/eslint-config-basic-0.36.0.tgz" - integrity sha512-2b3ZB7pO00nxAERDXo82iYPjLQ4l/AOMm0CTKmGmqWbN3RB33EIQWzYheZRboSbAVzWpI1/3rg/Gu+7xYVMYHA== - dependencies: - eslint-plugin-antfu "0.36.0" - eslint-plugin-eslint-comments "^3.2.0" - eslint-plugin-html "^7.1.0" - eslint-plugin-import "^2.27.5" - eslint-plugin-jsonc "^2.6.0" - eslint-plugin-markdown "^3.0.0" - eslint-plugin-n "^15.6.1" - eslint-plugin-no-only-tests "^3.1.0" - eslint-plugin-promise "^6.1.1" - eslint-plugin-unicorn "^45.0.2" - eslint-plugin-unused-imports "^2.0.0" - eslint-plugin-yml "^1.5.0" - jsonc-eslint-parser "^2.1.0" - yaml-eslint-parser "^1.1.0" - -"@antfu/eslint-config-ts@0.36.0": - version "0.36.0" - resolved "https://registry.npmjs.org/@antfu/eslint-config-ts/-/eslint-config-ts-0.36.0.tgz" - integrity sha512-I/h2ZOPBIqgnALG2fQp6lOBsOXk51QwLDumyEayt7GRnitdP4o9D8i+YAPowrMJ8M3kU7puQUyhWuJmZLgo57A== - dependencies: - "@antfu/eslint-config-basic" "0.36.0" - "@typescript-eslint/eslint-plugin" "^5.53.0" - "@typescript-eslint/parser" "^5.53.0" - eslint-plugin-jest "^27.2.1" - -"@antfu/eslint-config-vue@0.36.0": - version "0.36.0" - resolved "https://registry.npmjs.org/@antfu/eslint-config-vue/-/eslint-config-vue-0.36.0.tgz" - integrity sha512-YuTcNlVlrEWX1ESOiPgr+e2Walfd6xt3Toa0kAKJxq2aBS1RWqIi1l3zIVGCHaX72lOrSXNmQ7bryaZyGADGDg== - dependencies: - "@antfu/eslint-config-basic" "0.36.0" - "@antfu/eslint-config-ts" "0.36.0" - eslint-plugin-vue "^9.9.0" - local-pkg "^0.4.3" - -"@antfu/eslint-config@^0.36.0": - version "0.36.0" - resolved "https://registry.npmjs.org/@antfu/eslint-config/-/eslint-config-0.36.0.tgz" - integrity sha512-otZ9PfKRT3gnGMMX1gS8URTNPMPCZ69K5jHZvLkYojru0gLBZ3IO5fCvjEZpWqOyIUHtAgg6NWELf1DbEF+NDw== - dependencies: - "@antfu/eslint-config-vue" "0.36.0" - "@typescript-eslint/eslint-plugin" "^5.53.0" - "@typescript-eslint/parser" "^5.53.0" - eslint-plugin-eslint-comments "^3.2.0" - eslint-plugin-html "^7.1.0" - eslint-plugin-import "^2.27.5" - eslint-plugin-jsonc "^2.6.0" - eslint-plugin-n "^15.6.1" - eslint-plugin-promise "^6.1.1" - eslint-plugin-unicorn "^45.0.2" - eslint-plugin-vue "^9.9.0" - eslint-plugin-yml "^1.5.0" - jsonc-eslint-parser "^2.1.0" - yaml-eslint-parser "^1.1.0" - -"@babel/code-frame@^7.0.0": - version "7.21.4" - resolved "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz" - integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== - dependencies: - "@babel/highlight" "^7.18.6" - -"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": - version "7.19.1" - resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== - -"@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== - dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/parser@^7.24.4": - version "7.24.4" - resolved "https://registry.npmjs.org/@babel/parser/-/parser-7.24.4.tgz" - integrity sha512-zTvEBcghmeBma9QIGunWevvBAp4/Qu9Bdq+2k0Ot4fVMD6v3dsC9WOcRSKk7tRRyBM/53yKMJko9xOatGQAwSg== - -"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.11.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.18.3", "@babel/runtime@^7.20.6", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.21.5", "@babel/runtime@^7.22.3", "@babel/runtime@^7.3.1": - version "7.22.3" - resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.3.tgz" - integrity sha512-XsDuspWKLUsxwCp6r7EhsExHtYfbe5oAGQ19kqngTdCPUoPQzOPdUbD/pB9PJiwb2ptYKQDjSJT3R6dC+EPqfQ== - dependencies: - regenerator-runtime "^0.13.11" - -"@braintree/sanitize-url@^6.0.1": - version "6.0.4" - resolved "https://registry.npmjs.org/@braintree/sanitize-url/-/sanitize-url-6.0.4.tgz" - integrity sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A== - -"@emnapi/runtime@^0.45.0": - version "0.45.0" - resolved "https://registry.npmjs.org/@emnapi/runtime/-/runtime-0.45.0.tgz#e754de04c683263f34fd0c7f32adfe718bbe4ddd" - integrity sha512-Txumi3td7J4A/xTTwlssKieHKTGl3j4A1tglBx72auZ49YK7ePY6XZricgIg9mnZT4xPfA+UPCUdnhRuEFDL+w== - dependencies: - tslib "^2.4.0" - -"@emoji-mart/data@^1.1.2": - version "1.1.2" - resolved "https://registry.npmjs.org/@emoji-mart/data/-/data-1.1.2.tgz" - integrity sha512-1HP8BxD2azjqWJvxIaWAMyTySeZY0Osr83ukYjltPVkNXeJvTz7yDrPLBtnrD5uqJ3tg4CcLuuBW09wahqL/fg== - -"@eslint-community/eslint-utils@^4.1.2", "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.3.0": - version "4.4.0" - resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== - dependencies: - eslint-visitor-keys "^3.3.0" - -"@eslint-community/regexpp@^4.4.0": - version "4.5.1" - resolved "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz" - integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== - -"@eslint/eslintrc@^2.0.1": - version "2.0.3" - resolved "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz" - integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.5.2" - globals "^13.19.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@eslint/js@8.36.0": - version "8.36.0" - resolved "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz" - integrity sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg== - -"@faker-js/faker@^7.6.0": - version "7.6.0" - resolved "https://registry.npmjs.org/@faker-js/faker/-/faker-7.6.0.tgz" - integrity sha512-XK6BTq1NDMo9Xqw/YkYyGjSsg44fbNwYRx7QK2CuoQgyy+f1rrTDHoExVM5PsyXCtfl2vs2vVJ0MN0yN6LppRw== - -"@floating-ui/core@^1.1.0", "@floating-ui/core@^1.4.1": - version "1.4.1" - resolved "https://registry.npmjs.org/@floating-ui/core/-/core-1.4.1.tgz" - integrity sha512-jk3WqquEJRlcyu7997NtR5PibI+y5bi+LS3hPmguVClypenMsCY3CBa3LAQnozRCtCrYWSEtAdiskpamuJRFOQ== - dependencies: - "@floating-ui/utils" "^0.1.1" - -"@floating-ui/dom@1.1.1": - version "1.1.1" - resolved "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.1.1.tgz" - integrity sha512-TpIO93+DIujg3g7SykEAGZMDtbJRrmnYRCNYSjJlvIbGhBjRSNTLVbNeDQBrzy9qDgUbiWdc7KA0uZHZ2tJmiw== - dependencies: - "@floating-ui/core" "^1.1.0" - -"@floating-ui/dom@^1.5.1": - version "1.5.1" - resolved "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.5.1.tgz" - integrity sha512-KwvVcPSXg6mQygvA1TjbN/gh///36kKtllIF8SUm0qpFj8+rvYrpvlYdL1JoA71SHpDqgSSdGOSoQ0Mp3uY5aw== - dependencies: - "@floating-ui/core" "^1.4.1" - "@floating-ui/utils" "^0.1.1" - -"@floating-ui/react-dom@^2.0.1": - version "2.0.2" - resolved "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.0.2.tgz" - integrity sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ== - dependencies: - "@floating-ui/dom" "^1.5.1" - -"@floating-ui/react@^0.25.2": - version "0.25.2" - resolved "https://registry.npmjs.org/@floating-ui/react/-/react-0.25.2.tgz" - integrity sha512-3e10G9LFOgl32/SMWLBOwT7oVCtB+d5zBsU2GxTSVOvRgZexwno5MlYbc0BaXr+TR5EEGpqe9tg9OUbjlrVRnQ== - dependencies: - "@floating-ui/react-dom" "^2.0.1" - "@floating-ui/utils" "^0.1.1" - tabbable "^6.0.1" - -"@floating-ui/utils@^0.1.1": - version "0.1.1" - resolved "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.1.1.tgz" - integrity sha512-m0G6wlnhm/AX0H12IOWtK8gASEMffnX08RtKkCgTdHb9JpHKGloI7icFfLg9ZmQeavcvR0PKmzxClyuFPSjKWw== - -"@formatjs/intl-localematcher@^0.5.4": - version "0.5.4" - resolved "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.4.tgz" - integrity sha512-zTwEpWOzZ2CiKcB93BLngUX59hQkuZjT2+SAQEscSm52peDW/getsawMcWF1rGRpMCX6D7nSJA3CzJ8gn13N/g== - dependencies: - tslib "^2.4.0" - -"@headlessui/react@^1.7.13": - version "1.7.15" - resolved "https://registry.npmjs.org/@headlessui/react/-/react-1.7.15.tgz" - integrity sha512-OTO0XtoRQ6JPB1cKNFYBZv2Q0JMqMGNhYP1CjPvcJvjz8YGokz8oAj89HIYZGN0gZzn/4kk9iUpmMF4Q21Gsqw== - dependencies: - client-only "^0.0.1" - -"@heroicons/react@^2.0.16": - version "2.0.18" - resolved "https://registry.npmjs.org/@heroicons/react/-/react-2.0.18.tgz" - integrity sha512-7TyMjRrZZMBPa+/5Y8lN0iyvUU/01PeMGX2+RE7cQWpEUIcb4QotzUObFkJDejj/HUH4qjP/eQ0gzzKs2f+6Yw== - -"@humanwhocodes/config-array@^0.11.8": - version "0.11.10" - resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz" - integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== - dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" - minimatch "^3.0.5" - -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== - -"@img/sharp-darwin-arm64@0.33.2": - version "0.33.2" - resolved "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.2.tgz" - integrity sha512-itHBs1rPmsmGF9p4qRe++CzCgd+kFYktnsoR1sbIAfsRMrJZau0Tt1AH9KVnufc2/tU02Gf6Ibujx+15qRE03w== - optionalDependencies: - "@img/sharp-libvips-darwin-arm64" "1.0.1" - -"@img/sharp-darwin-x64@0.33.2": - version "0.33.2" - resolved "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.2.tgz#982e26bb9d38a81f75915c4032539aed621d1c21" - integrity sha512-/rK/69Rrp9x5kaWBjVN07KixZanRr+W1OiyKdXcbjQD6KbW+obaTeBBtLUAtbBsnlTTmWthw99xqoOS7SsySDg== - optionalDependencies: - "@img/sharp-libvips-darwin-x64" "1.0.1" - -"@img/sharp-libvips-darwin-arm64@1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.1.tgz" - integrity sha512-kQyrSNd6lmBV7O0BUiyu/OEw9yeNGFbQhbxswS1i6rMDwBBSX+e+rPzu3S+MwAiGU3HdLze3PanQ4Xkfemgzcw== - -"@img/sharp-libvips-darwin-x64@1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.1.tgz#fc1fcd9d78a178819eefe2c1a1662067a83ab1d6" - integrity sha512-eVU/JYLPVjhhrd8Tk6gosl5pVlvsqiFlt50wotCvdkFGf+mDNBJxMh+bvav+Wt3EBnNZWq8Sp2I7XfSjm8siog== - -"@img/sharp-libvips-linux-arm64@1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.1.tgz#26eb8c556a9b0db95f343fc444abc3effb67ebcf" - integrity sha512-bnGG+MJjdX70mAQcSLxgeJco11G+MxTz+ebxlz8Y3dxyeb3Nkl7LgLI0mXupoO+u1wRNx/iRj5yHtzA4sde1yA== - -"@img/sharp-libvips-linux-arm@1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.1.tgz#2a377b959ff7dd6528deee486c25461296a4fa8b" - integrity sha512-FtdMvR4R99FTsD53IA3LxYGghQ82t3yt0ZQ93WMZ2xV3dqrb0E8zq4VHaTOuLEAuA83oDawHV3fd+BsAPadHIQ== - -"@img/sharp-libvips-linux-s390x@1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.1.tgz#af28ac9ba929204467ecdf843330d791e9421e10" - integrity sha512-3+rzfAR1YpMOeA2zZNp+aYEzGNWK4zF3+sdMxuCS3ey9HhDbJ66w6hDSHDMoap32DueFwhhs3vwooAB2MaK4XQ== - -"@img/sharp-libvips-linux-x64@1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.1.tgz#4273d182aa51912e655e1214ea47983d7c1f7f8d" - integrity sha512-3NR1mxFsaSgMMzz1bAnnKbSAI+lHXVTqAHgc1bgzjHuXjo4hlscpUxc0vFSAPKI3yuzdzcZOkq7nDPrP2F8Jgw== - -"@img/sharp-libvips-linuxmusl-arm64@1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.1.tgz#d150c92151cea2e8d120ad168b9c358d09c77ce8" - integrity sha512-5aBRcjHDG/T6jwC3Edl3lP8nl9U2Yo8+oTl5drd1dh9Z1EBfzUKAJFUDTDisDjUwc7N4AjnPGfCA3jl3hY8uDg== - -"@img/sharp-libvips-linuxmusl-x64@1.0.1": - version "1.0.1" - resolved "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.1.tgz#e297c1a4252c670d93b0f9e51fca40a7a5b6acfd" - integrity sha512-dcT7inI9DBFK6ovfeWRe3hG30h51cBAP5JXlZfx6pzc/Mnf9HFCQDLtYf4MCBjxaaTfjCCjkBxcy3XzOAo5txw== - -"@img/sharp-linux-arm64@0.33.2": - version "0.33.2" - resolved "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.2.tgz#af3409f801a9bee1d11d0c7e971dcd6180f80022" - integrity sha512-pz0NNo882vVfqJ0yNInuG9YH71smP4gRSdeL09ukC2YLE6ZyZePAlWKEHgAzJGTiOh8Qkaov6mMIMlEhmLdKew== - optionalDependencies: - "@img/sharp-libvips-linux-arm64" "1.0.1" - -"@img/sharp-linux-arm@0.33.2": - version "0.33.2" - resolved "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.2.tgz#181f7466e6ac074042a38bfb679eb82505e17083" - integrity sha512-Fndk/4Zq3vAc4G/qyfXASbS3HBZbKrlnKZLEJzPLrXoJuipFNNwTes71+Ki1hwYW5lch26niRYoZFAtZVf3EGA== - optionalDependencies: - "@img/sharp-libvips-linux-arm" "1.0.1" - -"@img/sharp-linux-s390x@0.33.2": - version "0.33.2" - resolved "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.2.tgz#9c171f49211f96fba84410b3e237b301286fa00f" - integrity sha512-MBoInDXDppMfhSzbMmOQtGfloVAflS2rP1qPcUIiITMi36Mm5YR7r0ASND99razjQUpHTzjrU1flO76hKvP5RA== - optionalDependencies: - "@img/sharp-libvips-linux-s390x" "1.0.1" - -"@img/sharp-linux-x64@0.33.2": - version "0.33.2" - resolved "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.2.tgz#b956dfc092adc58c2bf0fae2077e6f01a8b2d5d7" - integrity sha512-xUT82H5IbXewKkeF5aiooajoO1tQV4PnKfS/OZtb5DDdxS/FCI/uXTVZ35GQ97RZXsycojz/AJ0asoz6p2/H/A== - optionalDependencies: - "@img/sharp-libvips-linux-x64" "1.0.1" - -"@img/sharp-linuxmusl-arm64@0.33.2": - version "0.33.2" - resolved "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.2.tgz#10e0ec5a79d1234c6a71df44c9f3b0bef0bc0f15" - integrity sha512-F+0z8JCu/UnMzg8IYW1TMeiViIWBVg7IWP6nE0p5S5EPQxlLd76c8jYemG21X99UzFwgkRo5yz2DS+zbrnxZeA== - optionalDependencies: - "@img/sharp-libvips-linuxmusl-arm64" "1.0.1" - -"@img/sharp-linuxmusl-x64@0.33.2": - version "0.33.2" - resolved "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.2.tgz#29e0030c24aa27c38201b1fc84e3d172899fcbe0" - integrity sha512-+ZLE3SQmSL+Fn1gmSaM8uFusW5Y3J9VOf+wMGNnTtJUMUxFhv+P4UPaYEYT8tqnyYVaOVGgMN/zsOxn9pSsO2A== - optionalDependencies: - "@img/sharp-libvips-linuxmusl-x64" "1.0.1" - -"@img/sharp-wasm32@0.33.2": - version "0.33.2" - resolved "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.2.tgz#38d7c740a22de83a60ad1e6bcfce17462b0d4230" - integrity sha512-fLbTaESVKuQcpm8ffgBD7jLb/CQLcATju/jxtTXR1XCLwbOQt+OL5zPHSDMmp2JZIeq82e18yE0Vv7zh6+6BfQ== - dependencies: - "@emnapi/runtime" "^0.45.0" - -"@img/sharp-win32-ia32@0.33.2": - version "0.33.2" - resolved "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.2.tgz#09456314e223f68e5417c283b45c399635c16202" - integrity sha512-okBpql96hIGuZ4lN3+nsAjGeggxKm7hIRu9zyec0lnfB8E7Z6p95BuRZzDDXZOl2e8UmR4RhYt631i7mfmKU8g== - -"@img/sharp-win32-x64@0.33.2": - version "0.33.2" - resolved "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.2.tgz#148e96dfd6e68747da41a311b9ee4559bb1b1471" - integrity sha512-E4magOks77DK47FwHUIGH0RYWSgRBfGdK56kIHSVeB9uIS4pPFr4N2kIVsXdQQo4LzOsENKV5KAhRlRL7eMAdg== - -"@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" - -"@jridgewell/gen-mapping@^0.3.2": - version "0.3.3" - resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz" - integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/resolve-uri@3.1.0": - version "3.1.0" - resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== - -"@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== - -"@jridgewell/sourcemap-codec@1.4.14": - version "1.4.14" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - -"@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.15" - resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== - -"@jridgewell/trace-mapping@^0.3.9": - version "0.3.18" - resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz" - integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== - dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" - -"@lexical/clipboard@0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/clipboard/-/clipboard-0.12.2.tgz" - integrity sha512-RldmfZquuJJJCJ5WquCyoJ1/eZ+AnNgdksqvd+G+Yn/GyJl/+O3dnHM0QVaDSPvh/PynLFcCtz/57ySLo2kQxQ== - dependencies: - "@lexical/html" "0.12.2" - "@lexical/list" "0.12.2" - "@lexical/selection" "0.12.2" - "@lexical/utils" "0.12.2" - -"@lexical/code@0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/code/-/code-0.12.2.tgz" - integrity sha512-w2JeJdnMUtYnC/Fx78sL3iJBt9Ug8pFSDOcI9ay/BkMQFQV8oqq1iyuLLBBJSG4FAM8b2DXrVdGklRQ+jTfTVw== - dependencies: - "@lexical/utils" "0.12.2" - prismjs "^1.27.0" - -"@lexical/dragon@0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/dragon/-/dragon-0.12.2.tgz" - integrity sha512-Mt8NLzTOt+VgQtc2DKDbHBwKeRlvKqbLqRIMYUVk60gol+YV7NpVBsP1PAMuYYjrTQLhlckBSC32H1SUHZRavA== - -"@lexical/hashtag@0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/hashtag/-/hashtag-0.12.2.tgz" - integrity sha512-2vYzIu5Ldf+eYdUrNA2m80c3N3MF3vJ0fIJzpl5QyX8OdViggEWl1bh+lKtw1Ju0H0CUyDIXdDLZ2apW3WDkTA== - dependencies: - "@lexical/utils" "0.12.2" - -"@lexical/history@0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/history/-/history-0.12.2.tgz" - integrity sha512-PM/EDjnUyBPMWh1UiYb7T+FLbvTk14HwUWLXvZxn72S6Kj8ExH/PfLbWZWLCFL8RfzvbP407VwfSN8S0bF5H6g== - dependencies: - "@lexical/utils" "0.12.2" - -"@lexical/html@0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/html/-/html-0.12.2.tgz" - integrity sha512-LWUO6OKhDtDZa9X1spHAqzsp+4EF01exis4cz5H9y2sHi7EofogXnRCadZ+fa07NVwPVTZWsStkk5qdSe/NEzg== - dependencies: - "@lexical/selection" "0.12.2" - -"@lexical/link@0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/link/-/link-0.12.2.tgz" - integrity sha512-etOIONa7uyRDmwg8GN52kDlf8thD2Zk1LOFLeocHWz1V8fe3i2unGUek5s/rNPkc6ynpPpNsHdN1VEghOLCCmw== - dependencies: - "@lexical/utils" "0.12.2" - -"@lexical/list@0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/list/-/list-0.12.2.tgz" - integrity sha512-3CyWtYQC+IlK4cK/oiD8Uz1gSXD8UcKGOF2vVsDXkMU06O6zvHNmHZOnVJqA0JVNgZAoR9dMR1fi2xd4iuCAiw== - dependencies: - "@lexical/utils" "0.12.2" - -"@lexical/mark@0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/mark/-/mark-0.12.2.tgz" - integrity sha512-ub+37PDfmThsqAWipRTrwqpgE+83ckqJ5C3mKQUBZvhZfVZW1rEUXZnKjFh2Q3eZK6iT7zVgoVJWJS9ZgEEyag== - dependencies: - "@lexical/utils" "0.12.2" - -"@lexical/markdown@0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/markdown/-/markdown-0.12.2.tgz" - integrity sha512-F2jTFtBp7Q+yoA11BeUOEcxhROzW+HUhUGdsn20pSLhuxsWRj3oUuryWFeNKFofpzTCVoqU6dwpaMNMI2mL/sQ== - dependencies: - "@lexical/code" "0.12.2" - "@lexical/link" "0.12.2" - "@lexical/list" "0.12.2" - "@lexical/rich-text" "0.12.2" - "@lexical/text" "0.12.2" - "@lexical/utils" "0.12.2" - -"@lexical/offset@0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/offset/-/offset-0.12.2.tgz" - integrity sha512-rZLZXfOBmpmM8A2UZsX3cr/CQYw5F/ou67AbaKI0WImb5sjnIgICZqzu9VFUnkKlVNUurEpplV3UG3D1YYh1OQ== - -"@lexical/overflow@0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/overflow/-/overflow-0.12.2.tgz" - integrity sha512-UgE5j3ukO6qRFRpH4T7m/DvnodE9nCtImD7QinyGdsTa0hi5xlRnl0FUo605vH+vz7xEsUNAGwQXYPX9Sc/vig== - -"@lexical/plain-text@0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/plain-text/-/plain-text-0.12.2.tgz" - integrity sha512-Lcg6+ngRnX70//kz34azYhID3bvW66HSHCfu5UPhCXT+vQ/Jkd/InhRKajBwWXpaJxMM1huoi3sjzVDb3luNtw== - -"@lexical/react@^0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/react/-/react-0.12.2.tgz" - integrity sha512-ZBUvf5xmhiYWBw8pPrhYmLAEwFWrbF/cd15y76TUKD9l/2zDwwPs6nJQxBzfz3ei65r2/nnavLDV8W3QfvxfUA== - dependencies: - "@lexical/clipboard" "0.12.2" - "@lexical/code" "0.12.2" - "@lexical/dragon" "0.12.2" - "@lexical/hashtag" "0.12.2" - "@lexical/history" "0.12.2" - "@lexical/link" "0.12.2" - "@lexical/list" "0.12.2" - "@lexical/mark" "0.12.2" - "@lexical/markdown" "0.12.2" - "@lexical/overflow" "0.12.2" - "@lexical/plain-text" "0.12.2" - "@lexical/rich-text" "0.12.2" - "@lexical/selection" "0.12.2" - "@lexical/table" "0.12.2" - "@lexical/text" "0.12.2" - "@lexical/utils" "0.12.2" - "@lexical/yjs" "0.12.2" - react-error-boundary "^3.1.4" - -"@lexical/rich-text@0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/rich-text/-/rich-text-0.12.2.tgz" - integrity sha512-igsEuv7CwBOAj5c8jeE41cnx6zkhI/Bkbu4W7shT6S6lNA/3cnyZpAMlgixwyK5RoqjGRCT+IJK5l6yBxQfNkw== - -"@lexical/selection@0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/selection/-/selection-0.12.2.tgz" - integrity sha512-h+g3oOnihHKIyLTyG6uLCEVR/DmUEVdCcZO1iAoGsuW7nwWiWNPWj6oZ3Cw5J1Mk5u62DHnkkVDQsVSZbAwmtg== - -"@lexical/table@0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/table/-/table-0.12.2.tgz" - integrity sha512-tiAmTq6RKHDVER9v589Ajm9/RL+WTF1WschrH6HHVCtil6cfJfTJeJ+MF45+XEzB9fkqy2LfrScAfWxqLjVePA== - dependencies: - "@lexical/utils" "0.12.2" - -"@lexical/text@0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/text/-/text-0.12.2.tgz" - integrity sha512-HyuIGuQvVi5djJKKBf+jYEBjK+0Eo9cKHf6WS7dlFozuCZvcCQEJkFy2yceWOwIVk+f2kptVQ5uO7aiZHExH2A== - -"@lexical/utils@0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/utils/-/utils-0.12.2.tgz" - integrity sha512-xW4y4l2Yd37+qLwkBvBGyzsKCA9wnh1ljphBJeR2vreT193i2gaIwuku2ZKlER14VHw4192qNJF7vUoAEmwurQ== - dependencies: - "@lexical/list" "0.12.2" - "@lexical/selection" "0.12.2" - "@lexical/table" "0.12.2" - -"@lexical/yjs@0.12.2": - version "0.12.2" - resolved "https://registry.npmjs.org/@lexical/yjs/-/yjs-0.12.2.tgz" - integrity sha512-OPJhkJD1Mp9W80mfLzASTB3OFWFMzJteUYA+eSyDgiX9zNi1VGxAqmIITTkDvnCMa+qvw4EfhGeGezpjx6Og4A== - dependencies: - "@lexical/offset" "0.12.2" - -"@mdx-js/loader@^2.3.0": - version "2.3.0" - resolved "https://registry.npmjs.org/@mdx-js/loader/-/loader-2.3.0.tgz" - integrity sha512-IqsscXh7Q3Rzb+f5DXYk0HU71PK+WuFsEhf+mSV3fOhpLcEpgsHvTQ2h0T6TlZ5gHOaBeFjkXwB52by7ypMyNg== - dependencies: - "@mdx-js/mdx" "^2.0.0" - source-map "^0.7.0" - -"@mdx-js/mdx@^2.0.0": - version "2.3.0" - resolved "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-2.3.0.tgz" - integrity sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/mdx" "^2.0.0" - estree-util-build-jsx "^2.0.0" - estree-util-is-identifier-name "^2.0.0" - estree-util-to-js "^1.1.0" - estree-walker "^3.0.0" - hast-util-to-estree "^2.0.0" - markdown-extensions "^1.0.0" - periscopic "^3.0.0" - remark-mdx "^2.0.0" - remark-parse "^10.0.0" - remark-rehype "^10.0.0" - unified "^10.0.0" - unist-util-position-from-estree "^1.0.0" - unist-util-stringify-position "^3.0.0" - unist-util-visit "^4.0.0" - vfile "^5.0.0" - -"@mdx-js/react@^2.3.0": - version "2.3.0" - resolved "https://registry.npmjs.org/@mdx-js/react/-/react-2.3.0.tgz" - integrity sha512-zQH//gdOmuu7nt2oJR29vFhDv88oGPmVw6BggmrHeMI+xgEkp1B2dX9/bMBSYtK0dyLX/aOmesKS09g222K1/g== - dependencies: - "@types/mdx" "^2.0.0" - "@types/react" ">=16" - -"@miragejs/pretender-node-polyfill@^0.1.0": - version "0.1.2" - resolved "https://registry.npmjs.org/@miragejs/pretender-node-polyfill/-/pretender-node-polyfill-0.1.2.tgz" - integrity sha512-M/BexG/p05C5lFfMunxo/QcgIJnMT2vDVCd00wNqK2ImZONIlEETZwWJu1QtLxtmYlSHlCFl3JNzp0tLe7OJ5g== - -"@monaco-editor/loader@^1.4.0": - version "1.4.0" - resolved "https://registry.npmjs.org/@monaco-editor/loader/-/loader-1.4.0.tgz" - integrity sha512-00ioBig0x642hytVspPl7DbQyaSWRaolYie/UFNjoTdvoKPzo6xrXLhTk9ixgIKcLH5b5vDOjVNiGyY+uDCUlg== - dependencies: - state-local "^1.0.6" - -"@monaco-editor/react@^4.6.0": - version "4.6.0" - resolved "https://registry.npmjs.org/@monaco-editor/react/-/react-4.6.0.tgz" - integrity sha512-RFkU9/i7cN2bsq/iTkurMWOEErmYcY6JiQI3Jn+WeR/FGISH8JbHERjpS9oRuSOPvDMJI0Z8nJeKkbOs9sBYQw== - dependencies: - "@monaco-editor/loader" "^1.4.0" - -"@next/env@14.1.0": - version "14.1.0" - resolved "https://registry.npmjs.org/@next/env/-/env-14.1.0.tgz" - integrity sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw== - -"@next/eslint-plugin-next@14.1.0": - version "14.1.0" - resolved "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-14.1.0.tgz" - integrity sha512-x4FavbNEeXx/baD/zC/SdrvkjSby8nBn8KcCREqk6UuwvwoAPZmaV8TFCAuo/cpovBRTIY67mHhe86MQQm/68Q== - dependencies: - glob "10.3.10" - -"@next/mdx@^14.0.4": - version "14.1.0" - resolved "https://registry.npmjs.org/@next/mdx/-/mdx-14.1.0.tgz" - integrity sha512-YLYsViq91+H8+3oCtK1iuMWdeN14K70Hy6/tYScY+nfo5bQ84A/A+vA6UdNC9MkbWQ/373hQubx2p4JvUjlb2Q== - dependencies: - source-map "^0.7.0" - -"@next/swc-darwin-arm64@14.1.0": - version "14.1.0" - resolved "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.1.0.tgz" - integrity sha512-nUDn7TOGcIeyQni6lZHfzNoo9S0euXnu0jhsbMOmMJUBfgsnESdjN97kM7cBqQxZa8L/bM9om/S5/1dzCrW6wQ== - -"@next/swc-darwin-x64@14.1.0": - version "14.1.0" - resolved "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-14.1.0.tgz#0863a22feae1540e83c249384b539069fef054e9" - integrity sha512-1jgudN5haWxiAl3O1ljUS2GfupPmcftu2RYJqZiMJmmbBT5M1XDffjUtRUzP4W3cBHsrvkfOFdQ71hAreNQP6g== - -"@next/swc-linux-arm64-gnu@14.1.0": - version "14.1.0" - resolved "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.1.0.tgz#893da533d3fce4aec7116fe772d4f9b95232423c" - integrity sha512-RHo7Tcj+jllXUbK7xk2NyIDod3YcCPDZxj1WLIYxd709BQ7WuRYl3OWUNG+WUfqeQBds6kvZYlc42NJJTNi4tQ== - -"@next/swc-linux-arm64-musl@14.1.0": - version "14.1.0" - resolved "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.1.0.tgz#d81ddcf95916310b8b0e4ad32b637406564244c0" - integrity sha512-v6kP8sHYxjO8RwHmWMJSq7VZP2nYCkRVQ0qolh2l6xroe9QjbgV8siTbduED4u0hlk0+tjS6/Tuy4n5XCp+l6g== - -"@next/swc-linux-x64-gnu@14.1.0": - version "14.1.0" - resolved "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.1.0.tgz#18967f100ec19938354332dcb0268393cbacf581" - integrity sha512-zJ2pnoFYB1F4vmEVlb/eSe+VH679zT1VdXlZKX+pE66grOgjmKJHKacf82g/sWE4MQ4Rk2FMBCRnX+l6/TVYzQ== - -"@next/swc-linux-x64-musl@14.1.0": - version "14.1.0" - resolved "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.1.0.tgz#77077cd4ba8dda8f349dc7ceb6230e68ee3293cf" - integrity sha512-rbaIYFt2X9YZBSbH/CwGAjbBG2/MrACCVu2X0+kSykHzHnYH5FjHxwXLkcoJ10cX0aWCEynpu+rP76x0914atg== - -"@next/swc-win32-arm64-msvc@14.1.0": - version "14.1.0" - resolved "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.1.0.tgz#5f0b8cf955644104621e6d7cc923cad3a4c5365a" - integrity sha512-o1N5TsYc8f/HpGt39OUQpQ9AKIGApd3QLueu7hXk//2xq5Z9OxmV6sQfNp8C7qYmiOlHYODOGqNNa0e9jvchGQ== - -"@next/swc-win32-ia32-msvc@14.1.0": - version "14.1.0" - resolved "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.1.0.tgz#21f4de1293ac5e5a168a412b139db5d3420a89d0" - integrity sha512-XXIuB1DBRCFwNO6EEzCTMHT5pauwaSj4SWs7CYnME57eaReAKBXCnkUE80p/pAZcewm7hs+vGvNqDPacEXHVkw== - -"@next/swc-win32-x64-msvc@14.1.0": - version "14.1.0" - resolved "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.1.0.tgz#e561fb330466d41807123d932b365cf3d33ceba2" - integrity sha512-9WEbVRRAqJ3YFVqEZIxUqkiO8l1nool1LmNxygr5HWF8AcSYsEpneUDhmjUVJEzO2A04+oPtZdombzzPPkTtgg== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== - -"@pkgr/utils@^2.3.1": - version "2.4.1" - resolved "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.1.tgz" - integrity sha512-JOqwkgFEyi+OROIyq7l4Jy28h/WwhDnG/cPkXG2Z1iFbubB6jsHW1NDvmyOzTBxHr3yg68YGirmh1JUgMqa+9w== - dependencies: - cross-spawn "^7.0.3" - fast-glob "^3.2.12" - is-glob "^4.0.3" - open "^9.1.0" - picocolors "^1.0.0" - tslib "^2.5.0" - -"@reactflow/background@11.3.8": - version "11.3.8" - resolved "https://registry.npmjs.org/@reactflow/background/-/background-11.3.8.tgz" - integrity sha512-U4aI54F7PwqgYI0Knv72QFRI/wXeipPmIYAlDsA0j51+tlPxs3Nk2z7G1/4pC11GxEZkgQVfcIXro4l1Fk+bIQ== - dependencies: - "@reactflow/core" "11.10.3" - classcat "^5.0.3" - zustand "^4.4.1" - -"@reactflow/controls@11.2.8": - version "11.2.8" - resolved "https://registry.npmjs.org/@reactflow/controls/-/controls-11.2.8.tgz" - integrity sha512-Y9YVx38sRjYtbPsI/xa+B1FGN73FV1GqqajlmGfrc1TmqhJaX+gaMXMvVazT/N5haK1hMJvOApUTLQ2V/5Rdbg== - dependencies: - "@reactflow/core" "11.10.3" - classcat "^5.0.3" - zustand "^4.4.1" - -"@reactflow/core@11.10.3": - version "11.10.3" - resolved "https://registry.npmjs.org/@reactflow/core/-/core-11.10.3.tgz" - integrity sha512-nV3nep4fjBy3h8mYSnJcclGcQtj8fkUBmNkEwCZCK4ps+n3HNkXFB0BRisSnQz6GRQlYboSsi0cThEl3KdNITw== - dependencies: - "@types/d3" "^7.4.0" - "@types/d3-drag" "^3.0.1" - "@types/d3-selection" "^3.0.3" - "@types/d3-zoom" "^3.0.1" - classcat "^5.0.3" - d3-drag "^3.0.0" - d3-selection "^3.0.0" - d3-zoom "^3.0.0" - zustand "^4.4.1" - -"@reactflow/minimap@11.7.8": - version "11.7.8" - resolved "https://registry.npmjs.org/@reactflow/minimap/-/minimap-11.7.8.tgz" - integrity sha512-MwyP5q3VomC91Dhd4P6YcxEfnjDbREGYV6rRxbSJSTHiG0x7ETQCcPelYDGy7JvQej77Pa2yJ4g0FDwP7CsQEA== - dependencies: - "@reactflow/core" "11.10.3" - "@types/d3-selection" "^3.0.3" - "@types/d3-zoom" "^3.0.1" - classcat "^5.0.3" - d3-selection "^3.0.0" - d3-zoom "^3.0.0" - zustand "^4.4.1" - -"@reactflow/node-resizer@2.2.8": - version "2.2.8" - resolved "https://registry.npmjs.org/@reactflow/node-resizer/-/node-resizer-2.2.8.tgz" - integrity sha512-u/EXLpvOfAmq1sGoPYwoX4gi0PnCi0mH3eHVClHNc8JQD0WCqcV1UeVV7H3PF+1SGhhg/aOv/vPG1PcQ5fu4jQ== - dependencies: - "@reactflow/core" "11.10.3" - classcat "^5.0.4" - d3-drag "^3.0.0" - d3-selection "^3.0.0" - zustand "^4.4.1" - -"@reactflow/node-toolbar@1.3.8": - version "1.3.8" - resolved "https://registry.npmjs.org/@reactflow/node-toolbar/-/node-toolbar-1.3.8.tgz" - integrity sha512-cfvlTPeJa/ciQTosx2bGrjHT8K/UL9kznpvpOzeZFnJm5UQXmbwAYt4Vo6GfkD51mORcIL7ujQJvB9ym3ZI9KA== - dependencies: - "@reactflow/core" "11.10.3" - classcat "^5.0.3" - zustand "^4.4.1" - -"@rgrove/parse-xml@^4.1.0": - version "4.1.0" - resolved "https://registry.npmjs.org/@rgrove/parse-xml/-/parse-xml-4.1.0.tgz" - integrity sha512-pBiltENdy8SfI0AeR1e5TRpS9/9Gl0eiOEt6ful2jQfzsgvZYWqsKiBWaOCLdocQuk0wS7KOHI37n0C1pnKqTw== - -"@rushstack/eslint-patch@^1.3.3": - version "1.7.2" - resolved "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.7.2.tgz" - integrity sha512-RbhOOTCNoCrbfkRyoXODZp75MlpiHMgbE5MEBZAnnnLyQNgrigEj4p0lzsMDyc1zVsJDLrivB58tgg3emX0eEA== - -"@sentry-internal/tracing@7.54.0": - version "7.54.0" - resolved "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.54.0.tgz" - integrity sha512-JsyhZ0wWZ+VqbHJg+azqRGdYJDkcI5R9+pnkO6SzbzxrRewqMAIwzkpPee3oI7vG99uhMEkOkMjHu0nQGwkOQw== - dependencies: - "@sentry/core" "7.54.0" - "@sentry/types" "7.54.0" - "@sentry/utils" "7.54.0" - tslib "^1.9.3" - -"@sentry/browser@7.54.0": - version "7.54.0" - resolved "https://registry.npmjs.org/@sentry/browser/-/browser-7.54.0.tgz" - integrity sha512-EvLAw03N9WE2m1CMl2/1YMeIs1icw9IEOVJhWmf3uJEysNJOFWXu6ZzdtHEz1E6DiJYhc1HzDya0ExZeJxNARA== - dependencies: - "@sentry-internal/tracing" "7.54.0" - "@sentry/core" "7.54.0" - "@sentry/replay" "7.54.0" - "@sentry/types" "7.54.0" - "@sentry/utils" "7.54.0" - tslib "^1.9.3" - -"@sentry/core@7.54.0": - version "7.54.0" - resolved "https://registry.npmjs.org/@sentry/core/-/core-7.54.0.tgz" - integrity sha512-MAn0E2EwgNn1pFQn4qxhU+1kz6edullWg6VE5wCmtpXWOVw6sILBUsQpeIG5djBKMcneJCdOlz5jeqcKPrLvZQ== - dependencies: - "@sentry/types" "7.54.0" - "@sentry/utils" "7.54.0" - tslib "^1.9.3" - -"@sentry/react@^7.54.0": - version "7.54.0" - resolved "https://registry.npmjs.org/@sentry/react/-/react-7.54.0.tgz" - integrity sha512-qUbwmRRpTh05m2rbC8A2zAFQYsoHhwIpxT5UXxh0P64ZlA3cSg1/DmTTgwnd1l+7gzKrc31UikXQ4y0YDbMNKg== - dependencies: - "@sentry/browser" "7.54.0" - "@sentry/types" "7.54.0" - "@sentry/utils" "7.54.0" - hoist-non-react-statics "^3.3.2" - tslib "^1.9.3" - -"@sentry/replay@7.54.0": - version "7.54.0" - resolved "https://registry.npmjs.org/@sentry/replay/-/replay-7.54.0.tgz" - integrity sha512-C0F0568ybphzGmKGe23duB6n5wJcgM7WLYhoeqW3o2bHeqpj1dGPSka/K3s9KzGaAgzn1zeOUYXJsOs+T/XdsA== - dependencies: - "@sentry/core" "7.54.0" - "@sentry/types" "7.54.0" - "@sentry/utils" "7.54.0" - -"@sentry/types@7.54.0": - version "7.54.0" - resolved "https://registry.npmjs.org/@sentry/types/-/types-7.54.0.tgz" - integrity sha512-D+i9xogBeawvQi2r0NOrM7zYcUaPuijeME4O9eOTrDF20tj71hWtJLilK+KTGLYFtpGg1h+9bPaz7OHEIyVopg== - -"@sentry/utils@7.54.0", "@sentry/utils@^7.54.0": - version "7.54.0" - resolved "https://registry.npmjs.org/@sentry/utils/-/utils-7.54.0.tgz" - integrity sha512-3Yf5KlKjIcYLddOexSt2ovu2TWlR4Fi7M+aCK8yUTzwNzf/xwFSWOstHlD/WiDy9HvfhWAOB/ukNTuAeJmtasw== - dependencies: - "@sentry/types" "7.54.0" - tslib "^1.9.3" - -"@swc/helpers@0.5.2": - version "0.5.2" - resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz" - integrity sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw== - dependencies: - tslib "^2.4.0" - -"@tailwindcss/line-clamp@^0.4.4": - version "0.4.4" - resolved "https://registry.npmjs.org/@tailwindcss/line-clamp/-/line-clamp-0.4.4.tgz" - integrity sha512-5U6SY5z8N42VtrCrKlsTAA35gy2VSyYtHWCsg1H87NU1SXnEfekTVlrga9fzUDrrHcGi2Lb5KenUWb4lRQT5/g== - -"@tailwindcss/typography@^0.5.9": - version "0.5.9" - resolved "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.9.tgz" - integrity sha512-t8Sg3DyynFysV9f4JDOVISGsjazNb48AeIYQwcL+Bsq5uf4RYL75C1giZ43KISjeDGBaTN3Kxh7Xj/vRSMJUUg== - dependencies: - lodash.castarray "^4.4.0" - lodash.isplainobject "^4.0.6" - lodash.merge "^4.6.2" - postcss-selector-parser "6.0.10" - -"@types/acorn@^4.0.0": - version "4.0.6" - resolved "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz" - integrity sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ== - dependencies: - "@types/estree" "*" - -"@types/crypto-js@^4.1.1": - version "4.1.1" - resolved "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-4.1.1.tgz" - integrity sha512-BG7fQKZ689HIoc5h+6D2Dgq1fABRa0RbBWKBd9SP/MVRVXROflpm5fhwyATX5duFmbStzyzyycPB8qUYKDH3NA== - -"@types/d3-array@*": - version "3.2.1" - resolved "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.1.tgz" - integrity sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg== - -"@types/d3-axis@*": - version "3.0.6" - resolved "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz" - integrity sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw== - dependencies: - "@types/d3-selection" "*" - -"@types/d3-brush@*": - version "3.0.6" - resolved "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz" - integrity sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A== - dependencies: - "@types/d3-selection" "*" - -"@types/d3-chord@*": - version "3.0.6" - resolved "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz" - integrity sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg== - -"@types/d3-color@*": - version "3.1.3" - resolved "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz" - integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A== - -"@types/d3-contour@*": - version "3.0.6" - resolved "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz" - integrity sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg== - dependencies: - "@types/d3-array" "*" - "@types/geojson" "*" - -"@types/d3-delaunay@*": - version "6.0.4" - resolved "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz" - integrity sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw== - -"@types/d3-dispatch@*": - version "3.0.6" - resolved "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.6.tgz" - integrity sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ== - -"@types/d3-drag@*", "@types/d3-drag@^3.0.1": - version "3.0.7" - resolved "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz" - integrity sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ== - dependencies: - "@types/d3-selection" "*" - -"@types/d3-dsv@*": - version "3.0.7" - resolved "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz" - integrity sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g== - -"@types/d3-ease@*": - version "3.0.2" - resolved "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz" - integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA== - -"@types/d3-fetch@*": - version "3.0.7" - resolved "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz" - integrity sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA== - dependencies: - "@types/d3-dsv" "*" - -"@types/d3-force@*": - version "3.0.9" - resolved "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.9.tgz" - integrity sha512-IKtvyFdb4Q0LWna6ymywQsEYjK/94SGhPrMfEr1TIc5OBeziTi+1jcCvttts8e0UWZIxpasjnQk9MNk/3iS+kA== - -"@types/d3-format@*": - version "3.0.4" - resolved "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz" - integrity sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g== - -"@types/d3-geo@*": - version "3.1.0" - resolved "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz" - integrity sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ== - dependencies: - "@types/geojson" "*" - -"@types/d3-hierarchy@*": - version "3.1.6" - resolved "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.6.tgz" - integrity sha512-qlmD/8aMk5xGorUvTUWHCiumvgaUXYldYjNVOWtYoTYY/L+WwIEAmJxUmTgr9LoGNG0PPAOmqMDJVDPc7DOpPw== - -"@types/d3-interpolate@*": - version "3.0.4" - resolved "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz" - integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA== - dependencies: - "@types/d3-color" "*" - -"@types/d3-path@*": - version "3.0.2" - resolved "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.0.2.tgz" - integrity sha512-WAIEVlOCdd/NKRYTsqCpOMHQHemKBEINf8YXMYOtXH0GA7SY0dqMB78P3Uhgfy+4X+/Mlw2wDtlETkN6kQUCMA== - -"@types/d3-polygon@*": - version "3.0.2" - resolved "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz" - integrity sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA== - -"@types/d3-quadtree@*": - version "3.0.6" - resolved "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz" - integrity sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg== - -"@types/d3-random@*": - version "3.0.3" - resolved "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz" - integrity sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ== - -"@types/d3-scale-chromatic@*", "@types/d3-scale-chromatic@^3.0.0": - version "3.0.0" - resolved "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz" - integrity sha512-dsoJGEIShosKVRBZB0Vo3C8nqSDqVGujJU6tPznsBJxNJNwMF8utmS83nvCBKQYPpjCzaaHcrf66iTRpZosLPw== - -"@types/d3-scale@*", "@types/d3-scale@^4.0.3": - version "4.0.4" - resolved "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.4.tgz" - integrity sha512-eq1ZeTj0yr72L8MQk6N6heP603ubnywSDRfNpi5enouR112HzGLS6RIvExCzZTraFF4HdzNpJMwA/zGiMoHUUw== - dependencies: - "@types/d3-time" "*" - -"@types/d3-selection@*", "@types/d3-selection@^3.0.3": - version "3.0.10" - resolved "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.10.tgz" - integrity sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg== - -"@types/d3-shape@*": - version "3.1.6" - resolved "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.6.tgz" - integrity sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA== - dependencies: - "@types/d3-path" "*" - -"@types/d3-time-format@*": - version "4.0.3" - resolved "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz" - integrity sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg== - -"@types/d3-time@*": - version "3.0.0" - resolved "https://registry.npmjs.org/@types/d3-time/-/d3-time-3.0.0.tgz" - integrity sha512-sZLCdHvBUcNby1cB6Fd3ZBrABbjz3v1Vm90nysCQ6Vt7vd6e/h9Lt7SiJUoEX0l4Dzc7P5llKyhqSi1ycSf1Hg== - -"@types/d3-timer@*": - version "3.0.2" - resolved "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz" - integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw== - -"@types/d3-transition@*": - version "3.0.8" - resolved "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.8.tgz" - integrity sha512-ew63aJfQ/ms7QQ4X7pk5NxQ9fZH/z+i24ZfJ6tJSfqxJMrYLiK01EAs2/Rtw/JreGUsS3pLPNV644qXFGnoZNQ== - dependencies: - "@types/d3-selection" "*" - -"@types/d3-zoom@*", "@types/d3-zoom@^3.0.1": - version "3.0.8" - resolved "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz" - integrity sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw== - dependencies: - "@types/d3-interpolate" "*" - "@types/d3-selection" "*" - -"@types/d3@^7.4.0": - version "7.4.3" - resolved "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz" - integrity sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww== - dependencies: - "@types/d3-array" "*" - "@types/d3-axis" "*" - "@types/d3-brush" "*" - "@types/d3-chord" "*" - "@types/d3-color" "*" - "@types/d3-contour" "*" - "@types/d3-delaunay" "*" - "@types/d3-dispatch" "*" - "@types/d3-drag" "*" - "@types/d3-dsv" "*" - "@types/d3-ease" "*" - "@types/d3-fetch" "*" - "@types/d3-force" "*" - "@types/d3-format" "*" - "@types/d3-geo" "*" - "@types/d3-hierarchy" "*" - "@types/d3-interpolate" "*" - "@types/d3-path" "*" - "@types/d3-polygon" "*" - "@types/d3-quadtree" "*" - "@types/d3-random" "*" - "@types/d3-scale" "*" - "@types/d3-scale-chromatic" "*" - "@types/d3-selection" "*" - "@types/d3-shape" "*" - "@types/d3-time" "*" - "@types/d3-time-format" "*" - "@types/d3-timer" "*" - "@types/d3-transition" "*" - "@types/d3-zoom" "*" - -"@types/dagre@^0.7.52": - version "0.7.52" - resolved "https://registry.npmjs.org/@types/dagre/-/dagre-0.7.52.tgz" - integrity sha512-XKJdy+OClLk3hketHi9Qg6gTfe1F3y+UFnHxKA2rn9Dw+oXa4Gb378Ztz9HlMgZKSxpPmn4BNVh9wgkpvrK1uw== - -"@types/debug@^4.0.0": - version "4.1.8" - resolved "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz" - integrity sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ== - dependencies: - "@types/ms" "*" - -"@types/estree-jsx@^1.0.0": - version "1.0.0" - resolved "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.0.tgz" - integrity sha512-3qvGd0z8F2ENTGr/GG1yViqfiKmRfrXVx5sJyHGFu3z7m5g5utCQtGp/g29JnjflhtQJBv1WDQukHiT58xPcYQ== - dependencies: - "@types/estree" "*" - -"@types/estree@*", "@types/estree@^1.0.0": - version "1.0.1" - resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz" - integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== - -"@types/geojson@*": - version "7946.0.14" - resolved "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.14.tgz" - integrity sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg== - -"@types/hast@^2.0.0": - version "2.3.4" - resolved "https://registry.npmjs.org/@types/hast/-/hast-2.3.4.tgz" - integrity sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g== - dependencies: - "@types/unist" "*" - -"@types/js-cookie@^2.x.x": - version "2.2.7" - resolved "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz" - integrity sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA== - -"@types/js-cookie@^3.0.3": - version "3.0.3" - resolved "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-3.0.3.tgz" - integrity sha512-Xe7IImK09HP1sv2M/aI+48a20VX+TdRJucfq4vfRVy6nWN8PYPOEnlMRSgxJAgYQIXJVL8dZ4/ilAM7dWNaOww== - -"@types/json-schema@^7.0.9": - version "7.0.12" - resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz" - integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz" - integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== - -"@types/katex@^0.14.0": - version "0.14.0" - resolved "https://registry.npmjs.org/@types/katex/-/katex-0.14.0.tgz" - integrity sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA== - -"@types/katex@^0.16.0": - version "0.16.0" - resolved "https://registry.npmjs.org/@types/katex/-/katex-0.16.0.tgz" - integrity sha512-hz+S3nV6Mym5xPbT9fnO8dDhBFQguMYpY0Ipxv06JMi1ORgnEM4M1ymWDUhUNer3ElLmT583opRo4RzxKmh9jw== - -"@types/lodash-es@^4.17.7": - version "4.17.7" - resolved "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.7.tgz" - integrity sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ== - dependencies: - "@types/lodash" "*" - -"@types/lodash@*": - version "4.14.195" - resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.195.tgz" - integrity sha512-Hwx9EUgdwf2GLarOjQp5ZH8ZmblzcbTBC2wtQWNKARBSxM9ezRIAUpeDTgoQRAFB0+8CNWXVA9+MaSOzOF3nPg== - -"@types/mdast@^3.0.0": - version "3.0.11" - resolved "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.11.tgz" - integrity sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw== - dependencies: - "@types/unist" "*" - -"@types/mdx@^2.0.0": - version "2.0.5" - resolved "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.5.tgz" - integrity sha512-76CqzuD6Q7LC+AtbPqrvD9AqsN0k8bsYo2bM2J8pmNldP1aIPAbzUQ7QbobyXL4eLr1wK5x8FZFe8eF/ubRuBg== - -"@types/ms@*": - version "0.7.31" - resolved "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz" - integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== - -"@types/negotiator@^0.6.1": - version "0.6.1" - resolved "https://registry.npmjs.org/@types/negotiator/-/negotiator-0.6.1.tgz" - integrity sha512-c4mvXFByghezQ/eVGN5HvH/jI63vm3B7FiE81BUzDAWmuiohRecCO6ddU60dfq29oKUMiQujsoB2h0JQC7JHKA== - -"@types/node@*", "@types/node@18.15.0": - version "18.15.0" - resolved "https://registry.npmjs.org/@types/node/-/node-18.15.0.tgz" - integrity sha512-z6nr0TTEOBGkzLGmbypWOGnpSpSIBorEhC4L+4HeQ2iezKCi4f77kyslRwvHeNitymGQ+oFyIWGP96l/DPSV9w== - -"@types/normalize-package-data@^2.4.0": - version "2.4.1" - resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz" - integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== - -"@types/papaparse@^5.3.1": - version "5.3.7" - resolved "https://registry.npmjs.org/@types/papaparse/-/papaparse-5.3.7.tgz" - integrity sha512-f2HKmlnPdCvS0WI33WtCs5GD7X1cxzzS/aduaxSu3I7TbhWlENjSPs6z5TaB9K0J+BH1jbmqTaM+ja5puis4wg== - dependencies: - "@types/node" "*" - -"@types/prop-types@*", "@types/prop-types@^15.0.0": - version "15.7.5" - resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz" - integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== - -"@types/qs@^6.9.7": - version "6.9.7" - resolved "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== - -"@types/react-dom@18.0.11": - version "18.0.11" - resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.11.tgz" - integrity sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw== - dependencies: - "@types/react" "*" - -"@types/react-slider@^1.3.1": - version "1.3.1" - resolved "https://registry.npmjs.org/@types/react-slider/-/react-slider-1.3.1.tgz" - integrity sha512-4X2yK7RyCIy643YCFL+bc6XNmcnBtt8n88uuyihvcn5G7Lut23eNQU3q3KmwF7MWIfKfsW5NxCjw0SeDZRtgaA== - dependencies: - "@types/react" "*" - -"@types/react-syntax-highlighter@^15.5.6": - version "15.5.7" - resolved "https://registry.npmjs.org/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.7.tgz" - integrity sha512-bo5fEO5toQeyCp0zVHBeggclqf5SQ/Z5blfFmjwO5dkMVGPgmiwZsJh9nu/Bo5L7IHTuGWrja6LxJVE2uB5ZrQ== - dependencies: - "@types/react" "*" - -"@types/react-window-infinite-loader@^1.0.6": - version "1.0.6" - resolved "https://registry.npmjs.org/@types/react-window-infinite-loader/-/react-window-infinite-loader-1.0.6.tgz" - integrity sha512-V8g8sBDLVeJJAfEENJS7VXZK+DRJ+jzPNtk8jpj2G+obhf+iqGNUDGwNWCbBhLiD+KpHhf3kWQlKBRi0tAeU4Q== - dependencies: - "@types/react" "*" - "@types/react-window" "*" - -"@types/react-window@*", "@types/react-window@^1.8.5": - version "1.8.5" - resolved "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.5.tgz" - integrity sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw== - dependencies: - "@types/react" "*" - -"@types/react@*", "@types/react@>=16": - version "18.0.28" - resolved "https://registry.npmjs.org/@types/react/-/react-18.0.28.tgz" - integrity sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - -"@types/react@^18.3.1": - version "18.3.1" - resolved "https://registry.npmjs.org/@types/react/-/react-18.3.1.tgz#fed43985caa834a2084d002e4771e15dfcbdbe8e" - integrity sha512-V0kuGBX3+prX+DQ/7r2qsv1NsdfnCLnTgnRJ1pYnxykBhGMz+qj+box5lq7XsO5mtZsBqpjwwTu/7wszPfMBcw== - dependencies: - "@types/prop-types" "*" - csstype "^3.0.2" - -"@types/recordrtc@^5.6.11": - version "5.6.11" - resolved "https://registry.npmjs.org/@types/recordrtc/-/recordrtc-5.6.11.tgz" - integrity sha512-X4XD5nltz0cjmyzsPNegQReOPF+C5ARTfSPAPhqnKV7SsfRta/M4FBJ5AtSInCaEveL71FLLSVQE9mg8Uuo++w== - -"@types/scheduler@*": - version "0.16.3" - resolved "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.3.tgz" - integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== - -"@types/semver@^7.3.12": - version "7.5.0" - resolved "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz" - integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== - -"@types/sortablejs@^1.15.1": - version "1.15.1" - resolved "https://registry.npmjs.org/@types/sortablejs/-/sortablejs-1.15.1.tgz" - integrity sha512-g/JwBNToh6oCTAwNS8UGVmjO7NLDKsejVhvE4x1eWiPTC3uCuNsa/TD4ssvX3du+MLiM+SHPNDuijp8y76JzLQ== - -"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2": - version "2.0.6" - resolved "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz" - integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== - -"@types/uuid@^9.0.8": - version "9.0.8" - resolved "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz" - integrity sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA== - -"@typescript-eslint/eslint-plugin@^5.53.0": - version "5.59.9" - resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.9.tgz" - integrity sha512-4uQIBq1ffXd2YvF7MAvehWKW3zVv/w+mSfRAu+8cKbfj3nwzyqJLNcZJpQ/WZ1HLbJDiowwmQ6NO+63nCA+fqA== - dependencies: - "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.59.9" - "@typescript-eslint/type-utils" "5.59.9" - "@typescript-eslint/utils" "5.59.9" - debug "^4.3.4" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - natural-compare-lite "^1.4.0" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/parser@^5.4.2 || ^6.0.0", "@typescript-eslint/parser@^5.53.0": - version "5.59.9" - resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.9.tgz" - integrity sha512-FsPkRvBtcLQ/eVK1ivDiNYBjn3TGJdXy2fhXX+rc7czWl4ARwnpArwbihSOHI2Peg9WbtGHrbThfBUkZZGTtvQ== - dependencies: - "@typescript-eslint/scope-manager" "5.59.9" - "@typescript-eslint/types" "5.59.9" - "@typescript-eslint/typescript-estree" "5.59.9" - debug "^4.3.4" - -"@typescript-eslint/scope-manager@5.59.9": - version "5.59.9" - resolved "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.9.tgz" - integrity sha512-8RA+E+w78z1+2dzvK/tGZ2cpGigBZ58VMEHDZtpE1v+LLjzrYGc8mMaTONSxKyEkz3IuXFM0IqYiGHlCsmlZxQ== - dependencies: - "@typescript-eslint/types" "5.59.9" - "@typescript-eslint/visitor-keys" "5.59.9" - -"@typescript-eslint/type-utils@5.59.9": - version "5.59.9" - resolved "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.59.9.tgz" - integrity sha512-ksEsT0/mEHg9e3qZu98AlSrONAQtrSTljL3ow9CGej8eRo7pe+yaC/mvTjptp23Xo/xIf2mLZKC6KPv4Sji26Q== - dependencies: - "@typescript-eslint/typescript-estree" "5.59.9" - "@typescript-eslint/utils" "5.59.9" - debug "^4.3.4" - tsutils "^3.21.0" - -"@typescript-eslint/types@5.59.9": - version "5.59.9" - resolved "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.9.tgz" - integrity sha512-uW8H5NRgTVneSVTfiCVffBb8AbwWSKg7qcA4Ot3JI3MPCJGsB4Db4BhvAODIIYE5mNj7Q+VJkK7JxmRhk2Lyjw== - -"@typescript-eslint/typescript-estree@5.59.9": - version "5.59.9" - resolved "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.9.tgz" - integrity sha512-pmM0/VQ7kUhd1QyIxgS+aRvMgw+ZljB3eDb+jYyp6d2bC0mQWLzUDF+DLwCTkQ3tlNyVsvZRXjFyV0LkU/aXjA== - dependencies: - "@typescript-eslint/types" "5.59.9" - "@typescript-eslint/visitor-keys" "5.59.9" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/utils@5.59.9", "@typescript-eslint/utils@^5.10.0", "@typescript-eslint/utils@^5.53.0": - version "5.59.9" - resolved "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.59.9.tgz" - integrity sha512-1PuMYsju/38I5Ggblaeb98TOoUvjhRvLpLa1DoTOFaLWqaXl/1iQ1eGurTXgBY58NUdtfTXKP5xBq7q9NDaLKg== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.59.9" - "@typescript-eslint/types" "5.59.9" - "@typescript-eslint/typescript-estree" "5.59.9" - eslint-scope "^5.1.1" - semver "^7.3.7" - -"@typescript-eslint/visitor-keys@5.59.9": - version "5.59.9" - resolved "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.9.tgz" - integrity sha512-bT7s0td97KMaLwpEBckbzj/YohnvXtqbe2XgqNvTl6RJVakY5mvENOTPvw5u66nljfZxthESpDozs86U+oLY8Q== - dependencies: - "@typescript-eslint/types" "5.59.9" - eslint-visitor-keys "^3.3.0" - -"@vue/compiler-core@3.4.25": - version "3.4.25" - resolved "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.25.tgz" - integrity sha512-Y2pLLopaElgWnMNolgG8w3C5nNUVev80L7hdQ5iIKPtMJvhVpG0zhnBG/g3UajJmZdvW0fktyZTotEHD1Srhbg== - dependencies: - "@babel/parser" "^7.24.4" - "@vue/shared" "3.4.25" - entities "^4.5.0" - estree-walker "^2.0.2" - source-map-js "^1.2.0" - -"@vue/compiler-dom@^3.2.47": - version "3.4.25" - resolved "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.25.tgz" - integrity sha512-Ugz5DusW57+HjllAugLci19NsDK+VyjGvmbB2TXaTcSlQxwL++2PETHx/+Qv6qFwNLzSt7HKepPe4DcTE3pBWg== - dependencies: - "@vue/compiler-core" "3.4.25" - "@vue/shared" "3.4.25" - -"@vue/shared@3.4.25": - version "3.4.25" - resolved "https://registry.npmjs.org/@vue/shared/-/shared-3.4.25.tgz" - integrity sha512-k0yappJ77g2+KNrIaF0FFnzwLvUBLUYr8VOwz+/6vLsmItFp51AcxLL7Ey3iPd7BIRyWPOcqUjMnm7OkahXllA== - -acorn-jsx@^5.0.0, acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn@^8.0.0, acorn@^8.5.0, acorn@^8.8.0: - version "8.8.2" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ahooks-v3-count@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/ahooks-v3-count/-/ahooks-v3-count-1.0.0.tgz" - integrity sha512-V7uUvAwnimu6eh/PED4mCDjE7tokeZQLKlxg9lCTMPhN+NjsSbtdacByVlR1oluXQzD3MOw55wylDmQo4+S9ZQ== - -ahooks@^3.7.5: - version "3.7.7" - resolved "https://registry.npmjs.org/ahooks/-/ahooks-3.7.7.tgz" - integrity sha512-5e5WlPq81Y84UnTLOKIQeq2cJw4aa7yj8fR2Nb/oMmXPrWMjIMCbPS1o+fpxSfCaNA3AzOnnMc8AehWRZltkJQ== - dependencies: - "@babel/runtime" "^7.21.0" - "@types/js-cookie" "^2.x.x" - ahooks-v3-count "^1.0.0" - dayjs "^1.9.1" - intersection-observer "^0.12.0" - js-cookie "^2.x.x" - lodash "^4.17.21" - resize-observer-polyfill "^1.5.1" - screenfull "^5.0.0" - tslib "^2.4.1" - -ajv@^6.10.0, ajv@^6.12.4: - version "6.12.6" - 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" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-escapes@^4.3.0: - version "4.3.2" - resolved "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^6.0.0, ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - -any-promise@^1.0.0: - version "1.3.0" - resolved "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz" - integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== - -anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -arg@^5.0.2: - version "5.0.2" - resolved "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz" - integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -aria-query@^5.1.3: - version "5.1.3" - resolved "https://registry.npmjs.org/aria-query/-/aria-query-5.1.3.tgz" - integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== - dependencies: - deep-equal "^2.0.5" - -array-buffer-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz" - integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== - dependencies: - call-bind "^1.0.2" - is-array-buffer "^3.0.1" - -array-includes@^3.1.5, array-includes@^3.1.6, array-includes@^3.1.7: - version "3.1.7" - resolved "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz" - integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - is-string "^1.0.7" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array.prototype.findlastindex@^1.2.3: - version "1.2.3" - resolved "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz" - integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - get-intrinsic "^1.2.1" - -array.prototype.flat@^1.3.2: - version "1.3.2" - resolved "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz" - integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - -array.prototype.flatmap@^1.3.1, array.prototype.flatmap@^1.3.2: - version "1.3.2" - resolved "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz" - integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - -array.prototype.tosorted@^1.1.1: - version "1.1.2" - resolved "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz" - integrity sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - get-intrinsic "^1.2.1" - -arraybuffer.prototype.slice@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz" - integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== - dependencies: - array-buffer-byte-length "^1.0.0" - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - is-array-buffer "^3.0.2" - is-shared-array-buffer "^1.0.2" - -ast-types-flow@^0.0.7: - version "0.0.7" - resolved "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz" - integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== - -astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== - -astring@^1.8.0: - version "1.8.6" - resolved "https://registry.npmjs.org/astring/-/astring-1.8.6.tgz" - integrity sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg== - -async@^2.6.4: - version "2.6.4" - resolved "https://registry.npmjs.org/async/-/async-2.6.4.tgz" - integrity sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA== - dependencies: - lodash "^4.17.14" - -asynciterator.prototype@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz" - integrity sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg== - dependencies: - has-symbols "^1.0.3" - -autoprefixer@^10.4.14: - version "10.4.14" - resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz" - integrity sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ== - dependencies: - browserslist "^4.21.5" - caniuse-lite "^1.0.30001464" - fraction.js "^4.2.0" - normalize-range "^0.1.2" - picocolors "^1.0.0" - postcss-value-parser "^4.2.0" - -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== - -axe-core@^4.6.2: - version "4.7.2" - resolved "https://registry.npmjs.org/axe-core/-/axe-core-4.7.2.tgz" - integrity sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g== - -axobject-query@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/axobject-query/-/axobject-query-3.1.1.tgz" - integrity sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg== - dependencies: - deep-equal "^2.0.5" - -bail@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz" - integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -big-integer@^1.6.44: - version "1.6.51" - resolved "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz" - integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -boolbase@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz" - integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== - -bplist-parser@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz" - integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== - dependencies: - big-integer "^1.6.44" - -brace-expansion@^1.1.7: - 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" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -browserslist@^4.21.5: - version "4.21.7" - resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.21.7.tgz" - integrity sha512-BauCXrQ7I2ftSqd2mvKHGo85XR0u7Ru3C/Hxsy/0TkfCtjrmAbPdzLGasmoiBxplpDXlPvdjX9u7srIMfgasNA== - dependencies: - caniuse-lite "^1.0.30001489" - electron-to-chromium "^1.4.411" - node-releases "^2.0.12" - update-browserslist-db "^1.0.11" - -builtin-modules@^3.3.0: - version "3.3.0" - resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz" - integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== - -builtins@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz" - integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ== - dependencies: - semver "^7.0.0" - -bundle-name@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz" - integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== - dependencies: - run-applescript "^5.0.0" - -busboy@1.6.0: - version "1.6.0" - resolved "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz" - integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== - dependencies: - streamsearch "^1.1.0" - -call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz" - integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== - dependencies: - function-bind "^1.1.2" - get-intrinsic "^1.2.1" - set-function-length "^1.1.1" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase-css@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz" - integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== - -caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001489, caniuse-lite@^1.0.30001579: - version "1.0.30001581" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001581.tgz" - integrity sha512-whlTkwhqV2tUmP3oYhtNfaWGYHDdS3JYFQBKXxcUR9qqPWsRhFHhoISO2Xnl/g0xyKzht9mI1LZpiNWfMzHixQ== - -ccount@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz" - integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== - -chalk@4.1.1, chalk@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz" - integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@5.2.0: - version "5.2.0" - resolved "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz" - integrity sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA== - -chalk@^2.0.0: - version "2.4.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0: - version "4.1.2" - resolved "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -character-entities-html4@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz" - integrity sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA== - -character-entities-legacy@^1.0.0: - version "1.1.4" - resolved "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz" - integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== - -character-entities-legacy@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz" - integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ== - -character-entities@^1.0.0: - version "1.2.4" - resolved "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz" - integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== - -character-entities@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz" - integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ== - -character-reference-invalid@^1.0.0: - version "1.1.4" - resolved "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz" - integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== - -character-reference-invalid@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz" - integrity sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw== - -"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.3: - version "3.5.3" - resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -ci-info@^3.6.1: - version "3.8.0" - resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz" - integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== - -classcat@^5.0.3, classcat@^5.0.4: - version "5.0.4" - resolved "https://registry.npmjs.org/classcat/-/classcat-5.0.4.tgz" - integrity sha512-sbpkOw6z413p+HDGcBENe498WM9woqWHiJxCq7nvmxe9WmrUmqfAcxpIwAiMtM5Q3AhYkzXcNQHqsWq0mND51g== - -classnames@2.3.1: - version "2.3.1" - resolved "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz" - integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== - -classnames@^2.2.1, classnames@^2.3.2: - version "2.3.2" - resolved "https://registry.npmjs.org/classnames/-/classnames-2.3.2.tgz" - integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== - -clean-regexp@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz" - integrity sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw== - dependencies: - escape-string-regexp "^1.0.5" - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -cli-truncate@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz" - integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== - dependencies: - slice-ansi "^3.0.0" - string-width "^4.2.0" - -cli-truncate@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz" - integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== - dependencies: - slice-ansi "^5.0.0" - string-width "^5.0.0" - -client-only@0.0.1, client-only@^0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz" - integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== - -code-inspector-core@0.13.0: - version "0.13.0" - resolved "https://registry.npmjs.org/code-inspector-core/-/code-inspector-core-0.13.0.tgz" - integrity sha512-oYPNLdJjn3SY50YtF3IuxZOKLBNwzXSRPOqiXVnZFceMz9Ar6ugP3+zj7HszouxrsLFb2dVtlv//5wr4+cq62A== - dependencies: - "@vue/compiler-dom" "^3.2.47" - chalk "^4.1.1" - portfinder "^1.0.28" - -code-inspector-plugin@^0.13.0: - version "0.13.0" - resolved "https://registry.npmjs.org/code-inspector-plugin/-/code-inspector-plugin-0.13.0.tgz" - integrity sha512-v4mq5hhHkyMmutembTzREVsFeZ/+KsCwfx20+0gTqm1Il/M1T4d2BCv9mZ4ivie3GvvDMt/pVz1iBBVP3SuzJA== - dependencies: - chalk "4.1.1" - code-inspector-core "0.13.0" - vite-code-inspector-plugin "0.13.0" - webpack-code-inspector-plugin "0.13.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - 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" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - -color-name@^1.0.0, color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -color-string@^1.9.0: - version "1.9.1" - resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz" - integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color@^4.2.3: - version "4.2.3" - resolved "https://registry.npmjs.org/color/-/color-4.2.3.tgz" - integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A== - dependencies: - color-convert "^2.0.1" - color-string "^1.9.0" - -colorette@^2.0.19: - version "2.0.20" - resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz" - integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== - -comma-separated-tokens@^1.0.0: - version "1.0.8" - resolved "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz" - integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== - -comma-separated-tokens@^2.0.0: - version "2.0.3" - resolved "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz" - integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== - -commander@7: - version "7.2.0" - resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - -commander@^10.0.0: - version "10.0.1" - resolved "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz" - integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== - -commander@^4.0.0: - version "4.1.1" - resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz" - integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== - -commander@^8.3.0: - version "8.3.0" - resolved "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz" - integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -copy-to-clipboard@^3.3.3: - version "3.3.3" - resolved "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz" - integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA== - dependencies: - toggle-selection "^1.0.6" - -cose-base@^1.0.0: - version "1.0.3" - resolved "https://registry.npmjs.org/cose-base/-/cose-base-1.0.3.tgz" - integrity sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg== - dependencies: - layout-base "^1.0.0" - -cose-base@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/cose-base/-/cose-base-2.2.0.tgz" - integrity sha512-AzlgcsCbUMymkADOJtQm3wO9S3ltPfYOFD5033keQn9NJzIbtnZj+UdBJe7DYml/8TdbtHJW3j58SOnKhWY/5g== - dependencies: - layout-base "^2.0.0" - -cross-env@^7.0.3: - version "7.0.3" - resolved "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz" - integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== - dependencies: - cross-spawn "^7.0.1" - -cross-spawn@^7.0.0, cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -crypto-js@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/crypto-js/-/crypto-js-4.2.0.tgz" - integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q== - -cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz" - integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== - -csstype@^3.0.2: - version "3.1.2" - resolved "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz" - integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== - -cytoscape-cose-bilkent@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/cytoscape-cose-bilkent/-/cytoscape-cose-bilkent-4.1.0.tgz" - integrity sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ== - dependencies: - cose-base "^1.0.0" - -cytoscape-fcose@^2.1.0: - version "2.2.0" - resolved "https://registry.npmjs.org/cytoscape-fcose/-/cytoscape-fcose-2.2.0.tgz" - integrity sha512-ki1/VuRIHFCzxWNrsshHYPs6L7TvLu3DL+TyIGEsRcvVERmxokbf5Gdk7mFxZnTdiGtnA4cfSmjZJMviqSuZrQ== - dependencies: - cose-base "^2.2.0" - -cytoscape@^3.23.0: - version "3.26.0" - resolved "https://registry.npmjs.org/cytoscape/-/cytoscape-3.26.0.tgz" - integrity sha512-IV+crL+KBcrCnVVUCZW+zRRRFUZQcrtdOPXki+o4CFUWLdAEYvuZLcBSJC9EBK++suamERKzeY7roq2hdovV3w== - dependencies: - heap "^0.2.6" - lodash "^4.17.21" - -"d3-array@1 - 2": - version "2.12.1" - resolved "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz" - integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== - dependencies: - internmap "^1.0.0" - -"d3-array@2 - 3", "d3-array@2.10.0 - 3", "d3-array@2.5.0 - 3", d3-array@3, d3-array@^3.2.0: - version "3.2.4" - resolved "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz" - integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== - dependencies: - internmap "1 - 2" - -d3-axis@3: - version "3.0.0" - resolved "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz" - integrity sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw== - -d3-brush@3: - version "3.0.0" - resolved "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz" - integrity sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ== - dependencies: - d3-dispatch "1 - 3" - d3-drag "2 - 3" - d3-interpolate "1 - 3" - d3-selection "3" - d3-transition "3" - -d3-chord@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz" - integrity sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g== - dependencies: - d3-path "1 - 3" - -"d3-color@1 - 3", d3-color@3: - version "3.1.0" - resolved "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz" - integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== - -d3-contour@4: - version "4.0.2" - resolved "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz" - integrity sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA== - dependencies: - d3-array "^3.2.0" - -d3-delaunay@6: - version "6.0.4" - resolved "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz" - integrity sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A== - dependencies: - delaunator "5" - -"d3-dispatch@1 - 3", d3-dispatch@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz" - integrity sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg== - -"d3-drag@2 - 3", d3-drag@3, d3-drag@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz" - integrity sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg== - dependencies: - d3-dispatch "1 - 3" - d3-selection "3" - -"d3-dsv@1 - 3", d3-dsv@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz" - integrity sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q== - dependencies: - commander "7" - iconv-lite "0.6" - rw "1" - -"d3-ease@1 - 3", d3-ease@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz" - integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== - -d3-fetch@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz" - integrity sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw== - dependencies: - d3-dsv "1 - 3" - -d3-force@3: - version "3.0.0" - resolved "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz" - integrity sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg== - dependencies: - d3-dispatch "1 - 3" - d3-quadtree "1 - 3" - d3-timer "1 - 3" - -"d3-format@1 - 3", d3-format@3: - version "3.1.0" - resolved "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz" - integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== - -d3-geo@3: - version "3.1.0" - resolved "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz" - integrity sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA== - dependencies: - d3-array "2.5.0 - 3" - -d3-hierarchy@3: - version "3.1.2" - resolved "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz" - integrity sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA== - -"d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 3", d3-interpolate@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz" - integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== - dependencies: - d3-color "1 - 3" - -d3-path@1: - version "1.0.9" - resolved "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz" - integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg== - -"d3-path@1 - 3", d3-path@3, d3-path@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz" - integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== - -d3-polygon@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz" - integrity sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg== - -"d3-quadtree@1 - 3", d3-quadtree@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz" - integrity sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw== - -d3-random@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz" - integrity sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ== - -d3-sankey@^0.12.3: - version "0.12.3" - resolved "https://registry.npmjs.org/d3-sankey/-/d3-sankey-0.12.3.tgz" - integrity sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ== - dependencies: - d3-array "1 - 2" - d3-shape "^1.2.0" - -d3-scale-chromatic@3: - version "3.0.0" - resolved "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz" - integrity sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g== - dependencies: - d3-color "1 - 3" - d3-interpolate "1 - 3" - -d3-scale@4: - version "4.0.2" - resolved "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz" - integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ== - dependencies: - d3-array "2.10.0 - 3" - d3-format "1 - 3" - d3-interpolate "1.2.0 - 3" - d3-time "2.1.1 - 3" - d3-time-format "2 - 4" - -"d3-selection@2 - 3", d3-selection@3, d3-selection@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz" - integrity sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ== - -d3-shape@3: - version "3.2.0" - resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz" - integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA== - dependencies: - d3-path "^3.1.0" - -d3-shape@^1.2.0: - version "1.3.7" - resolved "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz" - integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw== - dependencies: - d3-path "1" - -"d3-time-format@2 - 4", d3-time-format@4: - version "4.1.0" - resolved "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz" - integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg== - dependencies: - d3-time "1 - 3" - -"d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@3: - version "3.1.0" - resolved "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz" - integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q== - dependencies: - d3-array "2 - 3" - -"d3-timer@1 - 3", d3-timer@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz" - integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== - -"d3-transition@2 - 3", d3-transition@3: - version "3.0.1" - resolved "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz" - integrity sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w== - dependencies: - d3-color "1 - 3" - d3-dispatch "1 - 3" - d3-ease "1 - 3" - d3-interpolate "1 - 3" - d3-timer "1 - 3" - -d3-zoom@3, d3-zoom@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz" - integrity sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw== - dependencies: - d3-dispatch "1 - 3" - d3-drag "2 - 3" - d3-interpolate "1 - 3" - d3-selection "2 - 3" - d3-transition "2 - 3" - -d3@^7.4.0, d3@^7.8.2: - version "7.8.5" - resolved "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz" - integrity sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA== - dependencies: - d3-array "3" - d3-axis "3" - d3-brush "3" - d3-chord "3" - d3-color "3" - d3-contour "4" - d3-delaunay "6" - d3-dispatch "3" - d3-drag "3" - d3-dsv "3" - d3-ease "3" - d3-fetch "3" - d3-force "3" - d3-format "3" - d3-geo "3" - d3-hierarchy "3" - d3-interpolate "3" - d3-path "3" - d3-polygon "3" - d3-quadtree "3" - d3-random "3" - d3-scale "4" - d3-scale-chromatic "3" - d3-selection "3" - d3-shape "3" - d3-time "3" - d3-time-format "4" - d3-timer "3" - d3-transition "3" - d3-zoom "3" - -dagre-d3-es@7.0.10: - version "7.0.10" - resolved "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.10.tgz" - integrity sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A== - dependencies: - d3 "^7.8.2" - lodash-es "^4.17.21" - -dagre@^0.8.5: - version "0.8.5" - resolved "https://registry.npmjs.org/dagre/-/dagre-0.8.5.tgz" - integrity sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw== - dependencies: - graphlib "^2.1.8" - lodash "^4.17.15" - -damerau-levenshtein@^1.0.8: - version "1.0.8" - resolved "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz" - integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== - -dayjs@^1.11.7, dayjs@^1.9.1: - version "1.11.8" - resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.8.tgz" - integrity sha512-LcgxzFoWMEPO7ggRv1Y2N31hUf2R0Vj7fuy/m+Bg1K8rr+KAs1AEy4y9jd5DXe8pbHgX+srkHNS7TH6Q6ZhYeQ== - -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.0.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -decode-named-character-reference@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz" - integrity sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg== - dependencies: - character-entities "^2.0.0" - -deep-equal@^2.0.5: - version "2.2.1" - resolved "https://registry.npmjs.org/deep-equal/-/deep-equal-2.2.1.tgz" - integrity sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ== - dependencies: - array-buffer-byte-length "^1.0.0" - call-bind "^1.0.2" - es-get-iterator "^1.1.3" - get-intrinsic "^1.2.0" - is-arguments "^1.1.1" - is-array-buffer "^3.0.2" - is-date-object "^1.0.5" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - isarray "^2.0.5" - object-is "^1.1.5" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.5.0" - side-channel "^1.0.4" - which-boxed-primitive "^1.0.2" - which-collection "^1.0.1" - which-typed-array "^1.1.9" - -deep-is@^0.1.3: - 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== - -default-browser-id@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz" - integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== - dependencies: - bplist-parser "^0.2.0" - untildify "^4.0.0" - -default-browser@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz" - integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== - dependencies: - bundle-name "^3.0.0" - default-browser-id "^3.0.0" - execa "^7.1.1" - titleize "^3.0.0" - -define-data-property@^1.0.1, define-data-property@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz" - integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== - dependencies: - get-intrinsic "^1.2.1" - gopd "^1.0.1" - has-property-descriptors "^1.0.0" - -define-lazy-prop@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz" - integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== - -define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0, define-properties@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz" - integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== - dependencies: - define-data-property "^1.0.1" - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -delaunator@5: - version "5.0.0" - resolved "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz" - integrity sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw== - dependencies: - robust-predicates "^3.0.0" - -dequal@^2.0.0: - version "2.0.3" - resolved "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz" - integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== - -detect-libc@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz" - integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== - -didyoumean@^1.2.2: - version "1.2.2" - resolved "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz" - integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== - -diff@^5.0.0: - version "5.1.0" - resolved "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz" - integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -dlv@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz" - integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dom-serializer@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz" - integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== - dependencies: - domelementtype "^2.3.0" - domhandler "^5.0.2" - entities "^4.2.0" - -domelementtype@^2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz" - integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== - -domhandler@^5.0.2, domhandler@^5.0.3: - version "5.0.3" - resolved "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz" - integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== - dependencies: - domelementtype "^2.3.0" - -dompurify@^3.0.5: - version "3.0.5" - resolved "https://registry.npmjs.org/dompurify/-/dompurify-3.0.5.tgz" - integrity sha512-F9e6wPGtY+8KNMRAVfxeCOHU0/NPWMSENNq4pQctuXRqqdEPW7q3CrLbR5Nse044WwacyjHGOMlvNsBe1y6z9A== - -domutils@^3.0.1: - version "3.1.0" - resolved "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz" - integrity sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA== - dependencies: - dom-serializer "^2.0.0" - domelementtype "^2.3.0" - domhandler "^5.0.3" - -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - -echarts-for-react@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/echarts-for-react/-/echarts-for-react-3.0.2.tgz" - integrity sha512-DRwIiTzx8JfwPOVgGttDytBqdp5VzCSyMRIxubgU/g2n9y3VLUmF2FK7Icmg/sNVkv4+rktmrLN9w22U2yy3fA== - dependencies: - fast-deep-equal "^3.1.3" - size-sensor "^1.0.1" - -echarts@^5.4.1: - version "5.4.2" - resolved "https://registry.npmjs.org/echarts/-/echarts-5.4.2.tgz" - integrity sha512-2W3vw3oI2tWJdyAz+b8DuWS0nfXtSDqlDmqgin/lfzbkB01cuMEN66KWBlmur3YMp5nEDEEt5s23pllnAzB4EA== - dependencies: - tslib "2.3.0" - zrender "5.4.3" - -electron-to-chromium@^1.4.411: - version "1.4.423" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.423.tgz" - integrity sha512-y4A7YfQcDGPAeSWM1IuoWzXpg9RY1nwHzHSwRtCSQFp9FgAVDgdWlFf0RbdWfLWQ2WUI+bddUgk5RgTjqRE6FQ== - -elkjs@^0.8.2: - version "0.8.2" - resolved "https://registry.npmjs.org/elkjs/-/elkjs-0.8.2.tgz" - integrity sha512-L6uRgvZTH+4OF5NE/MBbzQx/WYpru1xCBE9respNj6qznEewGUIfhzmm7horWWxbNO2M0WckQypGctR8lH79xQ== - -emoji-mart@^5.5.2: - version "5.5.2" - resolved "https://registry.npmjs.org/emoji-mart/-/emoji-mart-5.5.2.tgz" - integrity sha512-Sqc/nso4cjxhOwWJsp9xkVm8OF5c+mJLZJFoFfzRuKO+yWiN7K8c96xmtughYb0d/fZ8UC6cLIQ/p4BR6Pv3/A== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -enhanced-resolve@^5.12.0: - version "5.14.1" - resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.1.tgz" - integrity sha512-Vklwq2vDKtl0y/vtwjSesgJ5MYS7Etuk5txS8VdKL4AOS1aUlD96zqIfsOSLQsdv3xgMRbtkWM8eG9XDfKUPow== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - -entities@^4.2.0, entities@^4.4.0, entities@^4.5.0: - version "4.5.0" - resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz" - integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.20.4, es-abstract@^1.22.1: - version "1.22.3" - resolved "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz" - integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== - dependencies: - array-buffer-byte-length "^1.0.0" - arraybuffer.prototype.slice "^1.0.2" - available-typed-arrays "^1.0.5" - call-bind "^1.0.5" - es-set-tostringtag "^2.0.1" - es-to-primitive "^1.2.1" - function.prototype.name "^1.1.6" - get-intrinsic "^1.2.2" - get-symbol-description "^1.0.0" - globalthis "^1.0.3" - gopd "^1.0.1" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" - internal-slot "^1.0.5" - is-array-buffer "^3.0.2" - is-callable "^1.2.7" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-typed-array "^1.1.12" - is-weakref "^1.0.2" - object-inspect "^1.13.1" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.5.1" - safe-array-concat "^1.0.1" - safe-regex-test "^1.0.0" - string.prototype.trim "^1.2.8" - string.prototype.trimend "^1.0.7" - string.prototype.trimstart "^1.0.7" - typed-array-buffer "^1.0.0" - typed-array-byte-length "^1.0.0" - typed-array-byte-offset "^1.0.0" - typed-array-length "^1.0.4" - unbox-primitive "^1.0.2" - which-typed-array "^1.1.13" - -es-get-iterator@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz" - integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - has-symbols "^1.0.3" - is-arguments "^1.1.1" - is-map "^2.0.2" - is-set "^2.0.2" - is-string "^1.0.7" - isarray "^2.0.5" - stop-iteration-iterator "^1.0.0" - -es-iterator-helpers@^1.0.12: - version "1.0.15" - resolved "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz" - integrity sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g== - dependencies: - asynciterator.prototype "^1.0.0" - call-bind "^1.0.2" - define-properties "^1.2.1" - es-abstract "^1.22.1" - es-set-tostringtag "^2.0.1" - function-bind "^1.1.1" - get-intrinsic "^1.2.1" - globalthis "^1.0.3" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" - has-symbols "^1.0.3" - internal-slot "^1.0.5" - iterator.prototype "^1.1.2" - safe-array-concat "^1.0.1" - -es-set-tostringtag@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz" - integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== - dependencies: - get-intrinsic "^1.1.3" - has "^1.0.3" - has-tostringtag "^1.0.0" - -es-shim-unscopables@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz" - integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== - dependencies: - has "^1.0.3" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escape-string-regexp@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz" - integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== - -eslint-config-next@^14.0.4: - version "14.1.0" - resolved "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-14.1.0.tgz" - integrity sha512-SBX2ed7DoRFXC6CQSLc/SbLY9Ut6HxNB2wPTcoIWjUMd7aF7O/SIE7111L8FdZ9TXsNV4pulUDnfthpyPtbFUg== - dependencies: - "@next/eslint-plugin-next" "14.1.0" - "@rushstack/eslint-patch" "^1.3.3" - "@typescript-eslint/parser" "^5.4.2 || ^6.0.0" - eslint-import-resolver-node "^0.3.6" - eslint-import-resolver-typescript "^3.5.2" - eslint-plugin-import "^2.28.1" - eslint-plugin-jsx-a11y "^6.7.1" - eslint-plugin-react "^7.33.2" - eslint-plugin-react-hooks "^4.5.0 || 5.0.0-canary-7118f5dd7-20230705" - -eslint-import-resolver-node@^0.3.6, eslint-import-resolver-node@^0.3.9: - version "0.3.9" - resolved "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz" - integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== - dependencies: - debug "^3.2.7" - is-core-module "^2.13.0" - resolve "^1.22.4" - -eslint-import-resolver-typescript@^3.5.2: - version "3.5.5" - resolved "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.5.tgz" - integrity sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw== - dependencies: - debug "^4.3.4" - enhanced-resolve "^5.12.0" - eslint-module-utils "^2.7.4" - get-tsconfig "^4.5.0" - globby "^13.1.3" - is-core-module "^2.11.0" - is-glob "^4.0.3" - synckit "^0.8.5" - -eslint-module-utils@^2.7.4, eslint-module-utils@^2.8.0: - version "2.8.0" - resolved "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz" - integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== - dependencies: - debug "^3.2.7" - -eslint-plugin-antfu@0.36.0: - version "0.36.0" - resolved "https://registry.npmjs.org/eslint-plugin-antfu/-/eslint-plugin-antfu-0.36.0.tgz" - integrity sha512-qLYtjZC2y6d1fvVtG4nvVGoBUDEuUwQsS4E1RwjoEZyONZAkHYDPfeoeULDlPS0IqumSW8uGR6zGSAXi5rrVMg== - dependencies: - "@typescript-eslint/utils" "^5.53.0" - -eslint-plugin-es@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz" - integrity sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ== - dependencies: - eslint-utils "^2.0.0" - regexpp "^3.0.0" - -eslint-plugin-eslint-comments@^3.2.0: - version "3.2.0" - resolved "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz" - integrity sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ== - dependencies: - escape-string-regexp "^1.0.5" - ignore "^5.0.5" - -eslint-plugin-html@^7.1.0: - version "7.1.0" - resolved "https://registry.npmjs.org/eslint-plugin-html/-/eslint-plugin-html-7.1.0.tgz" - integrity sha512-fNLRraV/e6j8e3XYOC9xgND4j+U7b1Rq+OygMlLcMg+wI/IpVbF+ubQa3R78EjKB9njT6TQOlcK5rFKBVVtdfg== - dependencies: - htmlparser2 "^8.0.1" - -eslint-plugin-import@^2.27.5, eslint-plugin-import@^2.28.1: - version "2.29.1" - resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz" - integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== - dependencies: - array-includes "^3.1.7" - array.prototype.findlastindex "^1.2.3" - array.prototype.flat "^1.3.2" - array.prototype.flatmap "^1.3.2" - debug "^3.2.7" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.9" - eslint-module-utils "^2.8.0" - hasown "^2.0.0" - is-core-module "^2.13.1" - is-glob "^4.0.3" - minimatch "^3.1.2" - object.fromentries "^2.0.7" - object.groupby "^1.0.1" - object.values "^1.1.7" - semver "^6.3.1" - tsconfig-paths "^3.15.0" - -eslint-plugin-jest@^27.2.1: - version "27.2.1" - resolved "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.2.1.tgz" - integrity sha512-l067Uxx7ZT8cO9NJuf+eJHvt6bqJyz2Z29wykyEdz/OtmcELQl2MQGQLX8J94O1cSJWAwUSEvCjwjA7KEK3Hmg== - dependencies: - "@typescript-eslint/utils" "^5.10.0" - -eslint-plugin-jsonc@^2.6.0: - version "2.8.0" - resolved "https://registry.npmjs.org/eslint-plugin-jsonc/-/eslint-plugin-jsonc-2.8.0.tgz" - integrity sha512-K4VsnztnNwpm+V49CcCu5laq8VjclJpuhfI9LFkOrOyK+BKdQHMzkWo43B4X4rYaVrChm4U9kw/tTU5RHh5Wtg== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - jsonc-eslint-parser "^2.0.4" - natural-compare "^1.4.0" - -eslint-plugin-jsx-a11y@^6.7.1: - version "6.7.1" - resolved "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz" - integrity sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA== - dependencies: - "@babel/runtime" "^7.20.7" - aria-query "^5.1.3" - array-includes "^3.1.6" - array.prototype.flatmap "^1.3.1" - ast-types-flow "^0.0.7" - axe-core "^4.6.2" - axobject-query "^3.1.1" - damerau-levenshtein "^1.0.8" - emoji-regex "^9.2.2" - has "^1.0.3" - jsx-ast-utils "^3.3.3" - language-tags "=1.0.5" - minimatch "^3.1.2" - object.entries "^1.1.6" - object.fromentries "^2.0.6" - semver "^6.3.0" - -eslint-plugin-markdown@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-3.0.0.tgz" - integrity sha512-hRs5RUJGbeHDLfS7ELanT0e29Ocyssf/7kBM+p7KluY5AwngGkDf8Oyu4658/NZSGTTq05FZeWbkxXtbVyHPwg== - dependencies: - mdast-util-from-markdown "^0.8.5" - -eslint-plugin-n@^15.6.1: - version "15.7.0" - resolved "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.7.0.tgz" - integrity sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q== - dependencies: - builtins "^5.0.1" - eslint-plugin-es "^4.1.0" - eslint-utils "^3.0.0" - ignore "^5.1.1" - is-core-module "^2.11.0" - minimatch "^3.1.2" - resolve "^1.22.1" - semver "^7.3.8" - -eslint-plugin-no-only-tests@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.1.0.tgz" - integrity sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw== - -eslint-plugin-promise@^6.1.1: - version "6.1.1" - resolved "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz" - integrity sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig== - -"eslint-plugin-react-hooks@^4.5.0 || 5.0.0-canary-7118f5dd7-20230705": - version "5.0.0-canary-7118f5dd7-20230705" - resolved "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.0.0-canary-7118f5dd7-20230705.tgz" - integrity sha512-AZYbMo/NW9chdL7vk6HQzQhT+PvTAEVqWk9ziruUoW2kAOcN5qNyelv70e0F1VNQAbvutOC9oc+xfWycI9FxDw== - -eslint-plugin-react@^7.33.2: - version "7.33.2" - resolved "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz" - integrity sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw== - dependencies: - array-includes "^3.1.6" - array.prototype.flatmap "^1.3.1" - array.prototype.tosorted "^1.1.1" - doctrine "^2.1.0" - es-iterator-helpers "^1.0.12" - estraverse "^5.3.0" - jsx-ast-utils "^2.4.1 || ^3.0.0" - minimatch "^3.1.2" - object.entries "^1.1.6" - object.fromentries "^2.0.6" - object.hasown "^1.1.2" - object.values "^1.1.6" - prop-types "^15.8.1" - resolve "^2.0.0-next.4" - semver "^6.3.1" - string.prototype.matchall "^4.0.8" - -eslint-plugin-unicorn@^45.0.2: - version "45.0.2" - resolved "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-45.0.2.tgz" - integrity sha512-Y0WUDXRyGDMcKLiwgL3zSMpHrXI00xmdyixEGIg90gHnj0PcHY4moNv3Ppje/kDivdAy5vUeUr7z211ImPv2gw== - dependencies: - "@babel/helper-validator-identifier" "^7.19.1" - "@eslint-community/eslint-utils" "^4.1.2" - ci-info "^3.6.1" - clean-regexp "^1.0.0" - esquery "^1.4.0" - indent-string "^4.0.0" - is-builtin-module "^3.2.0" - jsesc "^3.0.2" - lodash "^4.17.21" - pluralize "^8.0.0" - read-pkg-up "^7.0.1" - regexp-tree "^0.1.24" - regjsparser "^0.9.1" - safe-regex "^2.1.1" - semver "^7.3.8" - strip-indent "^3.0.0" - -eslint-plugin-unused-imports@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-2.0.0.tgz" - integrity sha512-3APeS/tQlTrFa167ThtP0Zm0vctjr4M44HMpeg1P4bK6wItarumq0Ma82xorMKdFsWpphQBlRPzw/pxiVELX1A== - dependencies: - eslint-rule-composer "^0.3.0" - -eslint-plugin-vue@^9.9.0: - version "9.14.1" - resolved "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.14.1.tgz" - integrity sha512-LQazDB1qkNEKejLe/b5a9VfEbtbczcOaui5lQ4Qw0tbRBbQYREyxxOV5BQgNDTqGPs9pxqiEpbMi9ywuIaF7vw== - dependencies: - "@eslint-community/eslint-utils" "^4.3.0" - natural-compare "^1.4.0" - nth-check "^2.0.1" - postcss-selector-parser "^6.0.9" - semver "^7.3.5" - vue-eslint-parser "^9.3.0" - xml-name-validator "^4.0.0" - -eslint-plugin-yml@^1.5.0: - version "1.7.0" - resolved "https://registry.npmjs.org/eslint-plugin-yml/-/eslint-plugin-yml-1.7.0.tgz" - integrity sha512-qq61FQJk+qIgWl0R06bec7UQQEIBrUH22jS+MroTbFUKu+3/iVlGRpZd8mjpOAm/+H/WEDFwy4x/+kKgVGbsWw== - dependencies: - debug "^4.3.2" - lodash "^4.17.21" - natural-compare "^1.4.0" - yaml-eslint-parser "^1.2.1" - -eslint-rule-composer@^0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz" - integrity sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg== - -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-scope@^7.1.1: - version "7.2.0" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz" - integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-utils@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz" - integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== - dependencies: - eslint-visitor-keys "^2.0.0" - -eslint-visitor-keys@^1.1.0: - version "1.3.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint-visitor-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz" - integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== - -eslint-visitor-keys@^3.0.0, eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: - version "3.4.1" - resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz" - integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== - -eslint@^8.36.0: - version "8.36.0" - resolved "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz" - integrity sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.4.0" - "@eslint/eslintrc" "^2.0.1" - "@eslint/js" "8.36.0" - "@humanwhocodes/config-array" "^0.11.8" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.1.1" - eslint-visitor-keys "^3.3.0" - espree "^9.5.0" - esquery "^1.4.2" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.19.0" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-sdsl "^4.1.4" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.1" - strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" - text-table "^0.2.0" - -espree@^9.0.0, espree@^9.3.1, espree@^9.5.0, espree@^9.5.2: - version "9.5.2" - resolved "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz" - integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== - dependencies: - acorn "^8.8.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" - -esquery@^1.4.0, esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: - version "5.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -estree-util-attach-comments@^2.0.0: - version "2.1.1" - resolved "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-2.1.1.tgz" - integrity sha512-+5Ba/xGGS6mnwFbXIuQiDPTbuTxuMCooq3arVv7gPZtYpjp+VXH/NkHAP35OOefPhNG/UGqU3vt/LTABwcHX0w== - dependencies: - "@types/estree" "^1.0.0" - -estree-util-build-jsx@^2.0.0: - version "2.2.2" - resolved "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-2.2.2.tgz" - integrity sha512-m56vOXcOBuaF+Igpb9OPAy7f9w9OIkb5yhjsZuaPm7HoGi4oTOQi0h2+yZ+AtKklYFZ+rPC4n0wYCJCEU1ONqg== - dependencies: - "@types/estree-jsx" "^1.0.0" - estree-util-is-identifier-name "^2.0.0" - estree-walker "^3.0.0" - -estree-util-is-identifier-name@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-2.1.0.tgz" - integrity sha512-bEN9VHRyXAUOjkKVQVvArFym08BTWB0aJPppZZr0UNyAqWsLaVfAqP7hbaTJjzHifmB5ebnR8Wm7r7yGN/HonQ== - -estree-util-to-js@^1.1.0: - version "1.2.0" - resolved "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-1.2.0.tgz" - integrity sha512-IzU74r1PK5IMMGZXUVZbmiu4A1uhiPgW5hm1GjcOfr4ZzHaMPpLNJjR7HjXiIOzi25nZDrgFTobHTkV5Q6ITjA== - dependencies: - "@types/estree-jsx" "^1.0.0" - astring "^1.8.0" - source-map "^0.7.0" - -estree-util-visit@^1.0.0: - version "1.2.1" - resolved "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-1.2.1.tgz" - integrity sha512-xbgqcrkIVbIG+lI/gzbvd9SGTJL4zqJKBFttUl5pP27KhAjtMKbX/mQXJ7qgyXpMgVy/zvpm0xoQQaGL8OloOw== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/unist" "^2.0.0" - -estree-walker@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz" - integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== - -estree-walker@^3.0.0: - version "3.0.3" - resolved "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz" - integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g== - dependencies: - "@types/estree" "^1.0.0" - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -execa@^7.0.0, execa@^7.1.1: - version "7.1.1" - resolved "https://registry.npmjs.org/execa/-/execa-7.1.1.tgz" - integrity sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.1" - human-signals "^4.3.0" - is-stream "^3.0.0" - merge-stream "^2.0.0" - npm-run-path "^5.1.0" - onetime "^6.0.0" - signal-exit "^3.0.7" - strip-final-newline "^3.0.0" - -extend@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -fake-xml-http-request@^2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/fake-xml-http-request/-/fake-xml-http-request-2.1.2.tgz" - integrity sha512-HaFMBi7r+oEC9iJNpc3bvcW7Z7iLmM26hPDmlb0mFwyANSsOQAtJxbdWsXITKOzZUyMYK0zYCv3h5yDj9TsiXg== - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - 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== - -fast-glob@^3.2.11, fast-glob@^3.2.12, fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@^2.0.0: - 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== - -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - -fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== - dependencies: - reusify "^1.0.4" - -fault@^1.0.0: - version "1.0.4" - resolved "https://registry.npmjs.org/fault/-/fault-1.0.4.tgz" - integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA== - dependencies: - format "^0.2.0" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== - -for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - -foreground-child@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz" - integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^4.0.1" - -format@^0.2.0: - version "0.2.2" - resolved "https://registry.npmjs.org/format/-/format-0.2.2.tgz" - integrity sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww== - -fraction.js@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz" - integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1, function-bind@^1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" - integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== - -function.prototype.name@^1.1.5, function.prototype.name@^1.1.6: - version "1.1.6" - resolved "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz" - integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - functions-have-names "^1.2.3" - -functions-have-names@^1.2.3: - version "1.2.3" - resolved "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: - version "1.2.2" - resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz" - integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== - dependencies: - function-bind "^1.1.2" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" - -get-stream@^6.0.0, get-stream@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -get-tsconfig@^4.5.0: - version "4.6.0" - resolved "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.6.0.tgz" - integrity sha512-lgbo68hHTQnFddybKbbs/RDRJnJT5YyGy2kQzVwbq+g67X73i+5MVTval34QxGkOe9X5Ujf1UYpCaphLyltjEg== - dependencies: - resolve-pkg-maps "^1.0.0" - -glob-parent@^5.1.2, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob@10.3.10: - version "10.3.10" - resolved "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz" - integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== - dependencies: - foreground-child "^3.1.0" - jackspeak "^2.3.5" - minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry "^1.10.1" - -glob@7.1.6: - version "7.1.6" - resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz" - integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.1.3: - version "7.2.3" - 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" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globals@^13.19.0: - version "13.20.0" - resolved "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== - dependencies: - type-fest "^0.20.2" - -globalthis@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz" - integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== - dependencies: - define-properties "^1.1.3" - -globby@^11.1.0: - version "11.1.0" - resolved "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -globby@^13.1.3: - version "13.1.4" - resolved "https://registry.npmjs.org/globby/-/globby-13.1.4.tgz" - integrity sha512-iui/IiiW+QrJ1X1hKH5qwlMQyv34wJAYwH1vrf8b9kBA4sNiif3gKsMHa+BrdnOpEudWjpotfa7LrTzB1ERS/g== - dependencies: - dir-glob "^3.0.1" - fast-glob "^3.2.11" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^4.0.0" - -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" - -graceful-fs@^4.2.11, graceful-fs@^4.2.4: - 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== - -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== - -graphlib@^2.1.8: - version "2.1.8" - resolved "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz" - integrity sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A== - dependencies: - lodash "^4.17.15" - -has-bigints@^1.0.1, has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz" - integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== - dependencies: - get-intrinsic "^1.2.2" - -has-proto@^1.0.1: - 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== - -has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has@^1.0.3: - 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" - -hasown@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz" - integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== - dependencies: - function-bind "^1.1.2" - -hast-util-from-dom@^4.0.0: - version "4.2.0" - resolved "https://registry.npmjs.org/hast-util-from-dom/-/hast-util-from-dom-4.2.0.tgz" - integrity sha512-t1RJW/OpJbCAJQeKi3Qrj1cAOLA0+av/iPFori112+0X7R3wng+jxLA+kXec8K4szqPRGI8vPxbbpEYvvpwaeQ== - dependencies: - hastscript "^7.0.0" - web-namespaces "^2.0.0" - -hast-util-from-html-isomorphic@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/hast-util-from-html-isomorphic/-/hast-util-from-html-isomorphic-1.0.0.tgz" - integrity sha512-Yu480AKeOEN/+l5LA674a+7BmIvtDj24GvOt7MtQWuhzUwlaaRWdEPXAh3Qm5vhuthpAipFb2vTetKXWOjmTvw== - dependencies: - "@types/hast" "^2.0.0" - hast-util-from-dom "^4.0.0" - hast-util-from-html "^1.0.0" - unist-util-remove-position "^4.0.0" - -hast-util-from-html@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/hast-util-from-html/-/hast-util-from-html-1.0.2.tgz" - integrity sha512-LhrTA2gfCbLOGJq2u/asp4kwuG0y6NhWTXiPKP+n0qNukKy7hc10whqqCFfyvIA1Q5U5d0sp9HhNim9gglEH4A== - dependencies: - "@types/hast" "^2.0.0" - hast-util-from-parse5 "^7.0.0" - parse5 "^7.0.0" - vfile "^5.0.0" - vfile-message "^3.0.0" - -hast-util-from-parse5@^7.0.0: - version "7.1.2" - resolved "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz" - integrity sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw== - dependencies: - "@types/hast" "^2.0.0" - "@types/unist" "^2.0.0" - hastscript "^7.0.0" - property-information "^6.0.0" - vfile "^5.0.0" - vfile-location "^4.0.0" - web-namespaces "^2.0.0" - -hast-util-is-element@^2.0.0: - version "2.1.3" - resolved "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-2.1.3.tgz" - integrity sha512-O1bKah6mhgEq2WtVMk+Ta5K7pPMqsBBlmzysLdcwKVrqzZQ0CHqUPiIVspNhAG1rvxpvJjtGee17XfauZYKqVA== - dependencies: - "@types/hast" "^2.0.0" - "@types/unist" "^2.0.0" - -hast-util-parse-selector@^2.0.0: - version "2.2.5" - resolved "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz" - integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ== - -hast-util-parse-selector@^3.0.0: - version "3.1.1" - resolved "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz" - integrity sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA== - dependencies: - "@types/hast" "^2.0.0" - -hast-util-to-estree@^2.0.0: - version "2.3.3" - resolved "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-2.3.3.tgz" - integrity sha512-ihhPIUPxN0v0w6M5+IiAZZrn0LH2uZomeWwhn7uP7avZC6TE7lIiEh2yBMPr5+zi1aUCXq6VoYRgs2Bw9xmycQ== - dependencies: - "@types/estree" "^1.0.0" - "@types/estree-jsx" "^1.0.0" - "@types/hast" "^2.0.0" - "@types/unist" "^2.0.0" - comma-separated-tokens "^2.0.0" - estree-util-attach-comments "^2.0.0" - estree-util-is-identifier-name "^2.0.0" - hast-util-whitespace "^2.0.0" - mdast-util-mdx-expression "^1.0.0" - mdast-util-mdxjs-esm "^1.0.0" - property-information "^6.0.0" - space-separated-tokens "^2.0.0" - style-to-object "^0.4.1" - unist-util-position "^4.0.0" - zwitch "^2.0.0" - -hast-util-to-text@^3.1.0: - version "3.1.2" - resolved "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-3.1.2.tgz" - integrity sha512-tcllLfp23dJJ+ju5wCCZHVpzsQQ43+moJbqVX3jNWPB7z/KFC4FyZD6R7y94cHL6MQ33YtMZL8Z0aIXXI4XFTw== - dependencies: - "@types/hast" "^2.0.0" - "@types/unist" "^2.0.0" - hast-util-is-element "^2.0.0" - unist-util-find-after "^4.0.0" - -hast-util-whitespace@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz" - integrity sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng== - -hastscript@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz" - integrity sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w== - dependencies: - "@types/hast" "^2.0.0" - comma-separated-tokens "^1.0.0" - hast-util-parse-selector "^2.0.0" - property-information "^5.0.0" - space-separated-tokens "^1.0.0" - -hastscript@^7.0.0: - version "7.2.0" - resolved "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz" - integrity sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw== - dependencies: - "@types/hast" "^2.0.0" - comma-separated-tokens "^2.0.0" - hast-util-parse-selector "^3.0.0" - property-information "^6.0.0" - space-separated-tokens "^2.0.0" - -heap@^0.2.6: - version "0.2.7" - resolved "https://registry.npmjs.org/heap/-/heap-0.2.7.tgz" - integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg== - -highlight.js@^10.4.1, highlight.js@~10.7.0: - version "10.7.3" - resolved "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz" - integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== - -hoist-non-react-statics@^3.3.2: - version "3.3.2" - resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz" - integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== - dependencies: - react-is "^16.7.0" - -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -html-parse-stringify@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz" - integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg== - dependencies: - void-elements "3.1.0" - -htmlparser2@^8.0.1: - version "8.0.2" - resolved "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz" - integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA== - dependencies: - domelementtype "^2.3.0" - domhandler "^5.0.3" - domutils "^3.0.1" - entities "^4.4.0" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -human-signals@^4.3.0: - version "4.3.1" - resolved "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz" - integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== - -husky@^8.0.3: - version "8.0.3" - resolved "https://registry.npmjs.org/husky/-/husky-8.0.3.tgz" - integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg== - -i18next-resources-to-backend@^1.1.3: - version "1.1.4" - resolved "https://registry.npmjs.org/i18next-resources-to-backend/-/i18next-resources-to-backend-1.1.4.tgz" - integrity sha512-hMyr9AOmIea17AOaVe1srNxK/l3mbk81P7Uf3fdcjlw3ehZy3UNTd0OP3EEi6yu4J02kf9jzhCcjokz6AFlEOg== - dependencies: - "@babel/runtime" "^7.21.5" - -i18next@^22.4.13: - version "22.5.1" - resolved "https://registry.npmjs.org/i18next/-/i18next-22.5.1.tgz" - integrity sha512-8TGPgM3pAD+VRsMtUMNknRz3kzqwp/gPALrWMsDnmC1mKqJwpWyooQRLMcbTwq8z8YwSmuj+ZYvc+xCuEpkssA== - dependencies: - "@babel/runtime" "^7.20.6" - -iconv-lite@0.6: - 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" - -ignore@^5.0.5, ignore@^5.1.1, ignore@^5.2.0: - version "5.2.4" - resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== - -immer@^9.0.19: - version "9.0.21" - resolved "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz" - integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== - -immutable@^4.0.0: - version "4.3.0" - resolved "https://registry.npmjs.org/immutable/-/immutable-4.3.0.tgz" - integrity sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg== - -import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - -inflected@^2.0.4: - version "2.1.0" - resolved "https://registry.npmjs.org/inflected/-/inflected-2.1.0.tgz" - integrity sha512-hAEKNxvHf2Iq3H60oMBHkB4wl5jn3TPF3+fXek/sRwAB5gP9xWs4r7aweSF95f99HFoz69pnZTcu8f0SIHV18w== - -inflight@^1.0.4: - version "1.0.6" - 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" - -inherits@2: - version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inline-style-parser@0.1.1: - version "0.1.1" - resolved "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.1.1.tgz" - integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== - -internal-slot@^1.0.4, internal-slot@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz" - integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== - dependencies: - get-intrinsic "^1.2.0" - has "^1.0.3" - side-channel "^1.0.4" - -"internmap@1 - 2": - version "2.0.3" - resolved "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz" - integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== - -internmap@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz" - integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== - -intersection-observer@^0.12.0: - version "0.12.2" - resolved "https://registry.npmjs.org/intersection-observer/-/intersection-observer-0.12.2.tgz" - integrity sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg== - -is-alphabetical@^1.0.0: - version "1.0.4" - resolved "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz" - integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== - -is-alphabetical@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz" - integrity sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ== - -is-alphanumerical@^1.0.0: - version "1.0.4" - resolved "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz" - integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== - dependencies: - is-alphabetical "^1.0.0" - is-decimal "^1.0.0" - -is-alphanumerical@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz" - integrity sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw== - dependencies: - is-alphabetical "^2.0.0" - is-decimal "^2.0.0" - -is-arguments@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz" - integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz" - integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.0" - is-typed-array "^1.1.10" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - -is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== - -is-async-function@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/is-async-function/-/is-async-function-2.0.0.tgz" - integrity sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA== - dependencies: - has-tostringtag "^1.0.0" - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-buffer@^2.0.0: - version "2.0.5" - resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz" - integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== - -is-builtin-module@^3.2.0: - version "3.2.1" - resolved "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz" - integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== - dependencies: - builtin-modules "^3.3.0" - -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: - version "1.2.7" - resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - -is-core-module@^2.11.0, is-core-module@^2.13.0, is-core-module@^2.13.1: - version "2.13.1" - resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz" - integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== - dependencies: - hasown "^2.0.0" - -is-date-object@^1.0.1, is-date-object@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-decimal@^1.0.0: - version "1.0.4" - resolved "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz" - integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== - -is-decimal@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz" - integrity sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A== - -is-docker@^2.0.0: - version "2.2.1" - resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - -is-docker@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz" - integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-finalizationregistry@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz" - integrity sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw== - dependencies: - call-bind "^1.0.2" - -is-fullwidth-code-point@^3.0.0: - 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== - -is-fullwidth-code-point@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz" - integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== - -is-generator-function@^1.0.10: - version "1.0.10" - resolved "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz" - integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== - dependencies: - has-tostringtag "^1.0.0" - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-hexadecimal@^1.0.0: - version "1.0.4" - resolved "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz" - integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== - -is-hexadecimal@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz" - integrity sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg== - -is-inside-container@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz" - integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== - dependencies: - is-docker "^3.0.0" - -is-map@^2.0.1, is-map@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz" - integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== - -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== - -is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== - dependencies: - has-tostringtag "^1.0.0" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-path-inside@^3.0.3: - version "3.0.3" - resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -is-plain-obj@^4.0.0: - version "4.1.0" - resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz" - integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== - -is-reference@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/is-reference/-/is-reference-3.0.1.tgz" - integrity sha512-baJJdQLiYaJdvFbJqXrcGv3WU3QCzBlUcI5QhbesIm6/xPsvmO+2CDoi/GMOFBQEQm+PXkwOPrp9KK5ozZsp2w== - dependencies: - "@types/estree" "*" - -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-set@^2.0.1, is-set@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/is-set/-/is-set-2.0.2.tgz" - integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== - -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== - dependencies: - call-bind "^1.0.2" - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz" - integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: - version "1.1.12" - resolved "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz" - integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== - dependencies: - which-typed-array "^1.1.11" - -is-weakmap@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/is-weakmap/-/is-weakmap-2.0.1.tgz" - integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== - -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - -is-weakset@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/is-weakset/-/is-weakset-2.0.2.tgz" - integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -iterator.prototype@^1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.2.tgz" - integrity sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w== - dependencies: - define-properties "^1.2.1" - get-intrinsic "^1.2.1" - has-symbols "^1.0.3" - reflect.getprototypeof "^1.0.4" - set-function-name "^2.0.1" - -jackspeak@^2.3.5: - version "2.3.6" - resolved "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz" - integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== - dependencies: - "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" - -jiti@^1.18.2: - version "1.18.2" - resolved "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz" - integrity sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg== - -js-audio-recorder@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/js-audio-recorder/-/js-audio-recorder-1.0.7.tgz" - integrity sha512-JiDODCElVHGrFyjGYwYyNi7zCbKk9va9C77w+zCPMmi4C6ix7zsX2h3ddHugmo4dOTOTCym9++b/wVW9nC0IaA== - -js-cookie@^2.x.x: - version "2.2.1" - resolved "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz" - integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== - -js-cookie@^3.0.1: - version "3.0.5" - resolved "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz" - integrity sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw== - -js-sdsl@^4.1.4: - version "4.4.0" - resolved "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz" - integrity sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg== - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -jsesc@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz" - integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz" - integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-traverse@^0.4.1: - 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== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== - -json5@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz" - integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== - dependencies: - minimist "^1.2.0" - -jsonc-eslint-parser@^2.0.4, jsonc-eslint-parser@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.3.0.tgz" - integrity sha512-9xZPKVYp9DxnM3sd1yAsh/d59iIaswDkai8oTxbursfKYbg/ibjX0IzFt35+VZ8iEW453TVTXztnRvYUQlAfUQ== - dependencies: - acorn "^8.5.0" - eslint-visitor-keys "^3.0.0" - espree "^9.0.0" - semver "^7.3.5" - -"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3: - version "3.3.3" - resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz" - integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== - dependencies: - array-includes "^3.1.5" - object.assign "^4.1.3" - -katex@^0.16.0, katex@^0.16.10: - version "0.16.10" - resolved "https://registry.npmjs.org/katex/-/katex-0.16.10.tgz" - integrity sha512-ZiqaC04tp2O5utMsl2TEZTXxa6WSC4yo0fv5ML++D3QZv/vx2Mct0mTlRx3O+uUkjfuAgOkzsCmq5MiUEsDDdA== - dependencies: - commander "^8.3.0" - -khroma@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/khroma/-/khroma-2.0.0.tgz" - integrity sha512-2J8rDNlQWbtiNYThZRvmMv5yt44ZakX+Tz5ZIp/mN1pt4snn+m030Va5Z4v8xA0cQFDXBwO/8i42xL4QPsVk3g== - -kleur@^4.0.3: - version "4.1.5" - resolved "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz" - integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== - -lamejs@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/lamejs/-/lamejs-1.2.1.tgz" - integrity sha512-s7bxvjvYthw6oPLCm5pFxvA84wUROODB8jEO2+CE1adhKgrIvVOlmMgY8zyugxGrvRaDHNJanOiS21/emty6dQ== - dependencies: - use-strict "1.0.1" - -language-subtag-registry@~0.3.2: - version "0.3.22" - resolved "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz" - integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== - -language-tags@=1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz" - integrity sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ== - dependencies: - language-subtag-registry "~0.3.2" - -layout-base@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/layout-base/-/layout-base-1.0.2.tgz" - integrity sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg== - -layout-base@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/layout-base/-/layout-base-2.0.1.tgz" - integrity sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg== - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -lexical@^0.12.2: - version "0.12.2" - resolved "https://registry.npmjs.org/lexical/-/lexical-0.12.2.tgz" - integrity sha512-Kxavd+ETjxtVwG/hvPd6WZfXD44sLOKe9Vlkwxy7lBQ1qZArS+rZfs+u5iXwXe6tX9f2PIM0u3RHsrCEDDE0fw== - -lilconfig@2.1.0, lilconfig@^2.0.5, lilconfig@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz" - integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -lint-staged@^13.2.2: - version "13.2.2" - resolved "https://registry.npmjs.org/lint-staged/-/lint-staged-13.2.2.tgz" - integrity sha512-71gSwXKy649VrSU09s10uAT0rWCcY3aewhMaHyl2N84oBk4Xs9HgxvUp3AYu+bNsK4NrOYYxvSgg7FyGJ+jGcA== - dependencies: - chalk "5.2.0" - cli-truncate "^3.1.0" - commander "^10.0.0" - debug "^4.3.4" - execa "^7.0.0" - lilconfig "2.1.0" - listr2 "^5.0.7" - micromatch "^4.0.5" - normalize-path "^3.0.0" - object-inspect "^1.12.3" - pidtree "^0.6.0" - string-argv "^0.3.1" - yaml "^2.2.2" - -listr2@^5.0.7: - version "5.0.8" - resolved "https://registry.npmjs.org/listr2/-/listr2-5.0.8.tgz" - integrity sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA== - dependencies: - cli-truncate "^2.1.0" - colorette "^2.0.19" - log-update "^4.0.0" - p-map "^4.0.0" - rfdc "^1.3.0" - rxjs "^7.8.0" - through "^2.3.8" - wrap-ansi "^7.0.0" - -local-pkg@^0.4.3: - version "0.4.3" - resolved "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz" - integrity sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g== - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash-es@^4.17.21: - version "4.17.21" - resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz" - integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== - -lodash.assign@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz" - integrity sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw== - -lodash.camelcase@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz" - integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== - -lodash.castarray@^4.4.0: - version "4.4.0" - resolved "https://registry.npmjs.org/lodash.castarray/-/lodash.castarray-4.4.0.tgz" - integrity sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q== - -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz" - integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== - -lodash.compact@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/lodash.compact/-/lodash.compact-3.0.1.tgz" - integrity sha512-2ozeiPi+5eBXW1CLtzjk8XQFhQOEMwwfxblqeq6EGyTxZJ1bPATqilY0e6g2SLQpP4KuMeuioBhEnWz5Pr7ICQ== - -lodash.find@^4.6.0: - version "4.6.0" - resolved "https://registry.npmjs.org/lodash.find/-/lodash.find-4.6.0.tgz" - integrity sha512-yaRZoAV3Xq28F1iafWN1+a0rflOej93l1DQUejs3SZ41h2O9UJBoS9aueGjPDgAl4B6tPC0NuuchLKaDQQ3Isg== - -lodash.flatten@^4.4.0: - version "4.4.0" - resolved "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz" - integrity sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g== - -lodash.forin@^4.4.0: - version "4.4.0" - resolved "https://registry.npmjs.org/lodash.forin/-/lodash.forin-4.4.0.tgz" - integrity sha512-APldePP4yvGhMcplVxv9L+exdLHMRHRhH1Q9O70zRJMm9HbTm6zxaihXtNl+ICOBApeFWoH7jNmFr/L4XfWeiQ== - -lodash.get@^4.4.2: - version "4.4.2" - resolved "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz" - integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ== - -lodash.has@^4.5.2: - version "4.5.2" - resolved "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz" - integrity sha512-rnYUdIo6xRCJnQmbVFEwcxF144erlD+M3YcJUVesflU9paQaE8p+fJDcIQrlMYbxoANFL+AB9hZrzSBBk5PL+g== - -lodash.invokemap@^4.6.0: - version "4.6.0" - resolved "https://registry.npmjs.org/lodash.invokemap/-/lodash.invokemap-4.6.0.tgz" - integrity sha512-CfkycNtMqgUlfjfdh2BhKO/ZXrP8ePOX5lEU/g0R3ItJcnuxWDwokMGKx1hWcfOikmyOVx6X9IwWnDGlgKl61w== - -lodash.isempty@^4.4.0: - version "4.4.0" - resolved "https://registry.npmjs.org/lodash.isempty/-/lodash.isempty-4.4.0.tgz" - integrity sha512-oKMuF3xEeqDltrGMfDxAPGIVMSSRv8tbRSODbrs4KGsRRLEhrW8N8Rd4DRgB2+621hY8A8XwwrTVhXWpxFvMzg== - -lodash.isequal@^4.5.0: - version "4.5.0" - resolved "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz" - integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== - -lodash.isfunction@^3.0.9: - version "3.0.9" - resolved "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz" - integrity sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw== - -lodash.isinteger@^4.0.4: - version "4.0.4" - resolved "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz" - integrity sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA== - -lodash.isplainobject@^4.0.6: - version "4.0.6" - resolved "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz" - integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA== - -lodash.lowerfirst@^4.3.1: - version "4.3.1" - resolved "https://registry.npmjs.org/lodash.lowerfirst/-/lodash.lowerfirst-4.3.1.tgz" - integrity sha512-UUKX7VhP1/JL54NXg2aq/E1Sfnjjes8fNYTNkPU8ZmsaVeBvPHKdbNaN79Re5XRL01u6wbq3j0cbYZj71Fcu5w== - -lodash.map@^4.6.0: - version "4.6.0" - resolved "https://registry.npmjs.org/lodash.map/-/lodash.map-4.6.0.tgz" - integrity sha512-worNHGKLDetmcEYDvh2stPCrrQRkP20E4l0iIS7F8EvzMqBBi7ltvFN5m1HvTf1P7Jk1txKhvFcmYsCr8O2F1Q== - -lodash.mapvalues@^4.6.0: - version "4.6.0" - resolved "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz" - integrity sha512-JPFqXFeZQ7BfS00H58kClY7SPVeHertPE0lNuCyZ26/XlN8TvakYD7b9bGyNmXbT/D3BbtPAAmq90gPWqLkxlQ== - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash.pick@^4.4.0: - version "4.4.0" - resolved "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz" - integrity sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q== - -lodash.snakecase@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz" - integrity sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw== - -lodash.uniq@^4.5.0: - version "4.5.0" - resolved "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz" - integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== - -lodash.uniqby@^4.7.0: - version "4.7.0" - resolved "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz" - integrity sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww== - -lodash.values@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/lodash.values/-/lodash.values-4.3.0.tgz" - integrity sha512-r0RwvdCv8id9TUblb/O7rYPwVy6lerCbcawrfdo9iC/1t1wsNMJknO79WNBgwkH0hIeJ08jmvvESbFpNb4jH0Q== - -lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.21: - version "4.17.21" - resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-update@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz" - integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== - dependencies: - ansi-escapes "^4.3.0" - cli-cursor "^3.1.0" - slice-ansi "^4.0.0" - wrap-ansi "^6.2.0" - -longest-streak@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz" - integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g== - -loose-envify@^1.1.0, loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -lowlight@^1.17.0: - version "1.20.0" - resolved "https://registry.npmjs.org/lowlight/-/lowlight-1.20.0.tgz" - integrity sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw== - dependencies: - fault "^1.0.0" - highlight.js "~10.7.0" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -"lru-cache@^9.1.1 || ^10.0.0": - version "10.2.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz" - integrity sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q== - -markdown-extensions@^1.0.0: - version "1.1.1" - resolved "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz" - integrity sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q== - -markdown-table@^3.0.0: - version "3.0.3" - resolved "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz" - integrity sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw== - -mdast-util-definitions@^5.0.0: - version "5.1.2" - resolved "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz" - integrity sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA== - dependencies: - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - unist-util-visit "^4.0.0" - -mdast-util-find-and-replace@^2.0.0: - version "2.2.2" - resolved "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-2.2.2.tgz" - integrity sha512-MTtdFRz/eMDHXzeK6W3dO7mXUlF82Gom4y0oOgvHhh/HXZAGvIQDUvQ0SuUx+j2tv44b8xTHOm8K/9OoRFnXKw== - dependencies: - "@types/mdast" "^3.0.0" - escape-string-regexp "^5.0.0" - unist-util-is "^5.0.0" - unist-util-visit-parents "^5.0.0" - -mdast-util-from-markdown@^0.8.5: - version "0.8.5" - resolved "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz" - integrity sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-to-string "^2.0.0" - micromark "~2.11.0" - parse-entities "^2.0.0" - unist-util-stringify-position "^2.0.0" - -mdast-util-from-markdown@^1.0.0, mdast-util-from-markdown@^1.1.0, mdast-util-from-markdown@^1.3.0: - version "1.3.1" - resolved "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz" - integrity sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww== - dependencies: - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - decode-named-character-reference "^1.0.0" - mdast-util-to-string "^3.1.0" - micromark "^3.0.0" - micromark-util-decode-numeric-character-reference "^1.0.0" - micromark-util-decode-string "^1.0.0" - micromark-util-normalize-identifier "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - unist-util-stringify-position "^3.0.0" - uvu "^0.5.0" - -mdast-util-gfm-autolink-literal@^1.0.0: - version "1.0.3" - resolved "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-1.0.3.tgz" - integrity sha512-My8KJ57FYEy2W2LyNom4n3E7hKTuQk/0SES0u16tjA9Z3oFkF4RrC/hPAPgjlSpezsOvI8ObcXcElo92wn5IGA== - dependencies: - "@types/mdast" "^3.0.0" - ccount "^2.0.0" - mdast-util-find-and-replace "^2.0.0" - micromark-util-character "^1.0.0" - -mdast-util-gfm-footnote@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-1.0.2.tgz" - integrity sha512-56D19KOGbE00uKVj3sgIykpwKL179QsVFwx/DCW0u/0+URsryacI4MAdNJl0dh+u2PSsD9FtxPFbHCzJ78qJFQ== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-to-markdown "^1.3.0" - micromark-util-normalize-identifier "^1.0.0" - -mdast-util-gfm-strikethrough@^1.0.0: - version "1.0.3" - resolved "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-1.0.3.tgz" - integrity sha512-DAPhYzTYrRcXdMjUtUjKvW9z/FNAMTdU0ORyMcbmkwYNbKocDpdk+PX1L1dQgOID/+vVs1uBQ7ElrBQfZ0cuiQ== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-to-markdown "^1.3.0" - -mdast-util-gfm-table@^1.0.0: - version "1.0.7" - resolved "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-1.0.7.tgz" - integrity sha512-jjcpmNnQvrmN5Vx7y7lEc2iIOEytYv7rTvu+MeyAsSHTASGCCRA79Igg2uKssgOs1i1po8s3plW0sTu1wkkLGg== - dependencies: - "@types/mdast" "^3.0.0" - markdown-table "^3.0.0" - mdast-util-from-markdown "^1.0.0" - mdast-util-to-markdown "^1.3.0" - -mdast-util-gfm-task-list-item@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-1.0.2.tgz" - integrity sha512-PFTA1gzfp1B1UaiJVyhJZA1rm0+Tzn690frc/L8vNX1Jop4STZgOE6bxUhnzdVSB+vm2GU1tIsuQcA9bxTQpMQ== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-to-markdown "^1.3.0" - -mdast-util-gfm@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-2.0.2.tgz" - integrity sha512-qvZ608nBppZ4icQlhQQIAdc6S3Ffj9RGmzwUKUWuEICFnd1LVkN3EktF7ZHAgfcEdvZB5owU9tQgt99e2TlLjg== - dependencies: - mdast-util-from-markdown "^1.0.0" - mdast-util-gfm-autolink-literal "^1.0.0" - mdast-util-gfm-footnote "^1.0.0" - mdast-util-gfm-strikethrough "^1.0.0" - mdast-util-gfm-table "^1.0.0" - mdast-util-gfm-task-list-item "^1.0.0" - mdast-util-to-markdown "^1.0.0" - -mdast-util-math@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/mdast-util-math/-/mdast-util-math-2.0.2.tgz" - integrity sha512-8gmkKVp9v6+Tgjtq6SYx9kGPpTf6FVYRa53/DLh479aldR9AyP48qeVOgNZ5X7QUK7nOy4yw7vg6mbiGcs9jWQ== - dependencies: - "@types/mdast" "^3.0.0" - longest-streak "^3.0.0" - mdast-util-to-markdown "^1.3.0" - -mdast-util-mdx-expression@^1.0.0: - version "1.3.2" - resolved "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-1.3.2.tgz" - integrity sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/hast" "^2.0.0" - "@types/mdast" "^3.0.0" - mdast-util-from-markdown "^1.0.0" - mdast-util-to-markdown "^1.0.0" - -mdast-util-mdx-jsx@^2.0.0: - version "2.1.4" - resolved "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-2.1.4.tgz" - integrity sha512-DtMn9CmVhVzZx3f+optVDF8yFgQVt7FghCRNdlIaS3X5Bnym3hZwPbg/XW86vdpKjlc1PVj26SpnLGeJBXD3JA== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/hast" "^2.0.0" - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - ccount "^2.0.0" - mdast-util-from-markdown "^1.1.0" - mdast-util-to-markdown "^1.3.0" - parse-entities "^4.0.0" - stringify-entities "^4.0.0" - unist-util-remove-position "^4.0.0" - unist-util-stringify-position "^3.0.0" - vfile-message "^3.0.0" - -mdast-util-mdx@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-2.0.1.tgz" - integrity sha512-38w5y+r8nyKlGvNjSEqWrhG0w5PmnRA+wnBvm+ulYCct7nsGYhFVb0lljS9bQav4psDAS1eGkP2LMVcZBi/aqw== - dependencies: - mdast-util-from-markdown "^1.0.0" - mdast-util-mdx-expression "^1.0.0" - mdast-util-mdx-jsx "^2.0.0" - mdast-util-mdxjs-esm "^1.0.0" - mdast-util-to-markdown "^1.0.0" - -mdast-util-mdxjs-esm@^1.0.0: - version "1.3.1" - resolved "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-1.3.1.tgz" - integrity sha512-SXqglS0HrEvSdUEfoXFtcg7DRl7S2cwOXc7jkuusG472Mmjag34DUDeOJUZtl+BVnyeO1frIgVpHlNRWc2gk/w== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/hast" "^2.0.0" - "@types/mdast" "^3.0.0" - mdast-util-from-markdown "^1.0.0" - mdast-util-to-markdown "^1.0.0" - -mdast-util-newline-to-break@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/mdast-util-newline-to-break/-/mdast-util-newline-to-break-1.0.0.tgz" - integrity sha512-491LcYv3gbGhhCrLoeALncQmega2xPh+m3gbsIhVsOX4sw85+ShLFPvPyibxc1Swx/6GtzxgVodq+cGa/47ULg== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-find-and-replace "^2.0.0" - -mdast-util-phrasing@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz" - integrity sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg== - dependencies: - "@types/mdast" "^3.0.0" - unist-util-is "^5.0.0" - -mdast-util-to-hast@^12.1.0: - version "12.3.0" - resolved "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz" - integrity sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw== - dependencies: - "@types/hast" "^2.0.0" - "@types/mdast" "^3.0.0" - mdast-util-definitions "^5.0.0" - micromark-util-sanitize-uri "^1.1.0" - trim-lines "^3.0.0" - unist-util-generated "^2.0.0" - unist-util-position "^4.0.0" - unist-util-visit "^4.0.0" - -mdast-util-to-markdown@^1.0.0, mdast-util-to-markdown@^1.3.0: - version "1.5.0" - resolved "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz" - integrity sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A== - dependencies: - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - longest-streak "^3.0.0" - mdast-util-phrasing "^3.0.0" - mdast-util-to-string "^3.0.0" - micromark-util-decode-string "^1.0.0" - unist-util-visit "^4.0.0" - zwitch "^2.0.0" - -mdast-util-to-string@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz" - integrity sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w== - -mdast-util-to-string@^3.0.0, mdast-util-to-string@^3.1.0: - version "3.2.0" - resolved "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz" - integrity sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg== - dependencies: - "@types/mdast" "^3.0.0" - -"memoize-one@>=3.1.1 <6": - version "5.2.1" - resolved "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz" - integrity sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q== - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -mermaid@10.4.0: - version "10.4.0" - resolved "https://registry.npmjs.org/mermaid/-/mermaid-10.4.0.tgz" - integrity sha512-4QCQLp79lvz7UZxow5HUX7uWTPJOaQBVExduo91tliXC7v78i6kssZOPHxLL+Xs30KU72cpPn3g3imw/xm/gaw== - dependencies: - "@braintree/sanitize-url" "^6.0.1" - "@types/d3-scale" "^4.0.3" - "@types/d3-scale-chromatic" "^3.0.0" - cytoscape "^3.23.0" - cytoscape-cose-bilkent "^4.1.0" - cytoscape-fcose "^2.1.0" - d3 "^7.4.0" - d3-sankey "^0.12.3" - dagre-d3-es "7.0.10" - dayjs "^1.11.7" - dompurify "^3.0.5" - elkjs "^0.8.2" - khroma "^2.0.0" - lodash-es "^4.17.21" - mdast-util-from-markdown "^1.3.0" - non-layered-tidy-tree-layout "^2.0.2" - stylis "^4.1.3" - ts-dedent "^2.2.0" - uuid "^9.0.0" - web-worker "^1.2.0" - -micromark-core-commonmark@^1.0.0, micromark-core-commonmark@^1.0.1: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz" - integrity sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw== - dependencies: - decode-named-character-reference "^1.0.0" - micromark-factory-destination "^1.0.0" - micromark-factory-label "^1.0.0" - micromark-factory-space "^1.0.0" - micromark-factory-title "^1.0.0" - micromark-factory-whitespace "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-chunked "^1.0.0" - micromark-util-classify-character "^1.0.0" - micromark-util-html-tag-name "^1.0.0" - micromark-util-normalize-identifier "^1.0.0" - micromark-util-resolve-all "^1.0.0" - micromark-util-subtokenize "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.1" - uvu "^0.5.0" - -micromark-extension-gfm-autolink-literal@^1.0.0: - version "1.0.5" - resolved "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-1.0.5.tgz" - integrity sha512-z3wJSLrDf8kRDOh2qBtoTRD53vJ+CWIyo7uyZuxf/JAbNJjiHsOpG1y5wxk8drtv3ETAHutCu6N3thkOOgueWg== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-sanitize-uri "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-extension-gfm-footnote@^1.0.0: - version "1.1.2" - resolved "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-1.1.2.tgz" - integrity sha512-Yxn7z7SxgyGWRNa4wzf8AhYYWNrwl5q1Z8ii+CSTTIqVkmGZF1CElX2JI8g5yGoM3GAman9/PVCUFUSJ0kB/8Q== - dependencies: - micromark-core-commonmark "^1.0.0" - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-normalize-identifier "^1.0.0" - micromark-util-sanitize-uri "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-extension-gfm-strikethrough@^1.0.0: - version "1.0.7" - resolved "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-1.0.7.tgz" - integrity sha512-sX0FawVE1o3abGk3vRjOH50L5TTLr3b5XMqnP9YDRb34M0v5OoZhG+OHFz1OffZ9dlwgpTBKaT4XW/AsUVnSDw== - dependencies: - micromark-util-chunked "^1.0.0" - micromark-util-classify-character "^1.0.0" - micromark-util-resolve-all "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-extension-gfm-table@^1.0.0: - version "1.0.7" - resolved "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-1.0.7.tgz" - integrity sha512-3ZORTHtcSnMQEKtAOsBQ9/oHp9096pI/UvdPtN7ehKvrmZZ2+bbWhi0ln+I9drmwXMt5boocn6OlwQzNXeVeqw== - dependencies: - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-extension-gfm-tagfilter@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-1.0.2.tgz" - integrity sha512-5XWB9GbAUSHTn8VPU8/1DBXMuKYT5uOgEjJb8gN3mW0PNW5OPHpSdojoqf+iq1xo7vWzw/P8bAHY0n6ijpXF7g== - dependencies: - micromark-util-types "^1.0.0" - -micromark-extension-gfm-task-list-item@^1.0.0: - version "1.0.5" - resolved "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-1.0.5.tgz" - integrity sha512-RMFXl2uQ0pNQy6Lun2YBYT9g9INXtWJULgbt01D/x8/6yJ2qpKyzdZD3pi6UIkzF++Da49xAelVKUeUMqd5eIQ== - dependencies: - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-extension-gfm@^2.0.0: - version "2.0.3" - resolved "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.3.tgz" - integrity sha512-vb9OoHqrhCmbRidQv/2+Bc6pkP0FrtlhurxZofvOEy5o8RtuuvTq+RQ1Vw5ZDNrVraQZu3HixESqbG+0iKk/MQ== - dependencies: - micromark-extension-gfm-autolink-literal "^1.0.0" - micromark-extension-gfm-footnote "^1.0.0" - micromark-extension-gfm-strikethrough "^1.0.0" - micromark-extension-gfm-table "^1.0.0" - micromark-extension-gfm-tagfilter "^1.0.0" - micromark-extension-gfm-task-list-item "^1.0.0" - micromark-util-combine-extensions "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-extension-math@^2.0.0: - version "2.1.2" - resolved "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-2.1.2.tgz" - integrity sha512-es0CcOV89VNS9wFmyn+wyFTKweXGW4CEvdaAca6SWRWPyYCbBisnjaHLjWO4Nszuiud84jCpkHsqAJoa768Pvg== - dependencies: - "@types/katex" "^0.16.0" - katex "^0.16.0" - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-extension-mdx-expression@^1.0.0: - version "1.0.8" - resolved "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-1.0.8.tgz" - integrity sha512-zZpeQtc5wfWKdzDsHRBY003H2Smg+PUi2REhqgIhdzAa5xonhP03FcXxqFSerFiNUr5AWmHpaNPQTBVOS4lrXw== - dependencies: - "@types/estree" "^1.0.0" - micromark-factory-mdx-expression "^1.0.0" - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-events-to-acorn "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-extension-mdx-jsx@^1.0.0: - version "1.0.5" - resolved "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-1.0.5.tgz" - integrity sha512-gPH+9ZdmDflbu19Xkb8+gheqEDqkSpdCEubQyxuz/Hn8DOXiXvrXeikOoBA71+e8Pfi0/UYmU3wW3H58kr7akA== - dependencies: - "@types/acorn" "^4.0.0" - "@types/estree" "^1.0.0" - estree-util-is-identifier-name "^2.0.0" - micromark-factory-mdx-expression "^1.0.0" - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - vfile-message "^3.0.0" - -micromark-extension-mdx-md@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-1.0.1.tgz" - integrity sha512-7MSuj2S7xjOQXAjjkbjBsHkMtb+mDGVW6uI2dBL9snOBCbZmoNgDAeZ0nSn9j3T42UE/g2xVNMn18PJxZvkBEA== - dependencies: - micromark-util-types "^1.0.0" - -micromark-extension-mdxjs-esm@^1.0.0: - version "1.0.5" - resolved "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-1.0.5.tgz" - integrity sha512-xNRBw4aoURcyz/S69B19WnZAkWJMxHMT5hE36GtDAyhoyn/8TuAeqjFJQlwk+MKQsUD7b3l7kFX+vlfVWgcX1w== - dependencies: - "@types/estree" "^1.0.0" - micromark-core-commonmark "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-events-to-acorn "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - unist-util-position-from-estree "^1.1.0" - uvu "^0.5.0" - vfile-message "^3.0.0" - -micromark-extension-mdxjs@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-1.0.1.tgz" - integrity sha512-7YA7hF6i5eKOfFUzZ+0z6avRG52GpWR8DL+kN47y3f2KhxbBZMhmxe7auOeaTBrW2DenbbZTf1ea9tA2hDpC2Q== - dependencies: - acorn "^8.0.0" - acorn-jsx "^5.0.0" - micromark-extension-mdx-expression "^1.0.0" - micromark-extension-mdx-jsx "^1.0.0" - micromark-extension-mdx-md "^1.0.0" - micromark-extension-mdxjs-esm "^1.0.0" - micromark-util-combine-extensions "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-factory-destination@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz" - integrity sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-factory-label@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz" - integrity sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-factory-mdx-expression@^1.0.0: - version "1.0.9" - resolved "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-1.0.9.tgz" - integrity sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA== - dependencies: - "@types/estree" "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-events-to-acorn "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - unist-util-position-from-estree "^1.0.0" - uvu "^0.5.0" - vfile-message "^3.0.0" - -micromark-factory-space@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz" - integrity sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-factory-title@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz" - integrity sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ== - dependencies: - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-factory-whitespace@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz" - integrity sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ== - dependencies: - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-util-character@^1.0.0: - version "1.2.0" - resolved "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz" - integrity sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg== - dependencies: - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-util-chunked@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz" - integrity sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ== - dependencies: - micromark-util-symbol "^1.0.0" - -micromark-util-classify-character@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz" - integrity sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-util-combine-extensions@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz" - integrity sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA== - dependencies: - micromark-util-chunked "^1.0.0" - micromark-util-types "^1.0.0" - -micromark-util-decode-numeric-character-reference@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz" - integrity sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw== - dependencies: - micromark-util-symbol "^1.0.0" - -micromark-util-decode-string@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz" - integrity sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ== - dependencies: - decode-named-character-reference "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-decode-numeric-character-reference "^1.0.0" - micromark-util-symbol "^1.0.0" - -micromark-util-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz" - integrity sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw== - -micromark-util-events-to-acorn@^1.0.0: - version "1.2.3" - resolved "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-1.2.3.tgz" - integrity sha512-ij4X7Wuc4fED6UoLWkmo0xJQhsktfNh1J0m8g4PbIMPlx+ek/4YdW5mvbye8z/aZvAPUoxgXHrwVlXAPKMRp1w== - dependencies: - "@types/acorn" "^4.0.0" - "@types/estree" "^1.0.0" - "@types/unist" "^2.0.0" - estree-util-visit "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - vfile-message "^3.0.0" - -micromark-util-html-tag-name@^1.0.0: - version "1.2.0" - resolved "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz" - integrity sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q== - -micromark-util-normalize-identifier@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz" - integrity sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q== - dependencies: - micromark-util-symbol "^1.0.0" - -micromark-util-resolve-all@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz" - integrity sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA== - dependencies: - micromark-util-types "^1.0.0" - -micromark-util-sanitize-uri@^1.0.0, micromark-util-sanitize-uri@^1.1.0: - version "1.2.0" - resolved "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz" - integrity sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-encode "^1.0.0" - micromark-util-symbol "^1.0.0" - -micromark-util-subtokenize@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz" - integrity sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A== - dependencies: - micromark-util-chunked "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - -micromark-util-symbol@^1.0.0: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz" - integrity sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag== - -micromark-util-types@^1.0.0, micromark-util-types@^1.0.1: - version "1.1.0" - resolved "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz" - integrity sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg== - -micromark@^3.0.0: - version "3.2.0" - resolved "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz" - integrity sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA== - dependencies: - "@types/debug" "^4.0.0" - debug "^4.0.0" - decode-named-character-reference "^1.0.0" - micromark-core-commonmark "^1.0.1" - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-chunked "^1.0.0" - micromark-util-combine-extensions "^1.0.0" - micromark-util-decode-numeric-character-reference "^1.0.0" - micromark-util-encode "^1.0.0" - micromark-util-normalize-identifier "^1.0.0" - micromark-util-resolve-all "^1.0.0" - micromark-util-sanitize-uri "^1.0.0" - micromark-util-subtokenize "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.1" - uvu "^0.5.0" - -micromark@~2.11.0: - version "2.11.4" - resolved "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz" - integrity sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA== - dependencies: - debug "^4.0.0" - parse-entities "^2.0.0" - -micromatch@^4.0.4, micromatch@^4.0.5: - version "4.0.5" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -mimic-fn@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz" - integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== - -min-indent@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz" - integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== - -minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: - 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" - -minimatch@^9.0.1: - version "9.0.3" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - -minimist@^1.2.0, minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": - version "7.0.4" - resolved "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz" - integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== - -miragejs@^0.1.47: - version "0.1.47" - resolved "https://registry.npmjs.org/miragejs/-/miragejs-0.1.47.tgz" - integrity sha512-99tuCbIAlMhNhyF3s5d3+5/FdJ7O4jSq/5e3e+sDv7L8dZdwJuwutXe0pobJ7hm6yRChTDjK+Nn8dZZd175wbg== - dependencies: - "@miragejs/pretender-node-polyfill" "^0.1.0" - inflected "^2.0.4" - lodash.assign "^4.2.0" - lodash.camelcase "^4.3.0" - lodash.clonedeep "^4.5.0" - lodash.compact "^3.0.1" - lodash.find "^4.6.0" - lodash.flatten "^4.4.0" - lodash.forin "^4.4.0" - lodash.get "^4.4.2" - lodash.has "^4.5.2" - lodash.invokemap "^4.6.0" - lodash.isempty "^4.4.0" - lodash.isequal "^4.5.0" - lodash.isfunction "^3.0.9" - lodash.isinteger "^4.0.4" - lodash.isplainobject "^4.0.6" - lodash.lowerfirst "^4.3.1" - lodash.map "^4.6.0" - lodash.mapvalues "^4.6.0" - lodash.pick "^4.4.0" - lodash.snakecase "^4.1.1" - lodash.uniq "^4.5.0" - lodash.uniqby "^4.7.0" - lodash.values "^4.3.0" - pretender "^3.4.7" - -mkdirp@^0.5.6: - version "0.5.6" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" - integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== - dependencies: - minimist "^1.2.6" - -mri@^1.1.0: - version "1.2.0" - resolved "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz" - integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== - -ms@2.1.2, ms@^2.1.1: - version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -mz@^2.7.0: - version "2.7.0" - resolved "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz" - integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== - dependencies: - any-promise "^1.0.0" - object-assign "^4.0.1" - thenify-all "^1.0.0" - -nanoid@^3.3.6: - version "3.3.6" - resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz" - integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== - -natural-compare-lite@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz" - integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -negotiator@^0.6.3: - version "0.6.3" - resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - -next-nprogress-bar@^2.3.8: - version "2.3.11" - resolved "https://registry.npmjs.org/next-nprogress-bar/-/next-nprogress-bar-2.3.11.tgz" - integrity sha512-OjSvsQwgSWa2qBMYO478QreGG9Jt82tr4wTQptmiyzNqqjzHCyKZNkhANnzPrjuFAoelIvmruJuakODofSnvTQ== - dependencies: - nprogress "^0.2.0" - -next@^14.0.4: - version "14.1.0" - resolved "https://registry.npmjs.org/next/-/next-14.1.0.tgz" - integrity sha512-wlzrsbfeSU48YQBjZhDzOwhWhGsy+uQycR8bHAOt1LY1bn3zZEcDyHQOEoN3aWzQ8LHCAJ1nqrWCc9XF2+O45Q== - dependencies: - "@next/env" "14.1.0" - "@swc/helpers" "0.5.2" - busboy "1.6.0" - caniuse-lite "^1.0.30001579" - graceful-fs "^4.2.11" - postcss "8.4.31" - styled-jsx "5.1.1" - optionalDependencies: - "@next/swc-darwin-arm64" "14.1.0" - "@next/swc-darwin-x64" "14.1.0" - "@next/swc-linux-arm64-gnu" "14.1.0" - "@next/swc-linux-arm64-musl" "14.1.0" - "@next/swc-linux-x64-gnu" "14.1.0" - "@next/swc-linux-x64-musl" "14.1.0" - "@next/swc-win32-arm64-msvc" "14.1.0" - "@next/swc-win32-ia32-msvc" "14.1.0" - "@next/swc-win32-x64-msvc" "14.1.0" - -node-releases@^2.0.12: - version "2.0.12" - resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.12.tgz" - integrity sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ== - -non-layered-tidy-tree-layout@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/non-layered-tidy-tree-layout/-/non-layered-tidy-tree-layout-2.0.2.tgz" - integrity sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw== - -normalize-package-data@^2.5.0: - version "2.5.0" - resolved "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -normalize-range@^0.1.2: - version "0.1.2" - resolved "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz" - integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -npm-run-path@^5.1.0: - version "5.1.0" - resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz" - integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== - dependencies: - path-key "^4.0.0" - -nprogress@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz" - integrity sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA== - -nth-check@^2.0.1: - version "2.1.1" - resolved "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz" - integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== - dependencies: - boolbase "^1.0.0" - -object-assign@^4.0.1, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -object-hash@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz" - integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== - -object-inspect@^1.12.3, object-inspect@^1.13.1, object-inspect@^1.9.0: - version "1.13.1" - resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz" - integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== - -object-is@^1.1.5: - version "1.1.5" - resolved "https://registry.npmjs.org/object-is/-/object-is-1.1.5.tgz" - integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.3, object.assign@^4.1.4: - version "4.1.4" - resolved "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - has-symbols "^1.0.3" - object-keys "^1.1.1" - -object.entries@^1.1.6: - version "1.1.6" - resolved "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz" - integrity sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - -object.fromentries@^2.0.6, object.fromentries@^2.0.7: - version "2.0.7" - resolved "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz" - integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -object.groupby@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz" - integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - -object.hasown@^1.1.2: - version "1.1.3" - resolved "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.3.tgz" - integrity sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA== - dependencies: - define-properties "^1.2.0" - es-abstract "^1.22.1" - -object.values@^1.1.6, object.values@^1.1.7: - version "1.1.7" - resolved "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz" - integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -once@^1.3.0: - 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" - -onetime@^5.1.0, onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -onetime@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz" - integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== - dependencies: - mimic-fn "^4.0.0" - -open@^9.1.0: - version "9.1.0" - resolved "https://registry.npmjs.org/open/-/open-9.1.0.tgz" - integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== - dependencies: - default-browser "^4.0.0" - define-lazy-prop "^3.0.0" - is-inside-container "^1.0.0" - is-wsl "^2.2.0" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.3" - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -papaparse@^5.3.1: - version "5.4.1" - resolved "https://registry.npmjs.org/papaparse/-/papaparse-5.4.1.tgz" - integrity sha512-HipMsgJkZu8br23pW15uvo6sib6wne/4woLZPlFf3rpDyMe9ywEXUsuD7+6K9PRkJlVT51j/sCOYDKGGS3ZJrw== - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-entities@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz" - integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ== - dependencies: - character-entities "^1.0.0" - character-entities-legacy "^1.0.0" - character-reference-invalid "^1.0.0" - is-alphanumerical "^1.0.0" - is-decimal "^1.0.0" - is-hexadecimal "^1.0.0" - -parse-entities@^4.0.0: - version "4.0.1" - resolved "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.1.tgz" - integrity sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w== - dependencies: - "@types/unist" "^2.0.0" - character-entities "^2.0.0" - character-entities-legacy "^3.0.0" - character-reference-invalid "^2.0.0" - decode-named-character-reference "^1.0.0" - is-alphanumerical "^2.0.0" - is-decimal "^2.0.0" - is-hexadecimal "^2.0.0" - -parse-json@^5.0.0: - version "5.2.0" - resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -parse5@^7.0.0: - version "7.1.2" - resolved "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz" - integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== - dependencies: - entities "^4.4.0" - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-key@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz" - integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== - -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-scurry@^1.10.1: - version "1.10.1" - resolved "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz" - integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== - dependencies: - lru-cache "^9.1.1 || ^10.0.0" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -periscopic@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz" - integrity sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw== - dependencies: - "@types/estree" "^1.0.0" - estree-walker "^3.0.0" - is-reference "^3.0.0" - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pidtree@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz" - integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== - -pify@^2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz" - integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== - -pirates@^4.0.1: - version "4.0.5" - resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz" - integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== - -pluralize@^8.0.0: - version "8.0.0" - resolved "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz" - integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== - -portfinder@^1.0.28: - version "1.0.32" - resolved "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz" - integrity sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg== - dependencies: - async "^2.6.4" - debug "^3.2.7" - mkdirp "^0.5.6" - -postcss-import@^15.1.0: - version "15.1.0" - resolved "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz" - integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew== - dependencies: - postcss-value-parser "^4.0.0" - read-cache "^1.0.0" - resolve "^1.1.7" - -postcss-js@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz" - integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== - dependencies: - camelcase-css "^2.0.1" - -postcss-load-config@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.1.tgz" - integrity sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA== - dependencies: - lilconfig "^2.0.5" - yaml "^2.1.1" - -postcss-nested@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/postcss-nested/-/postcss-nested-6.0.1.tgz" - integrity sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ== - dependencies: - postcss-selector-parser "^6.0.11" - -postcss-selector-parser@6.0.10, postcss-selector-parser@^6.0.9: - version "6.0.10" - resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz" - integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - -postcss-selector-parser@^6.0.11: - version "6.0.13" - resolved "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz" - integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - -postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz" - integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== - -postcss@8.4.31, postcss@^8.4.23, postcss@^8.4.31: - version "8.4.31" - resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz" - integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== - dependencies: - nanoid "^3.3.6" - picocolors "^1.0.0" - source-map-js "^1.0.2" - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -pretender@^3.4.7: - version "3.4.7" - resolved "https://registry.npmjs.org/pretender/-/pretender-3.4.7.tgz" - integrity sha512-jkPAvt1BfRi0RKamweJdEcnjkeu7Es8yix3bJ+KgBC5VpG/Ln4JE3hYN6vJym4qprm8Xo5adhWpm3HCoft1dOw== - dependencies: - fake-xml-http-request "^2.1.2" - route-recognizer "^0.3.3" - -prismjs@^1.27.0: - version "1.29.0" - resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz" - integrity sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q== - -prismjs@~1.27.0: - version "1.27.0" - resolved "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz" - integrity sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA== - -prop-types@^15.0.0, prop-types@^15.5.8, prop-types@^15.8.1: - version "15.8.1" - resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz" - integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.13.1" - -property-information@^5.0.0: - version "5.6.0" - resolved "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz" - integrity sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA== - dependencies: - xtend "^4.0.0" - -property-information@^6.0.0: - version "6.2.0" - resolved "https://registry.npmjs.org/property-information/-/property-information-6.2.0.tgz" - integrity sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg== - -punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -qrcode.react@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/qrcode.react/-/qrcode.react-3.1.0.tgz" - integrity sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q== - -qs@^6.11.1: - 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" - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -rc-input@~1.3.5: - version "1.3.6" - resolved "https://registry.npmjs.org/rc-input/-/rc-input-1.3.6.tgz" - integrity sha512-/HjTaKi8/Ts4zNbYaB5oWCquxFyFQO4Co1MnMgoCeGJlpe7k8Eir2HN0a0F9IHDmmo+GYiGgPpz7w/d/krzsJA== - dependencies: - "@babel/runtime" "^7.11.1" - classnames "^2.2.1" - rc-util "^5.18.1" - -rc-resize-observer@^1.0.0: - version "1.4.0" - resolved "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-1.4.0.tgz" - integrity sha512-PnMVyRid9JLxFavTjeDXEXo65HCRqbmLBw9xX9gfC4BZiSzbLXKzW3jPz+J0P71pLbD5tBMTT+mkstV5gD0c9Q== - dependencies: - "@babel/runtime" "^7.20.7" - classnames "^2.2.1" - rc-util "^5.38.0" - resize-observer-polyfill "^1.5.1" - -rc-textarea@^1.5.2: - version "1.5.2" - resolved "https://registry.npmjs.org/rc-textarea/-/rc-textarea-1.5.2.tgz" - integrity sha512-VVwKYtkp5whZVhP+llX8zM8TtI3dv+BDA0FUbmBMGLaW/tuBJ7Yh35yPabO63V+Bi68xv17eI4hy+/4p2G0gFg== - dependencies: - "@babel/runtime" "^7.10.1" - classnames "^2.2.1" - rc-input "~1.3.5" - rc-resize-observer "^1.0.0" - rc-util "^5.27.0" - -rc-util@^5.18.1, rc-util@^5.27.0, rc-util@^5.38.0: - version "5.38.1" - resolved "https://registry.npmjs.org/rc-util/-/rc-util-5.38.1.tgz" - integrity sha512-e4ZMs7q9XqwTuhIK7zBIVFltUtMSjphuPPQXHoHlzRzNdOwUxDejo0Zls5HYaJfRKNURcsS/ceKVULlhjBrxng== - dependencies: - "@babel/runtime" "^7.18.3" - react-is "^18.2.0" - -react-18-input-autosize@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/react-18-input-autosize/-/react-18-input-autosize-3.0.0.tgz" - integrity sha512-7tsUc9PJWg6Vsp8qYuzlKKBf7hbCoTBdNfjYZSprEPbxf3meuhjklg9QPBe9rIyoR3uDAzmG7NpoJ1+kP5ns+w== - dependencies: - prop-types "^15.5.8" - -react-dom@^18.2.0: - version "18.2.0" - resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz" - integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== - dependencies: - loose-envify "^1.1.0" - scheduler "^0.23.0" - -react-error-boundary@^3.1.4: - version "3.1.4" - resolved "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz" - integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA== - dependencies: - "@babel/runtime" "^7.12.5" - -react-error-boundary@^4.0.2: - version "4.0.9" - resolved "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-4.0.9.tgz" - integrity sha512-f6DcHVdTDZmc9ixmRmuLDZpkdghYR/HKZdUzMLHD58s4cR2C4R6y4ktYztCosM6pyeK4/C8IofwqxgID25W6kw== - dependencies: - "@babel/runtime" "^7.12.5" - -react-headless-pagination@^1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/react-headless-pagination/-/react-headless-pagination-1.1.4.tgz" - integrity sha512-Z5d55g3gM2BQMvHJUGm1jbbQ5Bgtq54kNlI5ca1NTwdVR8ZNunN0EdOtNKNobsFRKuZGkQ24VTIu6ulNq190Iw== - dependencies: - classnames "2.3.1" - -react-i18next@^12.2.0: - version "12.3.1" - resolved "https://registry.npmjs.org/react-i18next/-/react-i18next-12.3.1.tgz" - integrity sha512-5v8E2XjZDFzK7K87eSwC7AJcAkcLt5xYZ4+yTPDAW1i7C93oOY1dnr4BaQM7un4Hm+GmghuiPvevWwlca5PwDA== - dependencies: - "@babel/runtime" "^7.20.6" - html-parse-stringify "^3.0.1" - -react-infinite-scroll-component@^6.1.0: - version "6.1.0" - resolved "https://registry.npmjs.org/react-infinite-scroll-component/-/react-infinite-scroll-component-6.1.0.tgz" - integrity sha512-SQu5nCqy8DxQWpnUVLx7V7b7LcA37aM7tvoWjTLZp1dk6EJibM5/4EJKzOnl07/BsM1Y40sKLuqjCwwH/xV0TQ== - dependencies: - throttle-debounce "^2.1.0" - -react-is@^16.13.1, react-is@^16.7.0: - version "16.13.1" - resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - -react-is@^18.0.0, react-is@^18.2.0: - version "18.2.0" - resolved "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== - -react-markdown@^8.0.6: - version "8.0.7" - resolved "https://registry.npmjs.org/react-markdown/-/react-markdown-8.0.7.tgz" - integrity sha512-bvWbzG4MtOU62XqBx3Xx+zB2raaFFsq4mYiAzfjXJMEz2sixgeAfraA3tvzULF02ZdOMUOKTBFFaZJDDrq+BJQ== - dependencies: - "@types/hast" "^2.0.0" - "@types/prop-types" "^15.0.0" - "@types/unist" "^2.0.0" - comma-separated-tokens "^2.0.0" - hast-util-whitespace "^2.0.0" - prop-types "^15.0.0" - property-information "^6.0.0" - react-is "^18.0.0" - remark-parse "^10.0.0" - remark-rehype "^10.0.0" - space-separated-tokens "^2.0.0" - style-to-object "^0.4.0" - unified "^10.0.0" - unist-util-visit "^4.0.0" - vfile "^5.0.0" - -react-multi-email@^1.0.14: - version "1.0.16" - resolved "https://registry.npmjs.org/react-multi-email/-/react-multi-email-1.0.16.tgz" - integrity sha512-dgg4TY3P5FWz6c4ghgxH1bjZOgYL3S/HN+EUNe6dqHbLMVzeyud1ztDUlqvft4NX1sUxKx2IF2zDq1yAJQA5yQ== - -react-papaparse@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/react-papaparse/-/react-papaparse-4.1.0.tgz" - integrity sha512-sGJqK+OE2rVVQPxQUCCDW2prLIglv9kTdizhNe2awXvKo0gLShmhpRN3BwA+ujw5M2gSJ/KGNEwtgII0OsLgkg== - dependencies: - "@types/papaparse" "^5.3.1" - papaparse "^5.3.1" - -react-slider@^2.0.4: - version "2.0.5" - resolved "https://registry.npmjs.org/react-slider/-/react-slider-2.0.5.tgz" - integrity sha512-MU5gaK1yYCKnbDDN3CMiVcgkKZwMvdqK2xUEW7fFU37NAzRgS1FZbF9N7vP08E3XXNVhiuZnwVzUa3PYQAZIMg== - dependencies: - prop-types "^15.8.1" - -react-sortablejs@^6.1.4: - version "6.1.4" - resolved "https://registry.npmjs.org/react-sortablejs/-/react-sortablejs-6.1.4.tgz" - integrity sha512-fc7cBosfhnbh53Mbm6a45W+F735jwZ1UFIYSrIqcO/gRIFoDyZeMtgKlpV4DdyQfbCzdh5LoALLTDRxhMpTyXQ== - dependencies: - classnames "2.3.1" - tiny-invariant "1.2.0" - -react-syntax-highlighter@^15.5.0: - version "15.5.0" - resolved "https://registry.npmjs.org/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz" - integrity sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg== - dependencies: - "@babel/runtime" "^7.3.1" - highlight.js "^10.4.1" - lowlight "^1.17.0" - prismjs "^1.27.0" - refractor "^3.6.0" - -react-tooltip@5.8.3: - version "5.8.3" - resolved "https://registry.npmjs.org/react-tooltip/-/react-tooltip-5.8.3.tgz" - integrity sha512-h7maAlm2Xeymc14gWKhhrzsENeB83N65EzZ+AcQIGrOpNE0yefVRJIHhNcWHEJ0FEtf7VZXxtsj5glVXKxEtvA== - dependencies: - "@floating-ui/dom" "1.1.1" - classnames "^2.3.2" - -react-window-infinite-loader@^1.0.9: - version "1.0.9" - resolved "https://registry.npmjs.org/react-window-infinite-loader/-/react-window-infinite-loader-1.0.9.tgz" - integrity sha512-5Hg89IdU4Vrp0RT8kZYKeTIxWZYhNkVXeI1HbKo01Vm/Z7qztDvXljwx16sMzsa9yapRJQW3ODZfMUw38SOWHw== - -react-window@^1.8.9: - version "1.8.9" - resolved "https://registry.npmjs.org/react-window/-/react-window-1.8.9.tgz" - integrity sha512-+Eqx/fj1Aa5WnhRfj9dJg4VYATGwIUP2ItwItiJ6zboKWA6EX3lYDAXfGF2hyNqplEprhbtjbipiADEcwQ823Q== - dependencies: - "@babel/runtime" "^7.0.0" - memoize-one ">=3.1.1 <6" - -react@^18.2.0: - version "18.2.0" - resolved "https://registry.npmjs.org/react/-/react-18.2.0.tgz" - integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== - dependencies: - loose-envify "^1.1.0" - -reactflow@^11.10.3: - version "11.10.3" - resolved "https://registry.npmjs.org/reactflow/-/reactflow-11.10.3.tgz" - integrity sha512-DGNrTdkWjZtPOhj5MV8fiWWGkJo+otMVdoJ9l67bQL+Xf+8NkJ4AHmRXoYIxtgcENzwTr5WTAIJlswV9i91cyw== - dependencies: - "@reactflow/background" "11.3.8" - "@reactflow/controls" "11.2.8" - "@reactflow/core" "11.10.3" - "@reactflow/minimap" "11.7.8" - "@reactflow/node-resizer" "2.2.8" - "@reactflow/node-toolbar" "1.3.8" - -read-cache@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz" - integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== - dependencies: - pify "^2.3.0" - -read-pkg-up@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz" - integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== - dependencies: - find-up "^4.1.0" - read-pkg "^5.2.0" - type-fest "^0.8.1" - -read-pkg@^5.2.0: - version "5.2.0" - resolved "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz" - integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== - dependencies: - "@types/normalize-package-data" "^2.4.0" - normalize-package-data "^2.5.0" - parse-json "^5.0.0" - type-fest "^0.6.0" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -recordrtc@^5.6.2: - version "5.6.2" - resolved "https://registry.npmjs.org/recordrtc/-/recordrtc-5.6.2.tgz" - integrity sha512-1QNKKNtl7+KcwD1lyOgP3ZlbiJ1d0HtXnypUy7yq49xEERxk31PHvE9RCciDrulPCY7WJ+oz0R9hpNxgsIurGQ== - -reflect.getprototypeof@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz" - integrity sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - globalthis "^1.0.3" - which-builtin-type "^1.1.3" - -refractor@^3.6.0: - version "3.6.0" - resolved "https://registry.npmjs.org/refractor/-/refractor-3.6.0.tgz" - integrity sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA== - dependencies: - hastscript "^6.0.0" - parse-entities "^2.0.0" - prismjs "~1.27.0" - -regenerator-runtime@^0.13.11: - version "0.13.11" - resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz" - integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== - -regexp-tree@^0.1.24, regexp-tree@~0.1.1: - version "0.1.27" - resolved "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz" - integrity sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA== - -regexp.prototype.flags@^1.5.0, regexp.prototype.flags@^1.5.1: - version "1.5.1" - resolved "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz" - integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - set-function-name "^2.0.0" - -regexpp@^3.0.0: - version "3.2.0" - resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== - -regjsparser@^0.9.1: - version "0.9.1" - resolved "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz" - integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== - dependencies: - jsesc "~0.5.0" - -rehype-katex@^6.0.2: - version "6.0.3" - resolved "https://registry.npmjs.org/rehype-katex/-/rehype-katex-6.0.3.tgz" - integrity sha512-ByZlRwRUcWegNbF70CVRm2h/7xy7jQ3R9LaY4VVSvjnoVWwWVhNL60DiZsBpC5tSzYQOCvDbzncIpIjPZWodZA== - dependencies: - "@types/hast" "^2.0.0" - "@types/katex" "^0.14.0" - hast-util-from-html-isomorphic "^1.0.0" - hast-util-to-text "^3.1.0" - katex "^0.16.0" - unist-util-visit "^4.0.0" - -remark-breaks@^3.0.2: - version "3.0.3" - resolved "https://registry.npmjs.org/remark-breaks/-/remark-breaks-3.0.3.tgz" - integrity sha512-C7VkvcUp1TPUc2eAYzsPdaUh8Xj4FSbQnYA5A9f80diApLZscTDeG7efiWP65W8hV2sEy3JuGVU0i6qr5D8Hug== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-newline-to-break "^1.0.0" - unified "^10.0.0" - -remark-gfm@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/remark-gfm/-/remark-gfm-3.0.1.tgz" - integrity sha512-lEFDoi2PICJyNrACFOfDD3JlLkuSbOa5Wd8EPt06HUdptv8Gn0bxYTdbU/XXQ3swAPkEaGxxPN9cbnMHvVu1Ig== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-gfm "^2.0.0" - micromark-extension-gfm "^2.0.0" - unified "^10.0.0" - -remark-math@^5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/remark-math/-/remark-math-5.1.1.tgz" - integrity sha512-cE5T2R/xLVtfFI4cCePtiRn+e6jKMtFDR3P8V3qpv8wpKjwvHoBA4eJzvX+nVrnlNy0911bdGmuspCSwetfYHw== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-math "^2.0.0" - micromark-extension-math "^2.0.0" - unified "^10.0.0" - -remark-mdx@^2.0.0: - version "2.3.0" - resolved "https://registry.npmjs.org/remark-mdx/-/remark-mdx-2.3.0.tgz" - integrity sha512-g53hMkpM0I98MU266IzDFMrTD980gNF3BJnkyFcmN+dD873mQeD5rdMO3Y2X+x8umQfbSE0PcoEDl7ledSA+2g== - dependencies: - mdast-util-mdx "^2.0.0" - micromark-extension-mdxjs "^1.0.0" - -remark-parse@^10.0.0: - version "10.0.2" - resolved "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz" - integrity sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-from-markdown "^1.0.0" - unified "^10.0.0" - -remark-rehype@^10.0.0: - version "10.1.0" - resolved "https://registry.npmjs.org/remark-rehype/-/remark-rehype-10.1.0.tgz" - integrity sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw== - dependencies: - "@types/hast" "^2.0.0" - "@types/mdast" "^3.0.0" - mdast-util-to-hast "^12.1.0" - unified "^10.0.0" - -resize-observer-polyfill@^1.5.1: - version "1.5.1" - resolved "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz" - integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg== - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-pkg-maps@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz" - integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== - -resolve@^1.1.7, resolve@^1.10.0, resolve@^1.22.1, resolve@^1.22.2: - version "1.22.2" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz" - integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== - dependencies: - is-core-module "^2.11.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -resolve@^1.22.4: - version "1.22.8" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz" - integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== - dependencies: - is-core-module "^2.13.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -resolve@^2.0.0-next.4: - version "2.0.0-next.5" - resolved "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz" - integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== - dependencies: - is-core-module "^2.13.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rfdc@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz" - integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== - -rimraf@^3.0.2: - 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" - -robust-predicates@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz" - integrity sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg== - -route-recognizer@^0.3.3: - version "0.3.4" - resolved "https://registry.npmjs.org/route-recognizer/-/route-recognizer-0.3.4.tgz" - integrity sha512-2+MhsfPhvauN1O8KaXpXAOfR/fwe8dnUXVM+xw7yt40lJRfPVQxV6yryZm0cgRvAj5fMF/mdRZbL2ptwbs5i2g== - -run-applescript@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz" - integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== - dependencies: - execa "^5.0.0" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -rw@1: - version "1.3.3" - resolved "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz" - integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ== - -rxjs@^7.8.0: - version "7.8.1" - resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz" - integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== - dependencies: - tslib "^2.1.0" - -sade@^1.7.3: - version "1.8.1" - resolved "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz" - integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A== - dependencies: - mri "^1.1.0" - -safe-array-concat@^1.0.1: - version "1.1.0" - resolved "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz" - integrity sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg== - dependencies: - call-bind "^1.0.5" - get-intrinsic "^1.2.2" - has-symbols "^1.0.3" - isarray "^2.0.5" - -safe-regex-test@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz" - integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - is-regex "^1.1.4" - -safe-regex@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/safe-regex/-/safe-regex-2.1.1.tgz" - integrity sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A== - dependencies: - regexp-tree "~0.1.1" - -"safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sass@^1.61.0: - version "1.62.1" - resolved "https://registry.npmjs.org/sass/-/sass-1.62.1.tgz" - integrity sha512-NHpxIzN29MXvWiuswfc1W3I0N8SXBd8UR26WntmDlRYf0bSADnwnOjsyMZ3lMezSlArD33Vs3YFhp7dWvL770A== - dependencies: - chokidar ">=3.0.0 <4.0.0" - immutable "^4.0.0" - source-map-js ">=0.6.2 <2.0.0" - -scheduler@^0.23.0: - version "0.23.0" - resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz" - integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== - dependencies: - loose-envify "^1.1.0" - -screenfull@^5.0.0: - version "5.2.0" - resolved "https://registry.npmjs.org/screenfull/-/screenfull-5.2.0.tgz" - integrity sha512-9BakfsO2aUQN2K9Fdbj87RJIEZ82Q9IGim7FqM5OsebfoFC6ZHXgDq/KvniuLTPdeM8wY2o6Dj3WQ7KeQCj3cA== - -"semver@2 || 3 || 4 || 5": - version "5.7.1" - resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@^6.3.0: - version "6.3.0" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -semver@^6.3.1: - version "6.3.1" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^7.0.0, semver@^7.3.5, semver@^7.3.6, semver@^7.3.7, semver@^7.3.8, semver@^7.5.4: - version "7.5.4" - resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -server-only@^0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/server-only/-/server-only-0.0.1.tgz" - integrity sha512-qepMx2JxAa5jjfzxG79yPPq+8BuFToHd1hm7kI+Z4zAq1ftQiP7HcxMhDDItrbtwVeLg/cY2JnKnrcFkmiswNA== - -set-function-length@^1.1.1: - version "1.2.0" - resolved "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz" - integrity sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w== - dependencies: - define-data-property "^1.1.1" - function-bind "^1.1.2" - get-intrinsic "^1.2.2" - gopd "^1.0.1" - has-property-descriptors "^1.0.1" - -set-function-name@^2.0.0, set-function-name@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz" - integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== - dependencies: - define-data-property "^1.0.1" - functions-have-names "^1.2.3" - has-property-descriptors "^1.0.0" - -sharp@^0.33.2: - version "0.33.2" - resolved "https://registry.npmjs.org/sharp/-/sharp-0.33.2.tgz" - integrity sha512-WlYOPyyPDiiM07j/UO+E720ju6gtNtHjEGg5vovUk1Lgxyjm2LFO+37Nt/UI3MMh2l6hxTWQWi7qk3cXJTutcQ== - dependencies: - color "^4.2.3" - detect-libc "^2.0.2" - semver "^7.5.4" - optionalDependencies: - "@img/sharp-darwin-arm64" "0.33.2" - "@img/sharp-darwin-x64" "0.33.2" - "@img/sharp-libvips-darwin-arm64" "1.0.1" - "@img/sharp-libvips-darwin-x64" "1.0.1" - "@img/sharp-libvips-linux-arm" "1.0.1" - "@img/sharp-libvips-linux-arm64" "1.0.1" - "@img/sharp-libvips-linux-s390x" "1.0.1" - "@img/sharp-libvips-linux-x64" "1.0.1" - "@img/sharp-libvips-linuxmusl-arm64" "1.0.1" - "@img/sharp-libvips-linuxmusl-x64" "1.0.1" - "@img/sharp-linux-arm" "0.33.2" - "@img/sharp-linux-arm64" "0.33.2" - "@img/sharp-linux-s390x" "0.33.2" - "@img/sharp-linux-x64" "0.33.2" - "@img/sharp-linuxmusl-arm64" "0.33.2" - "@img/sharp-linuxmusl-x64" "0.33.2" - "@img/sharp-wasm32" "0.33.2" - "@img/sharp-win32-ia32" "0.33.2" - "@img/sharp-win32-x64" "0.33.2" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -side-channel@^1.0.4: - 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" - -signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -signal-exit@^4.0.1: - version "4.1.0" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz" - integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== - -simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz" - integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== - dependencies: - is-arrayish "^0.3.1" - -size-sensor@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/size-sensor/-/size-sensor-1.0.1.tgz" - integrity sha512-QTy7MnuugCFXIedXRpUSk9gUnyNiaxIdxGfUjr8xxXOqIB3QvBUYP9+b51oCg2C4dnhaeNk/h57TxjbvoJrJUA== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -slash@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz" - integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== - -slice-ansi@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz" - integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - -slice-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - -slice-ansi@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz" - integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== - dependencies: - ansi-styles "^6.0.0" - is-fullwidth-code-point "^4.0.0" - -sortablejs@^1.15.0: - version "1.15.0" - resolved "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.0.tgz" - integrity sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w== - -"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2, source-map-js@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz" - integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== - -source-map@^0.7.0: - version "0.7.4" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz" - integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== - -space-separated-tokens@^1.0.0: - version "1.1.5" - resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz" - integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== - -space-separated-tokens@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz" - integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== - -spdx-correct@^3.0.0: - version "3.2.0" - resolved "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz" - integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.13" - resolved "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz" - integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== - -state-local@^1.0.6: - version "1.0.7" - resolved "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz" - integrity sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w== - -stop-iteration-iterator@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz" - integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== - dependencies: - internal-slot "^1.0.4" - -streamsearch@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz" - integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== - -string-argv@^0.3.1: - version "0.3.2" - resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz" - integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== - -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0: - version "4.2.3" - 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" - strip-ansi "^6.0.1" - -string-width@^5.0.0, string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - -string.prototype.matchall@^4.0.8: - version "4.0.10" - resolved "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz" - integrity sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - has-symbols "^1.0.3" - internal-slot "^1.0.5" - regexp.prototype.flags "^1.5.0" - set-function-name "^2.0.0" - side-channel "^1.0.4" - -string.prototype.trim@^1.2.8: - version "1.2.8" - resolved "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz" - integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -string.prototype.trimend@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz" - integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -string.prototype.trimstart@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz" - integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -stringify-entities@^4.0.0: - version "4.0.3" - resolved "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.3.tgz" - integrity sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g== - dependencies: - character-entities-html4 "^2.0.0" - character-entities-legacy "^3.0.0" - -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^7.0.1: - version "7.1.0" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== - dependencies: - ansi-regex "^6.0.1" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-final-newline@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz" - integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== - -strip-indent@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz" - integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== - dependencies: - min-indent "^1.0.0" - -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -style-to-object@^0.4.0, style-to-object@^0.4.1: - version "0.4.1" - resolved "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.1.tgz" - integrity sha512-HFpbb5gr2ypci7Qw+IOhnP2zOU7e77b+rzM+wTzXzfi1PrtBCX0E7Pk4wL4iTLnhzZ+JgEGAhX81ebTg/aYjQw== - dependencies: - inline-style-parser "0.1.1" - -styled-jsx@5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.1.tgz" - integrity sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw== - dependencies: - client-only "0.0.1" - -stylis@^4.1.3: - version "4.3.0" - resolved "https://registry.npmjs.org/stylis/-/stylis-4.3.0.tgz" - integrity sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ== - -sucrase@^3.32.0: - version "3.32.0" - resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.32.0.tgz" - integrity sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ== - dependencies: - "@jridgewell/gen-mapping" "^0.3.2" - commander "^4.0.0" - glob "7.1.6" - lines-and-columns "^1.1.6" - mz "^2.7.0" - pirates "^4.0.1" - ts-interface-checker "^0.1.9" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -swr@^2.1.0: - version "2.1.5" - resolved "https://registry.npmjs.org/swr/-/swr-2.1.5.tgz" - integrity sha512-/OhfZMcEpuz77KavXST5q6XE9nrOBOVcBLWjMT+oAE/kQHyE3PASrevXCtQDZ8aamntOfFkbVJp7Il9tNBQWrw== - dependencies: - use-sync-external-store "^1.2.0" - -synckit@^0.8.5: - version "0.8.5" - resolved "https://registry.npmjs.org/synckit/-/synckit-0.8.5.tgz" - integrity sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q== - dependencies: - "@pkgr/utils" "^2.3.1" - tslib "^2.5.0" - -tabbable@^6.0.1: - version "6.2.0" - resolved "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz" - integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew== - -tailwindcss@^3.3.3: - version "3.3.3" - resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.3.tgz" - integrity sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w== - dependencies: - "@alloc/quick-lru" "^5.2.0" - arg "^5.0.2" - chokidar "^3.5.3" - didyoumean "^1.2.2" - dlv "^1.1.3" - fast-glob "^3.2.12" - glob-parent "^6.0.2" - is-glob "^4.0.3" - jiti "^1.18.2" - lilconfig "^2.1.0" - micromatch "^4.0.5" - normalize-path "^3.0.0" - object-hash "^3.0.0" - picocolors "^1.0.0" - postcss "^8.4.23" - postcss-import "^15.1.0" - postcss-js "^4.0.1" - postcss-load-config "^4.0.1" - postcss-nested "^6.0.1" - postcss-selector-parser "^6.0.11" - resolve "^1.22.2" - sucrase "^3.32.0" - -tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -thenify-all@^1.0.0: - version "1.6.0" - resolved "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz" - integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== - dependencies: - thenify ">= 3.1.0 < 4" - -"thenify@>= 3.1.0 < 4": - version "3.3.1" - resolved "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz" - integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== - dependencies: - any-promise "^1.0.0" - -throttle-debounce@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-2.3.0.tgz" - integrity sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ== - -through@^2.3.8: - version "2.3.8" - resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== - -tiny-invariant@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.2.0.tgz" - integrity sha512-1Uhn/aqw5C6RI4KejVeTg6mIS7IqxnLJ8Mv2tV5rTc0qWobay7pDUz6Wi392Cnc8ak1H0F2cjoRzb2/AW4+Fvg== - -titleize@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz" - integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toggle-selection@^1.0.6: - version "1.0.6" - resolved "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz" - integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== - -trim-lines@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz" - integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg== - -trough@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/trough/-/trough-2.1.0.tgz" - integrity sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g== - -ts-dedent@^2.2.0: - version "2.2.0" - resolved "https://registry.npmjs.org/ts-dedent/-/ts-dedent-2.2.0.tgz" - integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== - -ts-interface-checker@^0.1.9: - version "0.1.13" - resolved "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz" - integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== - -tsconfig-paths@^3.15.0: - version "3.15.0" - resolved "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz" - integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tslib@2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz" - integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== - -tslib@^1.8.1, tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^2.1.0, tslib@^2.4.0, tslib@^2.4.1, tslib@^2.5.0: - version "2.5.3" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz" - integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w== - -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -type-fest@^0.6.0: - version "0.6.0" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz" - integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== - -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - -typed-array-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz" - integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" - is-typed-array "^1.1.10" - -typed-array-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz" - integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== - dependencies: - call-bind "^1.0.2" - for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" - -typed-array-byte-offset@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz" - integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" - -typed-array-length@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz" - integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== - dependencies: - call-bind "^1.0.2" - for-each "^0.3.3" - is-typed-array "^1.1.9" - -typescript@4.9.5: - version "4.9.5" - resolved "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== - -uglify-js@^3.17.4: - version "3.17.4" - resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz" - integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== - -unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== - dependencies: - call-bind "^1.0.2" - has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" - -unified@^10.0.0: - version "10.1.2" - resolved "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz" - integrity sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q== - dependencies: - "@types/unist" "^2.0.0" - bail "^2.0.0" - extend "^3.0.0" - is-buffer "^2.0.0" - is-plain-obj "^4.0.0" - trough "^2.0.0" - vfile "^5.0.0" - -unist-util-find-after@^4.0.0: - version "4.0.1" - resolved "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-4.0.1.tgz" - integrity sha512-QO/PuPMm2ERxC6vFXEPtmAutOopy5PknD+Oq64gGwxKtk4xwo9Z97t9Av1obPmGU0IyTa6EKYUfTrK2QJS3Ozw== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^5.0.0" - -unist-util-generated@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz" - integrity sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A== - -unist-util-is@^5.0.0: - version "5.2.1" - resolved "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz" - integrity sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw== - dependencies: - "@types/unist" "^2.0.0" - -unist-util-position-from-estree@^1.0.0, unist-util-position-from-estree@^1.1.0: - version "1.1.2" - resolved "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-1.1.2.tgz" - integrity sha512-poZa0eXpS+/XpoQwGwl79UUdea4ol2ZuCYguVaJS4qzIOMDzbqz8a3erUCOmubSZkaOuGamb3tX790iwOIROww== - dependencies: - "@types/unist" "^2.0.0" - -unist-util-position@^4.0.0: - version "4.0.4" - resolved "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz" - integrity sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg== - dependencies: - "@types/unist" "^2.0.0" - -unist-util-remove-position@^4.0.0: - version "4.0.2" - resolved "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-4.0.2.tgz" - integrity sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ== - dependencies: - "@types/unist" "^2.0.0" - unist-util-visit "^4.0.0" - -unist-util-stringify-position@^2.0.0: - version "2.0.3" - resolved "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz" - integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== - dependencies: - "@types/unist" "^2.0.2" - -unist-util-stringify-position@^3.0.0: - version "3.0.3" - resolved "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz" - integrity sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg== - dependencies: - "@types/unist" "^2.0.0" - -unist-util-visit-parents@^5.0.0, unist-util-visit-parents@^5.1.1: - version "5.1.3" - resolved "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz" - integrity sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^5.0.0" - -unist-util-visit@^4.0.0: - version "4.1.2" - resolved "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz" - integrity sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^5.0.0" - unist-util-visit-parents "^5.1.1" - -untildify@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz" - integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== - -update-browserslist-db@^1.0.11: - version "1.0.11" - resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz" - integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -use-context-selector@^1.4.1: - version "1.4.1" - resolved "https://registry.npmjs.org/use-context-selector/-/use-context-selector-1.4.1.tgz" - integrity sha512-Io2ArvcRO+6MWIhkdfMFt+WKQX+Vb++W8DS2l03z/Vw/rz3BclKpM0ynr4LYGyU85Eke+Yx5oIhTY++QR0ZDoA== - -use-strict@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/use-strict/-/use-strict-1.0.1.tgz" - integrity sha512-IeiWvvEXfW5ltKVMkxq6FvNf2LojMKvB2OCeja6+ct24S1XOmQw2dGr2JyndwACWAGJva9B7yPHwAmeA9QCqAQ== - -use-sync-external-store@1.2.0, use-sync-external-store@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz" - integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== - -util-deprecate@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -uuid@^9.0.0, uuid@^9.0.1: - version "9.0.1" - resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz" - integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== - -uvu@^0.5.0: - version "0.5.6" - resolved "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz" - integrity sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA== - dependencies: - dequal "^2.0.0" - diff "^5.0.0" - kleur "^4.0.3" - sade "^1.7.3" - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -vfile-location@^4.0.0: - version "4.1.0" - resolved "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz" - integrity sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw== - dependencies: - "@types/unist" "^2.0.0" - vfile "^5.0.0" - -vfile-message@^3.0.0: - version "3.1.4" - resolved "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz" - integrity sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw== - dependencies: - "@types/unist" "^2.0.0" - unist-util-stringify-position "^3.0.0" - -vfile@^5.0.0: - version "5.3.7" - resolved "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz" - integrity sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g== - dependencies: - "@types/unist" "^2.0.0" - is-buffer "^2.0.0" - unist-util-stringify-position "^3.0.0" - vfile-message "^3.0.0" - -vite-code-inspector-plugin@0.13.0: - version "0.13.0" - resolved "https://registry.npmjs.org/vite-code-inspector-plugin/-/vite-code-inspector-plugin-0.13.0.tgz" - integrity sha512-hvIn9G+IFzQHVVynWh2wGTBHo51CBJRqQBzYryeuuaL0BK0w8my2/tlpSAae5ofQxOBXBMhyXC2gWgYUJnNWrA== - dependencies: - code-inspector-core "0.13.0" - -void-elements@3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz" - integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w== - -vue-eslint-parser@^9.3.0: - version "9.3.0" - resolved "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-9.3.0.tgz" - integrity sha512-48IxT9d0+wArT1+3wNIy0tascRoywqSUe2E1YalIC1L8jsUGe5aJQItWfRok7DVFGz3UYvzEI7n5wiTXsCMAcQ== - dependencies: - debug "^4.3.4" - eslint-scope "^7.1.1" - eslint-visitor-keys "^3.3.0" - espree "^9.3.1" - esquery "^1.4.0" - lodash "^4.17.21" - semver "^7.3.6" - -web-namespaces@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz" - integrity sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ== - -web-worker@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/web-worker/-/web-worker-1.2.0.tgz" - integrity sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA== - -webpack-code-inspector-plugin@0.13.0: - version "0.13.0" - resolved "https://registry.npmjs.org/webpack-code-inspector-plugin/-/webpack-code-inspector-plugin-0.13.0.tgz" - integrity sha512-T3ZZ84NX0cVmwff5zyYhB9OuroZYsyaQpSgFicgiuYAWCsQePYApM/R3bHdvcECkBXO50hAVtr9SjWRTu1+Ntg== - dependencies: - code-inspector-core "0.13.0" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-builtin-type@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/which-builtin-type/-/which-builtin-type-1.1.3.tgz" - integrity sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw== - dependencies: - function.prototype.name "^1.1.5" - has-tostringtag "^1.0.0" - is-async-function "^2.0.0" - is-date-object "^1.0.5" - is-finalizationregistry "^1.0.2" - is-generator-function "^1.0.10" - is-regex "^1.1.4" - is-weakref "^1.0.2" - isarray "^2.0.5" - which-boxed-primitive "^1.0.2" - which-collection "^1.0.1" - which-typed-array "^1.1.9" - -which-collection@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/which-collection/-/which-collection-1.0.1.tgz" - integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== - dependencies: - is-map "^2.0.1" - is-set "^2.0.1" - is-weakmap "^2.0.1" - is-weakset "^2.0.1" - -which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.9: - version "1.1.13" - resolved "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz" - integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.4" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -word-wrap@^1.2.3: - version "1.2.3" - resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: - version "7.0.0" - 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" - strip-ansi "^6.0.0" - -wrap-ansi@^6.2.0: - version "6.2.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -xml-name-validator@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz" - integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw== - -xtend@^4.0.0: - version "4.0.2" - resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yaml-eslint-parser@^1.1.0, yaml-eslint-parser@^1.2.1: - version "1.2.2" - resolved "https://registry.npmjs.org/yaml-eslint-parser/-/yaml-eslint-parser-1.2.2.tgz" - integrity sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg== - dependencies: - eslint-visitor-keys "^3.0.0" - lodash "^4.17.21" - yaml "^2.0.0" - -yaml@^2.0.0, yaml@^2.1.1, yaml@^2.2.2: - version "2.3.1" - resolved "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz" - integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -zrender@5.4.3: - version "5.4.3" - resolved "https://registry.npmjs.org/zrender/-/zrender-5.4.3.tgz" - integrity sha512-DRUM4ZLnoaT0PBVvGBDO9oWIDBKFdAVieNWxWwK0niYzJCMwGchRk21/hsE+RKkIveH3XHCyvXcJDkgLVvfizQ== - dependencies: - tslib "2.3.0" - -zustand@^4.4.1, zustand@^4.5.1: - version "4.5.1" - resolved "https://registry.npmjs.org/zustand/-/zustand-4.5.1.tgz" - integrity sha512-XlauQmH64xXSC1qGYNv00ODaQ3B+tNPoy22jv2diYiP4eoDKr9LA+Bh5Bc3gplTrFdb6JVI+N4kc1DZ/tbtfPg== - dependencies: - use-sync-external-store "1.2.0" - -zwitch@^2.0.0: - version "2.0.4" - resolved "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz" - integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A== From b151a5bbcfce1e54f26706e64d066ba94054d821 Mon Sep 17 00:00:00 2001 From: chenhe Date: Fri, 10 May 2024 17:22:54 +0800 Subject: [PATCH 12/43] add auth for bearer key --- .../console/datasets/data_source.py | 22 ++++++------- api/core/rag/extractor/notion_extractor.py | 12 +++---- api/libs/bearer_data_source.py | 26 +++++++++++++++ api/libs/oauth_data_source.py | 32 +++++++++---------- api/models/source.py | 21 ++++++++++-- api/services/dataset_service.py | 22 ++++++------- api/tasks/document_indexing_sync_task.py | 12 +++---- 7 files changed, 94 insertions(+), 53 deletions(-) diff --git a/api/controllers/console/datasets/data_source.py b/api/controllers/console/datasets/data_source.py index 8b210cc756bc04..0ca0f0a85653dc 100644 --- a/api/controllers/console/datasets/data_source.py +++ b/api/controllers/console/datasets/data_source.py @@ -16,7 +16,7 @@ from fields.data_source_fields import integrate_list_fields, integrate_notion_info_list_fields from libs.login import login_required from models.dataset import Document -from models.source import DataSourceBinding +from models.source import DataSourceOauthBinding from services.dataset_service import DatasetService, DocumentService from tasks.document_indexing_sync_task import document_indexing_sync_task @@ -29,9 +29,9 @@ class DataSourceApi(Resource): @marshal_with(integrate_list_fields) def get(self): # get workspace data source integrates - data_source_integrates = db.session.query(DataSourceBinding).filter( - DataSourceBinding.tenant_id == current_user.current_tenant_id, - DataSourceBinding.disabled == False + data_source_integrates = db.session.query(DataSourceOauthBinding).filter( + DataSourceOauthBinding.tenant_id == current_user.current_tenant_id, + DataSourceOauthBinding.disabled == False ).all() base_url = request.url_root.rstrip('/') @@ -71,7 +71,7 @@ def get(self): def patch(self, binding_id, action): binding_id = str(binding_id) action = str(action) - data_source_binding = DataSourceBinding.query.filter_by( + data_source_binding = DataSourceOauthBinding.query.filter_by( id=binding_id ).first() if data_source_binding is None: @@ -124,7 +124,7 @@ def get(self): data_source_info = json.loads(document.data_source_info) exist_page_ids.append(data_source_info['notion_page_id']) # get all authorized pages - data_source_bindings = DataSourceBinding.query.filter_by( + data_source_bindings = DataSourceOauthBinding.query.filter_by( tenant_id=current_user.current_tenant_id, provider='notion', disabled=False @@ -163,12 +163,12 @@ class DataSourceNotionApi(Resource): def get(self, workspace_id, page_id, page_type): workspace_id = str(workspace_id) page_id = str(page_id) - data_source_binding = DataSourceBinding.query.filter( + data_source_binding = DataSourceOauthBinding.query.filter( db.and_( - DataSourceBinding.tenant_id == current_user.current_tenant_id, - DataSourceBinding.provider == 'notion', - DataSourceBinding.disabled == False, - DataSourceBinding.source_info['workspace_id'] == f'"{workspace_id}"' + DataSourceOauthBinding.tenant_id == current_user.current_tenant_id, + DataSourceOauthBinding.provider == 'notion', + DataSourceOauthBinding.disabled == False, + DataSourceOauthBinding.source_info['workspace_id'] == f'"{workspace_id}"' ) ).first() if not data_source_binding: diff --git a/api/core/rag/extractor/notion_extractor.py b/api/core/rag/extractor/notion_extractor.py index c40064fd1d8caf..1d2990166b2158 100644 --- a/api/core/rag/extractor/notion_extractor.py +++ b/api/core/rag/extractor/notion_extractor.py @@ -9,7 +9,7 @@ from core.rag.models.document import Document from extensions.ext_database import db from models.dataset import Document as DocumentModel -from models.source import DataSourceBinding +from models.source import DataSourceOauthBinding logger = logging.getLogger(__name__) @@ -351,12 +351,12 @@ def get_notion_last_edited_time(self) -> str: @classmethod def _get_access_token(cls, tenant_id: str, notion_workspace_id: str) -> str: - data_source_binding = DataSourceBinding.query.filter( + data_source_binding = DataSourceOauthBinding.query.filter( db.and_( - DataSourceBinding.tenant_id == tenant_id, - DataSourceBinding.provider == 'notion', - DataSourceBinding.disabled == False, - DataSourceBinding.source_info['workspace_id'] == f'"{notion_workspace_id}"' + DataSourceOauthBinding.tenant_id == tenant_id, + DataSourceOauthBinding.provider == 'notion', + DataSourceOauthBinding.disabled == False, + DataSourceOauthBinding.source_info['workspace_id'] == f'"{notion_workspace_id}"' ) ).first() diff --git a/api/libs/bearer_data_source.py b/api/libs/bearer_data_source.py index 9c14e8e2ff41cf..61d37b23a2ced4 100644 --- a/api/libs/bearer_data_source.py +++ b/api/libs/bearer_data_source.py @@ -3,6 +3,10 @@ from abc import abstractmethod import requests +from api.models.source import DataSourceBearerBinding +from flask_login import current_user + +from extensions.ext_database import db class BearerDataSource: @@ -39,3 +43,25 @@ def validate_bearer_data_source(self): return response.json().get("status") == "success" + def save_credentials(self): + # save data source binding + data_source_binding = DataSourceBearerBinding.query.filter( + db.and_( + DataSourceBearerBinding.tenant_id == current_user.current_tenant_id, + DataSourceBearerBinding.provider == 'firecrawl', + DataSourceBearerBinding.endpoint_url == self.api_base_url, + DataSourceBearerBinding.bearer_key == self.api_key + ) + ).first() + if data_source_binding: + data_source_binding.disabled = False + db.session.commit() + else: + new_data_source_binding = DataSourceBearerBinding( + tenant_id=current_user.current_tenant_id, + provider='firecrawl', + endpoint_url=self.api_base_url, + bearer_key=self.api_key + ) + db.session.add(new_data_source_binding) + db.session.commit() diff --git a/api/libs/oauth_data_source.py b/api/libs/oauth_data_source.py index a865ee85ab5c65..3f2889adbefa36 100644 --- a/api/libs/oauth_data_source.py +++ b/api/libs/oauth_data_source.py @@ -4,7 +4,7 @@ from flask_login import current_user from extensions.ext_database import db -from models.source import DataSourceBinding +from models.source import DataSourceOauthBinding class OAuthDataSource: @@ -63,11 +63,11 @@ def get_access_token(self, code: str): 'total': len(pages) } # save data source binding - data_source_binding = DataSourceBinding.query.filter( + data_source_binding = DataSourceOauthBinding.query.filter( db.and_( - DataSourceBinding.tenant_id == current_user.current_tenant_id, - DataSourceBinding.provider == 'notion', - DataSourceBinding.access_token == access_token + DataSourceOauthBinding.tenant_id == current_user.current_tenant_id, + DataSourceOauthBinding.provider == 'notion', + DataSourceOauthBinding.access_token == access_token ) ).first() if data_source_binding: @@ -75,7 +75,7 @@ def get_access_token(self, code: str): data_source_binding.disabled = False db.session.commit() else: - new_data_source_binding = DataSourceBinding( + new_data_source_binding = DataSourceOauthBinding( tenant_id=current_user.current_tenant_id, access_token=access_token, source_info=source_info, @@ -98,11 +98,11 @@ def save_internal_access_token(self, access_token: str): 'total': len(pages) } # save data source binding - data_source_binding = DataSourceBinding.query.filter( + data_source_binding = DataSourceOauthBinding.query.filter( db.and_( - DataSourceBinding.tenant_id == current_user.current_tenant_id, - DataSourceBinding.provider == 'notion', - DataSourceBinding.access_token == access_token + DataSourceOauthBinding.tenant_id == current_user.current_tenant_id, + DataSourceOauthBinding.provider == 'notion', + DataSourceOauthBinding.access_token == access_token ) ).first() if data_source_binding: @@ -110,7 +110,7 @@ def save_internal_access_token(self, access_token: str): data_source_binding.disabled = False db.session.commit() else: - new_data_source_binding = DataSourceBinding( + new_data_source_binding = DataSourceOauthBinding( tenant_id=current_user.current_tenant_id, access_token=access_token, source_info=source_info, @@ -121,12 +121,12 @@ def save_internal_access_token(self, access_token: str): def sync_data_source(self, binding_id: str): # save data source binding - data_source_binding = DataSourceBinding.query.filter( + data_source_binding = DataSourceOauthBinding.query.filter( db.and_( - DataSourceBinding.tenant_id == current_user.current_tenant_id, - DataSourceBinding.provider == 'notion', - DataSourceBinding.id == binding_id, - DataSourceBinding.disabled == False + DataSourceOauthBinding.tenant_id == current_user.current_tenant_id, + DataSourceOauthBinding.provider == 'notion', + DataSourceOauthBinding.id == binding_id, + DataSourceOauthBinding.disabled == False ) ).first() if data_source_binding: diff --git a/api/models/source.py b/api/models/source.py index 70b139ed25d280..671ff56ad38a89 100644 --- a/api/models/source.py +++ b/api/models/source.py @@ -4,7 +4,7 @@ from models import StringUUID -class DataSourceBinding(db.Model): +class DataSourceOauthBinding(db.Model): __tablename__ = 'data_source_bindings' __table_args__ = ( db.PrimaryKeyConstraint('id', name='source_binding_pkey'), @@ -15,10 +15,25 @@ class DataSourceBinding(db.Model): id = db.Column(StringUUID, server_default=db.text('uuid_generate_v4()')) tenant_id = db.Column(StringUUID, nullable=False) access_token = db.Column(db.String(255), nullable=False) - endpoint_url = db.Column(db.String(512), nullable=True) # For validation with endpoint + bearer key - bearer_key = db.Column(db.String(512), nullable=True) # For validation with endpoint + bearer key provider = db.Column(db.String(255), nullable=False) source_info = db.Column(JSONB, nullable=False) created_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) updated_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) disabled = db.Column(db.Boolean, nullable=True, server_default=db.text('false')) + + +class DataSourceBearerBinding(db.Model): + __tablename__ = 'data_source_bearer_bindings' + __table_args__ = ( + db.PrimaryKeyConstraint('id', name='source_bearer_binding_pkey'), + db.Index('source_bearer_binding_tenant_id_idx', 'tenant_id'), + ) + + id = db.Column(StringUUID, server_default=db.text('uuid_generate_v4()')) + tenant_id = db.Column(StringUUID, nullable=False) + provider = db.Column(db.String(255), nullable=False) + endpoint_url = db.Column(db.String(512), nullable=False) # For validation with endpoint + bearer key + bearer_key = db.Column(db.String(512), nullable=True) # For validation with endpoint + bearer key + created_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) + updated_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) + disabled = db.Column(db.Boolean, nullable=True, server_default=db.text('false')) \ No newline at end of file diff --git a/api/services/dataset_service.py b/api/services/dataset_service.py index fa2ed808852f4e..5dee72eac6eca8 100644 --- a/api/services/dataset_service.py +++ b/api/services/dataset_service.py @@ -32,7 +32,7 @@ DocumentSegment, ) from models.model import UploadFile -from models.source import DataSourceBinding +from models.source import DataSourceOauthBinding from services.errors.account import NoPermissionError from services.errors.dataset import DatasetNameDuplicateError from services.errors.document import DocumentIndexingError @@ -664,12 +664,12 @@ def save_document_with_dataset_id(dataset: Dataset, document_data: dict, exist_document[data_source_info['notion_page_id']] = document.id for notion_info in notion_info_list: workspace_id = notion_info['workspace_id'] - data_source_binding = DataSourceBinding.query.filter( + data_source_binding = DataSourceOauthBinding.query.filter( db.and_( - DataSourceBinding.tenant_id == current_user.current_tenant_id, - DataSourceBinding.provider == 'notion', - DataSourceBinding.disabled == False, - DataSourceBinding.source_info['workspace_id'] == f'"{workspace_id}"' + DataSourceOauthBinding.tenant_id == current_user.current_tenant_id, + DataSourceOauthBinding.provider == 'notion', + DataSourceOauthBinding.disabled == False, + DataSourceOauthBinding.source_info['workspace_id'] == f'"{workspace_id}"' ) ).first() if not data_source_binding: @@ -799,12 +799,12 @@ def update_document_with_dataset_id(dataset: Dataset, document_data: dict, notion_info_list = document_data["data_source"]['info_list']['notion_info_list'] for notion_info in notion_info_list: workspace_id = notion_info['workspace_id'] - data_source_binding = DataSourceBinding.query.filter( + data_source_binding = DataSourceOauthBinding.query.filter( db.and_( - DataSourceBinding.tenant_id == current_user.current_tenant_id, - DataSourceBinding.provider == 'notion', - DataSourceBinding.disabled == False, - DataSourceBinding.source_info['workspace_id'] == f'"{workspace_id}"' + DataSourceOauthBinding.tenant_id == current_user.current_tenant_id, + DataSourceOauthBinding.provider == 'notion', + DataSourceOauthBinding.disabled == False, + DataSourceOauthBinding.source_info['workspace_id'] == f'"{workspace_id}"' ) ).first() if not data_source_binding: diff --git a/api/tasks/document_indexing_sync_task.py b/api/tasks/document_indexing_sync_task.py index c35c18799a6039..4cced36ecdd856 100644 --- a/api/tasks/document_indexing_sync_task.py +++ b/api/tasks/document_indexing_sync_task.py @@ -11,7 +11,7 @@ from core.rag.index_processor.index_processor_factory import IndexProcessorFactory from extensions.ext_database import db from models.dataset import Dataset, Document, DocumentSegment -from models.source import DataSourceBinding +from models.source import DataSourceOauthBinding @shared_task(queue='dataset') @@ -43,12 +43,12 @@ def document_indexing_sync_task(dataset_id: str, document_id: str): page_id = data_source_info['notion_page_id'] page_type = data_source_info['type'] page_edited_time = data_source_info['last_edited_time'] - data_source_binding = DataSourceBinding.query.filter( + data_source_binding = DataSourceOauthBinding.query.filter( db.and_( - DataSourceBinding.tenant_id == document.tenant_id, - DataSourceBinding.provider == 'notion', - DataSourceBinding.disabled == False, - DataSourceBinding.source_info['workspace_id'] == f'"{workspace_id}"' + DataSourceOauthBinding.tenant_id == document.tenant_id, + DataSourceOauthBinding.provider == 'notion', + DataSourceOauthBinding.disabled == False, + DataSourceOauthBinding.source_info['workspace_id'] == f'"{workspace_id}"' ) ).first() if not data_source_binding: From 716b8c164615dd9071e8cdb7e4f52ca4d94267b6 Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Sat, 11 May 2024 17:08:17 +0800 Subject: [PATCH 13/43] add source bearer auth --- .../console/auth/data_source_bearer.py | 116 ------------------ .../console/auth/data_source_bearer_auth.py | 51 ++++++++ api/models/source.py | 31 +++-- api/services/auth/__init__.py | 0 api/services/auth/api_key_auth_service.py | 34 +++++ api/services/auth/firecrawl.py | 75 +++++++++++ api/tests/unit_tests/oss/__init__.py | 0 api/tests/unit_tests/oss/local/__init__.py | 0 8 files changed, 183 insertions(+), 124 deletions(-) delete mode 100644 api/controllers/console/auth/data_source_bearer.py create mode 100644 api/controllers/console/auth/data_source_bearer_auth.py create mode 100644 api/services/auth/__init__.py create mode 100644 api/services/auth/api_key_auth_service.py create mode 100644 api/services/auth/firecrawl.py create mode 100644 api/tests/unit_tests/oss/__init__.py create mode 100644 api/tests/unit_tests/oss/local/__init__.py diff --git a/api/controllers/console/auth/data_source_bearer.py b/api/controllers/console/auth/data_source_bearer.py deleted file mode 100644 index 293ec1c4d341c3..00000000000000 --- a/api/controllers/console/auth/data_source_bearer.py +++ /dev/null @@ -1,116 +0,0 @@ -import logging - -import requests -from flask import current_app, redirect, request -from flask_login import current_user -from flask_restful import Resource -from werkzeug.exceptions import Forbidden - -from controllers.console import api -from libs.login import login_required -from libs.oauth_data_source import NotionOAuth - -from ..setup import setup_required -from ..wraps import account_initialization_required - - -def get_oauth_providers(): - with current_app.app_context(): - notion_oauth = NotionOAuth(client_id=current_app.config.get('NOTION_CLIENT_ID'), - client_secret=current_app.config.get( - 'NOTION_CLIENT_SECRET'), - redirect_uri=current_app.config.get( - 'CONSOLE_API_URL') + '/console/api/oauth/data-source/callback/notion') - - OAUTH_PROVIDERS = { - 'notion': notion_oauth - } - return OAUTH_PROVIDERS - - -class OAuthDataSource(Resource): - def get(self, provider: str): - # The role of the current user in the table must be admin or owner - if not current_user.is_admin_or_owner: - raise Forbidden() - OAUTH_DATASOURCE_PROVIDERS = get_oauth_providers() - with current_app.app_context(): - oauth_provider = OAUTH_DATASOURCE_PROVIDERS.get(provider) - print(vars(oauth_provider)) - if not oauth_provider: - return {'error': 'Invalid provider'}, 400 - if current_app.config.get('NOTION_INTEGRATION_TYPE') == 'internal': - internal_secret = current_app.config.get('NOTION_INTERNAL_SECRET') - oauth_provider.save_internal_access_token(internal_secret) - return { 'data': '' } - else: - auth_url = oauth_provider.get_authorization_url() - return { 'data': auth_url }, 200 - - - - -class OAuthDataSourceCallback(Resource): - def get(self, provider: str): - OAUTH_DATASOURCE_PROVIDERS = get_oauth_providers() - with current_app.app_context(): - oauth_provider = OAUTH_DATASOURCE_PROVIDERS.get(provider) - if not oauth_provider: - return {'error': 'Invalid provider'}, 400 - if 'code' in request.args: - code = request.args.get('code') - - return redirect(f'{current_app.config.get("CONSOLE_WEB_URL")}?type=notion&code={code}') - elif 'error' in request.args: - error = request.args.get('error') - - return redirect(f'{current_app.config.get("CONSOLE_WEB_URL")}?type=notion&error={error}') - else: - return redirect(f'{current_app.config.get("CONSOLE_WEB_URL")}?type=notion&error=Access denied') - - -class OAuthDataSourceBinding(Resource): - def get(self, provider: str): - OAUTH_DATASOURCE_PROVIDERS = get_oauth_providers() - with current_app.app_context(): - oauth_provider = OAUTH_DATASOURCE_PROVIDERS.get(provider) - if not oauth_provider: - return {'error': 'Invalid provider'}, 400 - if 'code' in request.args: - code = request.args.get('code') - try: - oauth_provider.get_access_token(code) - except requests.exceptions.HTTPError as e: - logging.exception( - f"An error occurred during the OAuthCallback process with {provider}: {e.response.text}") - return {'error': 'OAuth data source process failed'}, 400 - - return {'result': 'success'}, 200 - - -class OAuthDataSourceSync(Resource): - @setup_required - @login_required - @account_initialization_required - def get(self, provider, binding_id): - provider = str(provider) - binding_id = str(binding_id) - OAUTH_DATASOURCE_PROVIDERS = get_oauth_providers() - with current_app.app_context(): - oauth_provider = OAUTH_DATASOURCE_PROVIDERS.get(provider) - if not oauth_provider: - return {'error': 'Invalid provider'}, 400 - try: - oauth_provider.sync_data_source(binding_id) - except requests.exceptions.HTTPError as e: - logging.exception( - f"An error occurred during the OAuthCallback process with {provider}: {e.response.text}") - return {'error': 'OAuth data source process failed'}, 400 - - return {'result': 'success'}, 200 - - -api.add_resource(OAuthDataSource, '/oauth/data-source/') -api.add_resource(OAuthDataSourceCallback, '/oauth/data-source/callback/') -api.add_resource(OAuthDataSourceBinding, '/oauth/data-source/binding/') -api.add_resource(OAuthDataSourceSync, '/oauth/data-source///sync') diff --git a/api/controllers/console/auth/data_source_bearer_auth.py b/api/controllers/console/auth/data_source_bearer_auth.py new file mode 100644 index 00000000000000..01cf81e6726968 --- /dev/null +++ b/api/controllers/console/auth/data_source_bearer_auth.py @@ -0,0 +1,51 @@ +import logging + +import requests +from flask import current_app, redirect, request +from flask_login import current_user +from flask_restful import Resource, reqparse +from werkzeug.exceptions import Forbidden + +from controllers.console import api +from libs.login import login_required +from libs.oauth_data_source import NotionOAuth +from services.auth.api_key_auth_service import ApiKeyAuthService + +from ..setup import setup_required +from ..wraps import account_initialization_required + + +class ApiKeyAuthDataSource(Resource): + @setup_required + @login_required + @account_initialization_required + def get(self): + # The role of the current user in the table must be admin or owner + if not current_user.is_admin_or_owner: + raise Forbidden() + data_source_api_key_bindings = ApiKeyAuthService.get_provider_auth_list(current_user.tenant_id) + if data_source_api_key_bindings: + return { + 'settings': [data_source_api_key_binding.to_dict() for data_source_api_key_binding in + data_source_api_key_bindings]} + return {'settings': []} + + +class ApiKeyAuthDataSourceBinding(Resource): + @setup_required + @login_required + @account_initialization_required + def post(self): + # The role of the current user in the table must be admin or owner + if not current_user.is_admin_or_owner: + raise Forbidden() + parser = reqparse.RequestParser() + parser.add_argument('category', type=str, required=True, nullable=False, location='json') + parser.add_argument('provider', type=str, required=True, nullable=False, location='json') + parser.add_argument('credential', type=dict, required=True, nullable=False, location='json') + args = parser.parse_args() + data_source_api_key_binding = ApiKeyAuthService.create_provider_auth(current_user.tenant_id, args) + + +api.add_resource(ApiKeyAuthDataSource, '/api-key-auth/data-source') +api.add_resource(ApiKeyAuthDataSourceBinding, '/api-key-auth/data-source/binding') diff --git a/api/models/source.py b/api/models/source.py index 671ff56ad38a89..b870f1fa37db74 100644 --- a/api/models/source.py +++ b/api/models/source.py @@ -1,3 +1,5 @@ +import json + from sqlalchemy.dialects.postgresql import JSONB from extensions.ext_database import db @@ -5,7 +7,7 @@ class DataSourceOauthBinding(db.Model): - __tablename__ = 'data_source_bindings' + __tablename__ = 'data_source_oauth_bindings' __table_args__ = ( db.PrimaryKeyConstraint('id', name='source_binding_pkey'), db.Index('source_binding_tenant_id_idx', 'tenant_id'), @@ -22,18 +24,31 @@ class DataSourceOauthBinding(db.Model): disabled = db.Column(db.Boolean, nullable=True, server_default=db.text('false')) -class DataSourceBearerBinding(db.Model): - __tablename__ = 'data_source_bearer_bindings' +class DataSourceApiKeyAuthBinding(db.Model): + __tablename__ = 'data_source_api_key_auth_bindings' __table_args__ = ( - db.PrimaryKeyConstraint('id', name='source_bearer_binding_pkey'), - db.Index('source_bearer_binding_tenant_id_idx', 'tenant_id'), + db.PrimaryKeyConstraint('id', name='data_source_api_key_auth_binding_pkey'), + db.Index('data_source_api_key_auth_binding_tenant_id_idx', 'tenant_id'), + db.Index('data_source_api_key_auth_binding_provider_idx', 'provider'), ) id = db.Column(StringUUID, server_default=db.text('uuid_generate_v4()')) tenant_id = db.Column(StringUUID, nullable=False) + category = db.Column(db.String(255), nullable=False) provider = db.Column(db.String(255), nullable=False) - endpoint_url = db.Column(db.String(512), nullable=False) # For validation with endpoint + bearer key - bearer_key = db.Column(db.String(512), nullable=True) # For validation with endpoint + bearer key + credentials = db.Column(db.Text, nullable=True) # JSON created_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) updated_at = db.Column(db.DateTime, nullable=False, server_default=db.text('CURRENT_TIMESTAMP(0)')) - disabled = db.Column(db.Boolean, nullable=True, server_default=db.text('false')) \ No newline at end of file + disabled = db.Column(db.Boolean, nullable=True, server_default=db.text('false')) + + def to_dict(self): + return { + 'id': self.id, + 'tenant_id': self.tenant_id, + 'category': self.category, + 'provider': self.provider, + 'credentials': json.dumps(self.credentials, ensure_ascii=False), + 'created_at': self.created_at, + 'updated_at': self.updated_at, + 'disabled': self.disabled + } diff --git a/api/services/auth/__init__.py b/api/services/auth/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/api/services/auth/api_key_auth_service.py b/api/services/auth/api_key_auth_service.py new file mode 100644 index 00000000000000..8630eb6615ff3f --- /dev/null +++ b/api/services/auth/api_key_auth_service.py @@ -0,0 +1,34 @@ +import uuid +from typing import List + +from flask_login import current_user +from sqlalchemy import func +from werkzeug.exceptions import NotFound + +from extensions.ext_database import db +from models.dataset import Dataset +from models.model import App, Tag, TagBinding +from models.source import DataSourceApiKeyAuthBinding + + +class ApiKeyAuthService: + + @staticmethod + def get_provider_auth_list(tenant_id: str) -> list: + data_source_api_key_bindings = db.session.query(DataSourceApiKeyAuthBinding).filter( + DataSourceApiKeyAuthBinding.tenant_id == tenant_id, + DataSourceApiKeyAuthBinding.disabled.is_(False) + ).all() + return data_source_api_key_bindings + + @staticmethod + def create_provider_auth(tenant_id: str, args: dict) -> DataSourceApiKeyAuthBinding: + data_source_api_key_binding = DataSourceApiKeyAuthBinding() + data_source_api_key_binding.tenant_id = tenant_id + data_source_api_key_binding.category = args['category'] + data_source_api_key_binding.provider = args['provider'] + data_source_api_key_binding.credentials = args['credential'] + db.session.add(data_source_api_key_binding) + db.session.commit() + return data_source_api_key_binding + pass diff --git a/api/services/auth/firecrawl.py b/api/services/auth/firecrawl.py new file mode 100644 index 00000000000000..f76b976739c226 --- /dev/null +++ b/api/services/auth/firecrawl.py @@ -0,0 +1,75 @@ +import os +import requests + + +class FirecrawlAuth: + def __init__(self, api_key=None, endpoint=None): + self.api_key = api_key or os.getenv('FIRECRAWL_API_KEY') + if self.api_key is None: + raise ValueError('No API key provided') + + def _validate_credentials(self): + headers = self._prepare_headers() + options = { + 'url': 'https://example.com', + 'crawlerOptions': { + 'excludes': [], + 'includes': [], + 'limit': 1 + }, + 'pageOptions': { + 'onlyMainContent': True + } + } + response = self._post_request('https://api.firecrawl.dev/v0/crawl', options, headers) + if response.status_code == 200: + return True + else: + self._handle_error(response, 'start crawl job') + + def check_crawl_status(self, job_id): + headers = self._prepare_headers() + response = self._get_request(f'https://api.firecrawl.dev/v0/crawl/status/{job_id}', headers) + if response.status_code == 200: + return response.json() + else: + self._handle_error(response, 'check crawl status') + + def _prepare_headers(self): + return { + 'Content-Type': 'application/json', + 'Authorization': f'Bearer {self.api_key}' + } + + def _post_request(self, url, data, headers): + return requests.post(url, headers=headers, json=data) + + def _get_request(self, url, headers): + return requests.get(url, headers=headers) + + def _monitor_job_status(self, job_id, headers, timeout): + import time + while True: + status_response = self._get_request(f'https://api.firecrawl.dev/v0/crawl/status/{job_id}', headers) + if status_response.status_code == 200: + status_data = status_response.json() + if status_data['status'] == 'completed': + if 'data' in status_data: + return status_data['data'] + else: + raise Exception('Crawl job completed but no data was returned') + elif status_data['status'] in ['active', 'paused', 'pending', 'queued']: + if timeout < 2: + timeout = 2 + time.sleep(timeout) # Wait for the specified timeout before checking again + else: + raise Exception(f'Crawl job failed or was stopped. Status: {status_data["status"]}') + else: + self._handle_error(status_response, 'check crawl status') + + def _handle_error(self, response, action): + if response.status_code in [402, 409, 500]: + error_message = response.json().get('error', 'Unknown error occurred') + raise Exception(f'Failed to {action}. Status code: {response.status_code}. Error: {error_message}') + else: + raise Exception(f'Unexpected error occurred while trying to {action}. Status code: {response.status_code}') diff --git a/api/tests/unit_tests/oss/__init__.py b/api/tests/unit_tests/oss/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/api/tests/unit_tests/oss/local/__init__.py b/api/tests/unit_tests/oss/local/__init__.py new file mode 100644 index 00000000000000..e69de29bb2d1d6 From 457526eb7a638ad46f0e9dac88a59ec96be5cf09 Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Tue, 14 May 2024 19:45:25 +0800 Subject: [PATCH 14/43] firecrawl web extract --- api/controllers/console/__init__.py | 4 +- .../console/auth/data_source_bearer_auth.py | 13 +- api/controllers/console/datasets/datasets.py | 1 + .../console/datasets/datasets_document.py | 2 +- api/controllers/console/datasets/website.py | 42 ++++++ api/core/indexing_runner.py | 14 ++ .../rag/extractor/entity/datasource_type.py | 2 +- .../rag/extractor/entity/extract_setting.py | 16 +-- api/core/rag/extractor/extract_processor.py | 16 ++- .../rag/extractor/firecrawl/firecrawl_app.py | 64 +-------- .../firecrawl/firecrawl_web_extractor.py | 42 ++---- .../7b45942e39bb_add_api_key_auth_binding.py | 67 +++++++++ api/services/auth/api_key_auth_base.py | 9 ++ api/services/auth/api_key_auth_factory.py | 14 ++ api/services/auth/api_key_auth_service.py | 44 +++--- api/services/auth/firecrawl.py | 60 +++----- api/services/dataset_service.py | 39 ++++++ api/services/website_service.py | 128 ++++++++++++++++++ 18 files changed, 396 insertions(+), 181 deletions(-) create mode 100644 api/controllers/console/datasets/website.py create mode 100644 api/migrations/versions/7b45942e39bb_add_api_key_auth_binding.py create mode 100644 api/services/auth/api_key_auth_base.py create mode 100644 api/services/auth/api_key_auth_factory.py create mode 100644 api/services/website_service.py diff --git a/api/controllers/console/__init__.py b/api/controllers/console/__init__.py index 498557cd512e6f..e6ccee079c5909 100644 --- a/api/controllers/console/__init__.py +++ b/api/controllers/console/__init__.py @@ -29,13 +29,13 @@ ) # Import auth controllers -from .auth import activate, data_source_oauth, login, oauth +from .auth import activate, data_source_oauth, login, oauth, data_source_bearer_auth # Import billing controllers from .billing import billing # Import datasets controllers -from .datasets import data_source, datasets, datasets_document, datasets_segments, file, hit_testing +from .datasets import data_source, datasets, datasets_document, datasets_segments, file, hit_testing, website # Import enterprise controllers from .enterprise import enterprise_sso diff --git a/api/controllers/console/auth/data_source_bearer_auth.py b/api/controllers/console/auth/data_source_bearer_auth.py index 01cf81e6726968..ab0cdbdc23126c 100644 --- a/api/controllers/console/auth/data_source_bearer_auth.py +++ b/api/controllers/console/auth/data_source_bearer_auth.py @@ -1,14 +1,9 @@ -import logging - -import requests -from flask import current_app, redirect, request from flask_login import current_user from flask_restful import Resource, reqparse from werkzeug.exceptions import Forbidden from controllers.console import api from libs.login import login_required -from libs.oauth_data_source import NotionOAuth from services.auth.api_key_auth_service import ApiKeyAuthService from ..setup import setup_required @@ -23,7 +18,7 @@ def get(self): # The role of the current user in the table must be admin or owner if not current_user.is_admin_or_owner: raise Forbidden() - data_source_api_key_bindings = ApiKeyAuthService.get_provider_auth_list(current_user.tenant_id) + data_source_api_key_bindings = ApiKeyAuthService.get_provider_auth_list(current_user.current_tenant_id) if data_source_api_key_bindings: return { 'settings': [data_source_api_key_binding.to_dict() for data_source_api_key_binding in @@ -42,9 +37,11 @@ def post(self): parser = reqparse.RequestParser() parser.add_argument('category', type=str, required=True, nullable=False, location='json') parser.add_argument('provider', type=str, required=True, nullable=False, location='json') - parser.add_argument('credential', type=dict, required=True, nullable=False, location='json') + parser.add_argument('credentials', type=dict, required=True, nullable=False, location='json') args = parser.parse_args() - data_source_api_key_binding = ApiKeyAuthService.create_provider_auth(current_user.tenant_id, args) + ApiKeyAuthService.validate_api_key_auth_args(args) + ApiKeyAuthService.create_provider_auth(current_user.current_tenant_id, args) + return {'result': 'success'}, 200 api.add_resource(ApiKeyAuthDataSource, '/api-key-auth/data-source') diff --git a/api/controllers/console/datasets/datasets.py b/api/controllers/console/datasets/datasets.py index 30dc6ac8459047..9cfe98b67ebcd5 100644 --- a/api/controllers/console/datasets/datasets.py +++ b/api/controllers/console/datasets/datasets.py @@ -512,6 +512,7 @@ def get(self, vector_type): else: raise ValueError("Unsupported vector db type.") + class DatasetErrorDocs(Resource): @setup_required @login_required diff --git a/api/controllers/console/datasets/datasets_document.py b/api/controllers/console/datasets/datasets_document.py index 9dedcefe0f7ba4..edec06576c7b59 100644 --- a/api/controllers/console/datasets/datasets_document.py +++ b/api/controllers/console/datasets/datasets_document.py @@ -250,7 +250,7 @@ def post(self, dataset_id): DocumentService.document_create_args_validate(args) try: - documents, batch = DocumentService.save_document_with_dataset_id(dataset, args, current_user) + documents, batch = DocumentService. save_document_with_dataset_id(dataset, args, current_user) except ProviderTokenNotInitError as ex: raise ProviderNotInitializeError(ex.description) except QuotaExceededError: diff --git a/api/controllers/console/datasets/website.py b/api/controllers/console/datasets/website.py new file mode 100644 index 00000000000000..6caf715aa31958 --- /dev/null +++ b/api/controllers/console/datasets/website.py @@ -0,0 +1,42 @@ +from flask_restful import Resource, reqparse + +from controllers.console import api +from controllers.console.setup import setup_required +from controllers.console.wraps import account_initialization_required +from libs.login import login_required +from services.website_service import WebsiteService + + +class WebsiteCrawlApi(Resource): + + @setup_required + @login_required + @account_initialization_required + def post(self): + parser = reqparse.RequestParser() + parser.add_argument('provider', type=str, choices=['firecrawl'], + required=True, nullable=True, location='json') + parser.add_argument('url', type=str, required=True, nullable=True, location='json') + parser.add_argument('options', type=dict, required=True, nullable=True, location='json') + args = parser.parse_args() + WebsiteService.document_create_args_validate(args) + # crawl url + result = WebsiteService.crawl_url(args) + return result, 200 + + +class WebsiteCrawlStatusApi(Resource): + @setup_required + @login_required + @account_initialization_required + def get(self, job_id: str): + parser = reqparse.RequestParser() + parser.add_argument('provider', type=str, choices=['firecrawl'], required=True, location='args') + args = parser.parse_args() + # get crawl status + result = WebsiteService.get_crawl_status(job_id, args['provider']) + return result, 200 + + +api.add_resource(WebsiteCrawlApi, '/website/crawl') +api.add_resource(WebsiteCrawlStatusApi, '/website/crawl/status/') diff --git a/api/core/indexing_runner.py b/api/core/indexing_runner.py index 51e77393d660e8..1de1033cc1c74e 100644 --- a/api/core/indexing_runner.py +++ b/api/core/indexing_runner.py @@ -376,6 +376,20 @@ def _extract(self, index_processor: BaseIndexProcessor, dataset_document: Datase document_model=dataset_document.doc_form ) text_docs = index_processor.extract(extract_setting, process_rule_mode=process_rule['mode']) + elif dataset_document.data_source_type == 'website': + if (not data_source_info or 'provider' not in data_source_info + or 'url' not in data_source_info or 'job_id' not in data_source_info): + raise ValueError("no website import info found") + extract_setting = ExtractSetting( + datasource_type="website", + website_info={ + "provider": data_source_info['provider'], + "job_id": data_source_info['job_id'], + "url": data_source_info['url'] + }, + document_model=dataset_document.doc_form + ) + text_docs = index_processor.extract(extract_setting, process_rule_mode=process_rule['mode']) # update document status to splitting self._update_document_index_status( document_id=dataset_document.id, diff --git a/api/core/rag/extractor/entity/datasource_type.py b/api/core/rag/extractor/entity/datasource_type.py index 902835571d94f4..4ce379e96bda71 100644 --- a/api/core/rag/extractor/entity/datasource_type.py +++ b/api/core/rag/extractor/entity/datasource_type.py @@ -4,4 +4,4 @@ class DatasourceType(Enum): FILE = "upload_file" NOTION = "notion_import" - URL = "url" + WEBSITE = "website" diff --git a/api/core/rag/extractor/entity/extract_setting.py b/api/core/rag/extractor/entity/extract_setting.py index 69b17039fbf200..096252f32f5047 100644 --- a/api/core/rag/extractor/entity/extract_setting.py +++ b/api/core/rag/extractor/entity/extract_setting.py @@ -20,18 +20,14 @@ class Config: def __init__(self, **data) -> None: super().__init__(**data) -class FirecrawlInfo(BaseModel): + +class WebsiteInfo(BaseModel): """ - Firecrawl import info. + website import info. """ + provider: str + job_id: str url: str - mode: str - ## [Review] Not sure if these belong here - firecrawl_api_key: str - firecrawl_base_url: str - ## --- - document: Document = None - tenant_id: str class Config: arbitrary_types_allowed = True @@ -47,7 +43,7 @@ class ExtractSetting(BaseModel): datasource_type: str upload_file: UploadFile = None notion_info: NotionInfo = None - firecrawl_info: FirecrawlInfo = None + website_info: WebsiteInfo = None document_model: str = None class Config: diff --git a/api/core/rag/extractor/extract_processor.py b/api/core/rag/extractor/extract_processor.py index dc416d5d376b3e..b18855db45c54d 100644 --- a/api/core/rag/extractor/extract_processor.py +++ b/api/core/rag/extractor/extract_processor.py @@ -142,12 +142,14 @@ def extract(cls, extract_setting: ExtractSetting, is_automatic: bool = False, tenant_id=extract_setting.notion_info.tenant_id, ) return extractor.extract() - elif extract_setting.datasource_type == DatasourceType.URL.value: - # [Review] Not sure if api key and base url belong here. - extractor = FirecrawlWebExtractor( - api_key=extract_setting.firecrawl_info.firecrawl_api_key, - base_url=extract_setting.firecrawl_info.firecrawl_base_url, - url=extract_setting.firecrawl_info.url, mode=extract_setting.firecrawl_info.mode) - return extractor.extract() + elif extract_setting.datasource_type == DatasourceType.WEBSITE.value: + if extract_setting.website_info.provider == 'firecrawl': + extractor = FirecrawlWebExtractor( + url=extract_setting.website_info.url, + job_id=extract_setting.website_info.job_id + ) + return extractor.extract() + else: + raise ValueError(f"Unsupported website provider: {extract_setting.website_info.provider}") else: raise ValueError(f"Unsupported datasource type: {extract_setting.datasource_type}") diff --git a/api/core/rag/extractor/firecrawl/firecrawl_app.py b/api/core/rag/extractor/firecrawl/firecrawl_app.py index bdb7c8e247aa7d..559ee3ba59ba72 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_app.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_app.py @@ -1,13 +1,12 @@ -import os import time import requests class FirecrawlApp: - def __init__(self, api_key=None, base_url='https://api.firecrawl.dev'): - self.api_key = api_key or os.getenv('FIRECRAWL_API_KEY') - self.base_url = base_url or os.getenv('FIRECRAWL_BASE_URL') + def __init__(self, api_key=None, base_url=None): + self.api_key = api_key + self.base_url = base_url or 'https://api.firecrawl.dev' if self.api_key is None and self.base_url == 'https://api.firecrawl.dev': raise ValueError('No API key provided') @@ -36,34 +35,8 @@ def scrape_url(self, url, params=None): raise Exception(f'Failed to scrape URL. Status code: {response.status_code}. Error: {error_message}') else: raise Exception(f'Failed to scrape URL. Status code: {response.status_code}') - - def search(self, query, params=None): - headers = { - 'Content-Type': 'application/json', - 'Authorization': f'Bearer {self.api_key}' - } - json_data = {'query': query} - if params: - json_data.update(params) - response = requests.post( - f'{self.base_url}/v0/search', - headers=headers, - json=json_data - ) - if response.status_code == 200: - response = response.json() - if response['success'] == True: - return response['data'] - else: - raise Exception(f'Failed to search. Error: {response["error"]}') - - elif response.status_code in [402, 409, 500]: - error_message = response.json().get('error', 'Unknown error occurred') - raise Exception(f'Failed to search. Status code: {response.status_code}. Error: {error_message}') - else: - raise Exception(f'Failed to search. Status code: {response.status_code}') - def crawl_url(self, url, params=None, wait_until_done=True, polling_interval=2, timeout=500): + def crawl_url(self, url, params=None) -> str: start_time = time.time() headers = self._prepare_headers() json_data = {'url': url} @@ -72,21 +45,12 @@ def crawl_url(self, url, params=None, wait_until_done=True, polling_interval=2, response = self._post_request(f'{self.base_url}/v0/crawl', json_data, headers) if response.status_code == 200: job_id = response.json().get('jobId') - if wait_until_done: - while True: - elapsed_time = time.time() - start_time - if elapsed_time > timeout: - raise Exception('Firecrawl: Crawl job timed out.') - result = self._monitor_job_status(job_id, headers, polling_interval) - if result is not None: - return result - else: - return {'jobId': job_id} + return job_id else: self._handle_error(response, 'start crawl job') - def check_crawl_status(self, job_id): + def check_crawl_status(self, job_id) -> dict: headers = self._prepare_headers() response = self._get_request(f'{self.base_url}/v0/crawl/status/{job_id}', headers) if response.status_code == 200: @@ -117,22 +81,6 @@ def _get_request(self, url, headers, retries=3, backoff_factor=0.5): else: return response return response - - def _monitor_job_status(self, job_id, headers, polling_interval): - status_response = self._get_request(f'{self.base_url}/v0/crawl/status/{job_id}', headers) - if status_response.status_code == 200: - status_data = status_response.json() - if status_data['status'] == 'completed': - if 'data' in status_data: - return status_data['data'] - else: - raise Exception('Crawl job completed but no data was returned') - elif status_data['status'] in ['active', 'paused', 'pending', 'queued']: - time.sleep(max(polling_interval, 2)) # Wait for the specified polling_interval before checking again - else: - raise Exception(f'Crawl job failed or was stopped. Status: {status_data["status"]}') - else: - self._handle_error(status_response, 'check crawl status') def _handle_error(self, response, action): if response.status_code in [402, 409, 500]: diff --git a/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py b/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py index f0d03956e7461c..5ff88e269d007f 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py @@ -1,6 +1,6 @@ from core.rag.extractor.extractor_base import BaseExtractor -from core.rag.extractor.firecrawl.firecrawl_app import FirecrawlApp from core.rag.models.document import Document +from services.website_service import WebsiteService class FirecrawlWebExtractor(BaseExtractor): @@ -20,42 +20,16 @@ class FirecrawlWebExtractor(BaseExtractor): def __init__( self, url: str, - api_key: str, - base_url: str = 'https://api.firecrawl.dev', - mode: str = 'crawl', + job_id: str ): """Initialize with url, api_key, base_url and mode.""" self._url = url - self._api_key = api_key - self._base_url = base_url - self._mode = mode - self._firecrawl_app = FirecrawlApp(api_key=self._api_key, base_url=self._base_url) + self.job_id = job_id def extract(self) -> list[Document]: + """Extract content from the URL.""" documents = [] - if self._mode == 'scrape': - content = self._scrape_url() - if content: - documents.append(self._create_document(content)) - elif self._mode in ['crawl', 'crawl_return_urls']: - items = self._crawl_url(return_only_urls=(self._mode == 'crawl_return_urls')) - for item in items: - if item: - documents.append(self._create_document(item, is_url=(self._mode == 'crawl_return_urls'))) - return documents - - def _create_document(self, content, is_url=False): - if is_url: - return Document(page_content=content.get('url', '')) - else: - return Document(page_content=content.get('markdown', '')) - - def _scrape_url(self): - return self._firecrawl_app.scrape_url(self._url) - - def _crawl_url(self, return_only_urls=False): - return self._firecrawl_app.crawl_url(self._url, { - "crawlerOptions": { - "returnOnlyUrls": return_only_urls - } - }) + document = WebsiteService.get_crawl_url_data(self.job_id, 'firecrawl', self._url) + if document: + documents.append(document) + return [] \ No newline at end of file diff --git a/api/migrations/versions/7b45942e39bb_add_api_key_auth_binding.py b/api/migrations/versions/7b45942e39bb_add_api_key_auth_binding.py new file mode 100644 index 00000000000000..1591e87f7ee592 --- /dev/null +++ b/api/migrations/versions/7b45942e39bb_add_api_key_auth_binding.py @@ -0,0 +1,67 @@ +"""add-api-key-auth-binding + +Revision ID: 7b45942e39bb +Revises: 47cc7df8c4f3 +Create Date: 2024-05-14 07:31:29.702766 + +""" +from alembic import op +import models as models +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision = '7b45942e39bb' +down_revision = '47cc7df8c4f3' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('data_source_api_key_auth_bindings', + sa.Column('id', models.StringUUID(), server_default=sa.text('uuid_generate_v4()'), nullable=False), + sa.Column('tenant_id', models.StringUUID(), nullable=False), + sa.Column('category', sa.String(length=255), nullable=False), + sa.Column('provider', sa.String(length=255), nullable=False), + sa.Column('credentials', sa.Text(), nullable=True), + sa.Column('created_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False), + sa.Column('updated_at', sa.DateTime(), server_default=sa.text('CURRENT_TIMESTAMP(0)'), nullable=False), + sa.Column('disabled', sa.Boolean(), server_default=sa.text('false'), nullable=True), + sa.PrimaryKeyConstraint('id', name='data_source_api_key_auth_binding_pkey') + ) + with op.batch_alter_table('data_source_api_key_auth_bindings', schema=None) as batch_op: + batch_op.create_index('data_source_api_key_auth_binding_provider_idx', ['provider'], unique=False) + batch_op.create_index('data_source_api_key_auth_binding_tenant_id_idx', ['tenant_id'], unique=False) + + with op.batch_alter_table('data_source_bindings', schema=None) as batch_op: + batch_op.drop_index('source_binding_tenant_id_idx') + batch_op.drop_index('source_info_idx') + + op.rename_table('data_source_bindings', 'data_source_oauth_bindings') + + with op.batch_alter_table('data_source_oauth_bindings', schema=None) as batch_op: + batch_op.create_index('source_binding_tenant_id_idx', ['tenant_id'], unique=False) + batch_op.create_index('source_info_idx', ['source_info'], unique=False, postgresql_using='gin') + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + + with op.batch_alter_table('data_source_oauth_bindings', schema=None) as batch_op: + batch_op.drop_index('source_info_idx', postgresql_using='gin') + batch_op.drop_index('source_binding_tenant_id_idx') + + op.rename_table('data_source_oauth_bindings', 'data_source_bindings') + + with op.batch_alter_table('data_source_bindings', schema=None) as batch_op: + batch_op.create_index('source_info_idx', ['source_info'], unique=False) + batch_op.create_index('source_binding_tenant_id_idx', ['tenant_id'], unique=False) + + with op.batch_alter_table('data_source_api_key_auth_bindings', schema=None) as batch_op: + batch_op.drop_index('data_source_api_key_auth_binding_tenant_id_idx') + batch_op.drop_index('data_source_api_key_auth_binding_provider_idx') + + op.drop_table('data_source_api_key_auth_bindings') + # ### end Alembic commands ### diff --git a/api/services/auth/api_key_auth_base.py b/api/services/auth/api_key_auth_base.py new file mode 100644 index 00000000000000..8484e9c410e2a6 --- /dev/null +++ b/api/services/auth/api_key_auth_base.py @@ -0,0 +1,9 @@ +from abc import ABC + + +class ApiKeyAuthBase(ABC): + def __init__(self, credentials: dict): + self.credentials = credentials + + def validate_credentials(self): + raise NotImplementedError diff --git a/api/services/auth/api_key_auth_factory.py b/api/services/auth/api_key_auth_factory.py new file mode 100644 index 00000000000000..ccd0023c44d84d --- /dev/null +++ b/api/services/auth/api_key_auth_factory.py @@ -0,0 +1,14 @@ + +from services.auth.firecrawl import FirecrawlAuth + + +class ApiKeyAuthFactory: + + def __init__(self, provider: str, credentials: dict): + if provider == 'firecrawl': + self.auth = FirecrawlAuth(credentials) + else: + raise ValueError('Invalid provider') + + def validate_credentials(self): + return self.auth.validate_credentials() diff --git a/api/services/auth/api_key_auth_service.py b/api/services/auth/api_key_auth_service.py index 8630eb6615ff3f..6fe572ebcd779b 100644 --- a/api/services/auth/api_key_auth_service.py +++ b/api/services/auth/api_key_auth_service.py @@ -1,14 +1,8 @@ -import uuid -from typing import List - -from flask_login import current_user -from sqlalchemy import func -from werkzeug.exceptions import NotFound +import json from extensions.ext_database import db -from models.dataset import Dataset -from models.model import App, Tag, TagBinding from models.source import DataSourceApiKeyAuthBinding +from services.auth.api_key_auth_factory import ApiKeyAuthFactory class ApiKeyAuthService: @@ -22,13 +16,27 @@ def get_provider_auth_list(tenant_id: str) -> list: return data_source_api_key_bindings @staticmethod - def create_provider_auth(tenant_id: str, args: dict) -> DataSourceApiKeyAuthBinding: - data_source_api_key_binding = DataSourceApiKeyAuthBinding() - data_source_api_key_binding.tenant_id = tenant_id - data_source_api_key_binding.category = args['category'] - data_source_api_key_binding.provider = args['provider'] - data_source_api_key_binding.credentials = args['credential'] - db.session.add(data_source_api_key_binding) - db.session.commit() - return data_source_api_key_binding - pass + def create_provider_auth(tenant_id: str, args: dict): + auth_result = ApiKeyAuthFactory(args['provider'], args['credentials']).validate_credentials() + if auth_result: + data_source_api_key_binding = DataSourceApiKeyAuthBinding() + data_source_api_key_binding.tenant_id = tenant_id + data_source_api_key_binding.category = args['category'] + data_source_api_key_binding.provider = args['provider'] + data_source_api_key_binding.credentials = json.dumps(args['credentials'], ensure_ascii=False) + db.session.add(data_source_api_key_binding) + db.session.commit() + + @classmethod + def validate_api_key_auth_args(cls, args): + if 'category' not in args or not args['category']: + raise ValueError('category is required') + if 'provider' not in args or not args['provider']: + raise ValueError('provider is required') + if 'credentials' not in args or not args['credentials']: + raise ValueError('credentials is required') + if not isinstance(args['credentials'], dict): + raise ValueError('credentials must be a dictionary') + if 'auth_type' not in args['credentials'] or not args['credentials']['auth_type']: + raise ValueError('auth_type is required') + diff --git a/api/services/auth/firecrawl.py b/api/services/auth/firecrawl.py index f76b976739c226..ee219a1bcb445b 100644 --- a/api/services/auth/firecrawl.py +++ b/api/services/auth/firecrawl.py @@ -1,14 +1,21 @@ -import os import requests +from services.auth.api_key_auth_base import ApiKeyAuthBase -class FirecrawlAuth: - def __init__(self, api_key=None, endpoint=None): - self.api_key = api_key or os.getenv('FIRECRAWL_API_KEY') - if self.api_key is None: + +class FirecrawlAuth(ApiKeyAuthBase): + def __init__(self, credentials: dict): + super().__init__(credentials) + auth_type = credentials.get('auth_type') + if auth_type != 'bearer': + raise ValueError('Invalid auth type, Firecrawl auth type must be Bearer') + self.api_key = credentials.get('config').get('api_key', None) + self.base_url = credentials.get('config').get('base_url', 'https://api.firecrawl.dev') + + if not self.api_key: raise ValueError('No API key provided') - def _validate_credentials(self): + def validate_credentials(self): headers = self._prepare_headers() options = { 'url': 'https://example.com', @@ -21,19 +28,11 @@ def _validate_credentials(self): 'onlyMainContent': True } } - response = self._post_request('https://api.firecrawl.dev/v0/crawl', options, headers) + response = self._post_request(f'{self.base_url}/v0/crawl', options, headers) if response.status_code == 200: return True else: - self._handle_error(response, 'start crawl job') - - def check_crawl_status(self, job_id): - headers = self._prepare_headers() - response = self._get_request(f'https://api.firecrawl.dev/v0/crawl/status/{job_id}', headers) - if response.status_code == 200: - return response.json() - else: - self._handle_error(response, 'check crawl status') + self._handle_error(response) def _prepare_headers(self): return { @@ -44,32 +43,9 @@ def _prepare_headers(self): def _post_request(self, url, data, headers): return requests.post(url, headers=headers, json=data) - def _get_request(self, url, headers): - return requests.get(url, headers=headers) - - def _monitor_job_status(self, job_id, headers, timeout): - import time - while True: - status_response = self._get_request(f'https://api.firecrawl.dev/v0/crawl/status/{job_id}', headers) - if status_response.status_code == 200: - status_data = status_response.json() - if status_data['status'] == 'completed': - if 'data' in status_data: - return status_data['data'] - else: - raise Exception('Crawl job completed but no data was returned') - elif status_data['status'] in ['active', 'paused', 'pending', 'queued']: - if timeout < 2: - timeout = 2 - time.sleep(timeout) # Wait for the specified timeout before checking again - else: - raise Exception(f'Crawl job failed or was stopped. Status: {status_data["status"]}') - else: - self._handle_error(status_response, 'check crawl status') - - def _handle_error(self, response, action): + def _handle_error(self, response): if response.status_code in [402, 409, 500]: error_message = response.json().get('error', 'Unknown error occurred') - raise Exception(f'Failed to {action}. Status code: {response.status_code}. Error: {error_message}') + raise Exception(f'Failed to authorize. Status code: {response.status_code}. Error: {error_message}') else: - raise Exception(f'Unexpected error occurred while trying to {action}. Status code: {response.status_code}') + raise Exception(f'Unexpected error occurred while trying to authorize. Status code: {response.status_code}') diff --git a/api/services/dataset_service.py b/api/services/dataset_service.py index 0ceef2f800be62..86ad29e3164055 100644 --- a/api/services/dataset_service.py +++ b/api/services/dataset_service.py @@ -523,6 +523,9 @@ def save_document_with_dataset_id(dataset: Dataset, document_data: dict, notion_info_list = document_data["data_source"]['info_list']['notion_info_list'] for notion_info in notion_info_list: count = count + len(notion_info['pages']) + elif document_data["data_source"]["type"] == "website": + website_info = document_data["data_source"]['info_list']['website_info'] + count = len(website_info['urls']) batch_upload_limit = int(current_app.config['BATCH_UPLOAD_LIMIT']) if count > batch_upload_limit: raise ValueError(f"You have reached the batch upload limit of {batch_upload_limit}.") @@ -695,6 +698,26 @@ def save_document_with_dataset_id(dataset: Dataset, document_data: dict, # delete not selected documents if len(exist_document) > 0: clean_notion_document_task.delay(list(exist_document.values()), dataset.id) + elif document_data["data_source"]["type"] == "website": + website_info = document_data["data_source"]['info_list']['website_info'] + urls = website_info['urls'] + for url in urls: + data_source_info = { + 'url': url, + 'provider': website_info['provider'], + 'job_id': website_info['job_id'] + } + document = DocumentService.build_document(dataset, dataset_process_rule.id, + document_data["data_source"]["type"], + document_data["doc_form"], + document_data["doc_language"], + data_source_info, created_from, position, + account, website_info['url'], batch) + db.session.add(document) + db.session.flush() + document_ids.append(document.id) + documents.append(document) + position += 1 db.session.commit() # trigger async task @@ -813,6 +836,15 @@ def update_document_with_dataset_id(dataset: Dataset, document_data: dict, "notion_page_icon": page['page_icon'], "type": page['type'] } + elif document_data["data_source"]["type"] == "website": + website_info = document_data["data_source"]['info_list']['website_info'] + urls = website_info['urls'] + for url in urls: + data_source_info = { + 'url': url, + 'provider': website_info['provider'], + 'job_id': website_info['job_id'] + } document.data_source_type = document_data["data_source"]["type"] document.data_source_info = json.dumps(data_source_info) document.name = file_name @@ -851,6 +883,9 @@ def save_document_without_dataset_id(tenant_id: str, document_data: dict, accoun notion_info_list = document_data["data_source"]['info_list']['notion_info_list'] for notion_info in notion_info_list: count = count + len(notion_info['pages']) + elif document_data["data_source"]["type"] == "website": + website_info = document_data["data_source"]['info_list']['website_info'] + count = len(website_info['urls']) batch_upload_limit = int(current_app.config['BATCH_UPLOAD_LIMIT']) if count > batch_upload_limit: raise ValueError(f"You have reached the batch upload limit of {batch_upload_limit}.") @@ -951,6 +986,10 @@ def data_source_args_validate(cls, args: dict): if 'notion_info_list' not in args['data_source']['info_list'] or not args['data_source']['info_list'][ 'notion_info_list']: raise ValueError("Notion source info is required") + if args['data_source']['type'] == 'website': + if 'website_info' not in args['data_source']['info_list'] or not args['data_source']['info_list'][ + 'website_info']: + raise ValueError("Website source info is required") @classmethod def process_rule_args_validate(cls, args: dict): diff --git a/api/services/website_service.py b/api/services/website_service.py new file mode 100644 index 00000000000000..11d1b0d0070dc0 --- /dev/null +++ b/api/services/website_service.py @@ -0,0 +1,128 @@ +import json + +from flask_login import current_user +from werkzeug.exceptions import NotFound + +from core.rag.extractor.firecrawl.firecrawl_app import FirecrawlApp +from extensions.ext_database import db +from models.source import DataSourceApiKeyAuthBinding + + +class WebsiteService: + + @classmethod + def document_create_args_validate(cls, args: dict): + if 'url' not in args or not args['url']: + raise ValueError('url is required') + if 'options' not in args or not args['options']: + raise ValueError('options is required') + if 'limit' not in args['options'] or not args['options']['limit']: + raise ValueError('limit is required') + + @classmethod + def crawl_url(cls, args: dict) -> dict: + provider = args.get('provider') + url = args.get('url') + options = args.get('options') + if provider == 'firecrawl': + data_source_api_key_bindings = db.session.query(DataSourceApiKeyAuthBinding).filter( + DataSourceApiKeyAuthBinding.tenant_id == current_user.current_tenant_id, + DataSourceApiKeyAuthBinding.category == 'website', + DataSourceApiKeyAuthBinding.provider == 'firecrawl', + DataSourceApiKeyAuthBinding.disabled.is_(False) + ).first() + if not data_source_api_key_bindings: + raise NotFound('Firecrawl API key not found') + credentials = json.loads(data_source_api_key_bindings.credentials) + firecrawl_app = FirecrawlApp(api_key=credentials.get('config').get('api_key'), + base_url=credentials.get('config').get('base_url', None)) + crawl_sub_pages = options.get('crawl_sub_pages', False) + only_main_content = options.get('only_main_content', False) + if not crawl_sub_pages: + params = { + 'crawlerOptions': { + "includes": [], + "excludes": [], + "generateImgAltText": True, + "maxDepth": 1, + "limit": 1, + 'returnOnlyUrls': False, + 'pageOptions': { + 'onlyMainContent': only_main_content, + "includeHtml": False + } + } + } + else: + includes = ','.join(options.get('includes')) if options.get('includes') else [] + excludes = ','.join(options.get('excludes')) if options.get('excludes') else [] + params = { + 'crawlerOptions': { + "includes": includes if includes else [], + "excludes": excludes if excludes else [], + "generateImgAltText": True, + "maxDepth": options.get('max_depth', 1), + "limit": options.get('limit', 1), + 'returnOnlyUrls': False, + 'pageOptions': { + 'onlyMainContent': only_main_content, + "includeHtml": False + } + } + } + job_id = firecrawl_app.crawl_url(url, params) + return { + 'status': 'active', + 'job_id': job_id + } + else: + raise ValueError('Invalid provider') + + @classmethod + def get_crawl_status(cls, job_id: str, provider: str) -> dict: + if provider == 'firecrawl': + data_source_api_key_bindings = db.session.query(DataSourceApiKeyAuthBinding).filter( + DataSourceApiKeyAuthBinding.tenant_id == current_user.current_tenant_id, + DataSourceApiKeyAuthBinding.category == 'website', + DataSourceApiKeyAuthBinding.provider == 'firecrawl', + DataSourceApiKeyAuthBinding.disabled.is_(False) + ).first() + if not data_source_api_key_bindings: + raise NotFound('Firecrawl API key not found') + credentials = json.loads(data_source_api_key_bindings.credentials) + firecrawl_app = FirecrawlApp(api_key=credentials.get('config').get('api_key'), + base_url=credentials.get('config').get('base_url', None)) + result = firecrawl_app.check_crawl_status(job_id) + crawl_status_data = { + 'status': result.get('status', 'active'), + 'job_id': job_id, + 'data': result.get('data', []) + } + else: + raise ValueError('Invalid provider') + return crawl_status_data + + @classmethod + def get_crawl_url_data(cls, job_id: str, provider: str, url: str) -> dict: + if provider == 'firecrawl': + data_source_api_key_bindings = db.session.query(DataSourceApiKeyAuthBinding).filter( + DataSourceApiKeyAuthBinding.tenant_id == current_user.current_tenant_id, + DataSourceApiKeyAuthBinding.category == 'website', + DataSourceApiKeyAuthBinding.provider == 'firecrawl', + DataSourceApiKeyAuthBinding.disabled.is_(False) + ).first() + if not data_source_api_key_bindings: + raise NotFound('Firecrawl API key not found') + credentials = json.loads(data_source_api_key_bindings.credentials) + firecrawl_app = FirecrawlApp(api_key=credentials.get('config').get('api_key'), + base_url=credentials.get('config').get('base_url', None)) + result = firecrawl_app.check_crawl_status(job_id) + if result.get('status') != 'completed': + raise ValueError('Crawl job is not completed') + data = result.get('data') + for item in data: + if item.get('data'): + if item.get('data').get('metadata').get('sourceURL') == url: + return item.get('data').get('markdown') + else: + raise ValueError('Invalid provider') \ No newline at end of file From e217ad9f5fc5e29ac0446b739c3e9b240b319dd3 Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Thu, 16 May 2024 16:38:59 +0800 Subject: [PATCH 15/43] add website sync --- .../console/datasets/datasets_document.py | 27 ++++++ api/core/indexing_runner.py | 10 +- .../rag/extractor/entity/datasource_type.py | 2 +- .../rag/extractor/entity/extract_setting.py | 2 + api/core/rag/extractor/extract_processor.py | 4 +- .../rag/extractor/firecrawl/firecrawl_app.py | 39 ++++++-- .../firecrawl/firecrawl_web_extractor.py | 38 ++++++-- api/models/source.py | 6 +- api/services/auth/api_key_auth_service.py | 18 ++++ api/services/dataset_service.py | 32 ++++-- api/services/website_service.py | 97 ++++++++++++------- .../sync_website_document_indexing_task.py | 90 +++++++++++++++++ .../rag/extractor/firecrawl/test_firecrawl.py | 51 +++++----- 13 files changed, 327 insertions(+), 89 deletions(-) create mode 100644 api/tasks/sync_website_document_indexing_task.py diff --git a/api/controllers/console/datasets/datasets_document.py b/api/controllers/console/datasets/datasets_document.py index edec06576c7b59..0e7ac9f8305641 100644 --- a/api/controllers/console/datasets/datasets_document.py +++ b/api/controllers/console/datasets/datasets_document.py @@ -924,6 +924,32 @@ def post(self, dataset_id): return {'result': 'success'}, 204 +class WebsiteDocumentSyncApi(DocumentResource): + @setup_required + @login_required + @account_initialization_required + def post(self, dataset_id, document_id): + """sync website document.""" + dataset_id = str(dataset_id) + dataset = DatasetService.get_dataset(dataset_id) + if not dataset: + raise NotFound('Dataset not found.') + document_id = str(document_id) + document = DocumentService.get_document(dataset.id, document_id) + if not document: + raise NotFound('Document not found.') + if document.tenant_id != current_user.current_tenant_id: + raise Forbidden('No permission.') + if document.data_source_type != 'website_crawl': + raise ValueError('Document is not a website document.') + # 403 if document is archived + if DocumentService.check_archived(document): + raise ArchivedDocumentImmutableError() + # sync document + DocumentService.sync_website_document(dataset_id, document) + + return {'result': 'success'}, 204 + api.add_resource(GetProcessRuleApi, '/datasets/process-rule') api.add_resource(DatasetDocumentListApi, '/datasets//documents') @@ -950,3 +976,4 @@ def post(self, dataset_id): api.add_resource(DocumentPauseApi, '/datasets//documents//processing/pause') api.add_resource(DocumentRecoverApi, '/datasets//documents//processing/resume') api.add_resource(DocumentRetryApi, '/datasets//retry') +api.add_resource(WebsiteDocumentSyncApi, '/datasets///website-sync') \ No newline at end of file diff --git a/api/core/indexing_runner.py b/api/core/indexing_runner.py index 1de1033cc1c74e..5578033e00c418 100644 --- a/api/core/indexing_runner.py +++ b/api/core/indexing_runner.py @@ -340,7 +340,7 @@ def indexing_estimate(self, tenant_id: str, extract_settings: list[ExtractSettin def _extract(self, index_processor: BaseIndexProcessor, dataset_document: DatasetDocument, process_rule: dict) \ -> list[Document]: # load file - if dataset_document.data_source_type not in ["upload_file", "notion_import"]: + if dataset_document.data_source_type not in ["upload_file", "notion_import", "website_crawl"]: return [] data_source_info = dataset_document.data_source_info_dict @@ -376,16 +376,18 @@ def _extract(self, index_processor: BaseIndexProcessor, dataset_document: Datase document_model=dataset_document.doc_form ) text_docs = index_processor.extract(extract_setting, process_rule_mode=process_rule['mode']) - elif dataset_document.data_source_type == 'website': + elif dataset_document.data_source_type == 'website_crawl': if (not data_source_info or 'provider' not in data_source_info or 'url' not in data_source_info or 'job_id' not in data_source_info): raise ValueError("no website import info found") extract_setting = ExtractSetting( - datasource_type="website", + datasource_type="website_crawl", website_info={ "provider": data_source_info['provider'], "job_id": data_source_info['job_id'], - "url": data_source_info['url'] + "url": data_source_info['url'], + "mode": data_source_info['mode'], + "only_main_content": data_source_info['only_main_content'] }, document_model=dataset_document.doc_form ) diff --git a/api/core/rag/extractor/entity/datasource_type.py b/api/core/rag/extractor/entity/datasource_type.py index 4ce379e96bda71..19ad300d110fe6 100644 --- a/api/core/rag/extractor/entity/datasource_type.py +++ b/api/core/rag/extractor/entity/datasource_type.py @@ -4,4 +4,4 @@ class DatasourceType(Enum): FILE = "upload_file" NOTION = "notion_import" - WEBSITE = "website" + WEBSITE = "website_crawl" diff --git a/api/core/rag/extractor/entity/extract_setting.py b/api/core/rag/extractor/entity/extract_setting.py index 096252f32f5047..9bf99d06af75ef 100644 --- a/api/core/rag/extractor/entity/extract_setting.py +++ b/api/core/rag/extractor/entity/extract_setting.py @@ -28,6 +28,8 @@ class WebsiteInfo(BaseModel): provider: str job_id: str url: str + mode: str + only_main_content: bool = False class Config: arbitrary_types_allowed = True diff --git a/api/core/rag/extractor/extract_processor.py b/api/core/rag/extractor/extract_processor.py index b18855db45c54d..88b3058554a046 100644 --- a/api/core/rag/extractor/extract_processor.py +++ b/api/core/rag/extractor/extract_processor.py @@ -146,7 +146,9 @@ def extract(cls, extract_setting: ExtractSetting, is_automatic: bool = False, if extract_setting.website_info.provider == 'firecrawl': extractor = FirecrawlWebExtractor( url=extract_setting.website_info.url, - job_id=extract_setting.website_info.job_id + job_id=extract_setting.website_info.job_id, + mode=extract_setting.website_info.mode, + only_main_content=extract_setting.website_info.only_main_content ) return extractor.extract() else: diff --git a/api/core/rag/extractor/firecrawl/firecrawl_app.py b/api/core/rag/extractor/firecrawl/firecrawl_app.py index 559ee3ba59ba72..e8fe59e44b8deb 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_app.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_app.py @@ -9,8 +9,8 @@ def __init__(self, api_key=None, base_url=None): self.base_url = base_url or 'https://api.firecrawl.dev' if self.api_key is None and self.base_url == 'https://api.firecrawl.dev': raise ValueError('No API key provided') - - def scrape_url(self, url, params=None): + + def scrape_url(self, url, params=None) -> dict: headers = { 'Content-Type': 'application/json', 'Authorization': f'Bearer {self.api_key}' @@ -26,10 +26,16 @@ def scrape_url(self, url, params=None): if response.status_code == 200: response = response.json() if response['success'] == True: - return response['data'] + data = response['data'] + return { + 'title': data.get('metadata').get('title'), + 'description': data.get('metadata').get('description'), + 'source_url': data.get('metadata').get('sourceURL'), + 'markdown': data.get('markdown') + } else: raise Exception(f'Failed to scrape URL. Error: {response["error"]}') - + elif response.status_code in [402, 409, 500]: error_message = response.json().get('error', 'Unknown error occurred') raise Exception(f'Failed to scrape URL. Status code: {response.status_code}. Error: {error_message}') @@ -49,12 +55,33 @@ def crawl_url(self, url, params=None) -> str: else: self._handle_error(response, 'start crawl job') - def check_crawl_status(self, job_id) -> dict: headers = self._prepare_headers() response = self._get_request(f'{self.base_url}/v0/crawl/status/{job_id}', headers) if response.status_code == 200: - return response.json() + crawl_status_response = response.json() + if crawl_status_response.get('status') != 'completed': + return { + 'status': crawl_status_response.get('status'), + 'data': [] + } + else: + data = crawl_status_response.get('data', []) + url_data_list = [] + for item in data: + if item.get('success', False): + if item.get('data'): + url_data = { + 'title': item.get('data').get('metadata').get('title'), + 'description': item.get('data').get('metadata').get('description'), + 'source_url': item.get('data').get('metadata').get('sourceURL'), + 'markdown': item.get('data').get('markdown') + } + url_data_list.append(url_data) + return { + 'status': 'completed', + 'data': url_data_list + } else: self._handle_error(response, 'check crawl status') diff --git a/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py b/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py index 5ff88e269d007f..870ae8d272458e 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py @@ -4,7 +4,6 @@ class FirecrawlWebExtractor(BaseExtractor): - """ Crawl and scrape websites and return content in clean llm-ready markdown. @@ -16,20 +15,43 @@ class FirecrawlWebExtractor(BaseExtractor): mode: The mode of operation. Defaults to 'scrape'. Options are 'crawl', 'scrape' and 'crawl_return_urls'. """ - def __init__( - self, - url: str, - job_id: str + self, + url: str, + job_id: str, + mode: str = 'crawl', + only_main_content: bool = False ): """Initialize with url, api_key, base_url and mode.""" self._url = url self.job_id = job_id + self.mode = mode + self.only_main_content = only_main_content def extract(self) -> list[Document]: """Extract content from the URL.""" documents = [] - document = WebsiteService.get_crawl_url_data(self.job_id, 'firecrawl', self._url) - if document: + if self.mode == 'crawl': + crawl_data = WebsiteService.get_crawl_url_data(self.job_id, 'firecrawl', self._url) + if crawl_data is None: + return [] + document = Document(page_content=crawl_data.get('markdown', ''), + metadata={ + 'source_url': crawl_data.get('source_url'), + 'description': crawl_data.get('description'), + 'title': crawl_data.get('title') + } + ) + documents.append(document) + elif self.mode == 'scrape': + scrape_data = WebsiteService.get_scrape_url_data('firecrawl', self._url, self.only_main_content) + + document = Document(page_content=scrape_data.get('markdown', ''), + metadata={ + 'source_url': scrape_data.get('source_url'), + 'description': scrape_data.get('description'), + 'title': scrape_data.get('title') + } + ) documents.append(document) - return [] \ No newline at end of file + return documents diff --git a/api/models/source.py b/api/models/source.py index b870f1fa37db74..265e68f014c6c2 100644 --- a/api/models/source.py +++ b/api/models/source.py @@ -47,8 +47,8 @@ def to_dict(self): 'tenant_id': self.tenant_id, 'category': self.category, 'provider': self.provider, - 'credentials': json.dumps(self.credentials, ensure_ascii=False), - 'created_at': self.created_at, - 'updated_at': self.updated_at, + 'credentials': json.loads(self.credentials), + 'created_at': self.created_at.timestamp(), + 'updated_at': self.updated_at.timestamp(), 'disabled': self.disabled } diff --git a/api/services/auth/api_key_auth_service.py b/api/services/auth/api_key_auth_service.py index 6fe572ebcd779b..6cab79f6924202 100644 --- a/api/services/auth/api_key_auth_service.py +++ b/api/services/auth/api_key_auth_service.py @@ -1,5 +1,6 @@ import json +from core.helper import encrypter from extensions.ext_database import db from models.source import DataSourceApiKeyAuthBinding from services.auth.api_key_auth_factory import ApiKeyAuthFactory @@ -19,6 +20,10 @@ def get_provider_auth_list(tenant_id: str) -> list: def create_provider_auth(tenant_id: str, args: dict): auth_result = ApiKeyAuthFactory(args['provider'], args['credentials']).validate_credentials() if auth_result: + # Encrypt the api key + api_key = encrypter.encrypt_token(tenant_id, args['credentials']['config']['api_key']) + args['credentials']['config']['api_key'] = api_key + data_source_api_key_binding = DataSourceApiKeyAuthBinding() data_source_api_key_binding.tenant_id = tenant_id data_source_api_key_binding.category = args['category'] @@ -27,6 +32,19 @@ def create_provider_auth(tenant_id: str, args: dict): db.session.add(data_source_api_key_binding) db.session.commit() + @staticmethod + def get_auth_credentials(tenant_id: str, category: str, provider: str): + data_source_api_key_bindings = db.session.query(DataSourceApiKeyAuthBinding).filter( + DataSourceApiKeyAuthBinding.tenant_id == tenant_id, + DataSourceApiKeyAuthBinding.category == category, + DataSourceApiKeyAuthBinding.provider == provider, + DataSourceApiKeyAuthBinding.disabled.is_(False) + ).first() + if not data_source_api_key_bindings: + return None + credentials = json.loads(data_source_api_key_bindings.credentials) + return credentials + @classmethod def validate_api_key_auth_args(cls, args): if 'category' not in args or not args['category']: diff --git a/api/services/dataset_service.py b/api/services/dataset_service.py index 86ad29e3164055..0966083314106c 100644 --- a/api/services/dataset_service.py +++ b/api/services/dataset_service.py @@ -49,6 +49,8 @@ from tasks.duplicate_document_indexing_task import duplicate_document_indexing_task from tasks.recover_document_indexing_task import recover_document_indexing_task from tasks.retry_document_indexing_task import retry_document_indexing_task +from tasks.sync_website_document_indexing_task import sync_website_document_indexing_task + class DatasetService: @@ -498,6 +500,20 @@ def retry_document(dataset_id: str, documents: list[Document]): retry_document_indexing_task.delay(dataset_id, document_ids) @staticmethod + def sync_website_document(dataset_id: str, document: Document): + # sync document indexing + document.indexing_status = 'waiting' + data_source_info = document.data_source_info_dict + data_source_info['mode'] = 'scrape' + document.data_source_info = json.dumps(data_source_info, ensure_ascii=False) + db.session.add(document) + db.session.commit() + # add sync flag + sync_indexing_cache_key = 'document_{}_is_sync'.format(document.id) + redis_client.setex(sync_indexing_cache_key, 600, 1) + + sync_website_document_indexing_task.delay(dataset_id, document.id) + @staticmethod def get_documents_position(dataset_id): document = Document.query.filter_by(dataset_id=dataset_id).order_by(Document.position.desc()).first() if document: @@ -523,8 +539,8 @@ def save_document_with_dataset_id(dataset: Dataset, document_data: dict, notion_info_list = document_data["data_source"]['info_list']['notion_info_list'] for notion_info in notion_info_list: count = count + len(notion_info['pages']) - elif document_data["data_source"]["type"] == "website": - website_info = document_data["data_source"]['info_list']['website_info'] + elif document_data["data_source"]["type"] == "website_crawl": + website_info = document_data["data_source"]['info_list']['website_info_list'] count = len(website_info['urls']) batch_upload_limit = int(current_app.config['BATCH_UPLOAD_LIMIT']) if count > batch_upload_limit: @@ -698,8 +714,8 @@ def save_document_with_dataset_id(dataset: Dataset, document_data: dict, # delete not selected documents if len(exist_document) > 0: clean_notion_document_task.delay(list(exist_document.values()), dataset.id) - elif document_data["data_source"]["type"] == "website": - website_info = document_data["data_source"]['info_list']['website_info'] + elif document_data["data_source"]["type"] == "website_crawl": + website_info = document_data["data_source"]['info_list']['website_info_list'] urls = website_info['urls'] for url in urls: data_source_info = { @@ -836,8 +852,8 @@ def update_document_with_dataset_id(dataset: Dataset, document_data: dict, "notion_page_icon": page['page_icon'], "type": page['type'] } - elif document_data["data_source"]["type"] == "website": - website_info = document_data["data_source"]['info_list']['website_info'] + elif document_data["data_source"]["type"] == "website_crawl": + website_info = document_data["data_source"]['info_list']['website_info_list'] urls = website_info['urls'] for url in urls: data_source_info = { @@ -883,8 +899,8 @@ def save_document_without_dataset_id(tenant_id: str, document_data: dict, accoun notion_info_list = document_data["data_source"]['info_list']['notion_info_list'] for notion_info in notion_info_list: count = count + len(notion_info['pages']) - elif document_data["data_source"]["type"] == "website": - website_info = document_data["data_source"]['info_list']['website_info'] + elif document_data["data_source"]["type"] == "website_crawl": + website_info = document_data["data_source"]['info_list']['website_info_list'] count = len(website_info['urls']) batch_upload_limit = int(current_app.config['BATCH_UPLOAD_LIMIT']) if count > batch_upload_limit: diff --git a/api/services/website_service.py b/api/services/website_service.py index 11d1b0d0070dc0..6d46a1626e4c7a 100644 --- a/api/services/website_service.py +++ b/api/services/website_service.py @@ -1,11 +1,14 @@ import json +from typing import Any from flask_login import current_user from werkzeug.exceptions import NotFound +from core.helper import encrypter from core.rag.extractor.firecrawl.firecrawl_app import FirecrawlApp from extensions.ext_database import db from models.source import DataSourceApiKeyAuthBinding +from services.auth.api_key_auth_service import ApiKeyAuthService class WebsiteService: @@ -24,17 +27,16 @@ def crawl_url(cls, args: dict) -> dict: provider = args.get('provider') url = args.get('url') options = args.get('options') + credentials = ApiKeyAuthService.get_auth_credentials(current_user.current_tenant_id, + 'website', + provider) if provider == 'firecrawl': - data_source_api_key_bindings = db.session.query(DataSourceApiKeyAuthBinding).filter( - DataSourceApiKeyAuthBinding.tenant_id == current_user.current_tenant_id, - DataSourceApiKeyAuthBinding.category == 'website', - DataSourceApiKeyAuthBinding.provider == 'firecrawl', - DataSourceApiKeyAuthBinding.disabled.is_(False) - ).first() - if not data_source_api_key_bindings: - raise NotFound('Firecrawl API key not found') - credentials = json.loads(data_source_api_key_bindings.credentials) - firecrawl_app = FirecrawlApp(api_key=credentials.get('config').get('api_key'), + # decrypt api_key + api_key = encrypter.decrypt_token( + tenant_id=current_user.current_tenant_id, + token=credentials.get('config').get('api_key') + ) + firecrawl_app = FirecrawlApp(api_key=api_key, base_url=credentials.get('config').get('base_url', None)) crawl_sub_pages = options.get('crawl_sub_pages', False) only_main_content = options.get('only_main_content', False) @@ -80,17 +82,16 @@ def crawl_url(cls, args: dict) -> dict: @classmethod def get_crawl_status(cls, job_id: str, provider: str) -> dict: + credentials = ApiKeyAuthService.get_auth_credentials(current_user.current_tenant_id, + 'website', + provider) if provider == 'firecrawl': - data_source_api_key_bindings = db.session.query(DataSourceApiKeyAuthBinding).filter( - DataSourceApiKeyAuthBinding.tenant_id == current_user.current_tenant_id, - DataSourceApiKeyAuthBinding.category == 'website', - DataSourceApiKeyAuthBinding.provider == 'firecrawl', - DataSourceApiKeyAuthBinding.disabled.is_(False) - ).first() - if not data_source_api_key_bindings: - raise NotFound('Firecrawl API key not found') - credentials = json.loads(data_source_api_key_bindings.credentials) - firecrawl_app = FirecrawlApp(api_key=credentials.get('config').get('api_key'), + # decrypt api_key + api_key = encrypter.decrypt_token( + tenant_id=current_user.current_tenant_id, + token=credentials.get('config').get('api_key') + ) + firecrawl_app = FirecrawlApp(api_key=api_key, base_url=credentials.get('config').get('base_url', None)) result = firecrawl_app.check_crawl_status(job_id) crawl_status_data = { @@ -103,26 +104,50 @@ def get_crawl_status(cls, job_id: str, provider: str) -> dict: return crawl_status_data @classmethod - def get_crawl_url_data(cls, job_id: str, provider: str, url: str) -> dict: + def get_crawl_url_data(cls, job_id: str, provider: str, url: str) -> dict | None: + credentials = ApiKeyAuthService.get_auth_credentials(current_user.current_tenant_id, + 'website', + provider) if provider == 'firecrawl': - data_source_api_key_bindings = db.session.query(DataSourceApiKeyAuthBinding).filter( - DataSourceApiKeyAuthBinding.tenant_id == current_user.current_tenant_id, - DataSourceApiKeyAuthBinding.category == 'website', - DataSourceApiKeyAuthBinding.provider == 'firecrawl', - DataSourceApiKeyAuthBinding.disabled.is_(False) - ).first() - if not data_source_api_key_bindings: - raise NotFound('Firecrawl API key not found') - credentials = json.loads(data_source_api_key_bindings.credentials) - firecrawl_app = FirecrawlApp(api_key=credentials.get('config').get('api_key'), + # decrypt api_key + api_key = encrypter.decrypt_token( + tenant_id=current_user.current_tenant_id, + token=credentials.get('config').get('api_key') + ) + firecrawl_app = FirecrawlApp(api_key=api_key, base_url=credentials.get('config').get('base_url', None)) result = firecrawl_app.check_crawl_status(job_id) if result.get('status') != 'completed': raise ValueError('Crawl job is not completed') data = result.get('data') - for item in data: - if item.get('data'): - if item.get('data').get('metadata').get('sourceURL') == url: - return item.get('data').get('markdown') + if data: + for item in data: + if item.get('data').get('source_url') == url: + return item + return None else: - raise ValueError('Invalid provider') \ No newline at end of file + raise ValueError('Invalid provider') + + @classmethod + def get_scrape_url_data(cls, provider: str, url: str, only_main_content: bool) -> dict | None: + credentials = ApiKeyAuthService.get_auth_credentials(current_user.current_tenant_id, + 'website', + provider) + if provider == 'firecrawl': + # decrypt api_key + api_key = encrypter.decrypt_token( + tenant_id=current_user.current_tenant_id, + token=credentials.get('config').get('api_key') + ) + firecrawl_app = FirecrawlApp(api_key=api_key, + base_url=credentials.get('config').get('base_url', None)) + params = { + 'pageOptions': { + 'onlyMainContent': only_main_content, + "includeHtml": False + } + } + result = firecrawl_app.scrape_url(url, params) + return result + else: + raise ValueError('Invalid provider') diff --git a/api/tasks/sync_website_document_indexing_task.py b/api/tasks/sync_website_document_indexing_task.py new file mode 100644 index 00000000000000..f96d68c90e4095 --- /dev/null +++ b/api/tasks/sync_website_document_indexing_task.py @@ -0,0 +1,90 @@ +import datetime +import logging +import time + +import click +from celery import shared_task + +from core.indexing_runner import IndexingRunner +from core.rag.index_processor.index_processor_factory import IndexProcessorFactory +from extensions.ext_database import db +from extensions.ext_redis import redis_client +from models.dataset import Dataset, Document, DocumentSegment +from services.feature_service import FeatureService + + +@shared_task(queue='dataset') +def sync_website_document_indexing_task(dataset_id: str, document_id: str): + """ + Async process document + :param dataset_id: + :param document_id: + + Usage: sunc_website_document_indexing_task.delay(dataset_id, document_id) + """ + start_at = time.perf_counter() + + dataset = db.session.query(Dataset).filter(Dataset.id == dataset_id).first() + + sync_indexing_cache_key = 'document_{}_is_sync'.format(document_id) + # check document limit + features = FeatureService.get_features(dataset.tenant_id) + try: + if features.billing.enabled: + vector_space = features.vector_space + if 0 < vector_space.limit <= vector_space.size: + raise ValueError("Your total number of documents plus the number of uploads have over the limit of " + "your subscription.") + except Exception as e: + document = db.session.query(Document).filter( + Document.id == document_id, + Document.dataset_id == dataset_id + ).first() + if document: + document.indexing_status = 'error' + document.error = str(e) + document.stopped_at = datetime.datetime.utcnow() + db.session.add(document) + db.session.commit() + redis_client.delete(sync_indexing_cache_key) + return + + logging.info(click.style('Start sync website document: {}'.format(document_id), fg='green')) + document = db.session.query(Document).filter( + Document.id == document_id, + Document.dataset_id == dataset_id + ).first() + try: + if document: + # clean old data + index_processor = IndexProcessorFactory(document.doc_form).init_index_processor() + + segments = db.session.query(DocumentSegment).filter(DocumentSegment.document_id == document_id).all() + if segments: + index_node_ids = [segment.index_node_id for segment in segments] + # delete from vector index + index_processor.clean(dataset, index_node_ids) + + for segment in segments: + db.session.delete(segment) + db.session.commit() + + document.indexing_status = 'parsing' + document.processing_started_at = datetime.datetime.utcnow() + db.session.add(document) + db.session.commit() + + indexing_runner = IndexingRunner() + indexing_runner.run([document]) + redis_client.delete(sync_indexing_cache_key) + except Exception as ex: + document.indexing_status = 'error' + document.error = str(ex) + document.stopped_at = datetime.datetime.utcnow() + db.session.add(document) + db.session.commit() + logging.info(click.style(str(ex), fg='yellow')) + redis_client.delete(sync_indexing_cache_key) + pass + end_at = time.perf_counter() + logging.info(click.style('Sync dataset: {} latency: {}'.format(dataset_id, end_at - start_at), fg='green')) diff --git a/api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py b/api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py index 19b372649911b1..7463ee38bf218d 100644 --- a/api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py +++ b/api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py @@ -1,37 +1,44 @@ import os +from core.rag.extractor.firecrawl.firecrawl_app import FirecrawlApp from core.rag.extractor.firecrawl.firecrawl_web_extractor import FirecrawlWebExtractor from core.rag.models.document import Document def test_firecrawl_web_extractor_scrape_mode(): url = "https://dify.ai" - api_key = os.getenv('FIRECRAWL_API_KEY') or 'fc-' + api_key = os.getenv('FIRECRAWL_API_KEY') or 'fc-' base_url = 'https://api.firecrawl.dev' - mode = 'scrape' - firecrawl_web_extractor = FirecrawlWebExtractor(url, api_key, base_url, mode) - documents = firecrawl_web_extractor.extract() - print(documents) - assert isinstance(documents, list) - assert all(isinstance(doc, Document) for doc in documents) + firecrawl_app = FirecrawlApp(api_key=api_key, + base_url=base_url) + params = { + 'pageOptions': { + 'onlyMainContent': True, + "includeHtml": False + } + } + data = firecrawl_app.scrape_url(url, params) + print(data) + assert isinstance(data, dict) + def test_firecrawl_web_extractor_crawl_mode(): url = "https://firecrawl.dev" api_key = os.getenv('FIRECRAWL_API_KEY') or 'fc-' base_url = 'https://api.firecrawl.dev' - mode = 'crawl' - firecrawl_web_extractor = FirecrawlWebExtractor(url, api_key, base_url, mode) - documents = firecrawl_web_extractor.extract() - print(documents) - assert isinstance(documents, list) - assert all(isinstance(doc, Document) for doc in documents) + firecrawl_app = FirecrawlApp(api_key=api_key, + base_url=base_url) + params = { + 'crawlerOptions': { + "includes": [], + "excludes": [], + "generateImgAltText": True, + "maxDepth": 1, + "limit": 1, + 'returnOnlyUrls': False, -def test_firecrawl_web_extractor_crawl_return_urls_mode(): - url = "https://mendable.ai" - api_key = os.getenv('FIRECRAWL_API_KEY') or 'fc-' - base_url = 'https://api.firecrawl.dev' - mode = 'crawl_return_urls' - firecrawl_web_extractor = FirecrawlWebExtractor(url, api_key, base_url, mode) - documents = firecrawl_web_extractor.extract() - assert isinstance(documents, list) - assert all(isinstance(doc, Document) for doc in documents) + } + } + job_id = firecrawl_app.crawl_url(url, params) + print(job_id) + assert isinstance(job_id, str) From 677ce6caaab30f9a970a91d208976e643e3dd263 Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Thu, 16 May 2024 16:46:55 +0800 Subject: [PATCH 16/43] add website sync --- api/services/dataset_service.py | 16 ++++++++++++---- api/tasks/sync_website_document_indexing_task.py | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/api/services/dataset_service.py b/api/services/dataset_service.py index 0966083314106c..5db6e80fb7c2bc 100644 --- a/api/services/dataset_service.py +++ b/api/services/dataset_service.py @@ -488,12 +488,16 @@ def recover_document(document): @staticmethod def retry_document(dataset_id: str, documents: list[Document]): for document in documents: + # add retry flag + retry_indexing_cache_key = 'document_{}_is_retried'.format(document.id) + cache_result = redis_client.get(retry_indexing_cache_key) + if cache_result is not None: + raise ValueError("Document is being retried, please try again later") # retry document indexing document.indexing_status = 'waiting' db.session.add(document) db.session.commit() - # add retry flag - retry_indexing_cache_key = 'document_{}_is_retried'.format(document.id) + redis_client.setex(retry_indexing_cache_key, 600, 1) # trigger async task document_ids = [document.id for document in documents] @@ -501,6 +505,11 @@ def retry_document(dataset_id: str, documents: list[Document]): @staticmethod def sync_website_document(dataset_id: str, document: Document): + # add sync flag + sync_indexing_cache_key = 'document_{}_is_sync'.format(document.id) + cache_result = redis_client.get(sync_indexing_cache_key) + if cache_result is not None: + raise ValueError("Document is being synced, please try again later") # sync document indexing document.indexing_status = 'waiting' data_source_info = document.data_source_info_dict @@ -508,8 +517,7 @@ def sync_website_document(dataset_id: str, document: Document): document.data_source_info = json.dumps(data_source_info, ensure_ascii=False) db.session.add(document) db.session.commit() - # add sync flag - sync_indexing_cache_key = 'document_{}_is_sync'.format(document.id) + redis_client.setex(sync_indexing_cache_key, 600, 1) sync_website_document_indexing_task.delay(dataset_id, document.id) diff --git a/api/tasks/sync_website_document_indexing_task.py b/api/tasks/sync_website_document_indexing_task.py index f96d68c90e4095..320da8718a12cb 100644 --- a/api/tasks/sync_website_document_indexing_task.py +++ b/api/tasks/sync_website_document_indexing_task.py @@ -87,4 +87,4 @@ def sync_website_document_indexing_task(dataset_id: str, document_id: str): redis_client.delete(sync_indexing_cache_key) pass end_at = time.perf_counter() - logging.info(click.style('Sync dataset: {} latency: {}'.format(dataset_id, end_at - start_at), fg='green')) + logging.info(click.style('Sync document: {} latency: {}'.format(document_id, end_at - start_at), fg='green')) From 8a4396a20974c8d116609a515409c364ec7a38b0 Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Thu, 16 May 2024 17:43:48 +0800 Subject: [PATCH 17/43] firecrawl Data format --- .../rag/extractor/firecrawl/firecrawl_app.py | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/api/core/rag/extractor/firecrawl/firecrawl_app.py b/api/core/rag/extractor/firecrawl/firecrawl_app.py index e8fe59e44b8deb..d30eb4b9a538e9 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_app.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_app.py @@ -69,15 +69,13 @@ def check_crawl_status(self, job_id) -> dict: data = crawl_status_response.get('data', []) url_data_list = [] for item in data: - if item.get('success', False): - if item.get('data'): - url_data = { - 'title': item.get('data').get('metadata').get('title'), - 'description': item.get('data').get('metadata').get('description'), - 'source_url': item.get('data').get('metadata').get('sourceURL'), - 'markdown': item.get('data').get('markdown') - } - url_data_list.append(url_data) + url_data = { + 'title': item.get('metadata').get('title'), + 'description': item.get('metadata').get('description'), + 'source_url': item.get('metadata').get('sourceURL'), + 'markdown': item.get('markdown') + } + url_data_list.append(url_data) return { 'status': 'completed', 'data': url_data_list From b9349b2a72c81675a35c4f2817cfaa86f66fcad6 Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Thu, 6 Jun 2024 15:02:08 +0800 Subject: [PATCH 18/43] add total and current page number --- api/core/rag/extractor/firecrawl/firecrawl_app.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/api/core/rag/extractor/firecrawl/firecrawl_app.py b/api/core/rag/extractor/firecrawl/firecrawl_app.py index d30eb4b9a538e9..7bb18bfc845a99 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_app.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_app.py @@ -63,6 +63,8 @@ def check_crawl_status(self, job_id) -> dict: if crawl_status_response.get('status') != 'completed': return { 'status': crawl_status_response.get('status'), + 'total': crawl_status_response.get('total'), + 'current': crawl_status_response.get('current'), 'data': [] } else: @@ -78,6 +80,8 @@ def check_crawl_status(self, job_id) -> dict: url_data_list.append(url_data) return { 'status': 'completed', + 'total': crawl_status_response.get('total'), + 'current': crawl_status_response.get('current'), 'data': url_data_list } else: From 131f1522556fd8a5a987669786bb573d0347f8d2 Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Thu, 6 Jun 2024 15:57:09 +0800 Subject: [PATCH 19/43] merge migration --- .../versions/7b45942e39bb_add_api_key_auth_binding.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/migrations/versions/7b45942e39bb_add_api_key_auth_binding.py b/api/migrations/versions/7b45942e39bb_add_api_key_auth_binding.py index 1591e87f7ee592..30992e00c9c01b 100644 --- a/api/migrations/versions/7b45942e39bb_add_api_key_auth_binding.py +++ b/api/migrations/versions/7b45942e39bb_add_api_key_auth_binding.py @@ -12,7 +12,7 @@ # revision identifiers, used by Alembic. revision = '7b45942e39bb' -down_revision = '47cc7df8c4f3' +down_revision = '4e99a8df00ff' branch_labels = None depends_on = None From 05674c5e3dec9339d20ae2c6c99c830ed987476a Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Thu, 6 Jun 2024 18:06:15 +0800 Subject: [PATCH 20/43] optimize firecrawl error msg --- api/controllers/console/auth/data_source_bearer_auth.py | 6 +++++- api/services/auth/firecrawl.py | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/api/controllers/console/auth/data_source_bearer_auth.py b/api/controllers/console/auth/data_source_bearer_auth.py index ab0cdbdc23126c..f4712036732302 100644 --- a/api/controllers/console/auth/data_source_bearer_auth.py +++ b/api/controllers/console/auth/data_source_bearer_auth.py @@ -5,6 +5,7 @@ from controllers.console import api from libs.login import login_required from services.auth.api_key_auth_service import ApiKeyAuthService +from .error import ApiKeyAuthFailedError from ..setup import setup_required from ..wraps import account_initialization_required @@ -40,7 +41,10 @@ def post(self): parser.add_argument('credentials', type=dict, required=True, nullable=False, location='json') args = parser.parse_args() ApiKeyAuthService.validate_api_key_auth_args(args) - ApiKeyAuthService.create_provider_auth(current_user.current_tenant_id, args) + try: + ApiKeyAuthService.create_provider_auth(current_user.current_tenant_id, args) + except Exception as e: + raise ApiKeyAuthFailedError(str(e)) return {'result': 'success'}, 200 diff --git a/api/services/auth/firecrawl.py b/api/services/auth/firecrawl.py index ee219a1bcb445b..69e3fb43c79dab 100644 --- a/api/services/auth/firecrawl.py +++ b/api/services/auth/firecrawl.py @@ -1,3 +1,5 @@ +import json + import requests from services.auth.api_key_auth_base import ApiKeyAuthBase @@ -48,4 +50,7 @@ def _handle_error(self, response): error_message = response.json().get('error', 'Unknown error occurred') raise Exception(f'Failed to authorize. Status code: {response.status_code}. Error: {error_message}') else: + if response.text: + error_message = json.loads(response.text).get('error', 'Unknown error occurred') + raise Exception(f'Failed to authorize. Status code: {response.status_code}. Error: {error_message}') raise Exception(f'Unexpected error occurred while trying to authorize. Status code: {response.status_code}') From 1ce9844e5a43e678fbbbb9cd407669742f325f0b Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Thu, 6 Jun 2024 18:23:46 +0800 Subject: [PATCH 21/43] optimize firecrawl error msg --- api/controllers/console/auth/data_source_bearer_auth.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/api/controllers/console/auth/data_source_bearer_auth.py b/api/controllers/console/auth/data_source_bearer_auth.py index f4712036732302..14fc1197c6ddb5 100644 --- a/api/controllers/console/auth/data_source_bearer_auth.py +++ b/api/controllers/console/auth/data_source_bearer_auth.py @@ -5,8 +5,6 @@ from controllers.console import api from libs.login import login_required from services.auth.api_key_auth_service import ApiKeyAuthService -from .error import ApiKeyAuthFailedError - from ..setup import setup_required from ..wraps import account_initialization_required @@ -44,7 +42,7 @@ def post(self): try: ApiKeyAuthService.create_provider_auth(current_user.current_tenant_id, args) except Exception as e: - raise ApiKeyAuthFailedError(str(e)) + return {'error': str(e)}, 500 return {'result': 'success'}, 200 From 2715a5a339a7cbb61286e8090097409db1fefa3a Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Thu, 6 Jun 2024 18:31:14 +0800 Subject: [PATCH 22/43] optimize firecrawl error msg --- api/controllers/console/auth/data_source_bearer_auth.py | 3 ++- api/controllers/console/auth/error.py | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) create mode 100644 api/controllers/console/auth/error.py diff --git a/api/controllers/console/auth/data_source_bearer_auth.py b/api/controllers/console/auth/data_source_bearer_auth.py index 14fc1197c6ddb5..eddb67f4bc30b9 100644 --- a/api/controllers/console/auth/data_source_bearer_auth.py +++ b/api/controllers/console/auth/data_source_bearer_auth.py @@ -1,6 +1,7 @@ from flask_login import current_user from flask_restful import Resource, reqparse from werkzeug.exceptions import Forbidden +from controllers.console.auth.error import ApiKeyAuthFailedError from controllers.console import api from libs.login import login_required @@ -42,7 +43,7 @@ def post(self): try: ApiKeyAuthService.create_provider_auth(current_user.current_tenant_id, args) except Exception as e: - return {'error': str(e)}, 500 + raise ApiKeyAuthFailedError(str(e)) return {'result': 'success'}, 200 diff --git a/api/controllers/console/auth/error.py b/api/controllers/console/auth/error.py new file mode 100644 index 00000000000000..c55ff8707d224f --- /dev/null +++ b/api/controllers/console/auth/error.py @@ -0,0 +1,7 @@ +from libs.exception import BaseHTTPException + + +class ApiKeyAuthFailedError(BaseHTTPException): + error_code = 'auth_failed' + description = "{message}" + code = 500 From 06764b2129641536a1655e1bbac6b110fcbfb3a8 Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Fri, 7 Jun 2024 14:23:45 +0800 Subject: [PATCH 23/43] add delete binding --- .../console/auth/data_source_bearer_auth.py | 15 +++++++++++++++ api/services/auth/api_key_auth_service.py | 10 ++++++++++ 2 files changed, 25 insertions(+) diff --git a/api/controllers/console/auth/data_source_bearer_auth.py b/api/controllers/console/auth/data_source_bearer_auth.py index eddb67f4bc30b9..f93e9180ad5ba6 100644 --- a/api/controllers/console/auth/data_source_bearer_auth.py +++ b/api/controllers/console/auth/data_source_bearer_auth.py @@ -47,5 +47,20 @@ def post(self): return {'result': 'success'}, 200 +class ApiKeyAuthDataSourceBindingDelete(Resource): + @setup_required + @login_required + @account_initialization_required + def delete(self, binding_id): + # The role of the current user in the table must be admin or owner + if not current_user.is_admin_or_owner: + raise Forbidden() + + ApiKeyAuthService.delete_provider_auth(current_user.current_tenant_id, binding_id) + + return {'result': 'success'}, 200 + + api.add_resource(ApiKeyAuthDataSource, '/api-key-auth/data-source') api.add_resource(ApiKeyAuthDataSourceBinding, '/api-key-auth/data-source/binding') +api.add_resource(ApiKeyAuthDataSourceBindingDelete, '/api-key-auth/data-source/') diff --git a/api/services/auth/api_key_auth_service.py b/api/services/auth/api_key_auth_service.py index 6cab79f6924202..43d0fbf98f2df7 100644 --- a/api/services/auth/api_key_auth_service.py +++ b/api/services/auth/api_key_auth_service.py @@ -45,6 +45,16 @@ def get_auth_credentials(tenant_id: str, category: str, provider: str): credentials = json.loads(data_source_api_key_bindings.credentials) return credentials + @staticmethod + def delete_provider_auth(tenant_id: str, binding_id: str): + data_source_api_key_binding = db.session.query(DataSourceApiKeyAuthBinding).filter( + DataSourceApiKeyAuthBinding.tenant_id == tenant_id, + DataSourceApiKeyAuthBinding.id == binding_id + ).first() + if data_source_api_key_binding: + db.session.delete(data_source_api_key_binding) + db.session.commit() + @classmethod def validate_api_key_auth_args(cls, args): if 'category' not in args or not args['category']: From e10c625ced863c99b9935baf16ade41b2c32f89f Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Fri, 7 Jun 2024 14:46:30 +0800 Subject: [PATCH 24/43] add delete binding --- api/models/dataset.py | 2 +- api/services/website_service.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/api/models/dataset.py b/api/models/dataset.py index 7f98bbde153494..5fe653fdcb4487 100644 --- a/api/models/dataset.py +++ b/api/models/dataset.py @@ -270,7 +270,7 @@ class Document(db.Model): 255), nullable=False, server_default=db.text("'text_model'::character varying")) doc_language = db.Column(db.String(255), nullable=True) - DATA_SOURCES = ['upload_file', 'notion_import'] + DATA_SOURCES = ['upload_file', 'notion_import', 'website'] @property def display_status(self): diff --git a/api/services/website_service.py b/api/services/website_service.py index 6d46a1626e4c7a..6158de749d089f 100644 --- a/api/services/website_service.py +++ b/api/services/website_service.py @@ -97,6 +97,8 @@ def get_crawl_status(cls, job_id: str, provider: str) -> dict: crawl_status_data = { 'status': result.get('status', 'active'), 'job_id': job_id, + 'total': result.get('total', 0), + 'current': result.get('current', 0), 'data': result.get('data', []) } else: From ead40f678758a0dd80691278bfc68a2275df5c54 Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Fri, 7 Jun 2024 15:04:00 +0800 Subject: [PATCH 25/43] add delete binding --- api/services/dataset_service.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/services/dataset_service.py b/api/services/dataset_service.py index 1af49bea4b4f98..0873c11259760a 100644 --- a/api/services/dataset_service.py +++ b/api/services/dataset_service.py @@ -1031,8 +1031,8 @@ def data_source_args_validate(cls, args: dict): 'notion_info_list']: raise ValueError("Notion source info is required") if args['data_source']['type'] == 'website': - if 'website_info' not in args['data_source']['info_list'] or not args['data_source']['info_list'][ - 'website_info']: + if 'website_info_list' not in args['data_source']['info_list'] or not args['data_source']['info_list'][ + 'website_info_list']: raise ValueError("Website source info is required") @classmethod From be91a909479f52320ce95451039cd3539469cda2 Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Fri, 7 Jun 2024 18:08:14 +0800 Subject: [PATCH 26/43] fix firecrawl issue --- api/controllers/console/datasets/datasets.py | 15 +++++++++++++++ .../console/datasets/datasets_document.py | 13 +++++++++++++ api/models/dataset.py | 4 ++-- api/services/dataset_service.py | 10 +++++++--- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/api/controllers/console/datasets/datasets.py b/api/controllers/console/datasets/datasets.py index 3f666949c8cd51..52577334acd8b5 100644 --- a/api/controllers/console/datasets/datasets.py +++ b/api/controllers/console/datasets/datasets.py @@ -311,6 +311,21 @@ def post(self): document_model=args['doc_form'] ) extract_settings.append(extract_setting) + elif args['info_list']['data_source_type'] == 'website_crawl': + website_info_list = args['info_list']['website_info_list'] + for url in website_info_list['urls']: + extract_setting = ExtractSetting( + datasource_type="website", + website_info={ + "provider": website_info_list['provider'], + "job_id": website_info_list['job_id'], + "url": url, + "mode": 'crawl', + "only_main_content": website_info_list['only_main_content'] + }, + document_model=args['doc_form'] + ) + extract_settings.append(extract_setting) else: raise ValueError('Data source type not support') indexing_runner = IndexingRunner() diff --git a/api/controllers/console/datasets/datasets_document.py b/api/controllers/console/datasets/datasets_document.py index a4b2423d62db0a..d88123adf640b5 100644 --- a/api/controllers/console/datasets/datasets_document.py +++ b/api/controllers/console/datasets/datasets_document.py @@ -465,6 +465,19 @@ def get(self, dataset_id, batch): document_model=document.doc_form ) extract_settings.append(extract_setting) + elif document.data_source_type == 'website_crawl': + extract_setting = ExtractSetting( + datasource_type="website", + website_info={ + "provider": data_source_info['provider'], + "job_id": data_source_info['job_id'], + "url": data_source_info['url'], + "mode": data_source_info['mode'], + "only_main_content": data_source_info['only_main_content'] + }, + document_model=document.doc_form + ) + extract_settings.append(extract_setting) else: raise ValueError('Data source type not support') diff --git a/api/models/dataset.py b/api/models/dataset.py index 5fe653fdcb4487..9f8b15be1a45ec 100644 --- a/api/models/dataset.py +++ b/api/models/dataset.py @@ -270,7 +270,7 @@ class Document(db.Model): 255), nullable=False, server_default=db.text("'text_model'::character varying")) doc_language = db.Column(db.String(255), nullable=True) - DATA_SOURCES = ['upload_file', 'notion_import', 'website'] + DATA_SOURCES = ['upload_file', 'notion_import', 'website_crawl'] @property def display_status(self): @@ -322,7 +322,7 @@ def data_source_detail_dict(self): 'created_at': file_detail.created_at.timestamp() } } - elif self.data_source_type == 'notion_import': + elif self.data_source_type == 'notion_import' or self.data_source_type == 'website_crawl': return json.loads(self.data_source_info) return {} diff --git a/api/services/dataset_service.py b/api/services/dataset_service.py index 0873c11259760a..33b96749f39047 100644 --- a/api/services/dataset_service.py +++ b/api/services/dataset_service.py @@ -749,7 +749,9 @@ def save_document_with_dataset_id(dataset: Dataset, document_data: dict, data_source_info = { 'url': url, 'provider': website_info['provider'], - 'job_id': website_info['job_id'] + 'job_id': website_info['job_id'], + 'only_main_content': website_info.get('only_main_content', False), + 'mode': 'crawl', } document = DocumentService.build_document(dataset, dataset_process_rule.id, document_data["data_source"]["type"], @@ -887,7 +889,9 @@ def update_document_with_dataset_id(dataset: Dataset, document_data: dict, data_source_info = { 'url': url, 'provider': website_info['provider'], - 'job_id': website_info['job_id'] + 'job_id': website_info['job_id'], + 'only_main_content': website_info.get('only_main_content', False), + 'mode': 'crawl', } document.data_source_type = document_data["data_source"]["type"] document.data_source_info = json.dumps(data_source_info) @@ -1030,7 +1034,7 @@ def data_source_args_validate(cls, args: dict): if 'notion_info_list' not in args['data_source']['info_list'] or not args['data_source']['info_list'][ 'notion_info_list']: raise ValueError("Notion source info is required") - if args['data_source']['type'] == 'website': + if args['data_source']['type'] == 'website_crawl': if 'website_info_list' not in args['data_source']['info_list'] or not args['data_source']['info_list'][ 'website_info_list']: raise ValueError("Website source info is required") From 5870e5ff036e782006a0a1d728e5d5c0360b0b7a Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Tue, 11 Jun 2024 14:32:46 +0800 Subject: [PATCH 27/43] fix firecrawl issue --- api/controllers/console/datasets/datasets.py | 2 +- api/controllers/console/datasets/datasets_document.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/controllers/console/datasets/datasets.py b/api/controllers/console/datasets/datasets.py index 52577334acd8b5..a40038881f68a1 100644 --- a/api/controllers/console/datasets/datasets.py +++ b/api/controllers/console/datasets/datasets.py @@ -315,7 +315,7 @@ def post(self): website_info_list = args['info_list']['website_info_list'] for url in website_info_list['urls']: extract_setting = ExtractSetting( - datasource_type="website", + datasource_type="website_crawl", website_info={ "provider": website_info_list['provider'], "job_id": website_info_list['job_id'], diff --git a/api/controllers/console/datasets/datasets_document.py b/api/controllers/console/datasets/datasets_document.py index d88123adf640b5..910f1bc589567b 100644 --- a/api/controllers/console/datasets/datasets_document.py +++ b/api/controllers/console/datasets/datasets_document.py @@ -467,7 +467,7 @@ def get(self, dataset_id, batch): extract_settings.append(extract_setting) elif document.data_source_type == 'website_crawl': extract_setting = ExtractSetting( - datasource_type="website", + datasource_type="website_crawl", website_info={ "provider": data_source_info['provider'], "job_id": data_source_info['job_id'], From 419b715fdcc47a661a4e5fc478b4845a5a70941f Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Tue, 11 Jun 2024 14:56:31 +0800 Subject: [PATCH 28/43] fix firecrawl issue --- api/controllers/console/datasets/datasets.py | 1 + api/controllers/console/datasets/datasets_document.py | 1 + api/core/indexing_runner.py | 1 + api/core/rag/extractor/entity/extract_setting.py | 1 + api/core/rag/extractor/extract_processor.py | 1 + .../rag/extractor/firecrawl/firecrawl_web_extractor.py | 4 +++- api/services/dataset_service.py | 2 +- api/services/website_service.py | 8 ++++---- 8 files changed, 13 insertions(+), 6 deletions(-) diff --git a/api/controllers/console/datasets/datasets.py b/api/controllers/console/datasets/datasets.py index a40038881f68a1..1f49a7fc104dfb 100644 --- a/api/controllers/console/datasets/datasets.py +++ b/api/controllers/console/datasets/datasets.py @@ -320,6 +320,7 @@ def post(self): "provider": website_info_list['provider'], "job_id": website_info_list['job_id'], "url": url, + "tenant_id": current_user.current_tenant_id, "mode": 'crawl', "only_main_content": website_info_list['only_main_content'] }, diff --git a/api/controllers/console/datasets/datasets_document.py b/api/controllers/console/datasets/datasets_document.py index 910f1bc589567b..210faa0aa6a467 100644 --- a/api/controllers/console/datasets/datasets_document.py +++ b/api/controllers/console/datasets/datasets_document.py @@ -472,6 +472,7 @@ def get(self, dataset_id, batch): "provider": data_source_info['provider'], "job_id": data_source_info['job_id'], "url": data_source_info['url'], + "tenant_id": current_user.current_tenant_id, "mode": data_source_info['mode'], "only_main_content": data_source_info['only_main_content'] }, diff --git a/api/core/indexing_runner.py b/api/core/indexing_runner.py index 0ba0e8a933b083..c5f1d72a334334 100644 --- a/api/core/indexing_runner.py +++ b/api/core/indexing_runner.py @@ -384,6 +384,7 @@ def _extract(self, index_processor: BaseIndexProcessor, dataset_document: Datase website_info={ "provider": data_source_info['provider'], "job_id": data_source_info['job_id'], + "tenant_id": dataset_document.tenant_id, "url": data_source_info['url'], "mode": data_source_info['mode'], "only_main_content": data_source_info['only_main_content'] diff --git a/api/core/rag/extractor/entity/extract_setting.py b/api/core/rag/extractor/entity/extract_setting.py index 9bf99d06af75ef..4a3ecb7754ab2a 100644 --- a/api/core/rag/extractor/entity/extract_setting.py +++ b/api/core/rag/extractor/entity/extract_setting.py @@ -29,6 +29,7 @@ class WebsiteInfo(BaseModel): job_id: str url: str mode: str + tenant_id: str only_main_content: bool = False class Config: diff --git a/api/core/rag/extractor/extract_processor.py b/api/core/rag/extractor/extract_processor.py index 83a15a7ab0d09e..909bfdc137ff71 100644 --- a/api/core/rag/extractor/extract_processor.py +++ b/api/core/rag/extractor/extract_processor.py @@ -160,6 +160,7 @@ def extract(cls, extract_setting: ExtractSetting, is_automatic: bool = False, extractor = FirecrawlWebExtractor( url=extract_setting.website_info.url, job_id=extract_setting.website_info.job_id, + tenant_id=extract_setting.website_info.tenant_id, mode=extract_setting.website_info.mode, only_main_content=extract_setting.website_info.only_main_content ) diff --git a/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py b/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py index 870ae8d272458e..8030d437130fed 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py @@ -19,12 +19,14 @@ def __init__( self, url: str, job_id: str, + tenant_id: str, mode: str = 'crawl', only_main_content: bool = False ): """Initialize with url, api_key, base_url and mode.""" self._url = url self.job_id = job_id + self.tenant_id = tenant_id self.mode = mode self.only_main_content = only_main_content @@ -32,7 +34,7 @@ def extract(self) -> list[Document]: """Extract content from the URL.""" documents = [] if self.mode == 'crawl': - crawl_data = WebsiteService.get_crawl_url_data(self.job_id, 'firecrawl', self._url) + crawl_data = WebsiteService.get_crawl_url_data(self.job_id, 'firecrawl', self._url, self.tenant_id) if crawl_data is None: return [] document = Document(page_content=crawl_data.get('markdown', ''), diff --git a/api/services/dataset_service.py b/api/services/dataset_service.py index 33b96749f39047..fb3c791f680c8b 100644 --- a/api/services/dataset_service.py +++ b/api/services/dataset_service.py @@ -758,7 +758,7 @@ def save_document_with_dataset_id(dataset: Dataset, document_data: dict, document_data["doc_form"], document_data["doc_language"], data_source_info, created_from, position, - account, website_info['url'], batch) + account, url, batch) db.session.add(document) db.session.flush() document_ids.append(document.id) diff --git a/api/services/website_service.py b/api/services/website_service.py index 6158de749d089f..085e7492a5919f 100644 --- a/api/services/website_service.py +++ b/api/services/website_service.py @@ -106,14 +106,14 @@ def get_crawl_status(cls, job_id: str, provider: str) -> dict: return crawl_status_data @classmethod - def get_crawl_url_data(cls, job_id: str, provider: str, url: str) -> dict | None: - credentials = ApiKeyAuthService.get_auth_credentials(current_user.current_tenant_id, + def get_crawl_url_data(cls, job_id: str, provider: str, url: str, tenant_id: str) -> dict | None: + credentials = ApiKeyAuthService.get_auth_credentials(tenant_id, 'website', provider) if provider == 'firecrawl': # decrypt api_key api_key = encrypter.decrypt_token( - tenant_id=current_user.current_tenant_id, + tenant_id=tenant_id, token=credentials.get('config').get('api_key') ) firecrawl_app = FirecrawlApp(api_key=api_key, @@ -124,7 +124,7 @@ def get_crawl_url_data(cls, job_id: str, provider: str, url: str) -> dict | None data = result.get('data') if data: for item in data: - if item.get('data').get('source_url') == url: + if item.get('source_url') == url: return item return None else: From fc4212462bf69ba5875c36635745735c1fc1a963 Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Tue, 11 Jun 2024 16:01:00 +0800 Subject: [PATCH 29/43] fix firecrawl issue --- .../console/datasets/datasets_document.py | 9 +++++---- .../firecrawl/firecrawl_web_extractor.py | 3 ++- api/services/website_service.py | 19 ++++++++++++++++--- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/api/controllers/console/datasets/datasets_document.py b/api/controllers/console/datasets/datasets_document.py index 210faa0aa6a467..0ddd749639d19f 100644 --- a/api/controllers/console/datasets/datasets_document.py +++ b/api/controllers/console/datasets/datasets_document.py @@ -256,7 +256,7 @@ def post(self, dataset_id): DocumentService.document_create_args_validate(args) try: - documents, batch = DocumentService. save_document_with_dataset_id(dataset, args, current_user) + documents, batch = DocumentService.save_document_with_dataset_id(dataset, args, current_user) except ProviderTokenNotInitError as ex: raise ProviderNotInitializeError(ex.description) except QuotaExceededError: @@ -970,7 +970,7 @@ class WebsiteDocumentSyncApi(DocumentResource): @setup_required @login_required @account_initialization_required - def post(self, dataset_id, document_id): + def get(self, dataset_id, document_id): """sync website document.""" dataset_id = str(dataset_id) dataset = DatasetService.get_dataset(dataset_id) @@ -990,7 +990,8 @@ def post(self, dataset_id, document_id): # sync document DocumentService.sync_website_document(dataset_id, document) - return {'result': 'success'}, 204 + return {'result': 'success'}, 200 + api.add_resource(GetProcessRuleApi, '/datasets/process-rule') api.add_resource(DatasetDocumentListApi, @@ -1021,4 +1022,4 @@ def post(self, dataset_id, document_id): api.add_resource(DocumentRenameApi, '/datasets//documents//rename') -api.add_resource(WebsiteDocumentSyncApi, '/datasets///website-sync') \ No newline at end of file +api.add_resource(WebsiteDocumentSyncApi, '/datasets//documents//website-sync') diff --git a/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py b/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py index 8030d437130fed..8e2f107e5eb795 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_web_extractor.py @@ -46,7 +46,8 @@ def extract(self) -> list[Document]: ) documents.append(document) elif self.mode == 'scrape': - scrape_data = WebsiteService.get_scrape_url_data('firecrawl', self._url, self.only_main_content) + scrape_data = WebsiteService.get_scrape_url_data('firecrawl', self._url, self.tenant_id, + self.only_main_content) document = Document(page_content=scrape_data.get('markdown', ''), metadata={ diff --git a/api/services/website_service.py b/api/services/website_service.py index 085e7492a5919f..a1758d5bbd574c 100644 --- a/api/services/website_service.py +++ b/api/services/website_service.py @@ -1,3 +1,4 @@ +import datetime import json from typing import Any @@ -7,6 +8,7 @@ from core.helper import encrypter from core.rag.extractor.firecrawl.firecrawl_app import FirecrawlApp from extensions.ext_database import db +from extensions.ext_redis import redis_client from models.source import DataSourceApiKeyAuthBinding from services.auth.api_key_auth_service import ApiKeyAuthService @@ -73,6 +75,9 @@ def crawl_url(cls, args: dict) -> dict: } } job_id = firecrawl_app.crawl_url(url, params) + website_crawl_time_cache_key = f'website_crawl_{job_id}' + time = str(datetime.datetime.now().timestamp()) + redis_client.setex(website_crawl_time_cache_key, 3600, time) return { 'status': 'active', 'job_id': job_id @@ -101,6 +106,14 @@ def get_crawl_status(cls, job_id: str, provider: str) -> dict: 'current': result.get('current', 0), 'data': result.get('data', []) } + if crawl_status_data['status'] == 'completed': + website_crawl_time_cache_key = f'website_crawl_{job_id}' + start_time = redis_client.get(website_crawl_time_cache_key) + if start_time: + end_time = datetime.datetime.now().timestamp() + time_consuming = abs(end_time - float(start_time)) + crawl_status_data['time_consuming'] = f"{time_consuming:.2f}" + redis_client.delete(website_crawl_time_cache_key) else: raise ValueError('Invalid provider') return crawl_status_data @@ -131,14 +144,14 @@ def get_crawl_url_data(cls, job_id: str, provider: str, url: str, tenant_id: str raise ValueError('Invalid provider') @classmethod - def get_scrape_url_data(cls, provider: str, url: str, only_main_content: bool) -> dict | None: - credentials = ApiKeyAuthService.get_auth_credentials(current_user.current_tenant_id, + def get_scrape_url_data(cls, provider: str, url: str, tenant_id: str, only_main_content: bool) -> dict | None: + credentials = ApiKeyAuthService.get_auth_credentials(tenant_id, 'website', provider) if provider == 'firecrawl': # decrypt api_key api_key = encrypter.decrypt_token( - tenant_id=current_user.current_tenant_id, + tenant_id=tenant_id, token=credentials.get('config').get('api_key') ) firecrawl_app = FirecrawlApp(api_key=api_key, From 1f60ae9a394e55f59e0d86759616cc2d49b22e4e Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Wed, 12 Jun 2024 23:36:09 +0800 Subject: [PATCH 30/43] fix firecrawl issue --- api/controllers/console/datasets/error.py | 6 ++++++ api/controllers/console/datasets/website.py | 11 ++++++++-- .../rag/extractor/firecrawl/firecrawl_app.py | 20 ++++++++++++++----- 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/api/controllers/console/datasets/error.py b/api/controllers/console/datasets/error.py index 29142b80e627f3..3fb190a53725b1 100644 --- a/api/controllers/console/datasets/error.py +++ b/api/controllers/console/datasets/error.py @@ -71,3 +71,9 @@ class InvalidMetadataError(BaseHTTPException): error_code = 'invalid_metadata' description = "The metadata content is incorrect. Please check and verify." code = 400 + + +class WebsiteCrawlError(BaseHTTPException): + error_code = 'crawl_failed' + description = "{message}" + code = 500 diff --git a/api/controllers/console/datasets/website.py b/api/controllers/console/datasets/website.py index 6caf715aa31958..bbd91256f1c29c 100644 --- a/api/controllers/console/datasets/website.py +++ b/api/controllers/console/datasets/website.py @@ -1,6 +1,7 @@ from flask_restful import Resource, reqparse from controllers.console import api +from controllers.console.datasets.error import WebsiteCrawlError from controllers.console.setup import setup_required from controllers.console.wraps import account_initialization_required from libs.login import login_required @@ -21,7 +22,10 @@ def post(self): args = parser.parse_args() WebsiteService.document_create_args_validate(args) # crawl url - result = WebsiteService.crawl_url(args) + try: + result = WebsiteService.crawl_url(args) + except Exception as e: + raise WebsiteCrawlError(str(e)) return result, 200 @@ -34,7 +38,10 @@ def get(self, job_id: str): parser.add_argument('provider', type=str, choices=['firecrawl'], required=True, location='args') args = parser.parse_args() # get crawl status - result = WebsiteService.get_crawl_status(job_id, args['provider']) + try: + result = WebsiteService.get_crawl_status(job_id, args['provider']) + except Exception as e: + raise WebsiteCrawlError(str(e)) return result, 200 diff --git a/api/core/rag/extractor/firecrawl/firecrawl_app.py b/api/core/rag/extractor/firecrawl/firecrawl_app.py index 7bb18bfc845a99..b6447fd237a609 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_app.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_app.py @@ -1,7 +1,10 @@ +import json import time import requests +from extensions.ext_storage import storage + class FirecrawlApp: def __init__(self, api_key=None, base_url=None): @@ -68,6 +71,9 @@ def check_crawl_status(self, job_id) -> dict: 'data': [] } else: + total = crawl_status_response.get('total', 0) + if total == 0: + raise Exception(f'Failed to check crawl status. Error: No page found') data = crawl_status_response.get('data', []) url_data_list = [] for item in data: @@ -78,6 +84,11 @@ def check_crawl_status(self, job_id) -> dict: 'markdown': item.get('markdown') } url_data_list.append(url_data) + # if url_data_list: + # file_key = 'website_files/' + job_id + '.txt' + # if storage.exists(file_key): + # storage.delete(file_key) + # storage.save(file_key, json.dumps(url_data_list).encode('utf-8')) return { 'status': 'completed', 'total': crawl_status_response.get('total'), @@ -112,8 +123,7 @@ def _get_request(self, url, headers, retries=3, backoff_factor=0.5): return response def _handle_error(self, response, action): - if response.status_code in [402, 409, 500]: - error_message = response.json().get('error', 'Unknown error occurred') - raise Exception(f'Failed to {action}. Status code: {response.status_code}. Error: {error_message}') - else: - raise Exception(f'Unexpected error occurred while trying to {action}. Status code: {response.status_code}') + error_message = response.json().get('error', 'Unknown error occurred') + raise Exception(f'Failed to {action}. Status code: {response.status_code}. Error: {error_message}') + + From e2212bdfb4fc8f4155bc0e4a3ccad7a428bcb0c5 Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Thu, 13 Jun 2024 12:32:25 +0800 Subject: [PATCH 31/43] fix firecrawl issue --- .../rag/extractor/firecrawl/firecrawl_app.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/api/core/rag/extractor/firecrawl/firecrawl_app.py b/api/core/rag/extractor/firecrawl/firecrawl_app.py index b6447fd237a609..82064390e056fe 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_app.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_app.py @@ -63,14 +63,7 @@ def check_crawl_status(self, job_id) -> dict: response = self._get_request(f'{self.base_url}/v0/crawl/status/{job_id}', headers) if response.status_code == 200: crawl_status_response = response.json() - if crawl_status_response.get('status') != 'completed': - return { - 'status': crawl_status_response.get('status'), - 'total': crawl_status_response.get('total'), - 'current': crawl_status_response.get('current'), - 'data': [] - } - else: + if crawl_status_response.get('status') == 'completed': total = crawl_status_response.get('total', 0) if total == 0: raise Exception(f'Failed to check crawl status. Error: No page found') @@ -95,6 +88,15 @@ def check_crawl_status(self, job_id) -> dict: 'current': crawl_status_response.get('current'), 'data': url_data_list } + + else: + return { + 'status': crawl_status_response.get('status'), + 'total': crawl_status_response.get('total'), + 'current': crawl_status_response.get('current'), + 'data': [] + } + else: self._handle_error(response, 'check crawl status') From 4c31a3313046eb085068769a22ccbe29df0e1bdd Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Fri, 14 Jun 2024 17:02:42 +0800 Subject: [PATCH 32/43] add crawl to s3 service --- .../rag/extractor/firecrawl/firecrawl_app.py | 10 +++---- api/services/website_service.py | 29 ++++++++++++------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/api/core/rag/extractor/firecrawl/firecrawl_app.py b/api/core/rag/extractor/firecrawl/firecrawl_app.py index 82064390e056fe..99bd7fb0fd322e 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_app.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_app.py @@ -77,11 +77,11 @@ def check_crawl_status(self, job_id) -> dict: 'markdown': item.get('markdown') } url_data_list.append(url_data) - # if url_data_list: - # file_key = 'website_files/' + job_id + '.txt' - # if storage.exists(file_key): - # storage.delete(file_key) - # storage.save(file_key, json.dumps(url_data_list).encode('utf-8')) + if url_data_list: + file_key = 'website_files/' + job_id + '.txt' + if storage.exists(file_key): + storage.delete(file_key) + storage.save(file_key, json.dumps(url_data_list).encode('utf-8')) return { 'status': 'completed', 'total': crawl_status_response.get('total'), diff --git a/api/services/website_service.py b/api/services/website_service.py index a1758d5bbd574c..334cf96cc2fc99 100644 --- a/api/services/website_service.py +++ b/api/services/website_service.py @@ -9,6 +9,7 @@ from core.rag.extractor.firecrawl.firecrawl_app import FirecrawlApp from extensions.ext_database import db from extensions.ext_redis import redis_client +from extensions.ext_storage import storage from models.source import DataSourceApiKeyAuthBinding from services.auth.api_key_auth_service import ApiKeyAuthService @@ -124,17 +125,23 @@ def get_crawl_url_data(cls, job_id: str, provider: str, url: str, tenant_id: str 'website', provider) if provider == 'firecrawl': - # decrypt api_key - api_key = encrypter.decrypt_token( - tenant_id=tenant_id, - token=credentials.get('config').get('api_key') - ) - firecrawl_app = FirecrawlApp(api_key=api_key, - base_url=credentials.get('config').get('base_url', None)) - result = firecrawl_app.check_crawl_status(job_id) - if result.get('status') != 'completed': - raise ValueError('Crawl job is not completed') - data = result.get('data') + file_key = 'website_files/' + job_id + '.txt' + if storage.exists(file_key): + data = storage.load_once(file_key) + if data: + data = json.loads(data.decode('utf-8')) + else: + # decrypt api_key + api_key = encrypter.decrypt_token( + tenant_id=tenant_id, + token=credentials.get('config').get('api_key') + ) + firecrawl_app = FirecrawlApp(api_key=api_key, + base_url=credentials.get('config').get('base_url', None)) + result = firecrawl_app.check_crawl_status(job_id) + if result.get('status') != 'completed': + raise ValueError('Crawl job is not completed') + data = result.get('data') if data: for item in data: if item.get('source_url') == url: From 240c7326fc478b30e9cca174bd56d43448463df1 Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Fri, 14 Jun 2024 18:06:50 +0800 Subject: [PATCH 33/43] add crawl to s3 service --- api/services/website_service.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/services/website_service.py b/api/services/website_service.py index 334cf96cc2fc99..afe3614b1bb631 100644 --- a/api/services/website_service.py +++ b/api/services/website_service.py @@ -49,7 +49,6 @@ def crawl_url(cls, args: dict) -> dict: "includes": [], "excludes": [], "generateImgAltText": True, - "maxDepth": 1, "limit": 1, 'returnOnlyUrls': False, 'pageOptions': { @@ -66,7 +65,6 @@ def crawl_url(cls, args: dict) -> dict: "includes": includes if includes else [], "excludes": excludes if excludes else [], "generateImgAltText": True, - "maxDepth": options.get('max_depth', 1), "limit": options.get('limit', 1), 'returnOnlyUrls': False, 'pageOptions': { @@ -75,6 +73,8 @@ def crawl_url(cls, args: dict) -> dict: } } } + if options.get('max_depth'): + params['crawlerOptions']['maxDepth'] = options.get('max_depth') job_id = firecrawl_app.crawl_url(url, params) website_crawl_time_cache_key = f'website_crawl_{job_id}' time = str(datetime.datetime.now().timestamp()) From d842ea16b4a4af1849d1b91d96547808e3716ae6 Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Fri, 14 Jun 2024 18:21:40 +0800 Subject: [PATCH 34/43] add crawl to s3 service --- api/services/website_service.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/api/services/website_service.py b/api/services/website_service.py index afe3614b1bb631..58ff0b012118a7 100644 --- a/api/services/website_service.py +++ b/api/services/website_service.py @@ -1,16 +1,12 @@ import datetime import json -from typing import Any from flask_login import current_user -from werkzeug.exceptions import NotFound from core.helper import encrypter from core.rag.extractor.firecrawl.firecrawl_app import FirecrawlApp -from extensions.ext_database import db from extensions.ext_redis import redis_client from extensions.ext_storage import storage -from models.source import DataSourceApiKeyAuthBinding from services.auth.api_key_auth_service import ApiKeyAuthService From bea2557f0b0bbea4ea5574bceec657e0a6f658d4 Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Fri, 14 Jun 2024 19:02:55 +0800 Subject: [PATCH 35/43] lint --- api/controllers/console/__init__.py | 2 +- api/controllers/console/auth/data_source_bearer_auth.py | 3 ++- api/core/rag/extractor/firecrawl/firecrawl_app.py | 2 +- .../versions/7b45942e39bb_add_api_key_auth_binding.py | 4 ++-- api/services/dataset_service.py | 1 - 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/api/controllers/console/__init__.py b/api/controllers/console/__init__.py index 12dd975e728f75..29eac070a08fcb 100644 --- a/api/controllers/console/__init__.py +++ b/api/controllers/console/__init__.py @@ -29,7 +29,7 @@ ) # Import auth controllers -from .auth import activate, data_source_oauth, login, oauth, data_source_bearer_auth +from .auth import activate, data_source_bearer_auth, data_source_oauth, login, oauth # Import billing controllers from .billing import billing diff --git a/api/controllers/console/auth/data_source_bearer_auth.py b/api/controllers/console/auth/data_source_bearer_auth.py index f93e9180ad5ba6..81678f61fcbf02 100644 --- a/api/controllers/console/auth/data_source_bearer_auth.py +++ b/api/controllers/console/auth/data_source_bearer_auth.py @@ -1,11 +1,12 @@ from flask_login import current_user from flask_restful import Resource, reqparse from werkzeug.exceptions import Forbidden -from controllers.console.auth.error import ApiKeyAuthFailedError from controllers.console import api +from controllers.console.auth.error import ApiKeyAuthFailedError from libs.login import login_required from services.auth.api_key_auth_service import ApiKeyAuthService + from ..setup import setup_required from ..wraps import account_initialization_required diff --git a/api/core/rag/extractor/firecrawl/firecrawl_app.py b/api/core/rag/extractor/firecrawl/firecrawl_app.py index 99bd7fb0fd322e..fcab0f382034d1 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_app.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_app.py @@ -66,7 +66,7 @@ def check_crawl_status(self, job_id) -> dict: if crawl_status_response.get('status') == 'completed': total = crawl_status_response.get('total', 0) if total == 0: - raise Exception(f'Failed to check crawl status. Error: No page found') + raise Exception('Failed to check crawl status. Error: No page found') data = crawl_status_response.get('data', []) url_data_list = [] for item in data: diff --git a/api/migrations/versions/7b45942e39bb_add_api_key_auth_binding.py b/api/migrations/versions/7b45942e39bb_add_api_key_auth_binding.py index 30992e00c9c01b..f63bad93457d30 100644 --- a/api/migrations/versions/7b45942e39bb_add_api_key_auth_binding.py +++ b/api/migrations/versions/7b45942e39bb_add_api_key_auth_binding.py @@ -5,10 +5,10 @@ Create Date: 2024-05-14 07:31:29.702766 """ +import sqlalchemy as sa from alembic import op + import models as models -import sqlalchemy as sa -from sqlalchemy.dialects import postgresql # revision identifiers, used by Alembic. revision = '7b45942e39bb' diff --git a/api/services/dataset_service.py b/api/services/dataset_service.py index fb3c791f680c8b..c1ac8400064b58 100644 --- a/api/services/dataset_service.py +++ b/api/services/dataset_service.py @@ -51,7 +51,6 @@ from tasks.sync_website_document_indexing_task import sync_website_document_indexing_task - class DatasetService: @staticmethod From 66a73f778ecbdf0305d72ebcee7be7eb501cbefa Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Fri, 14 Jun 2024 19:07:44 +0800 Subject: [PATCH 36/43] lint --- api/core/rag/extractor/firecrawl/firecrawl_app.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/api/core/rag/extractor/firecrawl/firecrawl_app.py b/api/core/rag/extractor/firecrawl/firecrawl_app.py index fcab0f382034d1..af6b5689366904 100644 --- a/api/core/rag/extractor/firecrawl/firecrawl_app.py +++ b/api/core/rag/extractor/firecrawl/firecrawl_app.py @@ -70,13 +70,14 @@ def check_crawl_status(self, job_id) -> dict: data = crawl_status_response.get('data', []) url_data_list = [] for item in data: - url_data = { - 'title': item.get('metadata').get('title'), - 'description': item.get('metadata').get('description'), - 'source_url': item.get('metadata').get('sourceURL'), - 'markdown': item.get('markdown') - } - url_data_list.append(url_data) + if isinstance(item, dict) and 'metadata' in item and 'markdown' in item: + url_data = { + 'title': item.get('metadata').get('title'), + 'description': item.get('metadata').get('description'), + 'source_url': item.get('metadata').get('sourceURL'), + 'markdown': item.get('markdown') + } + url_data_list.append(url_data) if url_data_list: file_key = 'website_files/' + job_id + '.txt' if storage.exists(file_key): From 867f17be566660cf8ce9a8cabbbdd832c70c5b26 Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Fri, 14 Jun 2024 19:59:57 +0800 Subject: [PATCH 37/43] lint --- api/services/website_service.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/services/website_service.py b/api/services/website_service.py index 58ff0b012118a7..c166b01237b6c4 100644 --- a/api/services/website_service.py +++ b/api/services/website_service.py @@ -54,8 +54,8 @@ def crawl_url(cls, args: dict) -> dict: } } else: - includes = ','.join(options.get('includes')) if options.get('includes') else [] - excludes = ','.join(options.get('excludes')) if options.get('excludes') else [] + includes = options.get('includes').split(',') if options.get('includes') else [] + excludes = options.get('excludes').split(',') if options.get('excludes') else [] params = { 'crawlerOptions': { "includes": includes if includes else [], From 4f33ad20c3c0d948f4b47dff5eca6d43f3014b1e Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Fri, 14 Jun 2024 23:56:53 +0800 Subject: [PATCH 38/43] lint --- api/libs/bearer_data_source.py | 7 ++---- api/services/auth/api_key_auth_base.py | 1 + .../rag/extractor/firecrawl/test_firecrawl.py | 25 ++++++------------- 3 files changed, 10 insertions(+), 23 deletions(-) diff --git a/api/libs/bearer_data_source.py b/api/libs/bearer_data_source.py index 61d37b23a2ced4..04de1fb6daefbd 100644 --- a/api/libs/bearer_data_source.py +++ b/api/libs/bearer_data_source.py @@ -1,4 +1,3 @@ - # [REVIEW] Implement if Needed? Do we need a new type of data source from abc import abstractmethod @@ -19,14 +18,13 @@ def validate_bearer_data_source(self): """ Validate the data source """ - class FireCrawlDataSource(BearerDataSource): def validate_bearer_data_source(self): TEST_CRAWL_SITE_URL = "https://www.google.com" FIRECRAWL_API_VERSION = "v0" - + test_api_endpoint = self.api_base_url.rstrip('/') + f"/{FIRECRAWL_API_VERSION}/scrape" headers = { @@ -42,9 +40,8 @@ def validate_bearer_data_source(self): return response.json().get("status") == "success" - def save_credentials(self): - # save data source binding + # save data source binding data_source_binding = DataSourceBearerBinding.query.filter( db.and_( DataSourceBearerBinding.tenant_id == current_user.current_tenant_id, diff --git a/api/services/auth/api_key_auth_base.py b/api/services/auth/api_key_auth_base.py index 8484e9c410e2a6..75f4e2c020b36f 100644 --- a/api/services/auth/api_key_auth_base.py +++ b/api/services/auth/api_key_auth_base.py @@ -5,5 +5,6 @@ class ApiKeyAuthBase(ABC): def __init__(self, credentials: dict): self.credentials = credentials + @staticmethod def validate_credentials(self): raise NotImplementedError diff --git a/api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py b/api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py index 7463ee38bf218d..a8bba11e16db1f 100644 --- a/api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py +++ b/api/tests/unit_tests/core/rag/extractor/firecrawl/test_firecrawl.py @@ -1,28 +1,13 @@ import os +from unittest import mock from core.rag.extractor.firecrawl.firecrawl_app import FirecrawlApp from core.rag.extractor.firecrawl.firecrawl_web_extractor import FirecrawlWebExtractor from core.rag.models.document import Document +from tests.unit_tests.core.rag.extractor.test_notion_extractor import _mock_response -def test_firecrawl_web_extractor_scrape_mode(): - url = "https://dify.ai" - api_key = os.getenv('FIRECRAWL_API_KEY') or 'fc-' - base_url = 'https://api.firecrawl.dev' - firecrawl_app = FirecrawlApp(api_key=api_key, - base_url=base_url) - params = { - 'pageOptions': { - 'onlyMainContent': True, - "includeHtml": False - } - } - data = firecrawl_app.scrape_url(url, params) - print(data) - assert isinstance(data, dict) - - -def test_firecrawl_web_extractor_crawl_mode(): +def test_firecrawl_web_extractor_crawl_mode(mocker): url = "https://firecrawl.dev" api_key = os.getenv('FIRECRAWL_API_KEY') or 'fc-' base_url = 'https://api.firecrawl.dev' @@ -39,6 +24,10 @@ def test_firecrawl_web_extractor_crawl_mode(): } } + mocked_firecrawl = { + "jobId": "test", + } + mocker.patch("requests.post", return_value=_mock_response(mocked_firecrawl)) job_id = firecrawl_app.crawl_url(url, params) print(job_id) assert isinstance(job_id, str) From 2915103b7e4050f1122dbf24327331c579be521c Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Fri, 14 Jun 2024 23:57:43 +0800 Subject: [PATCH 39/43] lint --- api/services/auth/api_key_auth_base.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/services/auth/api_key_auth_base.py b/api/services/auth/api_key_auth_base.py index 75f4e2c020b36f..dd74a8f1b539a0 100644 --- a/api/services/auth/api_key_auth_base.py +++ b/api/services/auth/api_key_auth_base.py @@ -1,10 +1,10 @@ -from abc import ABC +from abc import ABC, abstractmethod class ApiKeyAuthBase(ABC): def __init__(self, credentials: dict): self.credentials = credentials - @staticmethod + @abstractmethod def validate_credentials(self): raise NotImplementedError From 84a3015e9f9876a825cc807e2ff7de939ad9aa3e Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Sat, 15 Jun 2024 00:18:28 +0800 Subject: [PATCH 40/43] lint --- api/.env.example | 3 --- api/config.py | 4 ---- 2 files changed, 7 deletions(-) diff --git a/api/.env.example b/api/.env.example index bf43af47c56790..b91daab851a31f 100644 --- a/api/.env.example +++ b/api/.env.example @@ -216,7 +216,4 @@ WORKFLOW_CALL_MAX_DEPTH=5 # App configuration APP_MAX_EXECUTION_TIME=1200 -# Firecrawl Web Extractor -FIRECRAWL_API_KEY= -FIRECRAWL_BASE_URL= diff --git a/api/config.py b/api/config.py index 1e83965c11f20c..a57faba53b7bfd 100644 --- a/api/config.py +++ b/api/config.py @@ -397,10 +397,6 @@ def __init__(self): self.NOTION_INTERNAL_SECRET = get_env('NOTION_INTERNAL_SECRET') self.NOTION_INTEGRATION_TOKEN = get_env('NOTION_INTEGRATION_TOKEN') - # Firecrawl integration setting - self.FIRECRAWL_API_KEY = get_env('FIRECRAWL_API_KEY') - self.FIRECRAWL_BASE_URL = get_env('FIRECRAWL_BASE_URL') - # ------------------------ # Platform Configurations. # ------------------------ From 177d54d7db217eb49126a5d92a2511a9be47f8c6 Mon Sep 17 00:00:00 2001 From: takatost Date: Sat, 15 Jun 2024 00:20:28 +0800 Subject: [PATCH 41/43] fix bug --- api/core/model_runtime/model_providers/togetherai/llm/llm.py | 1 - 1 file changed, 1 deletion(-) diff --git a/api/core/model_runtime/model_providers/togetherai/llm/llm.py b/api/core/model_runtime/model_providers/togetherai/llm/llm.py index f38e4089426701..bb802d407157bf 100644 --- a/api/core/model_runtime/model_providers/togetherai/llm/llm.py +++ b/api/core/model_runtime/model_providers/togetherai/llm/llm.py @@ -125,7 +125,6 @@ def get_customizable_model_schema(self, model: str, credentials: dict) -> AIMode min=-2, max=2 ), - ParameterRule ], pricing=PriceConfig( input=Decimal(cred_with_endpoint.get('input_price', 0)), From 281ade3f2624ac77be127d316855b9e419a3b3a7 Mon Sep 17 00:00:00 2001 From: jyong <718720800@qq.com> Date: Sat, 15 Jun 2024 00:28:10 +0800 Subject: [PATCH 42/43] add optional type --- api/core/rag/extractor/entity/extract_setting.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/api/core/rag/extractor/entity/extract_setting.py b/api/core/rag/extractor/entity/extract_setting.py index adc50449c5b01f..e474cf376f0632 100644 --- a/api/core/rag/extractor/entity/extract_setting.py +++ b/api/core/rag/extractor/entity/extract_setting.py @@ -1,3 +1,5 @@ +from typing import Optional + from pydantic import BaseModel, ConfigDict from models.dataset import Document @@ -42,10 +44,10 @@ class ExtractSetting(BaseModel): Model class for provider response. """ datasource_type: str - upload_file: UploadFile = None - notion_info: NotionInfo = None - website_info: WebsiteInfo = None - document_model: str = None + upload_file: Optional[UploadFile] + notion_info: Optional[NotionInfo] + website_info: Optional[WebsiteInfo] + document_model: Optional[str] model_config = ConfigDict(arbitrary_types_allowed=True) def __init__(self, **data) -> None: From 6ae7117f702e9964653ef981956fd9e52ab88afb Mon Sep 17 00:00:00 2001 From: takatost Date: Sat, 15 Jun 2024 00:30:45 +0800 Subject: [PATCH 43/43] remove lock --- web/bun.lockb | Bin 394413 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 web/bun.lockb diff --git a/web/bun.lockb b/web/bun.lockb deleted file mode 100755 index b30ced5c52268ea6570fec3c05751af617b795a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 394413 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%0DqQesb@BYrwmJXWMe0pI?J-0-kNl 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

Gwcz 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 E0LrBH9smFU