diff --git a/.cspell.json b/.cspell.json
new file mode 100644
index 0000000000..6e5c3664ec
--- /dev/null
+++ b/.cspell.json
@@ -0,0 +1,10 @@
+{
+ "version": "0.2",
+ "language": "en",
+ "words": [
+ "githubusercontent",
+ "commitlint",
+ "EDITMSG",
+ "codespell"
+ ]
+}
\ No newline at end of file
diff --git a/.github/hooks/todo-warning.sh b/.github/hooks/todo-warning.sh
new file mode 100755
index 0000000000..fa3b7aab7a
--- /dev/null
+++ b/.github/hooks/todo-warning.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+
+ORANGE='\033[0;33m'
+NC='\033[0m'
+BOLD='\033[1m'
+NORMAL='\033[0m'
+
+
+echo $GIT_COMMIT
+
+check_file() {
+ local file=$1
+ local match_pattern=$2
+
+ local file_changes_with_context=$(git diff -U999999999 -p --cached --color=always -- $file)
+ local matched_additions=$(echo "$file_changes_with_context" | grep -C4 $'^\e\\[32m\+.*'"$match_pattern")
+
+ if [ -n "$matched_additions" ]; then
+ echo -e "${ORANGE}[WARNING]${NC} ${BOLD}$file${NORMAL} contains some $match_pattern."
+ echo "$matched_additions"
+ echo -e "\n"
+ fi
+}
+
+
+for file in `git diff --cached -p --name-status | cut -c3-`; do
+ check_file $file 'TODO'
+done
+exit
\ No newline at end of file
diff --git a/.github/workflows/validate-pr-title.yaml b/.github/workflows/validate-pr-title.yaml
new file mode 100644
index 0000000000..1bba088bb1
--- /dev/null
+++ b/.github/workflows/validate-pr-title.yaml
@@ -0,0 +1,72 @@
+name: Validate PR Title
+on:
+ pull_request:
+ types: [opened, edited, synchronize]
+permissions:
+ pull-requests: write
+ contents: read
+jobs:
+ lint:
+ name: 'Lint'
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ - name: Install Commitlint and CSpell
+ run: npm install --save-dev @commitlint/{config-conventional,cli} cspell
+ - run: echo "${{ github.event.pull_request.title }}" > pr-title.txt
+ - name: Run Commitlint
+ id: commitlint
+ run: npx commitlint --edit pr-title.txt > commitlint_output.txt 2>&1
+ if: always()
+ - name: Run CSpell
+ id: cspell
+ run: npx cspell --config .cspell.json pr-title.txt > cspell_output.txt 2>&1
+ if: always()
+ - name: Delete Old Bot Comments
+ if: always()
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ # Fetch all comments on the PR
+ COMMENTS=$(gh api repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments --jq '.[] | select(.user.login == "github-actions[bot]") | .id')
+
+ # Delete comments authored by the bot
+ for COMMENT_ID in $COMMENTS; do
+ gh api repos/${{ github.repository }}/issues/comments/$COMMENT_ID -X DELETE
+ done
+ - name: Post PR Comment
+ if: always()
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ # Initialize status messages
+ STATUS_COMMITLINT="PASSED"
+ STATUS_CSPELL="PASSED"
+ COMMITLINT_OUTPUT=$(cat commitlint_output.txt)
+ CSPELL_OUTPUT=$(cat cspell_output.txt)
+ COMMENT_BODY="### Found Issues In PR Title\n"
+
+ if [ "${{ steps.commitlint.outcome }}" == "failure" ]; then
+ STATUS_COMMITLINT="FAILED"
+ fi
+
+ if [ "${{ steps.cspell.outcome }}" == "failure" ]; then
+ STATUS_CSPELL="FAILED"
+ fi
+
+ if [ "$STATUS_COMMITLINT" == "FAILED" ]; then
+ COMMENT_BODY+="**❌ Conventional Commit Format**\n"
+ COMMENT_BODY+="\n\`\`\`\n$COMMITLINT_OUTPUT\n\`\`\`\n"
+ fi
+ if [ "$STATUS_CSPELL" == "FAILED" ]; then
+ COMMENT_BODY+="**❌ Spelling Error**\n"
+ COMMENT_BODY+="\n\`\`\`\n$CSPELL_OUTPUT\n\`\`\`\n"
+ COMMENT_BODY+="\n> If you believe the spelling error is a false positive, please add the word in **cspell.json** file.\n"
+ fi
+
+ if [ "$STATUS_COMMITLINT" == "FAILED" ] || [ "$STATUS_CSPELL" == "FAILED" ]; then
+ # Post the comment
+ echo -e "$COMMENT_BODY" | gh pr comment ${{ github.event.pull_request.number }} --body-file -
+ fi
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index c30be2de52..30c315a294 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -32,10 +32,38 @@ repos:
- id: check-toml
- id: check-yaml
-
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.6.5
hooks:
- id: ruff
args: [--fix]
- - id: ruff-format
\ No newline at end of file
+ - id: ruff-format
+
+ - repo: local
+ hooks:
+ - id: commitlint
+ name: check commit message format
+ entry: npx commitlint --edit .git/COMMIT_EDITMSG
+ language: system
+ stages: [commit-msg]
+ always_run: true
+
+ - id: cspell-commit-msg
+ name: check commit message spelling
+ entry: npx cspell --config .cspell.json .git/COMMIT_EDITMSG
+ language: system
+ stages: [commit-msg]
+ always_run: true
+
+ - id: cspell-modified-files
+ name: check spelling of files
+ entry: sh -c "npx cspell --config .cspell.json `git diff --cached -p --name-status | cut -c3- | tr '\n' ' '`"
+ language: system
+ stages: [pre-commit]
+
+ - id: todo-warning
+ name: check todos
+ entry: .github/hooks/todo-warning.sh
+ language: script
+ stages: [pre-commit]
+ verbose: true
diff --git a/commitlint.config.js b/commitlint.config.js
index 8847564e53..21be2907dd 100644
--- a/commitlint.config.js
+++ b/commitlint.config.js
@@ -1,25 +1,11 @@
module.exports = {
- parserPreset: 'conventional-changelog-conventionalcommits',
+ extends: ['@commitlint/config-conventional'],
rules: {
- 'subject-empty': [2, 'never'],
- 'type-case': [2, 'always', 'lower-case'],
- 'type-empty': [2, 'never'],
- 'type-enum': [
- 2,
- 'always',
- [
- 'build',
- 'chore',
- 'ci',
- 'docs',
- 'feat',
- 'fix',
- 'perf',
- 'refactor',
- 'revert',
- 'style',
- 'test',
- ],
- ],
+ 'header-max-length': [2, 'always', 72],
+ 'subject-case': [2, 'always', 'sentence-case'],
+ 'scope-case': [2, 'always', 'kebab-case'],
+ 'body-case': [2, 'always', 'sentence-case'],
+ 'body-leading-blank': [2, 'always'],
+ 'footer-leading-blank': [2, 'always'],
},
};
diff --git a/dashboard/src2/components/NavigationItems.vue b/dashboard/src2/components/NavigationItems.vue
index 03055b9b4a..8a88848b9b 100644
--- a/dashboard/src2/components/NavigationItems.vue
+++ b/dashboard/src2/components/NavigationItems.vue
@@ -14,6 +14,7 @@ import WalletCards from '~icons/lucide/wallet-cards';
import Settings from '~icons/lucide/settings';
import App from '~icons/lucide/layout-grid';
import DatabaseZap from '~icons/lucide/database-zap';
+import Activity from '~icons/lucide/activity';
import Logs from '~icons/lucide/scroll-text';
import Globe from '~icons/lucide/globe';
import Notification from '~icons/lucide/inbox';
@@ -129,9 +130,18 @@ export default {
icon: () => h(Logs),
route: '/log-browser',
isActive: routeName === 'Log Browser'
+ },
+ {
+ name: 'DB Analyzer',
+ icon: () => h(Activity),
+ route: '/database-analyzer',
+ isActive: routeName === 'DB Analyzer',
+ condition: this.$team.doc?.is_desk_user
}
- ],
- isActive: ['SQL Playground', 'Log Browser'].includes(routeName),
+ ].filter(item => item.condition ?? true),
+ isActive: ['SQL Playground', 'DB Analyzer', 'Log Browser'].includes(
+ routeName
+ ),
disabled: enforce2FA
},
{
diff --git a/dashboard/src2/components/ToggleContent.vue b/dashboard/src2/components/ToggleContent.vue
new file mode 100644
index 0000000000..01a1e049fc
--- /dev/null
+++ b/dashboard/src2/components/ToggleContent.vue
@@ -0,0 +1,51 @@
+
+
+
+
+
+ {{ label }}
+
+
+ {{ subLabel }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dashboard/src2/components/devtools/database/DatabaseAddIndexButton.vue b/dashboard/src2/components/devtools/database/DatabaseAddIndexButton.vue
new file mode 100644
index 0000000000..49ec1289cd
--- /dev/null
+++ b/dashboard/src2/components/devtools/database/DatabaseAddIndexButton.vue
@@ -0,0 +1,76 @@
+
+
+
+
+
diff --git a/dashboard/src2/components/devtools/database/DatabasePerformanceSchemaDisabledNotice.vue b/dashboard/src2/components/devtools/database/DatabasePerformanceSchemaDisabledNotice.vue
new file mode 100644
index 0000000000..7a85817e8f
--- /dev/null
+++ b/dashboard/src2/components/devtools/database/DatabasePerformanceSchemaDisabledNotice.vue
@@ -0,0 +1,19 @@
+
+
+
+ Performance Schema is not enabled on database server
+
+
+ Please reach out to
+ support
+ to enable it
+
+
+
+
diff --git a/dashboard/src2/components/devtools/database/DatabaseProcessKillButton.vue b/dashboard/src2/components/devtools/database/DatabaseProcessKillButton.vue
new file mode 100644
index 0000000000..89a72ae51e
--- /dev/null
+++ b/dashboard/src2/components/devtools/database/DatabaseProcessKillButton.vue
@@ -0,0 +1,55 @@
+
+ Process Killed
+
+
+
diff --git a/dashboard/src2/components/devtools/database/DatabaseTableSchemaDialog.vue b/dashboard/src2/components/devtools/database/DatabaseTableSchemaDialog.vue
index 6e88a09148..5bd9143cd6 100644
--- a/dashboard/src2/components/devtools/database/DatabaseTableSchemaDialog.vue
+++ b/dashboard/src2/components/devtools/database/DatabaseTableSchemaDialog.vue
@@ -20,7 +20,10 @@
v-if="selectedSchema"
/>
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/dashboard/src2/components/site_database_user/SiteDatabaseUserCredentialDialog.vue b/dashboard/src2/components/site_database_user/SiteDatabaseUserCredentialDialog.vue
index 27ef6ecc72..706554001f 100644
--- a/dashboard/src2/components/site_database_user/SiteDatabaseUserCredentialDialog.vue
+++ b/dashboard/src2/components/site_database_user/SiteDatabaseUserCredentialDialog.vue
@@ -43,7 +43,7 @@
- Using MariaDB Client
+ Using MariaDB CLI
Run this command in your terminal to access MariaDB console
@@ -55,12 +55,43 @@
computer.
+
+
SSL Info
+
+ You need to use SSL to connect to the database.
+
+
Download Full Chain SSL Certificate (.pem)
+
+
+
+
Need Help?
+
+ Please check out the
+ documentation
+ to get guides on troubleshooting.
+
+
diff --git a/dashboard/src2/pages/devtools/database/DatabaseSQLPlayground.vue b/dashboard/src2/pages/devtools/database/DatabaseSQLPlayground.vue
index 7abd8543f8..db6dd68da2 100644
--- a/dashboard/src2/pages/devtools/database/DatabaseSQLPlayground.vue
+++ b/dashboard/src2/pages/devtools/database/DatabaseSQLPlayground.vue
@@ -63,6 +63,8 @@
v-model="query"
v-if="sqlSchemaForAutocompletion"
:schema="sqlSchemaForAutocompletion"
+ @codeSelected="handleCodeSelected"
+ @codeUnselected="handleCodeUnselected"
/>
@@ -73,13 +75,24 @@
Logs
- runSQLQuery()"
- :loading="$resources.runSQLQuery.loading"
- iconLeft="play"
- variant="solid"
- >Run Query
+
+
+ Run Selected Query
+
+ runSQLQuery()"
+ :loading="$resources.runSQLQuery.loading"
+ iconLeft="play"
+ variant="solid"
+ >Run Query
+
@@ -143,7 +157,7 @@
import { toast } from 'vue-sonner';
import Header from '../../../components/Header.vue';
import { Tabs, Breadcrumbs } from 'frappe-ui';
-import SQLResultTable from '../../../components/devtools/database/SQLResultTable.vue';
+import SQLResultTable from '../../../components/devtools/database/ResultTable.vue';
import SQLCodeEditor from '../../../components/devtools/database/SQLCodeEditor.vue';
import { confirmDialog } from '../../../utils/components';
import DatabaseSQLPlaygroundLog from '../../../components/devtools/database/DatabaseSQLPlaygroundLog.vue';
@@ -170,6 +184,7 @@ export default {
site: null,
tabIndex: 0,
query: '',
+ selectedQuery: null,
commit: false,
execution_successful: null,
data: null,
@@ -250,7 +265,7 @@ export default {
for (const tableName in tableSchemas) {
childrenSchemas[tableName] = {
self: { label: tableName, type: 'table' },
- children: tableSchemas[tableName].map(x => ({
+ children: tableSchemas[tableName].columns.map(x => ({
label: x.column,
type: 'column',
detail: x.data_type
@@ -284,6 +299,12 @@ export default {
}
},
methods: {
+ handleCodeSelected(selectedCode) {
+ this.selectedQuery = selectedCode;
+ },
+ handleCodeUnselected() {
+ this.selectedQuery = null;
+ },
fetchTableSchemas({ site_name = null, reload = false } = {}) {
if (!site_name) site_name = this.site;
if (!site_name) return;
@@ -296,7 +317,7 @@ export default {
}
});
},
- runSQLQuery(ignore_validation = false) {
+ runSQLQuery(ignore_validation = false, run_selected_query = false) {
if (!this.query) return;
if (this.mode === 'read-only' || ignore_validation) {
this.$resources.runSQLQuery.submit({
@@ -304,7 +325,7 @@ export default {
dn: this.site,
method: 'run_sql_query_in_database',
args: {
- query: this.query,
+ query: run_selected_query ? this.selectedQuery : this.query,
commit: this.mode === 'read-write'
}
});
@@ -321,7 +342,28 @@ Are you sure you want to run the query?`,
label: 'Run Query',
variant: 'solid',
onClick: ({ hide }) => {
- this.runSQLQuery(true);
+ this.runSQLQuery(true, run_selected_query);
+ hide();
+ }
+ }
+ });
+ },
+ runSelectedSQLQuery() {
+ if (!this.selectedQuery) {
+ return;
+ }
+ confirmDialog({
+ title: 'Verify Query',
+ message: `
+Are you sure you want to run the query?
+
+${this.selectedQuery}
+ `,
+ primaryAction: {
+ label: 'Run Query',
+ variant: 'solid',
+ onClick: ({ hide }) => {
+ this.runSQLQuery(false, true);
hide();
}
}
diff --git a/dashboard/src2/router.js b/dashboard/src2/router.js
index 3113d083bd..19afb7b733 100644
--- a/dashboard/src2/router.js
+++ b/dashboard/src2/router.js
@@ -291,6 +291,11 @@ let router = createRouter({
component: () =>
import('./pages/devtools/database/DatabaseSQLPlayground.vue')
},
+ {
+ path: '/database-analyzer',
+ name: 'DB Analyzer',
+ component: () => import('./pages/devtools/database/DatabaseAnalyzer.vue')
+ },
{
path: '/log-browser/:mode?/:docName?/:logId?',
name: 'Log Browser',
diff --git a/package.json b/package.json
index 6b0c346679..969e90b6e2 100644
--- a/package.json
+++ b/package.json
@@ -20,7 +20,10 @@
"@tailwindcss/typography": "^0.5.1",
"autoprefixer": "^10.4.2",
"postcss": "^8.4.6",
- "tailwindcss": "^3.2"
+ "tailwindcss": "^3.2",
+ "@commitlint/config-conventional": "^19.6.0",
+ "commitlint": "^19.6.1",
+ "cspell": "^8.17.1"
},
"dependencies": {
"dayjs": "^1.11.10",
diff --git a/press/agent.py b/press/agent.py
index 34ea88f61f..b102b736cf 100644
--- a/press/agent.py
+++ b/press/agent.py
@@ -1161,13 +1161,18 @@ def get_site_apps(self, site):
apps: list[str] = [line.split()[0] for line in raw_apps_list["data"].splitlines() if line]
return apps
- def fetch_database_table_schema(self, site):
+ def fetch_database_table_schema(
+ self, site, include_table_size: bool = False, include_index_info: bool = False
+ ):
return self.create_agent_job(
"Fetch Database Table Schema",
f"benches/{site.bench}/sites/{site.name}/database/schema",
bench=site.bench,
site=site.name,
- data={},
+ data={
+ "include_table_size": include_table_size,
+ "include_index_info": include_index_info,
+ },
reference_doctype="Site",
reference_name=site.name,
)
@@ -1178,6 +1183,48 @@ def run_sql_query_in_database(self, site, query, commit):
data={"query": query, "commit": commit, "as_dict": False},
)
+ def get_summarized_performance_report_of_database(self, site):
+ return self.post(
+ f"benches/{site.bench}/sites/{site.name}/database/performance-report",
+ data={"mariadb_root_password": get_mariadb_root_password(site)},
+ )
+
+ def analyze_slow_queries(self, site, normalized_queries: list[dict]):
+ """
+ normalized_queries format:
+ [
+ {
+ "example": "",
+ "normalized" : "",
+ }
+ ]
+ """
+ return self.create_agent_job(
+ "Analyze Slow Queries",
+ f"benches/{site.bench}/sites/{site.name}/database/analyze-slow-queries",
+ data={
+ "queries": normalized_queries,
+ "mariadb_root_password": get_mariadb_root_password(site),
+ },
+ site=site.name,
+ )
+
+ def fetch_database_processes(self, site):
+ return self.post(
+ f"benches/{site.bench}/sites/{site.name}/database/processes",
+ data={
+ "mariadb_root_password": get_mariadb_root_password(site),
+ },
+ )
+
+ def kill_database_process(self, site, id):
+ return self.post(
+ f"benches/{site.bench}/sites/{site.name}/database/kill-process/{id}",
+ data={
+ "mariadb_root_password": get_mariadb_root_password(site),
+ },
+ )
+
class AgentCallbackException(Exception):
pass
diff --git a/press/api/__init__.py b/press/api/__init__.py
index 1a47323294..ad1fcc1c79 100644
--- a/press/api/__init__.py
+++ b/press/api/__init__.py
@@ -1,9 +1,10 @@
import frappe
-from press.utils import get_minified_script, get_minified_script_2
+from press.api.client import dashboard_whitelist
from press.saas.doctype.product_trial_request.product_trial_request import (
get_app_trial_page_url,
)
+from press.utils import get_full_chain_cert_of_domain, get_minified_script, get_minified_script_2, log_error
@frappe.whitelist(allow_guest=True)
@@ -20,3 +21,18 @@ def script_2():
def handle_suspended_site_redirection():
frappe.local.response["type"] = "redirect"
frappe.local.response["location"] = get_app_trial_page_url() or "/dashboard"
+
+
+@dashboard_whitelist()
+def download_ssl_cert(domain: str):
+ if (
+ not (domain.endswith("frappe.cloud") or domain.endswith("frappecloud.com"))
+ and not frappe.conf.developer_mode
+ ):
+ frappe.throw("Invalid domain provided")
+
+ try:
+ return get_full_chain_cert_of_domain(domain)
+ except Exception as e:
+ log_error("Error downloading SSL certificate", data=e)
+ frappe.throw("Failed to download SSL certificate. Please try again later.")
diff --git a/press/api/analytics.py b/press/api/analytics.py
index a00d11ecad..63e491f16a 100644
--- a/press/api/analytics.py
+++ b/press/api/analytics.py
@@ -24,9 +24,6 @@
from press.agent import Agent
from press.api.site import protected
from press.press.doctype.site_plan.site_plan import get_plan_config
-from press.press.report.binary_log_browser.binary_log_browser import (
- convert_user_timezone_to_utc,
-)
from press.press.report.binary_log_browser.binary_log_browser import (
get_data as get_binary_log_data,
)
@@ -654,7 +651,7 @@ def get_current_cpu_usage_for_sites_on_server(server):
metric = row["usage"]["counter"]["top"]
if metric:
result[site] = metric[0]["metrics"]["json.request.counter"]
- return result
+ return result
@frappe.whitelist()
@@ -767,28 +764,19 @@ def mariadb_slow_queries(
@frappe.whitelist()
@protected("Site")
-def deadlock_report(site, start, end, max_lines=20):
- from press.press.report.mariadb_deadlock_browser.mariadb_deadlock_browser import (
- post_process,
- )
-
- server = frappe.db.get_value("Site", site, "server")
- db_server_name = frappe.db.get_value("Server", server, "database_server")
- database_server = frappe.get_doc("Database Server", db_server_name)
- agent = Agent(database_server.name, "Database Server")
-
- data = {
- "private_ip": database_server.private_ip,
- "mariadb_root_password": database_server.get_password("mariadb_root_password"),
- "database": database_server.name,
- "start_datetime": convert_user_timezone_to_utc(start),
- "stop_datetime": convert_user_timezone_to_utc(end),
- "max_lines": max_lines,
- }
-
- results = agent.post("database/deadlocks", data=data)
+def deadlock_report(name, start_datetime, stop_datetime, max_log_size=500):
+ from press.press.report.mariadb_deadlock_browser.mariadb_deadlock_browser import execute
- return post_process(results)
+ meta = frappe._dict(
+ {
+ "site": name,
+ "start_datetime": start_datetime,
+ "stop_datetime": stop_datetime,
+ "max_log_size": max_log_size,
+ }
+ )
+ _, data = execute(filters=meta)
+ return data
# MARKETPLACE - Plausible
diff --git a/press/api/dboptimize.py b/press/api/dboptimize.py
deleted file mode 100644
index 37209e0408..0000000000
--- a/press/api/dboptimize.py
+++ /dev/null
@@ -1,176 +0,0 @@
-import json
-
-import frappe
-
-from press.api.site import protected
-from press.press.report.mariadb_slow_queries.db_optimizer import (
- ColumnStat,
- DBExplain,
- DBOptimizer,
- DBTable,
-)
-from press.press.report.mariadb_slow_queries.mariadb_slow_queries import (
- OptimizeDatabaseQuery,
- _fetch_column_stats,
- _fetch_table_stats,
-)
-from press.utils import log_error
-
-
-@frappe.whitelist()
-@protected("Site")
-def mariadb_analyze_query(name, row):
- return analyze_query(row=row, site=name)
-
-
-def analyze_query(row, site):
- # if mariadb_analyze_query_already_exists(site, row["query"]):
- # frappe.throw("The query seems to have already been optimized")
- doc = frappe.get_doc(
- {
- "doctype": "MariaDB Analyze Query",
- "site": site,
- "tables_in_query": [],
- }
- )
- doc.status = "Running"
-
- query = row["example"]
- doc.query = query
- doc.normalized_query = row["query"]
-
- if not query.lower().startswith(("select", "update", "delete")):
- doc.status = "Failure"
- doc.save(ignore_permissions=True)
- frappe.db.commit()
- return None
-
- doc.save(ignore_permissions=True)
- frappe.db.commit()
-
- analyzer = OptimizeDatabaseQuery(site, query)
- explain_output = analyzer.fetch_explain() or []
- doc.explain_output = json.dumps(explain_output)
- explain_output = [DBExplain.from_frappe_ouput(e) for e in explain_output]
-
- optimizer = DBOptimizer(query=analyzer.query, explain_plan=explain_output)
- for table in optimizer.tables_examined:
- stats = _fetch_table_stats(analyzer.site, table)
- doc.append("tables_in_query", {"table": table, "table_statistics": json.dumps(stats)})
-
- if not stats:
- # Old framework version
- doc.status = "Failure"
- doc.save(ignore_permissions=True)
- frappe.db.commit()
- return None
-
- # This is an agent job. Remaining is processed in the callback.
- _fetch_column_stats(analyzer.site, table, doc.get_title())
-
- doc.save(ignore_permissions=True)
- return doc.status
-
-
-def check_if_all_fetch_column_stats_was_successful(doc):
- return all(item.status == "Success" for item in doc.tables_in_query)
-
-
-def fetch_column_stats_update(job, response_data):
- request_data_json = json.loads(job.request_data)
- doc_name = request_data_json["doc_name"]
- table = request_data_json["table"]
-
- if job.status == "Success":
- column_statistics = response_data["steps"][0]["data"]["output"]
- doc = frappe.get_doc("MariaDB Analyze Query", doc_name)
- for item in doc.tables_in_query:
- if item.table == table:
- item.column_statistics = column_statistics
- item.status = "Success"
- doc.save()
- frappe.db.commit()
- if check_if_all_fetch_column_stats_was_successful(doc):
- doc.status = "Success"
- doc.save()
- frappe.db.commit()
- # Persists within doctype
- save_suggested_index(doc)
- elif job.status == "Failure":
- doc = frappe.get_doc("MariaDB Analyze Query", doc_name)
- for item in doc.tables_in_query:
- if item.table == table:
- item.status = "Failure"
- doc.save()
-
- doc.status = "Failure"
- doc.save()
- frappe.db.commit()
-
-
-def save_suggested_index(doc):
- explain_output = json.loads(doc.explain_output)
- explain_output = [DBExplain.from_frappe_ouput(e) for e in explain_output]
- optimizer = DBOptimizer(query=doc.query, explain_plan=explain_output)
- for item in doc.tables_in_query:
- stats = json.loads(item.table_statistics)
- if not stats:
- # Old framework version
- return
- db_table = DBTable.from_frappe_ouput(stats)
- column_stats = json.loads(item.column_statistics)
- column_stats = [ColumnStat.from_frappe_ouput(c) for c in column_stats]
- db_table.update_cardinality(column_stats)
- optimizer.update_table_data(db_table)
- index = optimizer.suggest_index()
- doc.suggested_index = f"{index.table}.{index.column}"
- doc.save()
-
-
-@frappe.whitelist()
-@protected("Site")
-def get_status_of_mariadb_analyze_query(name, query):
- filters = {"site": name, "query": query}
- doc = frappe.get_all(
- "MariaDB Analyze Query",
- filters=filters,
- fields=["status", "suggested_index"],
- limit=1,
- )
- if doc:
- return doc[0]
- return None
-
-
-def mariadb_analyze_query_already_exists(site, normalized_query):
- if frappe.db.exists("MariaDB Analyze Query", {"site": site, "normalized_query": normalized_query}):
- return True
- return False
-
-
-@frappe.whitelist()
-@protected("Site")
-def mariadb_analyze_query_already_running_for_site(name):
- if frappe.db.exists("MariaDB Analyze Query", {"site": name, "status": "Running"}):
- return True
- return False
-
-
-@frappe.whitelist()
-@protected("Site")
-def get_suggested_index(name, normalized_query):
- return frappe.get_value(
- "MariaDB Analyze Query",
- {"site": name, "status": "Success", "normalized_query": normalized_query},
- ["site", "normalized_query", "suggested_index"],
- as_dict=True,
- )
-
-
-def delete_all_occurences_of_mariadb_analyze_query(job):
- try:
- if job.status == "Success" or job.status == "Failure":
- frappe.db.delete("MariaDB Analyze Query", {"site": job.site})
- frappe.db.commit()
- except Exception as e:
- log_error("Deleting all occurrences of MariaDB Analyze Query Failed", data=e)
diff --git a/press/api/server.py b/press/api/server.py
index df37dbd7ab..e36746ef47 100644
--- a/press/api/server.py
+++ b/press/api/server.py
@@ -300,6 +300,42 @@ def analytics(name, query, timezone, duration):
f"""node_memory_MemTotal_bytes{{instance="{name}",job="node"}} - node_memory_MemFree_bytes{{instance="{name}",job="node"}} - (node_memory_Cached_bytes{{instance="{name}",job="node"}} + node_memory_Buffers_bytes{{instance="{name}",job="node"}})""",
lambda x: "Used",
),
+ "database_uptime": (
+ f"""mysql_up{{instance="{name}",job="mariadb"}}""",
+ lambda x: "Uptime",
+ ),
+ "database_commands_count": (
+ f"""sum(round(increase(mysql_global_status_commands_total{{instance='{name}', command=~"select|update|insert|delete|begin|commit|rollback"}}[{timegrain}s]))) by (command)""",
+ lambda x: x["command"],
+ ),
+ "database_connections": (
+ f"""{{__name__=~"mysql_global_status_threads_connected|mysql_global_variables_max_connections", instance="{name}"}}""",
+ lambda x: "Max Connections"
+ if x["__name__"] == "mysql_global_variables_max_connections"
+ else "Connected Clients",
+ ),
+ "innodb_bp_size": (
+ f"""mysql_global_variables_innodb_buffer_pool_size{{instance='{name}'}}""",
+ lambda x: "Buffer Pool Size",
+ ),
+ "innodb_bp_size_of_total_ram": (
+ f"""avg by (instance) ((mysql_global_variables_innodb_buffer_pool_size{{instance=~"{name}"}} * 100)) / on (instance) (avg by (instance) (node_memory_MemTotal_bytes{{instance=~"{name}"}}))""",
+ lambda x: "Buffer Pool Size of Total Ram",
+ ),
+ "innodb_bp_miss_percent": (
+ f"""
+avg by (instance) (
+ rate(mysql_global_status_innodb_buffer_pool_reads{{instance=~"{name}"}}[{timegrain}s])
+ /
+ rate(mysql_global_status_innodb_buffer_pool_read_requests{{instance=~"{name}"}}[{timegrain}s])
+)
+""",
+ lambda x: "Buffer Pool Miss Percentage",
+ ),
+ "innodb_avg_row_lock_time": (
+ f"""(rate(mysql_global_status_innodb_row_lock_time{{instance="{name}"}}[{timegrain}s]) / 1000)/rate(mysql_global_status_innodb_row_lock_waits{{instance="{name}"}}[{timegrain}s])""",
+ lambda x: "Avg Row Lock Time",
+ ),
}
return prometheus_query(query_map[query][0], query_map[query][1], timezone, timespan, timegrain)
diff --git a/press/fixtures/agent_job_type.json b/press/fixtures/agent_job_type.json
index b6b044d9e4..a4b52ccdaa 100644
--- a/press/fixtures/agent_job_type.json
+++ b/press/fixtures/agent_job_type.json
@@ -2260,5 +2260,35 @@
"step_name": "Modify Database User Permissions"
}
]
+ },
+ {
+ "disabled_auto_retry": 1,
+ "docstatus": 0,
+ "doctype": "Agent Job Type",
+ "max_retry_count": 1,
+ "modified": "2024-10-28 14:49:19.894247",
+ "name": "Fetch Database Table Schema",
+ "request_method": "POST",
+ "request_path": "/benches/{bench}/sites/{site}/database/schema",
+ "steps": [
+ {
+ "step_name": "Fetch Database Table Schema"
+ }
+ ]
+ },
+ {
+ "disabled_auto_retry": 1,
+ "docstatus": 0,
+ "doctype": "Agent Job Type",
+ "max_retry_count": 3,
+ "modified": "2024-12-19 17:21:14.136650",
+ "name": "Analyze Slow Queries",
+ "request_method": "POST",
+ "request_path": "/benches/{bench}/sites/{site}/database/analyze-slow-queries",
+ "steps": [
+ {
+ "step_name": "Analyze Slow Queries"
+ }
+ ]
}
]
\ No newline at end of file
diff --git a/press/press/doctype/account_request/account_request.py b/press/press/doctype/account_request/account_request.py
index 3cf9287121..f907bca7a5 100644
--- a/press/press/doctype/account_request/account_request.py
+++ b/press/press/doctype/account_request/account_request.py
@@ -10,7 +10,7 @@
from frappe.model.document import Document
from frappe.utils import get_url, random_string
-from press.utils import get_country_info
+from press.utils import get_country_info, is_valid_email_address
from press.utils.telemetry import capture
@@ -63,6 +63,17 @@ class AccountRequest(Document):
# end: auto-generated types
def before_insert(self):
+ # This pre-verification is only beneficial for SaaS signup
+ # because, in general flow we already have e-mail link/otp based verification
+ if (
+ not frappe.conf.developer_mode
+ and frappe.db.get_single_value("Press Settings", "enable_email_pre_verification")
+ and self.saas
+ and not self.oauth_signup
+ and not is_valid_email_address(self.email)
+ ):
+ frappe.throw(f"{self.email} is not a valid email address")
+
if not self.team:
self.team = self.email
diff --git a/press/press/doctype/agent_job/agent_job.py b/press/press/doctype/agent_job/agent_job.py
index 69ab83a916..f0c7589f62 100644
--- a/press/press/doctype/agent_job/agent_job.py
+++ b/press/press/doctype/agent_job/agent_job.py
@@ -879,10 +879,6 @@ def process_job_updates(job_name: str, response_data: dict | None = None): # no
start = now_datetime()
try:
- from press.api.dboptimize import (
- delete_all_occurences_of_mariadb_analyze_query,
- fetch_column_stats_update,
- )
from press.press.doctype.agent_job.agent_job_notifications import (
send_job_failure_notification,
)
@@ -912,6 +908,7 @@ def process_job_updates(job_name: str, response_data: dict | None = None): # no
process_archive_site_job_update,
process_complete_setup_wizard_job_update,
process_create_user_job_update,
+ process_fetch_database_table_schema_job_update,
process_install_app_site_job_update,
process_migrate_site_job_update,
process_move_site_to_bench_job_update,
@@ -923,9 +920,6 @@ def process_job_updates(job_name: str, response_data: dict | None = None): # no
process_uninstall_app_site_job_update,
)
from press.press.doctype.site_backup.site_backup import process_backup_site_job_update
- from press.press.doctype.site_database_table_schema.site_database_table_schema import (
- SiteDatabaseTableSchema,
- )
from press.press.doctype.site_domain.site_domain import process_new_host_job_update
from press.press.doctype.site_update.site_update import (
process_update_site_job_update,
@@ -1001,23 +995,8 @@ def process_job_updates(job_name: str, response_data: dict | None = None): # no
AppPatch.process_patch_app(job)
elif job.job_type == "Run Remote Builder":
DeployCandidate.process_run_build(job, response_data)
- elif job.job_type == "Column Statistics":
- frappe.enqueue(
- fetch_column_stats_update,
- queue="default",
- timeout=None,
- is_async=True,
- now=False,
- job_name="Fetch Column Updates Through Enque",
- enqueue_after_commit=False,
- at_front=False,
- job=job,
- response_data=response_data,
- )
elif job.job_type == "Create User":
process_create_user_job_update(job)
- elif job.job_type == "Add Database Index":
- delete_all_occurences_of_mariadb_analyze_query(job)
elif job.job_type == "Complete Setup Wizard":
process_complete_setup_wizard_job_update(job)
elif job.job_type == "Update Bench In Place":
@@ -1025,7 +1004,7 @@ def process_job_updates(job_name: str, response_data: dict | None = None): # no
elif job.job_type == "Recover Update In Place":
Bench.process_recover_update_inplace(job)
elif job.job_type == "Fetch Database Table Schema":
- SiteDatabaseTableSchema.process_job_update(job)
+ process_fetch_database_table_schema_job_update(job)
elif job.job_type in [
"Create Database User",
"Remove Database User",
diff --git a/press/press/doctype/bench/bench.py b/press/press/doctype/bench/bench.py
index 29bd5b4bf2..b3ee8b2cdc 100644
--- a/press/press/doctype/bench/bench.py
+++ b/press/press/doctype/bench/bench.py
@@ -598,6 +598,14 @@ def allocate_workers(
round(self.workload / server_workload * max_gunicorn_workers),
), # min 2 max 36
)
+ if self.gunicorn_threads_per_worker:
+ # Allocate fewer workers if threaded workers are used
+ # Roughly workers / threads_per_worker = total number of workers
+ # 1. At least one worker
+ # 2. Slightly more workers than required
+ self.gunicorn_workers = frappe.utils.ceil(
+ self.gunicorn_workers / self.gunicorn_threads_per_worker
+ )
self.background_workers = min(
max_bg or MAX_BACKGROUND_WORKERS,
max(
diff --git a/press/press/doctype/invoice/invoice.py b/press/press/doctype/invoice/invoice.py
index 3c4c0d5d6c..143c29c97c 100644
--- a/press/press/doctype/invoice/invoice.py
+++ b/press/press/doctype/invoice/invoice.py
@@ -506,11 +506,23 @@ def validate_dates(self):
def update_item_descriptions(self):
for item in self.items:
- if not item.description and item.document_type == "Site" and item.plan:
- site_name = item.document_name.split(".archived")[0]
- plan = frappe.get_cached_value("Site Plan", item.plan, "plan_title")
+ if not item.description:
how_many_days = f"{cint(item.quantity)} day{'s' if item.quantity > 1 else ''}"
- item.description = f"{site_name} active for {how_many_days} on {plan} plan"
+ if item.document_type == "Site" and item.plan:
+ site_name = item.document_name.split(".archived")[0]
+ plan = frappe.get_cached_value("Site Plan", item.plan, "plan_title")
+ item.description = f"{site_name} active for {how_many_days} on {plan} plan"
+ elif item.document_type in ["Server", "Database Server"]:
+ server_title = frappe.get_cached_value(item.document_type, item.document_name, "title")
+ if item.plan == "Add-on Storage plan":
+ item.description = f"{server_title} Storage Add-on for {how_many_days}"
+ else:
+ item.description = f"{server_title} active for {how_many_days}"
+ elif item.document_type == "Marketplace App":
+ app_title = frappe.get_cached_value("Marketplace App", item.document_name, "title")
+ item.description = f"Marketplace app {app_title} active for {how_many_days}"
+ else:
+ item.description = "Prepaid Credits"
def add_usage_record(self, usage_record):
if self.type != "Subscription":
diff --git a/press/press/doctype/mariadb_analyze_query/__init__.py b/press/press/doctype/mariadb_analyze_query/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/press/press/doctype/mariadb_analyze_query/mariadb_analyze_query.js b/press/press/doctype/mariadb_analyze_query/mariadb_analyze_query.js
deleted file mode 100644
index f6228a4cd9..0000000000
--- a/press/press/doctype/mariadb_analyze_query/mariadb_analyze_query.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2024, Frappe and contributors
-// For license information, please see license.txt
-
-// frappe.ui.form.on("MariaDB Analyze Query", {
-// refresh(frm) {
-
-// },
-// });
diff --git a/press/press/doctype/mariadb_analyze_query/mariadb_analyze_query.json b/press/press/doctype/mariadb_analyze_query/mariadb_analyze_query.json
deleted file mode 100644
index 17e02dffe0..0000000000
--- a/press/press/doctype/mariadb_analyze_query/mariadb_analyze_query.json
+++ /dev/null
@@ -1,92 +0,0 @@
-{
- "actions": [],
- "allow_rename": 1,
- "creation": "2024-07-21 16:44:56.074012",
- "doctype": "DocType",
- "engine": "InnoDB",
- "field_order": [
- "site",
- "normalized_query",
- "column_break_holt",
- "query",
- "status",
- "section_break_cdwy",
- "explain_output",
- "tables_in_query",
- "suggested_index"
- ],
- "fields": [
- {
- "fieldname": "query",
- "fieldtype": "Long Text",
- "label": "Query",
- "reqd": 1
- },
- {
- "fieldname": "site",
- "fieldtype": "Data",
- "in_list_view": 1,
- "label": "Site",
- "reqd": 1
- },
- {
- "fieldname": "tables_in_query",
- "fieldtype": "Table",
- "label": "Tables In Query",
- "options": "MariaDB Analyze Query Tables"
- },
- {
- "fieldname": "suggested_index",
- "fieldtype": "Data",
- "label": "Suggested Index"
- },
- {
- "fieldname": "explain_output",
- "fieldtype": "Code",
- "label": "Explain Output"
- },
- {
- "fieldname": "status",
- "fieldtype": "Data",
- "label": "Status"
- },
- {
- "fieldname": "column_break_holt",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "normalized_query",
- "fieldtype": "Long Text",
- "label": "Normalized Query",
- "reqd": 1
- },
- {
- "fieldname": "section_break_cdwy",
- "fieldtype": "Section Break"
- }
- ],
- "index_web_pages_for_search": 1,
- "links": [],
- "modified": "2024-07-29 17:32:21.578471",
- "modified_by": "Administrator",
- "module": "Press",
- "name": "MariaDB Analyze Query",
- "owner": "Administrator",
- "permissions": [
- {
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "System Manager",
- "share": 1,
- "write": 1
- }
- ],
- "sort_field": "creation",
- "sort_order": "DESC",
- "states": []
-}
\ No newline at end of file
diff --git a/press/press/doctype/mariadb_analyze_query/mariadb_analyze_query.py b/press/press/doctype/mariadb_analyze_query/mariadb_analyze_query.py
deleted file mode 100644
index cb963a42af..0000000000
--- a/press/press/doctype/mariadb_analyze_query/mariadb_analyze_query.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (c) 2024, Frappe and contributors
-# For license information, please see license.txt
-
-# import frappe
-from frappe.model.document import Document
-
-
-class MariaDBAnalyzeQuery(Document):
- # begin: auto-generated types
- # This code is auto-generated. Do not modify anything in this block.
-
- from typing import TYPE_CHECKING
-
- if TYPE_CHECKING:
- from frappe.types import DF
- from press.press.doctype.mariadb_analyze_query_tables.mariadb_analyze_query_tables import (
- MariaDBAnalyzeQueryTables,
- )
-
- explain_output: DF.Code | None
- normalized_query: DF.LongText
- query: DF.LongText
- site: DF.Data
- status: DF.Data | None
- suggested_index: DF.Data | None
- tables_in_query: DF.Table[MariaDBAnalyzeQueryTables]
- # end: auto-generated types
-
- pass
diff --git a/press/press/doctype/mariadb_analyze_query/test_mariadb_analyze_query.py b/press/press/doctype/mariadb_analyze_query/test_mariadb_analyze_query.py
deleted file mode 100644
index 082e41b5b7..0000000000
--- a/press/press/doctype/mariadb_analyze_query/test_mariadb_analyze_query.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright (c) 2024, Frappe and Contributors
-# See license.txt
-
-# import frappe
-from frappe.tests.utils import FrappeTestCase
-
-
-class TestMariaDBAnalyzeQuery(FrappeTestCase):
- pass
diff --git a/press/press/doctype/mariadb_analyze_query_tables/__init__.py b/press/press/doctype/mariadb_analyze_query_tables/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/press/press/doctype/mariadb_analyze_query_tables/mariadb_analyze_query_tables.json b/press/press/doctype/mariadb_analyze_query_tables/mariadb_analyze_query_tables.json
deleted file mode 100644
index dc8bb19960..0000000000
--- a/press/press/doctype/mariadb_analyze_query_tables/mariadb_analyze_query_tables.json
+++ /dev/null
@@ -1,52 +0,0 @@
-{
- "actions": [],
- "allow_rename": 1,
- "creation": "2024-07-21 16:49:47.144539",
- "doctype": "DocType",
- "editable_grid": 1,
- "engine": "InnoDB",
- "field_order": [
- "table",
- "table_statistics",
- "column_statistics",
- "status"
- ],
- "fields": [
- {
- "fieldname": "table",
- "fieldtype": "Data",
- "in_list_view": 1,
- "label": "Table"
- },
- {
- "fieldname": "column_statistics",
- "fieldtype": "Code",
- "in_list_view": 1,
- "label": "Column Statistics"
- },
- {
- "fieldname": "table_statistics",
- "fieldtype": "Code",
- "in_list_view": 1,
- "label": "Table Statistics"
- },
- {
- "fieldname": "status",
- "fieldtype": "Data",
- "in_list_view": 1,
- "label": "Status"
- }
- ],
- "index_web_pages_for_search": 1,
- "istable": 1,
- "links": [],
- "modified": "2024-07-24 11:46:38.741427",
- "modified_by": "Administrator",
- "module": "Press",
- "name": "MariaDB Analyze Query Tables",
- "owner": "Administrator",
- "permissions": [],
- "sort_field": "creation",
- "sort_order": "DESC",
- "states": []
-}
\ No newline at end of file
diff --git a/press/press/doctype/mariadb_analyze_query_tables/mariadb_analyze_query_tables.py b/press/press/doctype/mariadb_analyze_query_tables/mariadb_analyze_query_tables.py
deleted file mode 100644
index c0a058d29d..0000000000
--- a/press/press/doctype/mariadb_analyze_query_tables/mariadb_analyze_query_tables.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (c) 2024, Frappe and contributors
-# For license information, please see license.txt
-
-# import frappe
-from frappe.model.document import Document
-
-
-class MariaDBAnalyzeQueryTables(Document):
- # begin: auto-generated types
- # This code is auto-generated. Do not modify anything in this block.
-
- from typing import TYPE_CHECKING
-
- if TYPE_CHECKING:
- from frappe.types import DF
-
- column_statistics: DF.Code | None
- parent: DF.Data
- parentfield: DF.Data
- parenttype: DF.Data
- status: DF.Data | None
- table: DF.Data | None
- table_statistics: DF.Code | None
- # end: auto-generated types
-
- pass
diff --git a/press/press/doctype/press_settings/press_settings.json b/press/press/doctype/press_settings/press_settings.json
index 71c8c7e90a..56f2644310 100644
--- a/press/press/doctype/press_settings/press_settings.json
+++ b/press/press/doctype/press_settings/press_settings.json
@@ -193,6 +193,7 @@
"column_break_rdlr",
"disable_auto_retry",
"disable_agent_job_deduplication",
+ "enable_email_pre_verification",
"section_break_jstu",
"enable_app_grouping",
"default_apps",
@@ -1249,8 +1250,8 @@
"fieldtype": "Link",
"label": "Press Trial Plan",
"options": "Site Plan"
- },
- {
+ },
+ {
"fieldname": "section_break_jstu",
"fieldtype": "Section Break"
},
@@ -1265,11 +1266,17 @@
"fieldtype": "Table",
"label": "Default Apps",
"options": "App Group"
+ },
+ {
+ "default": "0",
+ "fieldname": "enable_email_pre_verification",
+ "fieldtype": "Check",
+ "label": "Enable Email Pre-Verification"
}
],
"issingle": 1,
"links": [],
- "modified": "2024-10-14 21:02:12.948747",
+ "modified": "2024-12-10 15:07:57.494659",
"modified_by": "Administrator",
"module": "Press",
"name": "Press Settings",
diff --git a/press/press/doctype/press_settings/press_settings.py b/press/press/doctype/press_settings/press_settings.py
index cedb08f91c..bc4c1a559b 100644
--- a/press/press/doctype/press_settings/press_settings.py
+++ b/press/press/doctype/press_settings/press_settings.py
@@ -64,6 +64,7 @@ class PressSettings(Document):
domain: DF.Link | None
eff_registration_email: DF.Data
enable_app_grouping: DF.Check
+ enable_email_pre_verification: DF.Check
enable_google_oauth: DF.Check
enable_site_pooling: DF.Check
enforce_storage_limits: DF.Check
diff --git a/press/press/doctype/proxy_server/proxy_server.json b/press/press/doctype/proxy_server/proxy_server.json
index 6b1b73e31d..cb7a053fd9 100644
--- a/press/press/doctype/proxy_server/proxy_server.json
+++ b/press/press/doctype/proxy_server/proxy_server.json
@@ -18,6 +18,9 @@
"is_self_hosted",
"team",
"public",
+ "storage_section",
+ "auto_add_storage_min",
+ "auto_add_storage_max",
"section_break_8",
"ip",
"enabled_default_routing",
@@ -397,10 +400,31 @@
"fieldname": "public",
"fieldtype": "Check",
"label": "Public"
+ },
+ {
+ "fieldname": "storage_section",
+ "fieldtype": "Section Break",
+ "label": "Storage"
+ },
+ {
+ "default": "10",
+ "description": "Minimum storage to add automatically each time",
+ "fieldname": "auto_add_storage_min",
+ "fieldtype": "Int",
+ "label": "Auto Add Storage Min",
+ "non_negative": 1
+ },
+ {
+ "default": "50",
+ "description": "Maximum storage to add automatically each time",
+ "fieldname": "auto_add_storage_max",
+ "fieldtype": "Int",
+ "label": "Auto Add Storage Max",
+ "non_negative": 1
}
],
"links": [],
- "modified": "2024-09-10 15:44:10.989216",
+ "modified": "2024-12-26 13:20:05.120010",
"modified_by": "Administrator",
"module": "Press",
"name": "Proxy Server",
diff --git a/press/press/doctype/proxy_server/proxy_server.py b/press/press/doctype/proxy_server/proxy_server.py
index f2d77c5f81..6a517662da 100644
--- a/press/press/doctype/proxy_server/proxy_server.py
+++ b/press/press/doctype/proxy_server/proxy_server.py
@@ -1,7 +1,6 @@
-# -*- coding: utf-8 -*-
# Copyright (c) 2020, Frappe and contributors
# For license information, please see license.txt
-
+from __future__ import annotations
from typing import TYPE_CHECKING
@@ -9,13 +8,13 @@
from frappe.utils import unique
from press.agent import Agent
-from press.press.doctype.root_domain.root_domain import RootDomain
from press.press.doctype.server.server import BaseServer
from press.runner import Ansible
from press.utils import log_error
if TYPE_CHECKING:
from press.press.doctype.bench.bench import Bench
+ from press.press.doctype.root_domain.root_domain import RootDomain
class ProxyServer(BaseServer):
@@ -26,11 +25,12 @@ class ProxyServer(BaseServer):
if TYPE_CHECKING:
from frappe.types import DF
- from press.press.doctype.proxy_server_domain.proxy_server_domain import (
- ProxyServerDomain,
- )
+
+ from press.press.doctype.proxy_server_domain.proxy_server_domain import ProxyServerDomain
agent_password: DF.Password | None
+ auto_add_storage_max: DF.Int
+ auto_add_storage_min: DF.Int
cluster: DF.Link | None
disable_agent_job_auto_retry: DF.Check
domain: DF.Link | None
@@ -83,7 +83,7 @@ def validate_domains(self):
code_servers = [row.code_server for row in self.domains]
# Always include self.domain in the domains child table
# Remove duplicates
- domains = unique([self.domain] + domains)
+ domains = unique([self.domain, *domains])
self.domains = []
for i, domain in enumerate(domains):
if not frappe.db.exists(
@@ -133,23 +133,17 @@ def _setup_server(self):
"TLS Certificate", {"wildcard": True, "domain": self.domain}, "name"
)
certificate = frappe.get_doc("TLS Certificate", certificate_name)
- monitoring_password = frappe.get_doc("Cluster", self.cluster).get_password(
- "monitoring_password"
- )
+ monitoring_password = frappe.get_doc("Cluster", self.cluster).get_password("monitoring_password")
log_server = frappe.db.get_single_value("Press Settings", "log_server")
if log_server:
- kibana_password = frappe.get_doc("Log Server", log_server).get_password(
- "kibana_password"
- )
+ kibana_password = frappe.get_doc("Log Server", log_server).get_password("kibana_password")
else:
kibana_password = None
try:
ansible = Ansible(
- playbook="self_hosted_proxy.yml"
- if getattr(self, "is_self_hosted", False)
- else "proxy.yml",
+ playbook="self_hosted_proxy.yml" if getattr(self, "is_self_hosted", False) else "proxy.yml",
server=self,
user=self.ssh_user or "root",
port=self.ssh_port or 22,
@@ -181,9 +175,7 @@ def _setup_server(self):
self.save()
def _install_exporters(self):
- monitoring_password = frappe.get_doc("Cluster", self.cluster).get_password(
- "monitoring_password"
- )
+ monitoring_password = frappe.get_doc("Cluster", self.cluster).get_password("monitoring_password")
try:
ansible = Ansible(
playbook="proxy_exporters.yml",
@@ -201,9 +193,7 @@ def _install_exporters(self):
@frappe.whitelist()
def setup_ssh_proxy(self):
- frappe.enqueue_doc(
- self.doctype, self.name, "_setup_ssh_proxy", queue="long", timeout=1200
- )
+ frappe.enqueue_doc(self.doctype, self.name, "_setup_ssh_proxy", queue="long", timeout=1200)
def _setup_ssh_proxy(self):
settings = frappe.db.get_value(
@@ -238,9 +228,7 @@ def _setup_ssh_proxy(self):
def setup_fail2ban(self):
self.status = "Installing"
self.save()
- frappe.enqueue_doc(
- self.doctype, self.name, "_setup_fail2ban", queue="long", timeout=1200
- )
+ frappe.enqueue_doc(self.doctype, self.name, "_setup_fail2ban", queue="long", timeout=1200)
def _setup_fail2ban(self):
try:
@@ -261,9 +249,7 @@ def _setup_fail2ban(self):
@frappe.whitelist()
def setup_proxysql(self):
- frappe.enqueue_doc(
- self.doctype, self.name, "_setup_proxysql", queue="long", timeout=1200
- )
+ frappe.enqueue_doc(self.doctype, self.name, "_setup_proxysql", queue="long", timeout=1200)
def _setup_proxysql(self):
try:
@@ -294,9 +280,7 @@ def _setup_proxysql(self):
def setup_replication(self):
self.status = "Installing"
self.save()
- frappe.enqueue_doc(
- self.doctype, self.name, "_setup_replication", queue="long", timeout=1200
- )
+ frappe.enqueue_doc(self.doctype, self.name, "_setup_replication", queue="long", timeout=1200)
def _setup_replication(self):
self._setup_secondary()
@@ -351,9 +335,7 @@ def trigger_failover(self):
return
self.status = "Installing"
self.save()
- frappe.enqueue_doc(
- self.doctype, self.name, "_trigger_failover", queue="long", timeout=3600
- )
+ frappe.enqueue_doc(self.doctype, self.name, "_trigger_failover", queue="long", timeout=3600)
def stop_primary(self):
primary = frappe.get_doc("Proxy Server", self.primary)
@@ -387,9 +369,7 @@ def remove_primarys_access(self):
playbook="failover_remove_primary_access.yml",
server=self,
variables={
- "primary_public_key": frappe.db.get_value(
- "Proxy Server", self.primary, "frappe_public_key"
- )
+ "primary_public_key": frappe.db.get_value("Proxy Server", self.primary, "frappe_public_key")
},
)
ansible.run()
@@ -445,9 +425,7 @@ def add_ssh_users_for_existing_benches(self):
bench.add_ssh_user()
def update_app_servers(self):
- frappe.db.set_value(
- "Server", {"proxy_server": self.primary}, "proxy_server", self.name
- )
+ frappe.db.set_value("Server", {"proxy_server": self.primary}, "proxy_server", self.name)
def switch_primary(self):
frappe.db.set_value("Proxy Server", self.primary, "is_primary", False)
@@ -458,9 +436,7 @@ def switch_primary(self):
@frappe.whitelist()
def setup_proxysql_monitor(self):
- frappe.enqueue_doc(
- self.doctype, self.name, "_setup_proxysql_monitor", queue="long", timeout=1200
- )
+ frappe.enqueue_doc(self.doctype, self.name, "_setup_proxysql_monitor", queue="long", timeout=1200)
def _setup_proxysql_monitor(self):
try:
@@ -486,9 +462,7 @@ def _setup_proxysql_monitor(self):
@frappe.whitelist()
def setup_wireguard(self):
if not self.private_ip_interface_id:
- play = frappe.get_last_doc(
- "Ansible Play", {"play": "Ping Server", "server": self.name}
- )
+ play = frappe.get_last_doc("Ansible Play", {"play": "Ping Server", "server": self.name})
task = frappe.get_doc("Ansible Task", {"play": play.name, "task": "Gather Facts"})
import json
@@ -497,9 +471,7 @@ def setup_wireguard(self):
if task_res[i]["ipv4"]["address"] == self.private_ip:
self.private_ip_interface_id = task_res[i]["device"]
self.save()
- frappe.enqueue_doc(
- self.doctype, self.name, "_setup_wireguard", queue="long", timeout=1200
- )
+ frappe.enqueue_doc(self.doctype, self.name, "_setup_wireguard", queue="long", timeout=1200)
def _setup_wireguard(self):
try:
@@ -516,7 +488,7 @@ def _setup_wireguard(self):
"wireguard_private_key": False,
"wireguard_public_key": False,
"peers": "",
- "reload_wireguard": True if self.is_wireguard_setup else False,
+ "reload_wireguard": bool(self.is_wireguard_setup),
},
)
play = ansible.run()
@@ -536,9 +508,7 @@ def _setup_wireguard(self):
@frappe.whitelist()
def reload_wireguard(self):
- frappe.enqueue_doc(
- "Proxy Server", self.name, "_reload_wireguard", queue="default", timeout=1200
- )
+ frappe.enqueue_doc("Proxy Server", self.name, "_reload_wireguard", queue="default", timeout=1200)
def _reload_wireguard(self):
import json
diff --git a/press/press/doctype/server/server.py b/press/press/doctype/server/server.py
index 6631e40da9..cbdf82d9c9 100644
--- a/press/press/doctype/server/server.py
+++ b/press/press/doctype/server/server.py
@@ -15,6 +15,7 @@
from frappe.core.utils import find, find_all
from frappe.installer import subprocess
from frappe.model.document import Document
+from frappe.utils import cint
from frappe.utils.user import is_system_user
from press.agent import Agent
@@ -634,7 +635,7 @@ def create_subscription_for_storage(self, increment: int) -> None:
"Subscription",
existing_subscription.name,
"additional_storage",
- increment + int(existing_subscription.additional_storage),
+ increment + cint(existing_subscription.additional_storage),
)
else:
frappe.get_doc(
diff --git a/press/press/doctype/site/site.py b/press/press/doctype/site/site.py
index 39fd53254d..c6360ef912 100644
--- a/press/press/doctype/site/site.py
+++ b/press/press/doctype/site/site.py
@@ -13,6 +13,8 @@
import dateutil.parser
import frappe
+import frappe.data
+import frappe.utils
import pytz
import requests
from frappe import _
@@ -68,6 +70,9 @@
from press.press.doctype.site_activity.site_activity import log_site_activity
from press.press.doctype.site_analytics.site_analytics import create_site_analytics
from press.press.doctype.site_plan.site_plan import get_plan_config
+from press.press.report.mariadb_slow_queries.mariadb_slow_queries import (
+ get_doctype_name,
+)
from press.utils import (
convert,
fmt_timedelta,
@@ -2265,10 +2270,92 @@ def get_update_information(self):
out.update_available = any([app["update_available"] for app in out.apps])
return out
- @frappe.whitelist()
- def optimize_tables(self):
+ def fetch_running_optimize_tables_job(self):
+ return frappe.db.exists(
+ "Agent Job",
+ {
+ "site": self.name,
+ "job_type": "Optimize Tables",
+ "status": ["in", ["Undelivered", "Running", "Pending"]],
+ },
+ )
+
+ @dashboard_whitelist()
+ def optimize_tables(self, ignore_checks: bool = False):
+ if not ignore_checks:
+ # check for running `Optimize Tables` agent job
+ if job := self.fetch_running_optimize_tables_job():
+ return {
+ "success": True,
+ "message": "Optimize Tables job is already running on this site.",
+ "job_name": job,
+ }
+ # check if `Optimize Tables` has run in last 1 hour
+ recent_agent_job_name = frappe.db.exists(
+ "Agent Job",
+ {
+ "site": self.name,
+ "job_type": "Optimize Tables",
+ "status": ["not in", ["Failure", "Delivery Failure"]],
+ "creation": [">", frappe.utils.add_to_date(frappe.utils.now_datetime(), hours=-1)],
+ },
+ )
+ if recent_agent_job_name:
+ return {
+ "success": False,
+ "message": "Optimize Tables job has already run in the last 1 hour. Try later.",
+ "job_name": None,
+ }
+
agent = Agent(self.server)
- agent.optimize_tables(self)
+ job_name = agent.optimize_tables(self).name
+ return {
+ "success": True,
+ "message": "Optimize Tables has been triggered on this site.",
+ "job_name": job_name,
+ }
+
+ @dashboard_whitelist()
+ def get_database_performance_report(self):
+ from press.press.report.mariadb_slow_queries.mariadb_slow_queries import get_data as get_slow_queries
+
+ agent = Agent(self.server)
+ result = agent.get_summarized_performance_report_of_database(self)
+ # fetch slow queries of last 7 days
+ slow_queries = get_slow_queries(
+ frappe._dict(
+ {
+ "database": self.database_name,
+ "start_datetime": frappe.utils.add_to_date(None, days=-7),
+ "stop_datetime": frappe.utils.now_datetime(),
+ "search_pattern": ".*",
+ "max_lines": 2000,
+ "normalize_queries": True,
+ }
+ )
+ )
+ # remove `parent` & `creation` indexes from unused_indexes
+ result["unused_indexes"] = [
+ index
+ for index in result.get("unused_indexes", [])
+ if index["index_name"] not in ["parent", "creation"]
+ ]
+
+ # convert all the float to int
+ for query in slow_queries:
+ for key, value in query.items():
+ if isinstance(value, float):
+ query[key] = int(value)
+ # sort the slow queries by `rows_examined`
+ result["slow_queries"] = sorted(slow_queries, key=lambda x: x["rows_examined"], reverse=True)
+ result["is_performance_schema_enabled"] = False
+ if database_server := frappe.db.get_value("Server", self.server, "database_server"):
+ result["is_performance_schema_enabled"] = frappe.db.get_value(
+ "Database Server",
+ database_server,
+ "is_performance_schema_enabled",
+ )
+ return result
@property
def server_logs(self):
@@ -2625,19 +2712,66 @@ def forcefully_remove_site(self, bench):
@dashboard_whitelist()
def fetch_database_table_schema(self, reload=False):
- if not frappe.db.exists("Site Database Table Schema", {"site": self.name}):
- frappe.get_doc({"doctype": "Site Database Table Schema", "site": self.name}).insert(
- ignore_permissions=True
- )
+ """
+ Store dump in redis cache
+ """
+ key_for_schema = f"database_table_schema__data:{self.name}"
+ key_for_schema_status = (
+ f"database_table_schema__status:{self.name}" # 1 - loading, 2 - done, None - not available
+ )
+
+ if reload:
+ frappe.cache().delete_value(key_for_schema)
+ frappe.cache().delete_value(key_for_schema_status)
+
+ status = frappe.utils.cint(frappe.cache().get_value(key_for_schema_status))
+ if status:
+ if status == 1:
+ return {
+ "loading": True,
+ "data": [],
+ }
+ if status == 2:
+ return {
+ "loading": False,
+ "data": json.loads(frappe.cache().get_value(key_for_schema)),
+ }
- doc = frappe.get_doc("Site Database Table Schema", {"site": self.name})
- loading, data = doc.fetch(reload)
+ # Check if any agent job is created within 5 minutes and in pending/running condition
+ # Checks to prevent duplicate agent job creation due to race condition
+ if not frappe.db.exists(
+ "Agent Job",
+ {
+ "job_type": "Fetch Database Table Schema",
+ "site": self.name,
+ "status": ["in", ["Undelivered", "Pending", "Running"]],
+ "creation": (">", frappe.utils.add_to_date(None, minutes=-5)),
+ },
+ ):
+ # create the agent job and put it in loading state
+ frappe.cache().set_value(key_for_schema_status, 1, expires_in_sec=600)
+ Agent(self.server).fetch_database_table_schema(
+ self, include_index_info=True, include_table_size=True
+ )
return {
- "loading": loading,
- "data": data,
- "last_updated": doc.last_updated,
+ "loading": True,
+ "data": [],
}
+ @dashboard_whitelist()
+ def fetch_database_processes(self):
+ agent = Agent(self.server)
+ if agent.should_skip_requests():
+ return None
+ return agent.fetch_database_processes(self)
+
+ @dashboard_whitelist()
+ def kill_database_process(self, id):
+ agent = Agent(self.server)
+ if agent.should_skip_requests():
+ return None
+ return agent.kill_database_process(self, id)
+
@dashboard_whitelist()
def run_sql_query_in_database(self, query: str, commit: bool):
if not query:
@@ -2656,6 +2790,88 @@ def run_sql_query_in_database(self, query: str, commit: bool):
doc.insert(ignore_permissions=True)
return response
+ @dashboard_whitelist()
+ def suggest_database_indexes(self):
+ from press.press.report.mariadb_slow_queries.mariadb_slow_queries import get_data as get_slow_queries
+
+ existing_agent_job_name = frappe.db.exists(
+ "Agent Job",
+ {
+ "site": self.name,
+ "status": ("not in", ("Failure", "Delivery Failure")),
+ "job_type": "Analyze Slow Queries",
+ "creation": (
+ ">",
+ frappe.utils.add_to_date(None, minutes=-30),
+ ),
+ "retry_count": 0,
+ },
+ )
+
+ if existing_agent_job_name:
+ existing_agent_job = frappe.get_doc("Agent Job", existing_agent_job_name)
+ if existing_agent_job.status == "Success":
+ return {
+ "loading": False,
+ "data": json.loads(existing_agent_job.data).get("result", []),
+ }
+ return {
+ "loading": True,
+ "data": [],
+ }
+
+ # fetch slow queries of last 7 days
+ slow_queries = get_slow_queries(
+ frappe._dict(
+ {
+ "database": self.database_name,
+ "start_datetime": frappe.utils.add_to_date(None, days=-7),
+ "stop_datetime": frappe.utils.now_datetime(),
+ "search_pattern": ".*",
+ "max_lines": 1000,
+ "normalize_queries": True,
+ }
+ )
+ )
+ slow_queries = [{"example": x["example"], "normalized": x["query"]} for x in slow_queries]
+ if len(slow_queries) == 0:
+ return {
+ "loading": False,
+ "data": [],
+ }
+ agent = Agent(self.server)
+ agent.analyze_slow_queries(self, slow_queries)
+
+ return {
+ "loading": True,
+ "data": [],
+ }
+
+ @dashboard_whitelist()
+ def add_database_index(self, table, column):
+ record = frappe.db.exists(
+ "Agent Job",
+ {
+ "site": self.name,
+ "status": ["in", ["Undelivered", "Running", "Pending"]],
+ "job_type": "Add Database Index",
+ },
+ )
+ if record:
+ return {
+ "success": False,
+ "message": "There is already a job running for adding database index. Please wait until finished.",
+ "job_name": record,
+ }
+ doctype = get_doctype_name(table)
+ agent = Agent(self.server)
+ job = agent.add_database_index(self, doctype=doctype, columns=[column])
+ return {
+ "success": True,
+ "message": "Database index will be added on site.",
+ "job_name": job.name,
+ }
+
def site_cleanup_after_archive(site):
delete_site_domains(site)
@@ -2689,6 +2905,51 @@ def release_name(name):
frappe.rename_doc("Site", name, new_name)
+def process_fetch_database_table_schema_job_update(job):
+ key_for_schema = f"database_table_schema__data:{job.site}"
+ key_for_schema_status = (
+ f"database_table_schema__status:{job.site}" # 1 - loading, 2 - done, None - not available
+ )
+
+ if job.status in ["Failure", "Delivery Failure"]:
+ frappe.cache().delete_value(key_for_schema)
+ frappe.cache().delete_value(key_for_schema_status)
+ return
+
+ if job.status == "Success":
+ """
+ Support old agent versions
+ Remove this once all agents are updated
+ """
+ data = json.loads(job.data)
+ is_old_agent = False
+
+ if len(data) > 0 and isinstance(data[next(iter(data.keys()))], list):
+ is_old_agent = True
+
+ if is_old_agent:
+ data_copy = data.copy()
+ data = {}
+ for key, value in data_copy.items():
+ data[key] = {
+ "columns": value,
+ "size": {
+ "data_length": 0,
+ "index_length": 0,
+ "total_size": 0,
+ }, # old agent api doesn't have size info
+ }
+ for column in data[key]["columns"]:
+ column["index_info"] = {
+ "index_usage": {x: 0 for x in column["indexes"]}, # just fill some dummy value
+ "indexes": column["indexes"],
+ "is_indexed": len(column["indexes"]) > 0,
+ }
+
+ frappe.cache().set_value(key_for_schema, json.dumps(data), expires_in_sec=6000)
+ frappe.cache().set_value(key_for_schema_status, 2, expires_in_sec=6000)
+
+
def process_new_site_job_update(job): # noqa: C901
site_status = frappe.get_value("Site", job.site, "status", for_update=True)
diff --git a/press/press/doctype/site_database_table_schema/__init__.py b/press/press/doctype/site_database_table_schema/__init__.py
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/press/press/doctype/site_database_table_schema/site_database_table_schema.js b/press/press/doctype/site_database_table_schema/site_database_table_schema.js
deleted file mode 100644
index 4747337e12..0000000000
--- a/press/press/doctype/site_database_table_schema/site_database_table_schema.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright (c) 2024, Frappe and contributors
-// For license information, please see license.txt
-
-// frappe.ui.form.on("Site Database Table Schema", {
-// refresh(frm) {
-
-// },
-// });
diff --git a/press/press/doctype/site_database_table_schema/site_database_table_schema.json b/press/press/doctype/site_database_table_schema/site_database_table_schema.json
deleted file mode 100644
index 7917ec3755..0000000000
--- a/press/press/doctype/site_database_table_schema/site_database_table_schema.json
+++ /dev/null
@@ -1,91 +0,0 @@
-{
- "actions": [],
- "creation": "2024-10-28 11:45:28.634612",
- "doctype": "DocType",
- "engine": "InnoDB",
- "field_order": [
- "site",
- "column_break_mufi",
- "agent_job",
- "section_break_heok",
- "schema_json"
- ],
- "fields": [
- {
- "fieldname": "site",
- "fieldtype": "Link",
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Site",
- "options": "Site",
- "reqd": 1,
- "unique": 1
- },
- {
- "fieldname": "agent_job",
- "fieldtype": "Link",
- "in_list_view": 1,
- "in_standard_filter": 1,
- "label": "Agent Job",
- "options": "Agent Job"
- },
- {
- "fieldname": "column_break_mufi",
- "fieldtype": "Column Break"
- },
- {
- "fieldname": "section_break_heok",
- "fieldtype": "Section Break"
- },
- {
- "default": "{}",
- "fieldname": "schema_json",
- "fieldtype": "Long Text",
- "label": "Schema JSON",
- "reqd": 1
- }
- ],
- "index_web_pages_for_search": 1,
- "links": [],
- "modified": "2024-10-28 15:43:58.768773",
- "modified_by": "Administrator",
- "module": "Press",
- "name": "Site Database Table Schema",
- "owner": "Administrator",
- "permissions": [
- {
- "create": 1,
- "delete": 1,
- "email": 1,
- "export": 1,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "System Manager",
- "share": 1,
- "write": 1
- },
- {
- "email": 1,
- "export": 1,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Press Admin",
- "share": 1
- },
- {
- "email": 1,
- "export": 1,
- "print": 1,
- "read": 1,
- "report": 1,
- "role": "Press Member",
- "share": 1
- }
- ],
- "sort_field": "creation",
- "sort_order": "DESC",
- "states": [],
- "title_field": "site"
-}
\ No newline at end of file
diff --git a/press/press/doctype/site_database_table_schema/site_database_table_schema.py b/press/press/doctype/site_database_table_schema/site_database_table_schema.py
deleted file mode 100644
index cf13d99e5c..0000000000
--- a/press/press/doctype/site_database_table_schema/site_database_table_schema.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# Copyright (c) 2024, Frappe and contributors
-# For license information, please see license.txt
-from __future__ import annotations
-
-import json
-from typing import TYPE_CHECKING
-
-import frappe
-from frappe.model.document import Document
-
-from press.agent import Agent
-
-if TYPE_CHECKING:
- from press.press.doctype.site_migration.site_migration import AgentJob
-
-
-class SiteDatabaseTableSchema(Document):
- # begin: auto-generated types
- # This code is auto-generated. Do not modify anything in this block.
-
- from typing import TYPE_CHECKING
-
- if TYPE_CHECKING:
- from frappe.types import DF
-
- agent_job: DF.Link | None
- schema_json: DF.LongText
- site: DF.Link
- # end: auto-generated types
-
- def fetch(self, reload=False) -> tuple[bool, dict]:
- """
- This function will return the schema of the database table
-
- Args:
- reload: bool - if True, it will fetch the schema from the server again
-
- Returns:
- tuple[bool, list]
- - 1st element: bool - Loading status
- - 2nd element: dict - Dictionary of table schemas
- Example -
- {
- "__Auth": [
- {
- "column": "doctype",
- "data_type": "varchar",
- "default": "NULL",
- "indexes": [
- "PRIMARY"
- ],
- "is_nullable": false
- },
- ....
- ],
- ....
- }
- """
- if len(self.schema) > 0 and not reload:
- return False, self.schema
-
- if self.agent_job is not None and frappe.get_value("Agent Job", self.agent_job, "status") in [
- "Undelivered",
- "Pending",
- "Running",
- ]:
- return True, {}
-
- self.schema_json = "{}"
- site = frappe.get_doc("Site", self.site)
- self.agent_job = Agent(site.server).fetch_database_table_schema(site).name
- self.save(ignore_permissions=True)
-
- return True, {}
-
- @property
- def last_updated(self) -> str:
- return self.modified or self.creation
-
- @property
- def schema(self) -> dict:
- try:
- return json.loads(self.schema_json)
- except frappe.DoesNotExistError:
- return {}
-
- @staticmethod
- def process_job_update(job: "AgentJob"):
- if job.status != "Success":
- return
- response_data = json.loads(job.data) or {}
- if response_data and frappe.db.exists("Site Database Table Schema", {"site": job.site}):
- doc = frappe.get_doc("Site Database Table Schema", {"site": job.site})
- doc.schema_json = json.dumps(response_data)
- doc.save(ignore_permissions=True)
diff --git a/press/press/doctype/site_database_table_schema/test_site_database_table_schema.py b/press/press/doctype/site_database_table_schema/test_site_database_table_schema.py
deleted file mode 100644
index b75f628d81..0000000000
--- a/press/press/doctype/site_database_table_schema/test_site_database_table_schema.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (c) 2024, Frappe and Contributors
-# See license.txt
-
-# import frappe
-from frappe.tests import UnitTestCase
-
-# On IntegrationTestCase, the doctype test records and all
-# link-field test record depdendencies are recursively loaded
-# Use these module variables to add/remove to/from that list
-EXTRA_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
-IGNORE_TEST_RECORD_DEPENDENCIES = [] # eg. ["User"]
-
-
-class TestSiteDatabaseTableSchema(UnitTestCase):
- """
- Unit tests for SiteDatabaseTableSchema.
- Use this class for testing individual functions and methods.
- """
-
- pass
diff --git a/press/press/doctype/subscription/subscription.py b/press/press/doctype/subscription/subscription.py
index e85364a2be..fd707a178b 100644
--- a/press/press/doctype/subscription/subscription.py
+++ b/press/press/doctype/subscription/subscription.py
@@ -7,6 +7,7 @@
import rq
from frappe.model.document import Document
from frappe.query_builder.functions import Coalesce, Count
+from frappe.utils import cint
from press.overrides import get_permission_query_conditions_for_doctype
from press.press.doctype.site_plan.site_plan import SitePlan
@@ -127,12 +128,12 @@ def disable(self):
frappe.log_error(title="Disable Subscription Error")
@frappe.whitelist()
- def create_usage_record(self):
+ def create_usage_record(self, date: DF.Date | None = None):
cannot_charge = not self.can_charge_for_subscription()
if cannot_charge:
return None
- if self.is_usage_record_created():
+ if self.is_usage_record_created(date):
return None
team = frappe.get_cached_doc("Team", self.team)
@@ -151,7 +152,7 @@ def create_usage_record(self):
if self.additional_storage:
price = plan.price_inr if team.currency == "INR" else plan.price_usd
price_per_day = price / plan.period # no rounding off to avoid discrepancies
- amount = price_per_day * int(self.additional_storage)
+ amount = price_per_day * cint(self.additional_storage)
else:
amount = plan.get_price_for_interval(self.interval, team.currency)
@@ -163,6 +164,7 @@ def create_usage_record(self):
plan_type=self.plan_type,
plan=plan.name,
amount=amount,
+ date=date,
subscription=self.name,
interval=self.interval,
site=(
@@ -186,7 +188,7 @@ def can_charge_for_subscription(self):
return True
- def is_usage_record_created(self):
+ def is_usage_record_created(self, date=None):
filters = {
"team": self.team,
"document_type": self.document_type,
@@ -197,7 +199,8 @@ def is_usage_record_created(self):
}
if self.interval == "Daily":
- filters.update({"date": frappe.utils.today()})
+ date = date or frappe.utils.today()
+ filters.update({"date": date})
if self.interval == "Monthly":
date = frappe.utils.getdate()
diff --git a/press/press/doctype/team/team.py b/press/press/doctype/team/team.py
index 546d9cb06d..542b989e64 100644
--- a/press/press/doctype/team/team.py
+++ b/press/press/doctype/team/team.py
@@ -111,6 +111,7 @@ class Team(Document):
"is_developer",
"enable_performance_tuning",
"enable_inplace_updates",
+ "servers_enabled",
)
def get_doc(self, doc):
@@ -1094,7 +1095,9 @@ def suspend_sites(self, reason=None):
def get_sites_to_suspend(self):
plan = frappe.qb.DocType("Site Plan")
query = (
- frappe.qb.from_(plan).select(plan.name).where((plan.enabled == 1) & ((plan.is_frappe_plan == 1) | (plan.is_trial_plan == 1)))
+ frappe.qb.from_(plan)
+ .select(plan.name)
+ .where((plan.enabled == 1) & ((plan.is_frappe_plan == 1) | (plan.is_trial_plan == 1)))
).run(as_dict=True)
frappe_plans = [d.name for d in query]
diff --git a/press/press/doctype/virtual_disk_snapshot/virtual_disk_snapshot.py b/press/press/doctype/virtual_disk_snapshot/virtual_disk_snapshot.py
index 2ba94babf8..55c88c9505 100644
--- a/press/press/doctype/virtual_disk_snapshot/virtual_disk_snapshot.py
+++ b/press/press/doctype/virtual_disk_snapshot/virtual_disk_snapshot.py
@@ -184,6 +184,7 @@ def sync_all_snapshots_from_aws():
if _should_skip_snapshot(snapshot):
continue
try:
+ delete_duplicate_snapshot_docs(snapshot)
if _update_snapshot_if_exists(snapshot, random_snapshot):
continue
tag_name = next(tag["Value"] for tag in snapshot["Tags"] if tag["Key"] == "Name")
@@ -238,6 +239,23 @@ def _should_skip_snapshot(snapshot):
return False
+def delete_duplicate_snapshot_docs(snapshot):
+ # Delete all except one snapshot document
+ # It doesn't matter which one we keep
+ snapshot_id = snapshot["SnapshotId"]
+ snapshot_count = frappe.db.count("Virtual Disk Snapshot", {"snapshot_id": snapshot_id})
+ if snapshot_count > 1:
+ frappe.db.sql(
+ """
+ DELETE
+ FROM `tabVirtual Disk Snapshot`
+ WHERE snapshot_id=%s
+ LIMIT %s
+ """,
+ (snapshot_id, snapshot_count - 1),
+ )
+
+
def _update_snapshot_if_exists(snapshot, random_snapshot):
snapshot_id = snapshot["SnapshotId"]
if frappe.db.exists("Virtual Disk Snapshot", {"snapshot_id": snapshot_id}):
diff --git a/press/press/report/mariadb_deadlock_browser/mariadb_deadlock_browser.py b/press/press/report/mariadb_deadlock_browser/mariadb_deadlock_browser.py
index d0afa62572..3c58a3e5ac 100644
--- a/press/press/report/mariadb_deadlock_browser/mariadb_deadlock_browser.py
+++ b/press/press/report/mariadb_deadlock_browser/mariadb_deadlock_browser.py
@@ -248,7 +248,7 @@ def deadlock_summary(transactions: list[DatabaseTransactionLog]) -> list[dict]:
def execute(filters=None):
- frappe.only_for(["System Manager", "Site Manager"])
+ frappe.only_for(["System Manager", "Site Manager", "Press Admin", "Press Member"])
filters.database = frappe.db.get_value("Site", filters.site, "database_name")
if not filters.database:
frappe.throw(
diff --git a/press/press/report/mariadb_slow_queries/db_optimizer.py b/press/press/report/mariadb_slow_queries/db_optimizer.py
deleted file mode 100644
index 36f6ad5afb..0000000000
--- a/press/press/report/mariadb_slow_queries/db_optimizer.py
+++ /dev/null
@@ -1,352 +0,0 @@
-"""Basic DB optimizer for Frappe Framework based app.
-
-This is largely based on heuristics and known good practices for indexing.
-"""
-
-from collections import defaultdict
-from dataclasses import dataclass
-from typing import Literal
-import re
-import frappe
-from frappe.utils import cint, cstr, flt
-from sql_metadata import Parser
-
-# Any index that reads more than 30% table on average is not "useful"
-INDEX_SCORE_THRESHOLD = 0.3
-# Anything reading less than this percent of table is considered optimal
-OPTIMIZATION_THRESHOLD = 0.1
-
-
-@dataclass
-class DBExplain:
- # refer: https://mariadb.com/kb/en/explain/
- # Anything not explicitly encoded here is likely not supported.
- select_type: Literal["SIMPLE", "PRIMARY", "SUBQUERY", "UNION", "DERIVED"]
- table: str
- scan_type: Literal[ # What type of scan will be performed
- "ALL", # Full table scan
- "CONST", # Single row will be read
- "EQ_REF", # A single row is found from *unique* index
- "REF", # Index is used, but MIGHT hit more than 1 rows as it's non-unique
- "RANGE", # The table will be accessed with a key over one or more value ranges.
- "INDEX_MERGE", # multiple indexes are used and merged smartly. Equivalent to RANGE
- "INDEX_SUBQUERY",
- "INDEX", # Full index scan is performed. Similar to full table scan in case of large number of rows.
- "REF_OR_NULL",
- "UNIQUE_SUBQUERY",
- "FULLTEXT", # Full text index is used,
- ]
- possible_keys: list[str] | None = None # possible indexes that can be used
- key: str | None = None # This index is being used
- key_len: int | None = None # How many prefix bytes from index are being used
- ref: str | None = None # is reference constant or some other column
- rows: int = 0 # roughly how many rows will be examined
- extra: str | None = None
-
- @classmethod
- def from_frappe_ouput(cls, data) -> "DBExplain":
- return cls(
- select_type=cstr(data["select_type"]).upper(),
- table=data["table"],
- scan_type=cstr(data["type"]).upper(),
- possible_keys=data["possible_keys"],
- key=data["key"],
- key_len=cint(data["key_len"]) if data["key_len"] else None,
- ref=data["ref"],
- rows=cint(data["rows"]),
- extra=data.get("Extra"),
- )
-
-
-@dataclass
-class DBColumn:
- name: str
- cardinality: int | None
- is_nullable: bool
- default: str
- data_type: str
-
- @classmethod
- def from_frappe_ouput(cls, data) -> "DBColumn":
- "Parse DBColumn from output of describe-database-table command in Frappe"
- return cls(
- name=data["column"],
- cardinality=data.get("cardinality"),
- is_nullable=data["is_nullable"],
- default=data["default"],
- data_type=data["type"],
- )
-
-
-@dataclass
-class DBIndex:
- name: str
- column: str
- table: str
- unique: bool | None = None
- cardinality: int | None = None
- sequence: int = 1
- nullable: bool = True
- _score: float = 0.0
-
- def __eq__(self, other: "DBIndex") -> bool:
- return (
- self.column == other.column
- and self.sequence == other.sequence
- and self.table == other.table
- )
-
- def __repr__(self):
- return f"DBIndex(`{self.table}`.`{self.column}`)"
-
- @classmethod
- def from_frappe_ouput(cls, data, table) -> "DBIndex":
- "Parse DBIndex from output of describe-database-table command in Frappe"
- return cls(
- name=data["name"],
- table=table,
- unique=data["unique"],
- cardinality=data["cardinality"],
- sequence=data["sequence"],
- nullable=data["nullable"],
- column=data["column"],
- )
-
-
-@dataclass
-class ColumnStat:
- column_name: str
- avg_frequency: float
- avg_length: float
- nulls_ratio: float | None = None
- histogram: list[float] = None
-
- def __post_init__(self):
- if not self.histogram:
- self.histogram = []
-
- @classmethod
- def from_frappe_ouput(cls, data) -> "ColumnStat":
- return cls(
- column_name=data["column_name"],
- avg_frequency=data["avg_frequency"],
- avg_length=data["avg_length"],
- nulls_ratio=data["nulls_ratio"],
- histogram=[flt(bin) for bin in data["histogram"].split(",")]
- if data["histogram"]
- else [],
- )
-
-
-@dataclass
-class DBTable:
- name: str
- total_rows: int
- schema: list[DBColumn] | None = None
- indexes: list[DBIndex] | None = None
-
- def __post_init__(self):
- if not self.schema:
- self.schema = []
- if not self.indexes:
- self.indexes = []
-
- def update_cardinality(self, column_stats: list[ColumnStat]) -> None:
- """Estimate cardinality using mysql.column_stat"""
- for column_stat in column_stats:
- for col in self.schema:
- if (
- col.name == column_stat.column_name
- and not col.cardinality
- and column_stat.avg_frequency
- ):
- # "hack" or "math" - average frequency is on average how frequently a row value appears.
- # Avg = total_rows / cardinality, so...
- col.cardinality = self.total_rows / column_stat.avg_frequency
-
- @classmethod
- def from_frappe_ouput(cls, data) -> "DBTable":
- "Parse DBTable from output of describe-database-table command in Frappe"
- table_name = data["table_name"]
- return cls(
- name=table_name,
- total_rows=data["total_rows"],
- schema=[DBColumn.from_frappe_ouput(c) for c in data["schema"]],
- indexes=[DBIndex.from_frappe_ouput(i, table_name) for i in data["indexes"]],
- )
-
- def has_column(self, column: str) -> bool:
- for col in self.schema:
- if col.name == column:
- return True
- return False
-
-
-@dataclass
-class DBOptimizer:
- query: str # raw query in string format
- explain_plan: list[DBExplain] = None
- tables: dict[str, DBTable] = None
- parsed_query: Parser = None
-
- def __post_init__(self):
- if not self.explain_plan:
- self.explain_plan = []
- if not self.tables:
- self.tables = {}
- for explain_entry in self.explain_plan:
- explain_entry.select_type = explain_entry.select_type.upper()
- explain_entry.scan_type = explain_entry.scan_type.upper()
- self.parsed_query = Parser(re.sub(r'"(\S+)"', r"'\1'", self.query))
-
- @property
- def tables_examined(self) -> list[str]:
- return self.parsed_query.tables
-
- def update_table_data(self, table: DBTable):
- self.tables[table.name] = table
-
- def potential_indexes(self) -> list[DBIndex]:
- """Get all columns that can potentially be indexed to speed up this query."""
-
- possible_indexes = []
-
- # Where claus columns using these operators benefit from index
- # 1. = (equality)
- # 2. >, <, >=, <=
- # 3. LIKE 'xyz%' (Prefix search)
- # 4. BETWEEN (for date[time] fields)
- # 5. IN (similar to equality)
- if where_columns := self.parsed_query.columns_dict.get("where"):
- # TODO: Apply some heuristics here, not all columns in where clause are actually useful
- possible_indexes.extend(where_columns)
-
- # Join clauses - Both sides of join should ideally be indexed. One will *usually* be primary key.
- if join_columns := self.parsed_query.columns_dict.get("join"):
- possible_indexes.extend(join_columns)
-
- # Top N query variant - Order by column can possibly speed up the query
- if order_by_columns := self.parsed_query.columns_dict.get("order_by"):
- if self.parsed_query.limit_and_offset:
- possible_indexes.extend(order_by_columns)
-
- possible_db_indexes = [self._convert_to_db_index(i) for i in possible_indexes]
- possible_db_indexes = [
- i for i in possible_db_indexes if i.column not in ("*", "name")
- ]
- possible_db_indexes.sort(key=lambda i: (i.table, i.column))
-
- return self._remove_existing_indexes(possible_db_indexes)
-
- def _convert_to_db_index(self, column: str) -> DBIndex:
- column_name, table = None, None
-
- if "." in column:
- table, column_name = column.split(".")
- else:
- column_name = column
- for table_name, db_table in self.tables.items():
- if db_table.has_column(column):
- table = table_name
- break
- return DBIndex(column=column_name, name=column_name, table=table)
-
- def _remove_existing_indexes(self, potential_indexes: list[DBIndex]) -> list[DBIndex]:
- """Given list of potential index candidates remove the ones that already exist.
-
- This also removes multi-column indexes for parts that are applicable to query.
- Example: If multi-col index A+B+C exists and query utilizes A+B then
- A+B are removed from potential indexes.
- """
-
- def remove_maximum_indexes(idx: list[DBIndex]):
- """Try to remove entire index from potential indexes, if not possible, reduce one part and try again until no parts are left."""
- if not idx:
- return
- matched_sub_index = []
- for idx_part in list(idx):
- matching_part = [
- i
- for i in potential_indexes
- if i.column == idx_part.column and i.table == idx_part.table
- ]
- if not matching_part:
- # pop and recurse
- idx.pop()
- return remove_maximum_indexes(idx)
- else:
- matched_sub_index.extend(matching_part)
-
- # Every part matched now, lets remove those parts
- for i in matched_sub_index:
- potential_indexes.remove(i)
-
- # Reconstruct multi-col index
- for table in self.tables.values():
- merged_indexes = defaultdict(list)
- for index in table.indexes:
- merged_indexes[index.name].append(index)
-
- for idx in merged_indexes.values():
- idx.sort(key=lambda x: x.sequence)
-
- for idx in merged_indexes.values():
- remove_maximum_indexes(idx)
- return potential_indexes
-
- def suggest_index(self) -> DBIndex | None:
- """Suggest best possible column to index given query and table stats."""
- if missing_tables := (set(self.tables_examined) - set(self.tables.keys())):
- frappe.throw("DBTable infomation missing for: " + ", ".join(missing_tables))
-
- potential_indexes = self.potential_indexes()
-
- for index in list(potential_indexes):
- table = self.tables[index.table]
-
- # Data type is not easily indexable - skip
- column = [c for c in table.schema if c.name == index.column][0]
- if "text" in column.data_type.lower() or "json" in column.data_type.lower():
- potential_indexes.remove(index)
- # Update cardinality from column so scoring can be done
- index.cardinality = column.cardinality
-
- for index in potential_indexes:
- index._score = self.index_score(index)
-
- potential_indexes.sort(key=lambda i: i._score)
- if (
- potential_indexes
- and (best_index := potential_indexes[0])
- and best_index._score < INDEX_SCORE_THRESHOLD
- ):
- return best_index
-
- def index_score(self, index: DBIndex) -> float:
- """Score an index from 0 to 1 based on usefulness.
-
- A score of 0.5 indicates on average this index will read 50% of the table. (e.g. checkboxes)"""
- table = self.tables[index.table]
-
- cardinality = index.cardinality or 2
- total_rows = table.total_rows or cardinality or 1
-
- # We assume most unique values are evenly distributed, this is
- # definitely not the case IRL but it should be good enough assumptions
- # Score is rouhgly what percentage of table we will end up reading on typical query
- rows_fetched_on_average = (table.total_rows or cardinality) / cardinality
- return rows_fetched_on_average / total_rows
-
- def can_be_optimized(self) -> bool:
- """Return true if it's worth optimizeing.
-
- Few cases can not be optimized any further. E.g. ref/eq_ref/cost type
- of queries. Assume that anything that reads <10% of table already is
- not possible to truly optimize with these heuristics."""
- for explain in self.explain_plan:
- for table in self.tables.values():
- if table.name != explain.table:
- continue
- if (explain.rows / table.total_rows) > OPTIMIZATION_THRESHOLD:
- return True
- return False
diff --git a/press/press/report/mariadb_slow_queries/mariadb_slow_queries.json b/press/press/report/mariadb_slow_queries/mariadb_slow_queries.json
index 5897aaffd9..d32316c08f 100644
--- a/press/press/report/mariadb_slow_queries/mariadb_slow_queries.json
+++ b/press/press/report/mariadb_slow_queries/mariadb_slow_queries.json
@@ -1,15 +1,15 @@
{
"add_total_row": 0,
"columns": [],
- "creation": "2021-11-01 19:16:08.357082",
- "disable_prepared_report": 0,
+ "creation": "2024-12-23 11:36:40.301426",
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"filters": [],
"idx": 0,
"is_standard": "Yes",
- "modified": "2022-11-08 17:10:41.382656",
+ "letterhead": null,
+ "modified": "2024-12-23 11:36:40.301426",
"modified_by": "Administrator",
"module": "Press",
"name": "MariaDB Slow Queries",
@@ -25,5 +25,6 @@
{
"role": "Site Manager"
}
- ]
+ ],
+ "timeout": 0
}
\ No newline at end of file
diff --git a/press/press/report/mariadb_slow_queries/mariadb_slow_queries.py b/press/press/report/mariadb_slow_queries/mariadb_slow_queries.py
index 902c4cd70c..a546e699db 100644
--- a/press/press/report/mariadb_slow_queries/mariadb_slow_queries.py
+++ b/press/press/report/mariadb_slow_queries/mariadb_slow_queries.py
@@ -3,28 +3,16 @@
from __future__ import annotations
-import json
import re
from collections import defaultdict
-from dataclasses import dataclass
import frappe
import requests
import sqlparse
from frappe.core.doctype.access_log.access_log import make_access_log
from frappe.utils import convert_utc_to_timezone, get_system_timezone
-from frappe.utils.caching import redis_cache
from frappe.utils.password import get_decrypted_password
-from press.agent import Agent
-from press.api.site import protected
-from press.press.report.mariadb_slow_queries.db_optimizer import (
- DBExplain,
- DBIndex,
- DBOptimizer,
- DBTable,
-)
-
def execute(filters=None):
frappe.only_for(["System Manager", "Site Manager", "Press Admin", "Press Member"])
@@ -89,15 +77,6 @@ def execute(filters=None):
},
)
- if filters.analyze:
- columns.append(
- {
- "fieldname": "suggested_index",
- "label": frappe._("Suggest Index"),
- "fieldtype": "Data",
- },
- )
-
data = get_data(filters)
return columns, data
@@ -120,13 +99,13 @@ def get_data(filters):
get_system_timezone(),
)
+ # Filter out queries starting with `SET`
+ dql_stmt = ["SELECT", "UPDATE", "DELETE", "INSERT"]
+ rows = [x for x in rows if any(x["query"].startswith(stmt) for stmt in dql_stmt)]
+
if filters.normalize_queries:
rows = summarize_by_query(rows)
- # You can not analyze a query unless it has been normalized.
- if filters.analyze:
- rows = analyze_queries(rows, filters.site)
-
return rows
@@ -211,111 +190,5 @@ def summarize_by_query(data):
return result
-def analyze_queries(data, site):
- # TODO: handle old framework and old agents and general failures
- for row in data:
- query = row["example"]
- if not query.lower().startswith(("select", "update", "delete")):
- continue
- analyzer = OptimizeDatabaseQuery(site, query)
- if index := analyzer.analyze():
- row["suggested_index"] = f"{index.table}.{index.column}"
- return data
-
-
-@dataclass
-class OptimizeDatabaseQuery:
- site: str
- query: str
-
- def analyze(self) -> DBIndex | None:
- explain_output = self.fetch_explain() or []
-
- explain_output = [DBExplain.from_frappe_ouput(e) for e in explain_output]
- optimizer = DBOptimizer(query=self.query, explain_plan=explain_output)
- tables = optimizer.tables_examined
-
- for table in tables:
- stats = _fetch_table_stats(self.site, table)
- if not stats:
- # Old framework version
- return None
- db_table = DBTable.from_frappe_ouput(stats)
- column_stats = _fetch_column_stats(self.site, table)
- if not column_stats:
- # Failing due to large size, TODO: move this to a job
- return None
- db_table.update_cardinality(column_stats)
- optimizer.update_table_data(db_table)
-
- return optimizer.suggest_index()
-
- def fetch_explain(self) -> list[dict]:
- site = frappe.get_cached_doc("Site", self.site)
- db_server_name = frappe.db.get_value("Server", site.server, "database_server", cache=True)
- database_server = frappe.get_cached_doc("Database Server", db_server_name)
- agent = Agent(database_server.name, "Database Server")
-
- data = {
- "schema": site.database_name,
- "query": self.query,
- "private_ip": database_server.private_ip,
- "mariadb_root_password": database_server.get_password("mariadb_root_password"),
- }
-
- return agent.post("database/explain", data=data)
-
-
-@redis_cache(ttl=60 * 5)
-def _fetch_table_stats(site: str, table: str):
- site = frappe.get_cached_doc("Site", site)
- agent = Agent(site.server)
- return agent.describe_database_table(
- site,
- doctype=get_doctype_name(table),
- columns=[],
- )
-
-
-@redis_cache(ttl=60 * 5)
-def _fetch_column_stats(site, table, doc_name):
- site = frappe.get_cached_doc("Site", site)
- db_server_name = frappe.db.get_value("Server", site.server, "database_server", cache=True)
- database_server = frappe.get_cached_doc("Database Server", db_server_name)
- agent = Agent(database_server.name, "Database Server")
-
- data = {
- # "site": site,
- "doc_name": doc_name,
- "schema": site.database_name,
- "table": table,
- "private_ip": database_server.private_ip,
- "mariadb_root_password": database_server.get_password("mariadb_root_password"),
- }
- agent.create_agent_job("Column Statistics", "/database/column-stats", data)
-
-
def get_doctype_name(table_name: str) -> str:
return table_name.removeprefix("tab")
-
-
-@frappe.whitelist()
-@protected("Site")
-def add_suggested_index(name, indexes):
- if isinstance(indexes, str):
- indexes = json.loads(indexes)
- frappe.enqueue(_add_suggested_index, indexes=indexes, site_name=name)
-
-
-def _add_suggested_index(site_name, indexes):
- if not indexes:
- frappe.throw("No index suggested")
-
- for index in indexes:
- table, column = index.split(".")
- doctype = get_doctype_name(table)
-
- site = frappe.get_cached_doc("Site", site_name)
- agent = Agent(site.server)
- agent.add_database_index(site, doctype=doctype, columns=[column])
- frappe.msgprint(f"Index {index} added on site {site_name} successfully", realtime=True)
diff --git a/press/press/report/mariadb_slow_queries/test_db_optimizer.py b/press/press/report/mariadb_slow_queries/test_db_optimizer.py
deleted file mode 100644
index 65eead5535..0000000000
--- a/press/press/report/mariadb_slow_queries/test_db_optimizer.py
+++ /dev/null
@@ -1,618 +0,0 @@
-# Copyright (c) 2019, Frappe Technologies Pvt. Ltd. and Contributors
-# License: MIT. See LICENSE
-
-import json
-
-from frappe.tests.utils import FrappeTestCase
-
-from press.press.report.mariadb_slow_queries.db_optimizer import (
- DBExplain,
- DBOptimizer,
- DBTable,
-)
-
-
-class TestDBOptimizer(FrappeTestCase):
- def test_basic_index_existence_analysis(self):
- def possible_indexes(q):
- user = DBTable.from_frappe_ouput(USER_TABLE)
- has_role = DBTable.from_frappe_ouput(HAS_ROLE_TABLE)
- return [
- i.column
- for i in DBOptimizer(
- query=q,
- tables={"tabUser": user, "tabHas Role": has_role},
- ).potential_indexes()
- ]
-
- self.assertEqual(
- ["creation"],
- possible_indexes("select `name` from `tabUser` order by `creation` desc limit 1"),
- )
-
- self.assertEqual(
- ["full_name"],
- possible_indexes("select `name` from `tabUser` where full_name = 'xyz'"),
- )
-
- self.assertIn(
- "user",
- possible_indexes(
- "select `name` from `tabUser` u join `tabHas Role` h on h.user = u.name"
- ),
- )
-
- def test_suggestion_using_table_stats(self):
- user = DBTable.from_frappe_ouput(USER_TABLE)
- has_role = DBTable.from_frappe_ouput(HAS_ROLE_TABLE)
-
- tables = {"tabUser": user, "tabHas Role": has_role}
- self.assertEqual(user.total_rows, 92)
-
- # This should suggest adding api_key as it definitely has highest cardinality.
- optimizer = DBOptimizer(
- query="select name from tabUser where enabled = 1 and api_key = 'xyz'", tables=tables
- )
- self.assertIn("api_key", [i.column for i in optimizer.potential_indexes()])
-
- index = optimizer.suggest_index()
- self.assertEqual(index.column, "api_key")
-
- # This should suggest nothing as modified is already indexed
- optimizer = DBOptimizer(
- query="select name from tabUser order by modified asc",
- tables=tables,
- )
- self.assertIsNone(optimizer.suggest_index())
-
- # This should suggest nothing as modified is already indexed
- optimizer = DBOptimizer(
- query="select name from tabUser u join `tabHas Role` r on r.parent = u.name where r.role='System Manager'",
- tables=tables,
- )
- index = optimizer.suggest_index()
- self.assertEqual(index.column, "role")
- self.assertEqual(index.table, "tabHas Role")
-
- def test_complex_sub_query_aliases(self):
- """Check if table identification is correct for subqueries."""
-
- q = """SELECT *,
- (SELECT COUNT(*) FROM `tabHD Ticket Comment` WHERE `tabHD Ticket Comment`.`reference_ticket`=`tabHD Ticket`.`name`) `count_comment`,
- (SELECT COUNT(*) FROM `tabCommunication` WHERE `tabCommunication`.`reference_doctype`='HD Ticket' AND `tabCommunication`.`reference_name`=`tabHD Ticket`.`name`) `count_msg`,
- FROM `tabHD Ticket`
- WHERE `agent_group`='L2'
- ORDER BY `modified` DESC
- LIMIT 20
- """
- explain = [DBExplain.from_frappe_ouput(e) for e in json.loads(EXPLAIN_OUTPUT)]
- optimizer = DBOptimizer(query=q, explain_plan=explain)
- optimizer.update_table_data(DBTable.from_frappe_ouput(HD_TICKET_TABLE))
- optimizer.update_table_data(DBTable.from_frappe_ouput(HD_TICKET_COMMENT_TABLE))
- optimizer.update_table_data(DBTable.from_frappe_ouput(COMMUNICATION_TABLE))
-
- self.assertTrue(optimizer.can_be_optimized())
- index = optimizer.suggest_index()
- self.assertEqual(index.table, "tabHD Ticket Comment")
- self.assertEqual(index.column, "reference_ticket")
-
-
-# Table stats extracted using describe-database-table for testing.
-
-USER_TABLE = {
- "table_name": "tabUser",
- "total_rows": 92,
- "schema": [
- {
- "column": "name",
- "type": "varchar(140)",
- "is_nullable": False,
- "default": None,
- "cardinality": 91,
- },
- {"column": "creation", "type": "datetime(6)", "is_nullable": True, "default": None},
- {
- "column": "modified",
- "type": "datetime(6)",
- "is_nullable": True,
- "default": None,
- "cardinality": 91,
- },
- {
- "column": "modified_by",
- "type": "varchar(140)",
- "is_nullable": True,
- "default": None,
- },
- {"column": "owner", "type": "varchar(140)", "is_nullable": True, "default": None},
- {"column": "docstatus", "type": "int(1)", "is_nullable": False, "default": "0"},
- {"column": "idx", "type": "int(8)", "is_nullable": False, "default": "0"},
- {"column": "enabled", "type": "int(1)", "is_nullable": False, "default": "1"},
- {"column": "email", "type": "varchar(140)", "is_nullable": False, "default": ""},
- {
- "column": "first_name",
- "type": "varchar(140)",
- "is_nullable": True,
- "default": None,
- "cardinality": 88,
- },
- {
- "column": "reset_password_key",
- "type": "varchar(140)",
- "is_nullable": True,
- "default": None,
- "cardinality": 84,
- },
- {
- "column": "user_type",
- "type": "varchar(140)",
- "is_nullable": True,
- "default": "System User",
- "cardinality": 2,
- },
- {
- "column": "api_key",
- "type": "varchar(140)",
- "is_nullable": True,
- "default": None,
- "cardinality": 70,
- },
- {"column": "api_secret", "type": "text", "is_nullable": True, "default": None},
- {"column": "_user_tags", "type": "text", "is_nullable": True, "default": None},
- {"column": "_comments", "type": "text", "is_nullable": True, "default": None},
- {"column": "_assign", "type": "text", "is_nullable": True, "default": None},
- {"column": "_liked_by", "type": "text", "is_nullable": True, "default": None},
- ],
- "indexes": [
- {
- "unique": True,
- "cardinality": 91,
- "name": "PRIMARY",
- "sequence": 1,
- "nullable": False,
- "column": "name",
- "type": "BTREE",
- },
- {
- "unique": True,
- "cardinality": 91,
- "name": "username",
- "sequence": 1,
- "nullable": True,
- "column": "username",
- "type": "BTREE",
- },
- {
- "unique": False,
- "cardinality": 91,
- "name": "modified",
- "sequence": 1,
- "nullable": True,
- "column": "modified",
- "type": "BTREE",
- },
- {
- "unique": False,
- "cardinality": 91,
- "name": "reset_password_key_index",
- "sequence": 1,
- "nullable": True,
- "column": "reset_password_key",
- "type": "BTREE",
- },
- ],
-}
-
-
-HAS_ROLE_TABLE = {
- "table_name": "tabHas Role",
- "total_rows": 96,
- "schema": [
- {
- "column": "name",
- "type": "varchar(140)",
- "is_nullable": "NO",
- "default": None,
- "cardinality": 92,
- },
- {"column": "creation", "type": "datetime(6)", "is_nullable": "YES", "default": None},
- {"column": "modified", "type": "datetime(6)", "is_nullable": "YES", "default": None},
- {
- "column": "modified_by",
- "type": "varchar(140)",
- "is_nullable": "YES",
- "default": None,
- },
- {"column": "owner", "type": "varchar(140)", "is_nullable": "YES", "default": None},
- {"column": "docstatus", "type": "int(1)", "is_nullable": "NO", "default": "0"},
- {"column": "idx", "type": "int(8)", "is_nullable": "NO", "default": "0"},
- {
- "column": "role",
- "type": "varchar(140)",
- "is_nullable": "YES",
- "default": None,
- "cardinality": 78,
- },
- {
- "column": "parent",
- "type": "varchar(140)",
- "is_nullable": "YES",
- "default": None,
- "cardinality": 92,
- },
- {
- "column": "parentfield",
- "type": "varchar(140)",
- "is_nullable": "YES",
- "default": None,
- },
- {
- "column": "parenttype",
- "type": "varchar(140)",
- "is_nullable": "YES",
- "default": None,
- },
- ],
- "indexes": [
- {
- "unique": True,
- "cardinality": 92,
- "name": "PRIMARY",
- "sequence": 1,
- "nullable": "",
- "column": "name",
- "type": "BTREE",
- },
- {
- "unique": False,
- "cardinality": 92,
- "name": "parent",
- "sequence": 1,
- "nullable": "YES",
- "column": "parent",
- "type": "BTREE",
- },
- ],
-}
-
-
-HD_TICKET_TABLE = {
- "table_name": "tabHD Ticket",
- "total_rows": 3820,
- "schema": [
- {
- "column": "name",
- "type": "bigint(20)",
- "is_nullable": False,
- "default": None,
- "cardinality": 3529,
- },
- {"column": "creation", "type": "datetime(6)", "is_nullable": True, "default": None},
- {
- "column": "modified",
- "type": "datetime(6)",
- "is_nullable": True,
- "default": None,
- "cardinality": 3529,
- },
- {
- "column": "modified_by",
- "type": "varchar(140)",
- "is_nullable": True,
- "default": None,
- },
- {"column": "owner", "type": "varchar(140)", "is_nullable": True, "default": None},
- {"column": "docstatus", "type": "int(1)", "is_nullable": False, "default": "0"},
- {"column": "idx", "type": "int(8)", "is_nullable": False, "default": "0"},
- {"column": "subject", "type": "varchar(140)", "is_nullable": True, "default": None},
- {"column": "raised_by", "type": "varchar(140)", "is_nullable": True, "default": None},
- {
- "column": "status",
- "type": "varchar(140)",
- "is_nullable": True,
- "default": "Open",
- "cardinality": 8,
- },
- {"column": "priority", "type": "varchar(140)", "is_nullable": True, "default": None},
- {
- "column": "ticket_type",
- "type": "varchar(140)",
- "is_nullable": True,
- "default": None,
- },
- {
- "column": "agent_group",
- "type": "varchar(140)",
- "is_nullable": True,
- "default": "L1",
- "cardinality": 9,
- },
- {
- "column": "ticket_split_from",
- "type": "varchar(140)",
- "is_nullable": True,
- "default": None,
- },
- {"column": "description", "type": "longtext", "is_nullable": True, "default": None},
- {"column": "template", "type": "varchar(140)", "is_nullable": True, "default": None},
- {"column": "sla", "type": "varchar(140)", "is_nullable": True, "default": None},
- {
- "column": "response_by",
- "type": "datetime(6)",
- "is_nullable": True,
- "default": None,
- },
- {
- "column": "response_by_variance",
- "type": "decimal(21,9)",
- "is_nullable": True,
- "default": None,
- },
- {
- "column": "agreement_status",
- "type": "varchar(140)",
- "is_nullable": True,
- "default": None,
- },
- {
- "column": "resolution_by",
- "type": "datetime(6)",
- "is_nullable": True,
- "default": None,
- },
- {
- "column": "resolution_by_variance",
- "type": "decimal(21,9)",
- "is_nullable": True,
- "default": None,
- },
- {
- "column": "service_level_agreement_creation",
- "type": "datetime(6)",
- "is_nullable": True,
- "default": None,
- },
- {
- "column": "on_hold_since",
- "type": "datetime(6)",
- "is_nullable": True,
- "default": None,
- },
- {
- "column": "total_hold_time",
- "type": "decimal(21,9)",
- "is_nullable": True,
- "default": None,
- },
- {
- "column": "first_response_time",
- "type": "decimal(21,9)",
- "is_nullable": True,
- "default": None,
- },
- {
- "column": "first_responded_on",
- "type": "datetime(6)",
- "is_nullable": True,
- "default": None,
- },
- {
- "column": "avg_response_time",
- "type": "decimal(21,9)",
- "is_nullable": True,
- "default": None,
- },
- {
- "column": "resolution_details",
- "type": "longtext",
- "is_nullable": True,
- "default": None,
- },
- {"column": "opening_date", "type": "date", "is_nullable": True, "default": None},
- {"column": "opening_time", "type": "time(6)", "is_nullable": True, "default": None},
- {
- "column": "resolution_date",
- "type": "datetime(6)",
- "is_nullable": True,
- "default": None,
- },
- {
- "column": "resolution_time",
- "type": "decimal(21,9)",
- "is_nullable": True,
- "default": None,
- },
- {
- "column": "user_resolution_time",
- "type": "decimal(21,9)",
- "is_nullable": True,
- "default": None,
- },
- {"column": "contact", "type": "varchar(140)", "is_nullable": True, "default": None},
- {"column": "customer", "type": "varchar(140)", "is_nullable": True, "default": None},
- {
- "column": "email_account",
- "type": "varchar(140)",
- "is_nullable": True,
- "default": None,
- },
- {"column": "attachment", "type": "text", "is_nullable": True, "default": None},
- {"column": "_user_tags", "type": "text", "is_nullable": True, "default": None},
- {"column": "_comments", "type": "text", "is_nullable": True, "default": None},
- {"column": "_assign", "type": "text", "is_nullable": True, "default": None},
- {"column": "_liked_by", "type": "text", "is_nullable": True, "default": None},
- {"column": "_seen", "type": "text", "is_nullable": True, "default": None},
- ],
- "indexes": [
- {
- "unique": True,
- "cardinality": 3529,
- "name": "PRIMARY",
- "sequence": 1,
- "nullable": False,
- "column": "name",
- "type": "BTREE",
- },
- {
- "unique": False,
- "cardinality": 8,
- "name": "status",
- "sequence": 1,
- "nullable": True,
- "column": "status",
- "type": "BTREE",
- },
- {
- "unique": False,
- "cardinality": 3529,
- "name": "modified",
- "sequence": 1,
- "nullable": True,
- "column": "modified",
- "type": "BTREE",
- },
- ],
-}
-
-
-HD_TICKET_COMMENT_TABLE = {
- "table_name": "tabHD Ticket Comment",
- "total_rows": 2683,
- "schema": [
- {
- "column": "name",
- "type": "varchar(140)",
- "is_nullable": False,
- "default": None,
- "cardinality": 2683,
- },
- {"column": "creation", "type": "datetime(6)", "is_nullable": True, "default": None},
- {
- "column": "modified",
- "type": "datetime(6)",
- "is_nullable": True,
- "default": None,
- "cardinality": 2345,
- },
- {
- "column": "reference_ticket",
- "type": "varchar(140)",
- "is_nullable": True,
- "default": None,
- "cardinality": 1379,
- },
- {
- "column": "commented_by",
- "type": "varchar(140)",
- "is_nullable": True,
- "default": None,
- },
- {"column": "content", "type": "longtext", "is_nullable": True, "default": None},
- {"column": "is_pinned", "type": "int(1)", "is_nullable": False, "default": "0"},
- ],
- "indexes": [
- {
- "unique": True,
- "cardinality": 2345,
- "name": "PRIMARY",
- "sequence": 1,
- "nullable": False,
- "column": "name",
- "type": "BTREE",
- },
- {
- "unique": False,
- "cardinality": 2345,
- "name": "modified",
- "sequence": 1,
- "nullable": True,
- "column": "modified",
- "type": "BTREE",
- },
- ],
-}
-
-
-COMMUNICATION_TABLE = {
- "table_name": "tabCommunication",
- "total_rows": 20727,
- "schema": [
- {
- "column": "name",
- "type": "varchar(140)",
- "is_nullable": False,
- "default": None,
- "cardinality": 19713,
- },
- {"column": "creation", "type": "datetime(6)", "is_nullable": True, "default": None},
- {
- "column": "modified",
- "type": "datetime(6)",
- "is_nullable": True,
- "default": None,
- "cardinality": 19713,
- },
- {
- "column": "reference_doctype",
- "type": "varchar(140)",
- "is_nullable": True,
- "default": None,
- "cardinality": 1,
- },
- {
- "column": "reference_name",
- "type": "varchar(140)",
- "is_nullable": True,
- "default": None,
- "cardinality": 3798,
- },
- {
- "column": "reference_owner",
- "type": "varchar(140)",
- "is_nullable": True,
- "default": None,
- "cardinality": 1314,
- },
- ],
- "indexes": [
- {
- "unique": True,
- "cardinality": 19713,
- "name": "PRIMARY",
- "sequence": 1,
- "nullable": False,
- "column": "name",
- "type": "BTREE",
- },
- {
- "unique": False,
- "cardinality": 19713,
- "name": "modified",
- "sequence": 1,
- "nullable": True,
- "column": "modified",
- "type": "BTREE",
- },
- {
- "unique": False,
- "cardinality": 2,
- "name": "reference_doctype_reference_name_index",
- "sequence": 1,
- "nullable": True,
- "column": "reference_doctype",
- "type": "BTREE",
- },
- {
- "unique": False,
- "cardinality": 9856,
- "name": "reference_doctype_reference_name_index",
- "sequence": 2,
- "nullable": True,
- "column": "reference_name",
- "type": "BTREE",
- },
- ],
-}
-
-
-EXPLAIN_OUTPUT = """[{"Extra": "", "id": 1, "key": "modified", "key_len": "9", "possible_keys": null, "ref": null, "rows": "20", "select_type": "PRIMARY", "table": "tabHD Ticket", "type": "index"}, {"Extra": "Using index condition; Using where", "id": 4, "key": "reference_doctype_reference_name_index", "key_len": "563", "possible_keys": "reference_doctype_reference_name_index", "ref": "const", "rows": "10236", "select_type": "DEPENDENT SUBQUERY", "table": "tabCommunication", "type": "ref"}, {"Extra": "Using index condition; Using where", "id": 3, "key": "reference_doctype_reference_name_index", "key_len": "563", "possible_keys": "reference_doctype_reference_name_index", "ref": "const", "rows": "10236", "select_type": "DEPENDENT SUBQUERY", "table": "tabCommunication", "type": "ref"}, {"Extra": "Using where; Using index", "id": 2, "key": "reference_ticket_index", "key_len": "563", "possible_keys": "reference_ticket_index", "ref": null, "rows": "2823", "select_type": "DEPENDENT SUBQUERY", "table": "tabHD Ticket Comment", "type": "index"}]"""
diff --git a/press/utils/__init__.py b/press/utils/__init__.py
index 5d40ae330c..4f05b1190d 100644
--- a/press/utils/__init__.py
+++ b/press/utils/__init__.py
@@ -6,21 +6,29 @@
import functools
import json
import re
+import socket
+import ssl
import time
from datetime import datetime, timedelta
from pathlib import Path
from typing import TypedDict, TypeVar
from urllib.parse import urljoin
+from urllib.request import urlopen
import frappe
import pytz
import requests
import wrapt
from babel.dates import format_timedelta
+from cryptography import x509
+from cryptography.hazmat.backends import default_backend
+from cryptography.x509.oid import ExtensionOID
from frappe.utils import get_datetime, get_system_timezone
from frappe.utils.caching import site_cache
from pymysql.err import InterfaceError
+from press.utils.email_validator import validate_email
+
class SupervisorProcess(TypedDict):
program: str
@@ -840,3 +848,51 @@ def get_mariadb_root_password(site):
field = "mariadb_root_password"
return get_decrypted_password(doctype, name, field)
+
+
+def is_valid_email_address(email) -> bool:
+ if frappe.cache.exists(f"email_validity:{email}"):
+ return bool(frappe.utils.data.cint(frappe.cache.get_value(f"email_validity:{email}")))
+ try:
+ is_valid = bool(validate_email(email=email, check_mx=True, verify=True, smtp_timeout=10))
+ frappe.cache.set_value(f"email_validity:{email}", int(is_valid), expires_in_sec=3600)
+ if not is_valid:
+ log_error("Invalid email address on signup", data=email)
+ return bool(is_valid)
+ except Exception as e:
+ log_error("Email validation error on signup", data=e)
+ frappe.cache.set_value(f"email_validity:{email}", 0, expires_in_sec=3600)
+ return False
+
+
+def get_full_chain_cert_of_domain(domain: str) -> str:
+ cert_chain = []
+
+ # Get initial certificate
+ context = ssl.create_default_context()
+ with socket.create_connection((domain, 443)) as sock: # noqa: SIM117
+ with context.wrap_socket(sock, server_hostname=domain) as ssl_socket:
+ cert_pem = ssl.DER_cert_to_PEM_cert(ssl_socket.getpeercert(True))
+ cert = x509.load_pem_x509_certificate(cert_pem.encode(), default_backend())
+ cert_chain.append(cert_pem)
+
+ # Walk up the chain via certificate authority information access (AIA)
+ while True:
+ try:
+ aia = cert.extensions.get_extension_for_oid(ExtensionOID.AUTHORITY_INFORMATION_ACCESS)
+ for access in aia.value:
+ if access.access_method._name == "caIssuers":
+ uri = access.access_location._value
+ with urlopen(uri) as response:
+ der_cert = response.read()
+ pem_cert = ssl.DER_cert_to_PEM_cert(der_cert)
+ cert = x509.load_pem_x509_certificate(pem_cert.encode(), default_backend())
+ cert_chain.append(pem_cert)
+ break
+ except: # noqa: E722
+ break
+
+ cert_chain_str = ""
+ for cert in cert_chain:
+ cert_chain_str += cert + "\n"
+ return cert_chain_str
diff --git a/press/utils/email_validator.py b/press/utils/email_validator.py
new file mode 100644
index 0000000000..5cc03fb7e1
--- /dev/null
+++ b/press/utils/email_validator.py
@@ -0,0 +1,170 @@
+"""
+Customized function of validate-email package
+
+RFC 2822 - style email validation for Python
+
+(c) 2012 Syrus Akbary
+Extended from (c) 2011 Noel Bush for support of mx and user check
+
+This code is made available to you under the GNU LGPLv3.
+
+This module provides a single method, valid_email_address(), which returns True or False to indicate
+whether a given address is valid according to the 'addr-spec' part of the specification given in RFC
+2822. Ideally, we would like to find this in some other library, already thoroughly tested and
+well-maintained. The standard Python library email.utils contains a parse_addr() function, but it
+is not sufficient to detect many malformed addresses.
+
+This implementation aims to be faithful to the RFC, with the
+exception of a circular definition (see comments below), and
+with the omission of the pattern components marked as "obsolete".
+"""
+
+import contextlib
+import re
+import smtplib
+
+from dns.resolver import Resolver
+
+# All we are really doing is comparing the input string to one
+# gigantic regular expression. But building that regexp, and
+# ensuring its correctness, is made much easier by assembling it
+# from the "tokens" defined by the RFC. Each of these tokens is
+# tested in the accompanying unit test file.
+#
+# The section of RFC 2822 from which each pattern component is
+# derived is given in an accompanying comment.
+#
+# (To make things simple, every string below is given as 'raw',
+# even when it's not strictly necessary. This way we don't forget
+# when it is necessary.)
+
+WSP = r"[ \t]" # see 2.2.2. Structured Header Field Bodies
+CRLF = r"(?:\r\n)" # see 2.2.3. Long Header Fields
+NO_WS_CTL = r"\x01-\x08\x0b\x0c\x0f-\x1f\x7f" # see 3.2.1. Primitive Tokens
+QUOTED_PAIR = r"(?:\\.)" # see 3.2.2. Quoted characters
+FWS = r"(?:(?:" + WSP + r"*" + CRLF + r")?" + WSP + r"+)" # see 3.2.3. Folding white space and comments
+CTEXT = r"[" + NO_WS_CTL + r"\x21-\x27\x2a-\x5b\x5d-\x7e]" # see 3.2.3
+CCONTENT = r"(?:" + CTEXT + r"|" + QUOTED_PAIR + r")" # see 3.2.3 (NB: The RFC includes COMMENT here
+# as well, but that would be circular.)
+COMMENT = r"\((?:" + FWS + r"?" + CCONTENT + r")*" + FWS + r"?\)" # see 3.2.3
+CFWS = r"(?:" + FWS + r"?" + COMMENT + ")*(?:" + FWS + "?" + COMMENT + "|" + FWS + ")" # see 3.2.3
+ATEXT = r"[\w!#$%&\'\*\+\-/=\?\^`\{\|\}~]" # see 3.2.4. Atom
+ATOM = CFWS + r"?" + ATEXT + r"+" + CFWS + r"?" # see 3.2.4
+DOT_ATOM_TEXT = ATEXT + r"+(?:\." + ATEXT + r"+)*" # see 3.2.4
+DOT_ATOM = CFWS + r"?" + DOT_ATOM_TEXT + CFWS + r"?" # see 3.2.4
+QTEXT = r"[" + NO_WS_CTL + r"\x21\x23-\x5b\x5d-\x7e]" # see 3.2.5. Quoted strings
+QCONTENT = r"(?:" + QTEXT + r"|" + QUOTED_PAIR + r")" # see 3.2.5
+QUOTED_STRING = CFWS + r"?" + r'"(?:' + FWS + r"?" + QCONTENT + r")*" + FWS + r"?" + r'"' + CFWS + r"?"
+LOCAL_PART = r"(?:" + DOT_ATOM + r"|" + QUOTED_STRING + r")" # see 3.4.1. Addr-spec specification
+DTEXT = r"[" + NO_WS_CTL + r"\x21-\x5a\x5e-\x7e]" # see 3.4.1
+DCONTENT = r"(?:" + DTEXT + r"|" + QUOTED_PAIR + r")" # see 3.4.1
+DOMAIN_LITERAL = (
+ CFWS + r"?" + r"\[" + r"(?:" + FWS + r"?" + DCONTENT + r")*" + FWS + r"?\]" + CFWS + r"?"
+) # see 3.4.1
+DOMAIN = r"(?:" + DOT_ATOM + r"|" + DOMAIN_LITERAL + r")" # see 3.4.1
+ADDR_SPEC = LOCAL_PART + r"@" + DOMAIN # see 3.4.1
+
+# A valid address will match exactly the 3.4.1 addr-spec.
+VALID_ADDRESS_REGEXP = re.compile(r"^" + ADDR_SPEC + r"$")
+
+MX_DNS_CACHE = {}
+MX_CHECK_CACHE = {}
+
+
+def get_mx_ip(mx_host):
+ """
+ Get the IP address of a given MX host
+
+ :param mx_host: The host being looked up
+ :type mx_host: str
+ :return: A list of IP addresses
+ :rtype: list
+ """
+ if mx_host not in MX_DNS_CACHE:
+ try:
+ resolver = Resolver(configure=False)
+ resolver.nameservers = ["1.1.1.1", "1.0.0.1", "8.8.8.8", "8.8.4.4"]
+ answers = resolver.query(mx_host, "MX")
+
+ mx_lookup_result = []
+
+ for answer in answers:
+ mx_lookup_result.append((answer.preference, answer.exchange.to_text()[:-1]))
+ MX_DNS_CACHE[mx_host] = mx_lookup_result
+ except Exception:
+ raise
+ return MX_DNS_CACHE[mx_host]
+
+
+def check_mx_record(email, verify=False, smtp_timeout=10):
+ """
+ Checks for an MX record on the given email addresses' hostname.
+
+ :param email: The email address
+ :type email: str
+ :param verify: Whether the email address' existence should be verified
+ :type verify: bool
+ :param smtp_timeout: Maximum wait time on an SMTP connection
+ :type smtp_timeout: int
+ :return: bool or None
+ """
+ hostname = email[email.find("@") + 1 :]
+ mx_hosts = get_mx_ip(hostname)
+ if mx_hosts is None:
+ return False
+ for mx_host in mx_hosts:
+ with contextlib.suppress(Exception):
+ if not verify and mx_host[1] in MX_CHECK_CACHE:
+ return MX_CHECK_CACHE[mx_host[1]]
+ smtp = smtplib.SMTP(timeout=smtp_timeout)
+ smtp.connect(mx_host[1])
+ MX_CHECK_CACHE[mx_host[1]] = True
+ if not verify:
+ try: # noqa: SIM105
+ smtp.quit()
+ except smtplib.SMTPServerDisconnected:
+ pass
+ return True
+ status, _ = smtp.helo()
+ if status != 250:
+ smtp.quit()
+ continue
+ smtp.mail("")
+ status, _ = smtp.rcpt(email)
+ if status == 250:
+ smtp.quit()
+ return True
+ smtp.quit()
+ return None
+
+
+def validate_email(email, check_mx=False, verify=False, smtp_timeout=10, **kwargs):
+ """
+ Indicate whether the given string is a valid email address according to the 'addr-spec' portion
+ of RFC 2822 (see section 3.4.1). Parts of the spec that are marked obsolete are *not* included
+ in this test, and certain arcane constructions that depend on circular definitions in the spec
+ may not pass, but in general this should correctly identify any email address likely to be in
+ use as of 2011.
+
+ :param email: The email address to be validated
+ :type email: str
+ :param check_mx: Whether or not MX records should be verified
+ :type check_mx: bool
+ :param verify: Whether or not the email addresses' actual existence should be verified
+ :type verify: bool
+ :param smtp_timeout: Maximum wait time on an SMTP connection
+ :type smtp_timeout: int
+ :return: The validity of the given email address
+ :rtype: bool or None
+ """
+ try:
+ if re.match(VALID_ADDRESS_REGEXP, email) is not None:
+ check_mx |= verify
+ if check_mx:
+ return check_mx_record(email, verify=verify, smtp_timeout=smtp_timeout)
+ else:
+ return False
+ except Exception:
+ return None
+ else:
+ return True
diff --git a/setup-pre-commit.sh b/setup-pre-commit.sh
new file mode 100755
index 0000000000..7448d6c743
--- /dev/null
+++ b/setup-pre-commit.sh
@@ -0,0 +1,15 @@
+# !/usr/bin/env bash
+
+echo "Installing python dev dependencies"
+pip install -r dev-requirements.txt
+
+echo "Installing nodejs dev dependencies"
+yarn install --frozen-lockfile --dev
+
+echo "Setting up pre-commit hooks"
+pre-commit install
+
+echo "Setting up commit-msg hooks"
+pre-commit install -t commit-msg
+
+echo "Setup complete"
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 3fcc5b1c88..446208a131 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4,7 +4,7 @@
"@alloc/quick-lru@^5.2.0":
version "5.2.0"
- resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30"
+ resolved "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz"
integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==
"@babel/code-frame@^7.0.0":
@@ -15,9 +15,9 @@
"@babel/highlight" "^7.14.5"
"@babel/helper-validator-identifier@^7.14.5":
- version "7.14.9"
- resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz"
- integrity sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==
+ version "7.25.9"
+ resolved "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz"
+ integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==
"@babel/highlight@^7.14.5":
version "7.14.5"
@@ -28,16 +28,566 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
+"@commitlint/cli@^19.6.1":
+ version "19.6.1"
+ resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-19.6.1.tgz#24edd26595d911cc6b680cdfbb1fb083bfd5f73d"
+ integrity sha512-8hcyA6ZoHwWXC76BoC8qVOSr8xHy00LZhZpauiD0iO0VYbVhMnED0da85lTfIULxl7Lj4c6vZgF0Wu/ed1+jlQ==
+ dependencies:
+ "@commitlint/format" "^19.5.0"
+ "@commitlint/lint" "^19.6.0"
+ "@commitlint/load" "^19.6.1"
+ "@commitlint/read" "^19.5.0"
+ "@commitlint/types" "^19.5.0"
+ tinyexec "^0.3.0"
+ yargs "^17.0.0"
+
+"@commitlint/config-conventional@^19.6.0":
+ version "19.6.0"
+ resolved "https://registry.yarnpkg.com/@commitlint/config-conventional/-/config-conventional-19.6.0.tgz#badba72c8639ea79291e2941001bd7ea7fad3a2c"
+ integrity sha512-DJT40iMnTYtBtUfw9ApbsLZFke1zKh6llITVJ+x9mtpHD08gsNXaIRqHTmwTZL3dNX5+WoyK7pCN/5zswvkBCQ==
+ dependencies:
+ "@commitlint/types" "^19.5.0"
+ conventional-changelog-conventionalcommits "^7.0.2"
+
+"@commitlint/config-validator@^19.5.0":
+ version "19.5.0"
+ resolved "https://registry.yarnpkg.com/@commitlint/config-validator/-/config-validator-19.5.0.tgz#f0a4eda2109fc716ef01bb8831af9b02e3a1e568"
+ integrity sha512-CHtj92H5rdhKt17RmgALhfQt95VayrUo2tSqY9g2w+laAXyk7K/Ef6uPm9tn5qSIwSmrLjKaXK9eiNuxmQrDBw==
+ dependencies:
+ "@commitlint/types" "^19.5.0"
+ ajv "^8.11.0"
+
+"@commitlint/ensure@^19.5.0":
+ version "19.5.0"
+ resolved "https://registry.yarnpkg.com/@commitlint/ensure/-/ensure-19.5.0.tgz#b087374a6a0a0140e5925a82901d234885d9f6dd"
+ integrity sha512-Kv0pYZeMrdg48bHFEU5KKcccRfKmISSm9MvgIgkpI6m+ohFTB55qZlBW6eYqh/XDfRuIO0x4zSmvBjmOwWTwkg==
+ dependencies:
+ "@commitlint/types" "^19.5.0"
+ lodash.camelcase "^4.3.0"
+ lodash.kebabcase "^4.1.1"
+ lodash.snakecase "^4.1.1"
+ lodash.startcase "^4.4.0"
+ lodash.upperfirst "^4.3.1"
+
+"@commitlint/execute-rule@^19.5.0":
+ version "19.5.0"
+ resolved "https://registry.yarnpkg.com/@commitlint/execute-rule/-/execute-rule-19.5.0.tgz#c13da8c03ea0379f30856111e27d57518e25b8a2"
+ integrity sha512-aqyGgytXhl2ejlk+/rfgtwpPexYyri4t8/n4ku6rRJoRhGZpLFMqrZ+YaubeGysCP6oz4mMA34YSTaSOKEeNrg==
+
+"@commitlint/format@^19.5.0":
+ version "19.5.0"
+ resolved "https://registry.yarnpkg.com/@commitlint/format/-/format-19.5.0.tgz#d879db2d97d70ae622397839fb8603d56e85a250"
+ integrity sha512-yNy088miE52stCI3dhG/vvxFo9e4jFkU1Mj3xECfzp/bIS/JUay4491huAlVcffOoMK1cd296q0W92NlER6r3A==
+ dependencies:
+ "@commitlint/types" "^19.5.0"
+ chalk "^5.3.0"
+
+"@commitlint/is-ignored@^19.6.0":
+ version "19.6.0"
+ resolved "https://registry.yarnpkg.com/@commitlint/is-ignored/-/is-ignored-19.6.0.tgz#6adb9097d36b68e00b9c06a73d7a08e9f54c54dc"
+ integrity sha512-Ov6iBgxJQFR9koOupDPHvcHU9keFupDgtB3lObdEZDroiG4jj1rzky60fbQozFKVYRTUdrBGICHG0YVmRuAJmw==
+ dependencies:
+ "@commitlint/types" "^19.5.0"
+ semver "^7.6.0"
+
+"@commitlint/lint@^19.6.0":
+ version "19.6.0"
+ resolved "https://registry.yarnpkg.com/@commitlint/lint/-/lint-19.6.0.tgz#f9fc9b11b808c96bd3f85e882e056daabac40c36"
+ integrity sha512-LRo7zDkXtcIrpco9RnfhOKeg8PAnE3oDDoalnrVU/EVaKHYBWYL1DlRR7+3AWn0JiBqD8yKOfetVxJGdEtZ0tg==
+ dependencies:
+ "@commitlint/is-ignored" "^19.6.0"
+ "@commitlint/parse" "^19.5.0"
+ "@commitlint/rules" "^19.6.0"
+ "@commitlint/types" "^19.5.0"
+
+"@commitlint/load@^19.6.1":
+ version "19.6.1"
+ resolved "https://registry.yarnpkg.com/@commitlint/load/-/load-19.6.1.tgz#5fae8843a6048a2d3d1cc16da0af8ee532fa9db4"
+ integrity sha512-kE4mRKWWNju2QpsCWt428XBvUH55OET2N4QKQ0bF85qS/XbsRGG1MiTByDNlEVpEPceMkDr46LNH95DtRwcsfA==
+ dependencies:
+ "@commitlint/config-validator" "^19.5.0"
+ "@commitlint/execute-rule" "^19.5.0"
+ "@commitlint/resolve-extends" "^19.5.0"
+ "@commitlint/types" "^19.5.0"
+ chalk "^5.3.0"
+ cosmiconfig "^9.0.0"
+ cosmiconfig-typescript-loader "^6.1.0"
+ lodash.isplainobject "^4.0.6"
+ lodash.merge "^4.6.2"
+ lodash.uniq "^4.5.0"
+
+"@commitlint/message@^19.5.0":
+ version "19.5.0"
+ resolved "https://registry.yarnpkg.com/@commitlint/message/-/message-19.5.0.tgz#c062d9a1d2b3302c3a8cac25d6d1125ea9c019b2"
+ integrity sha512-R7AM4YnbxN1Joj1tMfCyBryOC5aNJBdxadTZkuqtWi3Xj0kMdutq16XQwuoGbIzL2Pk62TALV1fZDCv36+JhTQ==
+
+"@commitlint/parse@^19.5.0":
+ version "19.5.0"
+ resolved "https://registry.yarnpkg.com/@commitlint/parse/-/parse-19.5.0.tgz#b450dad9b5a95ac5ba472d6d0fdab822dce946fc"
+ integrity sha512-cZ/IxfAlfWYhAQV0TwcbdR1Oc0/r0Ik1GEessDJ3Lbuma/MRO8FRQX76eurcXtmhJC//rj52ZSZuXUg0oIX0Fw==
+ dependencies:
+ "@commitlint/types" "^19.5.0"
+ conventional-changelog-angular "^7.0.0"
+ conventional-commits-parser "^5.0.0"
+
+"@commitlint/read@^19.5.0":
+ version "19.5.0"
+ resolved "https://registry.yarnpkg.com/@commitlint/read/-/read-19.5.0.tgz#601f9f1afe69852b0f28aa81cd455b40979fad6b"
+ integrity sha512-TjS3HLPsLsxFPQj6jou8/CZFAmOP2y+6V4PGYt3ihbQKTY1Jnv0QG28WRKl/d1ha6zLODPZqsxLEov52dhR9BQ==
+ dependencies:
+ "@commitlint/top-level" "^19.5.0"
+ "@commitlint/types" "^19.5.0"
+ git-raw-commits "^4.0.0"
+ minimist "^1.2.8"
+ tinyexec "^0.3.0"
+
+"@commitlint/resolve-extends@^19.5.0":
+ version "19.5.0"
+ resolved "https://registry.yarnpkg.com/@commitlint/resolve-extends/-/resolve-extends-19.5.0.tgz#f3ec33e12d10df90cae0bfad8e593431fb61b18e"
+ integrity sha512-CU/GscZhCUsJwcKTJS9Ndh3AKGZTNFIOoQB2n8CmFnizE0VnEuJoum+COW+C1lNABEeqk6ssfc1Kkalm4bDklA==
+ dependencies:
+ "@commitlint/config-validator" "^19.5.0"
+ "@commitlint/types" "^19.5.0"
+ global-directory "^4.0.1"
+ import-meta-resolve "^4.0.0"
+ lodash.mergewith "^4.6.2"
+ resolve-from "^5.0.0"
+
+"@commitlint/rules@^19.6.0":
+ version "19.6.0"
+ resolved "https://registry.yarnpkg.com/@commitlint/rules/-/rules-19.6.0.tgz#2436da7974c3cf2a7236257f3ef5dd40c4d91312"
+ integrity sha512-1f2reW7lbrI0X0ozZMesS/WZxgPa4/wi56vFuJENBmed6mWq5KsheN/nxqnl/C23ioxpPO/PL6tXpiiFy5Bhjw==
+ dependencies:
+ "@commitlint/ensure" "^19.5.0"
+ "@commitlint/message" "^19.5.0"
+ "@commitlint/to-lines" "^19.5.0"
+ "@commitlint/types" "^19.5.0"
+
+"@commitlint/to-lines@^19.5.0":
+ version "19.5.0"
+ resolved "https://registry.yarnpkg.com/@commitlint/to-lines/-/to-lines-19.5.0.tgz#e4b7f34f09064568c96a74de4f1fc9f466c4d472"
+ integrity sha512-R772oj3NHPkodOSRZ9bBVNq224DOxQtNef5Pl8l2M8ZnkkzQfeSTr4uxawV2Sd3ui05dUVzvLNnzenDBO1KBeQ==
+
+"@commitlint/top-level@^19.5.0":
+ version "19.5.0"
+ resolved "https://registry.yarnpkg.com/@commitlint/top-level/-/top-level-19.5.0.tgz#0017ffe39b5ba3611a1debd62efe28803601a14f"
+ integrity sha512-IP1YLmGAk0yWrImPRRc578I3dDUI5A2UBJx9FbSOjxe9sTlzFiwVJ+zeMLgAtHMtGZsC8LUnzmW1qRemkFU4ng==
+ dependencies:
+ find-up "^7.0.0"
+
+"@commitlint/types@^19.5.0":
+ version "19.5.0"
+ resolved "https://registry.yarnpkg.com/@commitlint/types/-/types-19.5.0.tgz#c5084d1231d4dd50e40bdb656ee7601f691400b3"
+ integrity sha512-DSHae2obMSMkAtTBSOulg5X7/z+rGLxcXQIkg3OmWvY6wifojge5uVMydfhUvs7yQj+V7jNmRZ2Xzl8GJyqRgg==
+ dependencies:
+ "@types/conventional-commits-parser" "^5.0.0"
+ chalk "^5.3.0"
+
+"@cspell/cspell-bundled-dicts@8.17.1":
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/@cspell/cspell-bundled-dicts/-/cspell-bundled-dicts-8.17.1.tgz#61adad73f1bb1e12b182ffa04423d6052b18f0fc"
+ integrity sha512-HmkXS5uX4bk/XxsRS4Q+zRvhgRa81ddGiR2/Xfag9MIi5L5UnEJ4g21EpmIlXkMxYrTu2fp69SZFss5NfcFF9Q==
+ dependencies:
+ "@cspell/dict-ada" "^4.0.5"
+ "@cspell/dict-al" "^1.0.3"
+ "@cspell/dict-aws" "^4.0.7"
+ "@cspell/dict-bash" "^4.1.8"
+ "@cspell/dict-companies" "^3.1.8"
+ "@cspell/dict-cpp" "^6.0.2"
+ "@cspell/dict-cryptocurrencies" "^5.0.3"
+ "@cspell/dict-csharp" "^4.0.5"
+ "@cspell/dict-css" "^4.0.16"
+ "@cspell/dict-dart" "^2.2.4"
+ "@cspell/dict-django" "^4.1.3"
+ "@cspell/dict-docker" "^1.1.11"
+ "@cspell/dict-dotnet" "^5.0.8"
+ "@cspell/dict-elixir" "^4.0.6"
+ "@cspell/dict-en-common-misspellings" "^2.0.7"
+ "@cspell/dict-en-gb" "1.1.33"
+ "@cspell/dict-en_us" "^4.3.28"
+ "@cspell/dict-filetypes" "^3.0.9"
+ "@cspell/dict-flutter" "^1.0.3"
+ "@cspell/dict-fonts" "^4.0.3"
+ "@cspell/dict-fsharp" "^1.0.4"
+ "@cspell/dict-fullstack" "^3.2.3"
+ "@cspell/dict-gaming-terms" "^1.0.9"
+ "@cspell/dict-git" "^3.0.3"
+ "@cspell/dict-golang" "^6.0.17"
+ "@cspell/dict-google" "^1.0.4"
+ "@cspell/dict-haskell" "^4.0.4"
+ "@cspell/dict-html" "^4.0.10"
+ "@cspell/dict-html-symbol-entities" "^4.0.3"
+ "@cspell/dict-java" "^5.0.10"
+ "@cspell/dict-julia" "^1.0.4"
+ "@cspell/dict-k8s" "^1.0.9"
+ "@cspell/dict-latex" "^4.0.3"
+ "@cspell/dict-lorem-ipsum" "^4.0.3"
+ "@cspell/dict-lua" "^4.0.6"
+ "@cspell/dict-makefile" "^1.0.3"
+ "@cspell/dict-markdown" "^2.0.7"
+ "@cspell/dict-monkeyc" "^1.0.9"
+ "@cspell/dict-node" "^5.0.5"
+ "@cspell/dict-npm" "^5.1.17"
+ "@cspell/dict-php" "^4.0.13"
+ "@cspell/dict-powershell" "^5.0.13"
+ "@cspell/dict-public-licenses" "^2.0.11"
+ "@cspell/dict-python" "^4.2.13"
+ "@cspell/dict-r" "^2.0.4"
+ "@cspell/dict-ruby" "^5.0.7"
+ "@cspell/dict-rust" "^4.0.10"
+ "@cspell/dict-scala" "^5.0.6"
+ "@cspell/dict-software-terms" "^4.1.19"
+ "@cspell/dict-sql" "^2.1.8"
+ "@cspell/dict-svelte" "^1.0.5"
+ "@cspell/dict-swift" "^2.0.4"
+ "@cspell/dict-terraform" "^1.0.6"
+ "@cspell/dict-typescript" "^3.1.11"
+ "@cspell/dict-vue" "^3.0.3"
+
+"@cspell/cspell-json-reporter@8.17.1":
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/@cspell/cspell-json-reporter/-/cspell-json-reporter-8.17.1.tgz#c1678665f183589e5fc19a1c0933b8d362165a43"
+ integrity sha512-EV9Xkh42Xw3aORvDZfxusICX91DDbqQpYdGKBdPGuhgxWOUYYZKpLXsHCmDkhruMPo2m5gDh++/OqjLRPZofKQ==
+ dependencies:
+ "@cspell/cspell-types" "8.17.1"
+
+"@cspell/cspell-pipe@8.17.1":
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/@cspell/cspell-pipe/-/cspell-pipe-8.17.1.tgz#c247d4bd1c8ec43c49c46dc4458f00489e98232b"
+ integrity sha512-uhC99Ox+OH3COSgShv4fpVHiotR70dNvAOSkzRvKVRzV6IGyFnxHjmyVVPEV0dsqzVLxltwYTqFhwI+UOwm45A==
+
+"@cspell/cspell-resolver@8.17.1":
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/@cspell/cspell-resolver/-/cspell-resolver-8.17.1.tgz#6377c9c8c05c940fee675c74e31f893b7b2f38ab"
+ integrity sha512-XEK2ymTdQNgsV3ny60VkKzWskbICl4zNXh/DbxsoRXHqIRg43MXFpTNkEJ7j873EqdX7BU4opQQ+5D4stWWuhQ==
+ dependencies:
+ global-directory "^4.0.1"
+
+"@cspell/cspell-service-bus@8.17.1":
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/@cspell/cspell-service-bus/-/cspell-service-bus-8.17.1.tgz#8d6d82ea3ab0fc9d7efed8523b070e4842780bd1"
+ integrity sha512-2sFWQtMEWZ4tdz7bw0bAx4NaV1t0ynGfjpuKWdQppsJFKNb+ZPZZ6Ah1dC13AdRRMZaG194kDRFwzNvRaCgWkQ==
+
+"@cspell/cspell-types@8.17.1":
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/@cspell/cspell-types/-/cspell-types-8.17.1.tgz#5512030b4c2e7881a8822ab3afabbd4f5ddffb6f"
+ integrity sha512-NJbov7Jp57fh8addoxesjb8atg/APQfssCH5Q9uZuHBN06wEJDgs7fhfE48bU+RBViC9gltblsYZzZZQKzHYKg==
+
+"@cspell/dict-ada@^4.0.5":
+ version "4.0.5"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-ada/-/dict-ada-4.0.5.tgz#c14aae2faaecbad2d99f0d701e4700a48c68ef60"
+ integrity sha512-6/RtZ/a+lhFVmrx/B7bfP7rzC4yjEYe8o74EybXcvu4Oue6J4Ey2WSYj96iuodloj1LWrkNCQyX5h4Pmcj0Iag==
+
+"@cspell/dict-al@^1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-al/-/dict-al-1.0.3.tgz#09e288b5ab56b126dce895d3301faf7c0dd732d6"
+ integrity sha512-V1HClwlfU/qwSq2Kt+MkqRAsonNu3mxjSCDyGRecdLGIHmh7yeEeaxqRiO/VZ4KP+eVSiSIlbwrb5YNFfxYZbw==
+
+"@cspell/dict-aws@^4.0.7":
+ version "4.0.7"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-aws/-/dict-aws-4.0.7.tgz#f96f3b70cd52a25b895eb08e297de5a5cc3fc5b6"
+ integrity sha512-PoaPpa2NXtSkhGIMIKhsJUXB6UbtTt6Ao3x9JdU9kn7fRZkwD4RjHDGqulucIOz7KeEX/dNRafap6oK9xHe4RA==
+
+"@cspell/dict-bash@^4.1.8":
+ version "4.1.8"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-bash/-/dict-bash-4.1.8.tgz#26dc898e06eddea069cf1ad475ee0e867c89e632"
+ integrity sha512-I2CM2pTNthQwW069lKcrVxchJGMVQBzru2ygsHCwgidXRnJL/NTjAPOFTxN58Jc1bf7THWghfEDyKX/oyfc0yg==
+
+"@cspell/dict-companies@^3.1.8":
+ version "3.1.11"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-companies/-/dict-companies-3.1.11.tgz#3a4f6fd052d5ac5a2869c763e169aff3a1f062c6"
+ integrity sha512-1gbPfN4fk6Cmg8DbCc+3nFxnHJNNGN1R5T/VzGEp8UpVBcW3OFET2xXFKcJiKSh+DyXB+M2tAx3so6WBEwOK1Q==
+
+"@cspell/dict-cpp@^6.0.2":
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-cpp/-/dict-cpp-6.0.2.tgz#e4549ee1bdf4b6402c0b978eb9dd3deac0eb05df"
+ integrity sha512-yw5eejWvY4bAnc6LUA44m4WsFwlmgPt2uMSnO7QViGMBDuoeopMma4z9XYvs4lSjTi8fIJs/A1YDfM9AVzb8eg==
+
+"@cspell/dict-cryptocurrencies@^5.0.3":
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-cryptocurrencies/-/dict-cryptocurrencies-5.0.3.tgz#502f9fffcb2835a3379668ddebdc487678ce6207"
+ integrity sha512-bl5q+Mk+T3xOZ12+FG37dB30GDxStza49Rmoax95n37MTLksk9wBo1ICOlPJ6PnDUSyeuv4SIVKgRKMKkJJglA==
+
+"@cspell/dict-csharp@^4.0.5":
+ version "4.0.5"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-csharp/-/dict-csharp-4.0.5.tgz#c677c50be09ca5bb3a2cc0be15f3cd05141fd2f7"
+ integrity sha512-c/sFnNgtRwRJxtC3JHKkyOm+U3/sUrltFeNwml9VsxKBHVmvlg4tk4ar58PdpW9/zTlGUkWi2i85//DN1EsUCA==
+
+"@cspell/dict-css@^4.0.16":
+ version "4.0.16"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-css/-/dict-css-4.0.16.tgz#b7b87b5ea0f1157b023205bdb00070a7d231e367"
+ integrity sha512-70qu7L9z/JR6QLyJPk38fNTKitlIHnfunx0wjpWQUQ8/jGADIhMCrz6hInBjqPNdtGpYm8d1dNFyF8taEkOgrQ==
+
+"@cspell/dict-dart@^2.2.4":
+ version "2.2.4"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-dart/-/dict-dart-2.2.4.tgz#8b877161ccdc65cead912b742b71aa55099c1706"
+ integrity sha512-of/cVuUIZZK/+iqefGln8G3bVpfyN6ZtH+LyLkHMoR5tEj+2vtilGNk9ngwyR8L4lEqbKuzSkOxgfVjsXf5PsQ==
+
+"@cspell/dict-data-science@^2.0.5":
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-data-science/-/dict-data-science-2.0.5.tgz#816e9b394c2a423d14cdc9a5de5d6fc6141d3900"
+ integrity sha512-nNSILXmhSJox9/QoXICPQgm8q5PbiSQP4afpbkBqPi/u/b3K9MbNH5HvOOa6230gxcGdbZ9Argl2hY/U8siBlg==
+
+"@cspell/dict-django@^4.1.3":
+ version "4.1.3"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-django/-/dict-django-4.1.3.tgz#a02a4a9ef8c9f47344f2d4a0c3964bcb62069ef5"
+ integrity sha512-yBspeL3roJlO0a1vKKNaWABURuHdHZ9b1L8d3AukX0AsBy9snSggc8xCavPmSzNfeMDXbH+1lgQiYBd3IW03fg==
+
+"@cspell/dict-docker@^1.1.11":
+ version "1.1.11"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-docker/-/dict-docker-1.1.11.tgz#6fce86eb6d86d73f77e18d3e7b9747bad3ca98de"
+ integrity sha512-s0Yhb16/R+UT1y727ekbR/itWQF3Qz275DR1ahOa66wYtPjHUXmhM3B/LT3aPaX+hD6AWmK23v57SuyfYHUjsw==
+
+"@cspell/dict-dotnet@^5.0.8":
+ version "5.0.8"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-dotnet/-/dict-dotnet-5.0.8.tgz#8a110ca302946025e0273a9940079483ec33a88a"
+ integrity sha512-MD8CmMgMEdJAIPl2Py3iqrx3B708MbCIXAuOeZ0Mzzb8YmLmiisY7QEYSZPg08D7xuwARycP0Ki+bb0GAkFSqg==
+
+"@cspell/dict-elixir@^4.0.6":
+ version "4.0.6"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-elixir/-/dict-elixir-4.0.6.tgz#3d8965c558d8afd190356e9a900b02c546741feb"
+ integrity sha512-TfqSTxMHZ2jhiqnXlVKM0bUADtCvwKQv2XZL/DI0rx3doG8mEMS8SGPOmiyyGkHpR/pGOq18AFH3BEm4lViHIw==
+
+"@cspell/dict-en-common-misspellings@^2.0.7":
+ version "2.0.7"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-en-common-misspellings/-/dict-en-common-misspellings-2.0.7.tgz#62861cc9e813c947ebd71c7a50fc720767b4b543"
+ integrity sha512-qNFo3G4wyabcwnM+hDrMYKN9vNVg/k9QkhqSlSst6pULjdvPyPs1mqz1689xO/v9t8e6sR4IKc3CgUXDMTYOpA==
+
+"@cspell/dict-en-gb@1.1.33":
+ version "1.1.33"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-en-gb/-/dict-en-gb-1.1.33.tgz#7f1fd90fc364a5cb77111b5438fc9fcf9cc6da0e"
+ integrity sha512-tKSSUf9BJEV+GJQAYGw5e+ouhEe2ZXE620S7BLKe3ZmpnjlNG9JqlnaBhkIMxKnNFkLY2BP/EARzw31AZnOv4g==
+
+"@cspell/dict-en_us@^4.3.28":
+ version "4.3.28"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-en_us/-/dict-en_us-4.3.28.tgz#41169e1ed18465e7ff367a4f4488d4cbc6cf0baa"
+ integrity sha512-BN1PME7cOl7DXRQJ92pEd1f0Xk5sqjcDfThDGkKcsgwbSOY7KnTc/czBW6Pr3WXIchIm6cT12KEfjNqx7U7Rrw==
+
+"@cspell/dict-filetypes@^3.0.9":
+ version "3.0.9"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-filetypes/-/dict-filetypes-3.0.9.tgz#f4d5c35c341e6c3b77c08aec00678412641e1504"
+ integrity sha512-U7ycC1cE32A5aEgwzp/iE0TVabonUFnVt+Ygbf6NsIWqEuFWZgZChC7gfztA4T1fpuj602nFdp7eOnTWKORsnQ==
+
+"@cspell/dict-flutter@^1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-flutter/-/dict-flutter-1.0.3.tgz#23e552209ab2238733d30ca3f2a141359756af51"
+ integrity sha512-52C9aUEU22ptpgYh6gQyIdA4MP6NPwzbEqndfgPh3Sra191/kgs7CVqXiO1qbtZa9gnYHUoVApkoxRE7mrXHfg==
+
+"@cspell/dict-fonts@^4.0.3":
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-fonts/-/dict-fonts-4.0.3.tgz#abf578c10a2e7b2bd8f4374002677625288560d9"
+ integrity sha512-sPd17kV5qgYXLteuHFPn5mbp/oCHKgitNfsZLFC3W2fWEgZlhg4hK+UGig3KzrYhhvQ8wBnmZrAQm0TFKCKzsA==
+
+"@cspell/dict-fsharp@^1.0.4":
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-fsharp/-/dict-fsharp-1.0.4.tgz#19a7263a61ca89cd3ec9c17537e424907b81ef38"
+ integrity sha512-G5wk0o1qyHUNi9nVgdE1h5wl5ylq7pcBjX8vhjHcO4XBq20D5eMoXjwqMo/+szKAqzJ+WV3BgAL50akLKrT9Rw==
+
+"@cspell/dict-fullstack@^3.2.3":
+ version "3.2.3"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-fullstack/-/dict-fullstack-3.2.3.tgz#f6fff74eff00c6759cba510168acada0619004cc"
+ integrity sha512-62PbndIyQPH11mAv0PyiyT0vbwD0AXEocPpHlCHzfb5v9SspzCCbzQ/LIBiFmyRa+q5LMW35CnSVu6OXdT+LKg==
+
+"@cspell/dict-gaming-terms@^1.0.9":
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-gaming-terms/-/dict-gaming-terms-1.0.9.tgz#6b920386d281b89f70857e6dacea10ab89e88658"
+ integrity sha512-AVIrZt3YiUnxsUzzGYTZ1XqgtkgwGEO0LWIlEf+SiDUEVLtv4CYmmyXFQ+WXDN0pyJ0wOwDazWrP0Cu7avYQmQ==
+
+"@cspell/dict-git@^3.0.3":
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-git/-/dict-git-3.0.3.tgz#3a3805ab9902bffc9255ec48f648145b957eb30b"
+ integrity sha512-LSxB+psZ0qoj83GkyjeEH/ZViyVsGEF/A6BAo8Nqc0w0HjD2qX/QR4sfA6JHUgQ3Yi/ccxdK7xNIo67L2ScW5A==
+
+"@cspell/dict-golang@^6.0.17":
+ version "6.0.18"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-golang/-/dict-golang-6.0.18.tgz#44e144409c3141ee58d854e49e118f7d264c9d43"
+ integrity sha512-Mt+7NwfodDwUk7423DdaQa0YaA+4UoV3XSxQwZioqjpFBCuxfvvv4l80MxCTAAbK6duGj0uHbGTwpv8fyKYPKg==
+
+"@cspell/dict-google@^1.0.4":
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-google/-/dict-google-1.0.4.tgz#e15a7ea2dee73800231a81840a59d3b50d49346f"
+ integrity sha512-JThUT9eiguCja1mHHLwYESgxkhk17Gv7P3b1S7ZJzXw86QyVHPrbpVoMpozHk0C9o+Ym764B7gZGKmw9uMGduQ==
+
+"@cspell/dict-haskell@^4.0.4":
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-haskell/-/dict-haskell-4.0.4.tgz#37e9cb9a7f5be337a697bcffd0a0d25e80aab50d"
+ integrity sha512-EwQsedEEnND/vY6tqRfg9y7tsnZdxNqOxLXSXTsFA6JRhUlr8Qs88iUUAfsUzWc4nNmmzQH2UbtT25ooG9x4nA==
+
+"@cspell/dict-html-symbol-entities@^4.0.3":
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-html-symbol-entities/-/dict-html-symbol-entities-4.0.3.tgz#bf2887020ca4774413d8b1f27c9b6824ba89e9ef"
+ integrity sha512-aABXX7dMLNFdSE8aY844X4+hvfK7977sOWgZXo4MTGAmOzR8524fjbJPswIBK7GaD3+SgFZ2yP2o0CFvXDGF+A==
+
+"@cspell/dict-html@^4.0.10":
+ version "4.0.10"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-html/-/dict-html-4.0.10.tgz#7b536b2adca4b58ed92752c9d3c7ffc724dd5991"
+ integrity sha512-I9uRAcdtHbh0wEtYZlgF0TTcgH0xaw1B54G2CW+tx4vHUwlde/+JBOfIzird4+WcMv4smZOfw+qHf7puFUbI5g==
+
+"@cspell/dict-java@^5.0.10":
+ version "5.0.10"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-java/-/dict-java-5.0.10.tgz#e6383ca645046b9f05a04a2c2e858fcc80c6fc63"
+ integrity sha512-pVNcOnmoGiNL8GSVq4WbX/Vs2FGS0Nej+1aEeGuUY9CU14X8yAVCG+oih5ZoLt1jaR8YfR8byUF8wdp4qG4XIw==
+
+"@cspell/dict-julia@^1.0.4":
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-julia/-/dict-julia-1.0.4.tgz#e478c20d742cd6857b6de41dc61a92036dafb4bc"
+ integrity sha512-bFVgNX35MD3kZRbXbJVzdnN7OuEqmQXGpdOi9jzB40TSgBTlJWA4nxeAKV4CPCZxNRUGnLH0p05T/AD7Aom9/w==
+
+"@cspell/dict-k8s@^1.0.9":
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-k8s/-/dict-k8s-1.0.9.tgz#e9392a002797c67ffc3e96893156cc15af3774d1"
+ integrity sha512-Q7GELSQIzo+BERl2ya/nBEnZeQC+zJP19SN1pI6gqDYraM51uYJacbbcWLYYO2Y+5joDjNt/sd/lJtLaQwoSlA==
+
+"@cspell/dict-latex@^4.0.3":
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-latex/-/dict-latex-4.0.3.tgz#a1254c7d9c3a2d70cd6391a9f2f7694431b1b2cb"
+ integrity sha512-2KXBt9fSpymYHxHfvhUpjUFyzrmN4c4P8mwIzweLyvqntBT3k0YGZJSriOdjfUjwSygrfEwiuPI1EMrvgrOMJw==
+
+"@cspell/dict-lorem-ipsum@^4.0.3":
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-lorem-ipsum/-/dict-lorem-ipsum-4.0.3.tgz#c5fc631d934f1daf8b10c88b795278701a2469ec"
+ integrity sha512-WFpDi/PDYHXft6p0eCXuYnn7mzMEQLVeqpO+wHSUd+kz5ADusZ4cpslAA4wUZJstF1/1kMCQCZM6HLZic9bT8A==
+
+"@cspell/dict-lua@^4.0.6":
+ version "4.0.6"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-lua/-/dict-lua-4.0.6.tgz#7de412bfaead794445e26d566aec222e20ad69ba"
+ integrity sha512-Jwvh1jmAd9b+SP9e1GkS2ACbqKKRo9E1f9GdjF/ijmooZuHU0hPyqvnhZzUAxO1egbnNjxS/J2T6iUtjAUK2KQ==
+
+"@cspell/dict-makefile@^1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-makefile/-/dict-makefile-1.0.3.tgz#08d3349bf7cbd8f5dacf8641f3d35092ca0b8b38"
+ integrity sha512-R3U0DSpvTs6qdqfyBATnePj9Q/pypkje0Nj26mQJ8TOBQutCRAJbr2ZFAeDjgRx5EAJU/+8txiyVF97fbVRViw==
+
+"@cspell/dict-markdown@^2.0.7":
+ version "2.0.7"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-markdown/-/dict-markdown-2.0.7.tgz#15d6f9eed6bd1b33921b4332426ff387961163f1"
+ integrity sha512-F9SGsSOokFn976DV4u/1eL4FtKQDSgJHSZ3+haPRU5ki6OEqojxKa8hhj4AUrtNFpmBaJx/WJ4YaEzWqG7hgqg==
+
+"@cspell/dict-monkeyc@^1.0.9":
+ version "1.0.9"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-monkeyc/-/dict-monkeyc-1.0.9.tgz#58b5f6f15fc7c11ce0eeffd0742fba4b39fc0b8b"
+ integrity sha512-Jvf6g5xlB4+za3ThvenYKREXTEgzx5gMUSzrAxIiPleVG4hmRb/GBSoSjtkGaibN3XxGx5x809gSTYCA/IHCpA==
+
+"@cspell/dict-node@^5.0.5":
+ version "5.0.5"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-node/-/dict-node-5.0.5.tgz#11653612ebdd833208432e8b3cbe61bd6dd35dc3"
+ integrity sha512-7NbCS2E8ZZRZwlLrh2sA0vAk9n1kcTUiRp/Nia8YvKaItGXLfxYqD2rMQ3HpB1kEutal6hQLVic3N2Yi1X7AaA==
+
+"@cspell/dict-npm@^5.1.17":
+ version "5.1.20"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-npm/-/dict-npm-5.1.20.tgz#5e54b428d7609267263d426d0edc9d51d53f0a6f"
+ integrity sha512-vE9pFIifCDChsVhhUDuVtnwxygOdtHNluDm+8FkgC84M6LwiUVJr/CuSOI/SCR0oI9iiFp0VvMz194B6XwMv3g==
+
+"@cspell/dict-php@^4.0.13":
+ version "4.0.13"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-php/-/dict-php-4.0.13.tgz#86f1e6fb2174b2b0fa012baf86c448b2730f04f9"
+ integrity sha512-P6sREMZkhElzz/HhXAjahnICYIqB/HSGp1EhZh+Y6IhvC15AzgtDP8B8VYCIsQof6rPF1SQrFwunxOv8H1e2eg==
+
+"@cspell/dict-powershell@^5.0.13":
+ version "5.0.13"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-powershell/-/dict-powershell-5.0.13.tgz#f557aa04ee9bda4fe091308a0bcaea09ed12fa76"
+ integrity sha512-0qdj0XZIPmb77nRTynKidRJKTU0Fl+10jyLbAhFTuBWKMypVY06EaYFnwhsgsws/7nNX8MTEQuewbl9bWFAbsg==
+
+"@cspell/dict-public-licenses@^2.0.11":
+ version "2.0.11"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-public-licenses/-/dict-public-licenses-2.0.11.tgz#37550c4e0cd445991caba528bf4ba58ce7a935c3"
+ integrity sha512-rR5KjRUSnVKdfs5G+gJ4oIvQvm8+NJ6cHWY2N+GE69/FSGWDOPHxulCzeGnQU/c6WWZMSimG9o49i9r//lUQyA==
+
+"@cspell/dict-python@^4.2.13":
+ version "4.2.13"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-python/-/dict-python-4.2.13.tgz#c3dbaa7e2434c835e11540345e2168e5e685190a"
+ integrity sha512-mZIcmo9qif8LkJ6N/lqTZawcOk2kVTcuWIUOSbMcjyomO0XZ7iWz15TfONyr03Ea/l7o5ULV+MZ4vx76bAUb7w==
+ dependencies:
+ "@cspell/dict-data-science" "^2.0.5"
+
+"@cspell/dict-r@^2.0.4":
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-r/-/dict-r-2.0.4.tgz#31b5abd91cc12aebfffdde4be4d2902668789311"
+ integrity sha512-cBpRsE/U0d9BRhiNRMLMH1PpWgw+N+1A2jumgt1if9nBGmQw4MUpg2u9I0xlFVhstTIdzXiLXMxP45cABuiUeQ==
+
+"@cspell/dict-ruby@^5.0.7":
+ version "5.0.7"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-ruby/-/dict-ruby-5.0.7.tgz#3593a955baaffe3c5d28fb178b72fdf93c7eec71"
+ integrity sha512-4/d0hcoPzi5Alk0FmcyqlzFW9lQnZh9j07MJzPcyVO62nYJJAGKaPZL2o4qHeCS/od/ctJC5AHRdoUm0ktsw6Q==
+
+"@cspell/dict-rust@^4.0.10":
+ version "4.0.10"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-rust/-/dict-rust-4.0.10.tgz#8ae6eaf31a0ebce9dc8fd8dd68e5925e1d5290ee"
+ integrity sha512-6o5C8566VGTTctgcwfF3Iy7314W0oMlFFSQOadQ0OEdJ9Z9ERX/PDimrzP3LGuOrvhtEFoK8pj+BLnunNwRNrw==
+
+"@cspell/dict-scala@^5.0.6":
+ version "5.0.6"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-scala/-/dict-scala-5.0.6.tgz#5e925def2fe6dc27ee2ad1c452941c3d6790fb6d"
+ integrity sha512-tl0YWAfjUVb4LyyE4JIMVE8DlLzb1ecHRmIWc4eT6nkyDqQgHKzdHsnusxFEFMVLIQomgSg0Zz6hJ5S1E4W4ww==
+
+"@cspell/dict-software-terms@^4.1.19":
+ version "4.2.1"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-software-terms/-/dict-software-terms-4.2.1.tgz#d2fd5c9de75024eaabe329639110a5853bbade9b"
+ integrity sha512-8FiZHeeTqBdjsw4uBsZ9GIV9zEUbr49bBeEyVGFmUMZYwhAzC9riGqbTWco277X5Mabe8OjbYxqiP2/snC6w5w==
+
+"@cspell/dict-sql@^2.1.8":
+ version "2.1.8"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-sql/-/dict-sql-2.1.8.tgz#45ea53b3e57fd2cc5f839f49b644aa743dac4990"
+ integrity sha512-dJRE4JV1qmXTbbGm6WIcg1knmR6K5RXnQxF4XHs5HA3LAjc/zf77F95i5LC+guOGppVF6Hdl66S2UyxT+SAF3A==
+
+"@cspell/dict-svelte@^1.0.5":
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-svelte/-/dict-svelte-1.0.5.tgz#09752e01ff6667e737566d9dfc704c8dcc9a6492"
+ integrity sha512-sseHlcXOqWE4Ner9sg8KsjxwSJ2yssoJNqFHR9liWVbDV+m7kBiUtn2EB690TihzVsEmDr/0Yxrbb5Bniz70mA==
+
+"@cspell/dict-swift@^2.0.4":
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-swift/-/dict-swift-2.0.4.tgz#bc19522418ed68cf914736b612c4e4febbf07e8d"
+ integrity sha512-CsFF0IFAbRtYNg0yZcdaYbADF5F3DsM8C4wHnZefQy8YcHP/qjAF/GdGfBFBLx+XSthYuBlo2b2XQVdz3cJZBw==
+
+"@cspell/dict-terraform@^1.0.6":
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-terraform/-/dict-terraform-1.0.7.tgz#815a523c86f647cb7695d48b69e4a793c49f875e"
+ integrity sha512-Ip7tOlAt/qUVdWYyDMA7DlKMpQ6sjtrsXk4vcpqXoYpoJlzMoDce7pw+fPhHshtNOFBAZ4nOrszlLu6APuy+HQ==
+
+"@cspell/dict-typescript@^3.1.11":
+ version "3.1.11"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-typescript/-/dict-typescript-3.1.11.tgz#40586f13b0337bd9cba958e0661b35888580b249"
+ integrity sha512-FwvK5sKbwrVpdw0e9+1lVTl8FPoHYvfHRuQRQz2Ql5XkC0gwPPkpoyD1zYImjIyZRoYXk3yp9j8ss4iz7A7zoQ==
+
+"@cspell/dict-vue@^3.0.3":
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/@cspell/dict-vue/-/dict-vue-3.0.3.tgz#295c288f6fd363879898223202ec3be048663b98"
+ integrity sha512-akmYbrgAGumqk1xXALtDJcEcOMYBYMnkjpmGzH13Ozhq1mkPF4VgllFQlm1xYde+BUKNnzMgPEzxrL2qZllgYA==
+
+"@cspell/dynamic-import@8.17.1":
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/@cspell/dynamic-import/-/dynamic-import-8.17.1.tgz#2b3f3325b6013a067a1a49cda8b69ae73aaed36a"
+ integrity sha512-XQtr2olYOtqbg49E+8SISd6I5DzfxmsKINDn0ZgaTFeLalnNdF3ewDU4gOEbApIzGffRa1mW9t19MsiVrznSDw==
+ dependencies:
+ "@cspell/url" "8.17.1"
+ import-meta-resolve "^4.1.0"
+
+"@cspell/filetypes@8.17.1":
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/@cspell/filetypes/-/filetypes-8.17.1.tgz#d193afc5029364334f005ff23f4c4cb80170c374"
+ integrity sha512-AxYw6j7EPYtDFAFjwybjFpMc9waXQzurfBXmEVfQ5RQRlbylujLZWwR6GnMqofeNg4oGDUpEjcAZFrgdkvMQlA==
+
+"@cspell/strong-weak-map@8.17.1":
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/@cspell/strong-weak-map/-/strong-weak-map-8.17.1.tgz#2fa88f283ef10222fad25134b5ebb54edaad985f"
+ integrity sha512-8cY3vLAKdt5gQEMM3Gr57BuQ8sun2NjYNh9qTdrctC1S9gNC7XzFghTYAfHSWR4VrOUcMFLO/izMdsc1KFvFOA==
+
+"@cspell/url@8.17.1":
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/@cspell/url/-/url-8.17.1.tgz#e7daec1597fa31b4d0a7a685e7a24a11b0c8a193"
+ integrity sha512-LMvReIndW1ckvemElfDgTt282fb2C3C/ZXfsm0pJsTV5ZmtdelCHwzmgSBmY5fDr7D66XDp8EurotSE0K6BTvw==
+
"@floating-ui/core@^1.6.0":
version "1.6.4"
- resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.4.tgz#0140cf5091c8dee602bff9da5ab330840ff91df6"
+ resolved "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.4.tgz"
integrity sha512-a4IowK4QkXl4SCWTGUR0INAfEOX3wtsYw3rKK5InQEHMGObkR8Xk44qYQD9P4r6HHw0iIfK6GUKECmY8sTkqRA==
dependencies:
"@floating-ui/utils" "^0.2.4"
"@floating-ui/dom@^1.0.0", "@floating-ui/dom@^1.6.7":
version "1.6.7"
- resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.7.tgz#85d22f731fcc5b209db504478fb1df5116a83015"
+ resolved "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.7.tgz"
integrity sha512-wmVfPG5o2xnKDU4jx/m4w5qva9FWHcnZ8BvzEe90D/RpwsJaTAVYPEPdQ8sbr/N8zZTAHlZUTQdqg8ZUbzHmng==
dependencies:
"@floating-ui/core" "^1.6.0"
@@ -45,12 +595,12 @@
"@floating-ui/utils@^0.2.4":
version "0.2.4"
- resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.4.tgz#1d459cee5031893a08a0e064c406ad2130cced7c"
+ resolved "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.4.tgz"
integrity sha512-dWO2pw8hhi+WrXq1YJy2yCuWoL20PddgGaqTgVe4cOS9Q6qklXCiA1tJEqX6BEwRNSCP84/afac9hd4MS+zEUA==
"@floating-ui/vue@^1.1.0":
version "1.1.1"
- resolved "https://registry.yarnpkg.com/@floating-ui/vue/-/vue-1.1.1.tgz#008abc526108f3b01f005a7948f4f75e147d6321"
+ resolved "https://registry.npmjs.org/@floating-ui/vue/-/vue-1.1.1.tgz"
integrity sha512-cyawjk9etPZPl/RVtMRnWrwtAhWbPVSrRVYARgOzhLIqxr0k2up1APrrFjqP9QwRQ0AwjKSvbWg4YC6jESutow==
dependencies:
"@floating-ui/dom" "^1.0.0"
@@ -59,28 +609,28 @@
"@headlessui/vue@^1.7.14":
version "1.7.22"
- resolved "https://registry.yarnpkg.com/@headlessui/vue/-/vue-1.7.22.tgz#8d55a3a670c3d48beb660b7c47a7a8ff76caacfe"
+ resolved "https://registry.npmjs.org/@headlessui/vue/-/vue-1.7.22.tgz"
integrity sha512-Hoffjoolq1rY+LOfJ+B/OvkhuBXXBFgd8oBlN+l1TApma2dB0En0ucFZrwQtb33SmcCqd32EQd0y07oziXWNYg==
dependencies:
"@tanstack/vue-virtual" "^3.0.0-beta.60"
"@internationalized/date@^3.5.4":
version "3.5.4"
- resolved "https://registry.yarnpkg.com/@internationalized/date/-/date-3.5.4.tgz#49ba11634fd4350b7a9308e297032267b4063c44"
+ resolved "https://registry.npmjs.org/@internationalized/date/-/date-3.5.4.tgz"
integrity sha512-qoVJVro+O0rBaw+8HPjUB1iH8Ihf8oziEnqMnvhJUSuVIrHOuZ6eNLHNvzXJKUvAtaDiqMnRlg8Z2mgh09BlUw==
dependencies:
"@swc/helpers" "^0.5.0"
"@internationalized/number@^3.5.3":
version "3.5.3"
- resolved "https://registry.yarnpkg.com/@internationalized/number/-/number-3.5.3.tgz#9fa060c1c4809f23fb3d38dd3f3d1ae4c87e95a8"
+ resolved "https://registry.npmjs.org/@internationalized/number/-/number-3.5.3.tgz"
integrity sha512-rd1wA3ebzlp0Mehj5YTuTI50AQEx80gWFyHcQu+u91/5NgdwBecO8BH6ipPfE+lmQ9d63vpB3H9SHoIUiupllw==
dependencies:
"@swc/helpers" "^0.5.0"
"@jridgewell/gen-mapping@^0.3.2":
version "0.3.3"
- resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098"
+ 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"
@@ -89,22 +639,22 @@
"@jridgewell/resolve-uri@^3.1.0":
version "3.1.1"
- resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721"
+ resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz"
integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==
"@jridgewell/set-array@^1.0.1":
version "1.1.2"
- resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72"
+ resolved "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz"
integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14":
- version "1.4.15"
- resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
- integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
+ version "1.5.0"
+ resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz"
+ integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
"@jridgewell/trace-mapping@^0.3.9":
version "0.3.20"
- resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f"
+ resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz"
integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==
dependencies:
"@jridgewell/resolve-uri" "^3.1.0"
@@ -133,29 +683,29 @@
"@popperjs/core@^2.11.2", "@popperjs/core@^2.9.0":
version "2.11.8"
- resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f"
+ resolved "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz"
integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==
"@remirror/core-constants@^2.0.2":
version "2.0.2"
- resolved "https://registry.yarnpkg.com/@remirror/core-constants/-/core-constants-2.0.2.tgz#f05eccdc69e3a65e7d524b52548f567904a11a1a"
+ resolved "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-2.0.2.tgz"
integrity sha512-dyHY+sMF0ihPus3O27ODd4+agdHMEmuRdyiZJ2CCWjPV5UFmn17ZbElvk6WOGVE4rdCJKZQCrPV2BcikOMLUGQ==
"@socket.io/component-emitter@~3.1.0":
version "3.1.2"
- resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2"
+ resolved "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz"
integrity sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==
"@swc/helpers@^0.5.0":
version "0.5.12"
- resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.12.tgz#37aaca95284019eb5d2207101249435659709f4b"
+ resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.12.tgz"
integrity sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g==
dependencies:
tslib "^2.4.0"
"@tailwindcss/container-queries@^0.1.1":
version "0.1.1"
- resolved "https://registry.yarnpkg.com/@tailwindcss/container-queries/-/container-queries-0.1.1.tgz#9a759ce2cb8736a4c6a0cb93aeb740573a731974"
+ resolved "https://registry.npmjs.org/@tailwindcss/container-queries/-/container-queries-0.1.1.tgz"
integrity sha512-p18dswChx6WnTSaJCSGx6lTmrGzNNvm2FtXmiO6AuA1V4U5REyoqwmT6kgAsIMdjo07QdAfYXHJ4hnMtfHzWgA==
"@tailwindcss/forms@^0.4.0":
@@ -167,7 +717,7 @@
"@tailwindcss/forms@^0.5.3":
version "0.5.7"
- resolved "https://registry.yarnpkg.com/@tailwindcss/forms/-/forms-0.5.7.tgz#db5421f062a757b5f828bc9286ba626c6685e821"
+ resolved "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.7.tgz"
integrity sha512-QE7X69iQI+ZXwldE+rzasvbJiyV/ju1FGHH0Qn2W3FKbuYtqp8LKcy6iSw79fVUT5/Vvf+0XgLCeYVG+UV6hOw==
dependencies:
mini-svg-data-uri "^1.2.3"
@@ -215,7 +765,7 @@
"@tailwindcss/typography@^0.5.0":
version "0.5.13"
- resolved "https://registry.yarnpkg.com/@tailwindcss/typography/-/typography-0.5.13.tgz#cd788a4fa4d0ca2506e242d512f377b22c1f7932"
+ resolved "https://registry.npmjs.org/@tailwindcss/typography/-/typography-0.5.13.tgz"
integrity sha512-ADGcJ8dX21dVVHIwTRgzrcunY6YY9uSlAHHGVKvkA+vLc5qLwEszvKts40lx7z0qc4clpjclwLeK5rVCV2P/uw==
dependencies:
lodash.castarray "^4.4.0"
@@ -234,195 +784,195 @@
"@tanstack/virtual-core@3.8.3":
version "3.8.3"
- resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.8.3.tgz#9db61ab2a96e43d9e035b1cfd82eeede6d52f171"
+ resolved "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.8.3.tgz"
integrity sha512-vd2A2TnM5lbnWZnHi9B+L2gPtkSeOtJOAw358JqokIH1+v2J7vUAzFVPwB/wrye12RFOurffXu33plm4uQ+JBQ==
"@tanstack/vue-virtual@^3.0.0-beta.60", "@tanstack/vue-virtual@^3.8.1":
version "3.8.3"
- resolved "https://registry.yarnpkg.com/@tanstack/vue-virtual/-/vue-virtual-3.8.3.tgz#865410616bd6291387892db2bfc260c91926d770"
+ resolved "https://registry.npmjs.org/@tanstack/vue-virtual/-/vue-virtual-3.8.3.tgz"
integrity sha512-xrFLkOiqLoGwohgr1+Q880hkNdQWqwi19EXzx38iAjVEm1Db3KIAV0aVP57/dnNXU3NO1Vx8wnIHII5J4n1LyA==
dependencies:
"@tanstack/virtual-core" "3.8.3"
"@tiptap/core@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-2.5.4.tgz#8b08113512dd8dc9d98268ad6f982d62c85433d2"
+ resolved "https://registry.npmjs.org/@tiptap/core/-/core-2.5.4.tgz"
integrity sha512-Zs/hShr4+W02+0nOlpmr5cS2YjDRLqd+XMt+jsiQH0QNr3s1Lc82pfF6C3CjgLEZtdUzImZrW2ABtLlpvbogaA==
"@tiptap/extension-blockquote@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-blockquote/-/extension-blockquote-2.5.4.tgz#7b0bbf2bed91533a73887b0217bf8000681b8b5a"
+ resolved "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.5.4.tgz"
integrity sha512-UqeJunZM3IiCQGZE0X5YNUOWYkuIieqrwPgOEghAIjnhDcQizQcouRQ5R7cwwv/scNr2JvZHncOTLrALV3Janw==
"@tiptap/extension-bold@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-bold/-/extension-bold-2.5.4.tgz#c6e98a02da288ad171df4491a12870c7793c2ee2"
+ resolved "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.5.4.tgz"
integrity sha512-H5sjqloFMjq7VOSfE+U4T7dqGoflOiF6RW6/gZm/U6KYeHG2/bG0ktq7mWAnnhbiKiy7gUcxyJCV+ILdGX9C5g==
"@tiptap/extension-bubble-menu@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.5.4.tgz#eaff01a21869a9d65b8fd6e29043008c8ad1b03c"
+ resolved "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.5.4.tgz"
integrity sha512-GHwef912K1yd75pp9JGDnKSp1DvdOHH8BcHQv0no+a3q2ePFPYcgaSwVRR59jHRX9WzdVfoLcqDSAeoNGOrISw==
dependencies:
tippy.js "^6.3.7"
"@tiptap/extension-bullet-list@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-bullet-list/-/extension-bullet-list-2.5.4.tgz#96949f7e418fbc00614eb9f601377fa14606937b"
+ resolved "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.5.4.tgz"
integrity sha512-aAfpALeD6OxymkbtrzDqbgkAkzVVHudxOb8GsK1N6m42nFL7Q9JzHJ5/8KzB+xi25CcIbS+HmXJkRIQJXgNbSA==
"@tiptap/extension-code-block@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-code-block/-/extension-code-block-2.5.4.tgz#03931fa50e0498d3d032f34ab29ba20dacd55edc"
+ resolved "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.5.4.tgz"
integrity sha512-lZRz44ACSL0IC4syWkNsNSe90sZuLig0yidfV9rs2muSCLoS3PRcCIJv4GjdBHouangxxBZqzIqWgPBqe6pqwA==
"@tiptap/extension-code@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-code/-/extension-code-2.5.4.tgz#100d437183f0810195eaaf03870ca8a23a37aff8"
+ resolved "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.5.4.tgz"
integrity sha512-PCP0VcWR0Jsj3rum3czp1jateR+kv1iuB9E+TieGLN4vFqhoiUwSv2UAuhvD8x66MGCYLA3btgnmPov1w/iNmA==
"@tiptap/extension-color@^2.0.3":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-color/-/extension-color-2.5.4.tgz#9d046ea49428655194b49e8ead373201410fb599"
+ resolved "https://registry.npmjs.org/@tiptap/extension-color/-/extension-color-2.5.4.tgz"
integrity sha512-f4ltxa4Y9NzD6+xFkjVo925+OltZbtYEuwUSXQKU4NJyjiMBMUOzW+mCgQM2TB5V36VP2ttIvdQ+W99yazJqUg==
"@tiptap/extension-document@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-2.5.4.tgz#99279433ddd1572bd8e92f43cb40aa72ab576574"
+ resolved "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.5.4.tgz"
integrity sha512-4RDrhASxCTOZETYhIhEW1TfZqx3Tm+LQxouvBMFyODmT1PSgsg5Xz1FYpDPr+J49bGAK0Pr9ae0XcGW011L3sA==
"@tiptap/extension-dropcursor@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-dropcursor/-/extension-dropcursor-2.5.4.tgz#637984ea57d78ae24282c5d7f2328944855a1007"
+ resolved "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.5.4.tgz"
integrity sha512-jzSnuuYhlc0SsHvAteWkE9TJy3eRwkxQs4MO2JxALOzJECN4G82nlX8vciihBD6xf7lVgVSBACejK9+rsTHqCg==
"@tiptap/extension-floating-menu@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-2.5.4.tgz#a80e54c685c24c320ef389b8d13f7382bc7e8f8f"
+ resolved "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-2.5.4.tgz"
integrity sha512-EqD4rgi3UhnDcV3H1+ndAS4Ue2zpsU7hFKoevOIV6GS7xVnWN70AGt6swH24QzuHKKISFtWoLpKjrwRORNIxuA==
dependencies:
tippy.js "^6.3.7"
"@tiptap/extension-gapcursor@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-gapcursor/-/extension-gapcursor-2.5.4.tgz#45f6ef87458e7261e51fbc7f3343278c3e8f4534"
+ resolved "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.5.4.tgz"
integrity sha512-wzTh1piODZBS0wmuDgPjjg8PQwclYa5LssnxDIo9pDSnt4l3AfHSAJIJSGIfgt96KnzF1wqRTRpe08qNa1n7/g==
"@tiptap/extension-hard-break@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-2.5.4.tgz#df6e70930e6b426b527d1150ff0bde8118ea6d41"
+ resolved "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.5.4.tgz"
integrity sha512-nLn6HP9tqgdGGwbMORXVtcY30DTGctYFaWADRthvBjVgacYSeKlhUcsSu3YgaxtbxZp6BhfRvD2kKrxyQsSjnQ==
"@tiptap/extension-heading@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-heading/-/extension-heading-2.5.4.tgz#b901d08a2c268bda54eef345836efa2a0b5f388a"
+ resolved "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.5.4.tgz"
integrity sha512-DuAB58/e7eho1rkyad0Z/SjW+EB+H2hRqHlswEeZZYhBTjzey5UmBwkMWTGC/SQiRisx1xYQYTd8T0fiABi5hw==
"@tiptap/extension-highlight@^2.0.3":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-highlight/-/extension-highlight-2.5.4.tgz#c5b25bc01ab3b277cbcdb149da2b4d8d5361a0a8"
+ resolved "https://registry.npmjs.org/@tiptap/extension-highlight/-/extension-highlight-2.5.4.tgz"
integrity sha512-TSYnFBluZu1YQdTCyXl2wuxFuhFUYFzbaV0f1wq2P2Nc8U2OiiuaNz+QggHw5Hf3ILzkRxQCUQnq97Q/5smMwQ==
"@tiptap/extension-history@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-history/-/extension-history-2.5.4.tgz#53cda40d723120a3d599d75eee0ab2c533dbdd25"
+ resolved "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.5.4.tgz"
integrity sha512-WB1fZYGIlpahAD6Ba+mj9vIb1tk8S3TsADXDFKxLVpZWZPQ+B7duGJP7g/vRH2XAXEs836JzC2oxjKeaop3k7A==
"@tiptap/extension-horizontal-rule@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.5.4.tgz#2c595a17114653f11236107c0bb1f094ab7f261d"
+ resolved "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.5.4.tgz"
integrity sha512-uXLDe/iyzQbyfDkJ8kE5XaAkY3EOcbTFLjbueqGlkbWtjJgy+3LysGvh8fQj8PAOaIBMaFRFhTq7GMbW2ebRog==
"@tiptap/extension-image@^2.0.3":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-image/-/extension-image-2.5.4.tgz#bdf8dd9c820f17d8a77c2c5ae7db7f3f6f821659"
+ resolved "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-2.5.4.tgz"
integrity sha512-4ySSP7iPsbbo1SlPJYj546TKettuO6FGY5MQKxH8AGnZWyQGZYl89GpU1iGFAaeHq4dKUemM5D3ikgSynEQLow==
"@tiptap/extension-italic@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-italic/-/extension-italic-2.5.4.tgz#9bc9674f1094a6f55fa9b59a9dcacd3bec8c2b46"
+ resolved "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.5.4.tgz"
integrity sha512-TAhtl/fNBgv1elzF3HWES8uwVdpKBSYrq1e6yeYfj74mQn//3ksvdhWQrLzc1e+zcoHbk1PeOp/5ODdPuZ6tkg==
"@tiptap/extension-link@^2.0.3":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-link/-/extension-link-2.5.4.tgz#a256652198cc0abb662608802c7bb98ee1914067"
+ resolved "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.5.4.tgz"
integrity sha512-xTB/+T6SHHCXInJni8WdqOfF40a/MiFUf5OoWW9cPrApx3I7TzJ9j8/WDshM0BOnDDw80w1bl9F2zkUQjC0Y2A==
dependencies:
linkifyjs "^4.1.0"
"@tiptap/extension-list-item@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-list-item/-/extension-list-item-2.5.4.tgz#ad837a7ba2a0c6362020c2c1c4a2a14de684d80d"
+ resolved "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.5.4.tgz"
integrity sha512-bPxUCFt9HnAfoaZQgwqCfRAZ6L3QlYhIRDDbOvZag7IxCdQuZmeY4k5OZfQIGijNDTag7CN9cdL4fl9rnm6/sQ==
"@tiptap/extension-mention@^2.0.3":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-mention/-/extension-mention-2.5.4.tgz#9f535a1393c43bb4750b9773bacf30f51f39bef2"
+ resolved "https://registry.npmjs.org/@tiptap/extension-mention/-/extension-mention-2.5.4.tgz"
integrity sha512-U5Kqjhs7FraJzopZydy14/v0+X6unmfYYt42QHhVeSEdZ8y7QtyFigJktJUBzE12CpwGkyh8e3xI9Ozi7lFb0w==
"@tiptap/extension-ordered-list@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-ordered-list/-/extension-ordered-list-2.5.4.tgz#b007d46440568df87bfd166d3dea203239916744"
+ resolved "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.5.4.tgz"
integrity sha512-cl3cTJitY6yDUmxqgjDUtDWCyX1VVsZNJ6i9yiPeARcxvzFc81KmUJxTGl8WPT5TjqmM+TleRkZjsxgvXX57+Q==
"@tiptap/extension-paragraph@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-2.5.4.tgz#6aa8da578161ecedfb12e37cc515147d4bd5b476"
+ resolved "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.5.4.tgz"
integrity sha512-pC1YIkkRPXoU0eDrhfAf8ZrFJQzvw2ftP6KRhLnnSw/Ot1DOjT1r95l7zsFefS9oCDMT/L4HghTAiPZ4rcpPbg==
"@tiptap/extension-placeholder@^2.0.3":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-placeholder/-/extension-placeholder-2.5.4.tgz#6841b137011d7873725c99ff07074b0f21af847b"
+ resolved "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.5.4.tgz"
integrity sha512-mcj4j2Z/L1H5dzWHbbWChuAdJK9F2p06fcjqL4iyJtVx38QQFzCdVmGaTAim8CLp/EynbAOYJ5gk9w2PTdv7+w==
"@tiptap/extension-strike@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-strike/-/extension-strike-2.5.4.tgz#756af9aaef76d0b061741020d766654ea5bf1b63"
+ resolved "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.5.4.tgz"
integrity sha512-OSN6ePbCwEhi3hYZZOPow/P9Ym2Kv3NhVbUvasjZCiqQuk8TGc33xirPWl9DTjb/BLfL66TtJ2tKUEVOKl5dKg==
"@tiptap/extension-table-cell@^2.0.3":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-table-cell/-/extension-table-cell-2.5.4.tgz#2c2f41023f76d3c1eb47e78bd2604ecdf06df5d8"
+ resolved "https://registry.npmjs.org/@tiptap/extension-table-cell/-/extension-table-cell-2.5.4.tgz"
integrity sha512-ntiexoIOchSQEtyxJ7RfRcX8SIMKoNl/RZT7e7q8luh6O8BAg8ijbjOnPcwaSJhcQIR+fGHqZCqu7Qud2Usp/g==
"@tiptap/extension-table-header@^2.0.3":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-table-header/-/extension-table-header-2.5.4.tgz#4983591f2de9557a4802c12c383d16cb7976d0ef"
+ resolved "https://registry.npmjs.org/@tiptap/extension-table-header/-/extension-table-header-2.5.4.tgz"
integrity sha512-0JV7yxf7UQXcnNBeh0ruJzpgxbPWtJjQ5CB7R/2nGGJtK5Zd4qbBSvPwZb90rrzbfGG6gPyH/840nBOV9Hihqw==
"@tiptap/extension-table-row@^2.0.3":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-table-row/-/extension-table-row-2.5.4.tgz#72ecb52775990eb3f75bb45d7bc7eced64cac03b"
+ resolved "https://registry.npmjs.org/@tiptap/extension-table-row/-/extension-table-row-2.5.4.tgz"
integrity sha512-syE0HO+1nZ6cZP+A1BnOfyBLY5/fSzlqXId1SzDxp3w2RfUldXfrV9ltyyEE6wxruxCgI+V5J3wV3ObSXy9PMA==
"@tiptap/extension-table@^2.0.3":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-table/-/extension-table-2.5.4.tgz#5e68f06a812113671b8d23a3412cdbb42419accb"
+ resolved "https://registry.npmjs.org/@tiptap/extension-table/-/extension-table-2.5.4.tgz"
integrity sha512-EvK3XQmbuje0re8xCXuGcPO1NgnRh1MYUe2zi4++rPNDN2nTzCvJI1QdYfA9DYMdklnpvygnXCJhgvx1rB/26Q==
"@tiptap/extension-text-align@^2.0.3":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-text-align/-/extension-text-align-2.5.4.tgz#d4521ba87cab5249b5df7b0f1e4db5ac40c387a0"
+ resolved "https://registry.npmjs.org/@tiptap/extension-text-align/-/extension-text-align-2.5.4.tgz"
integrity sha512-hQT7wPVISw7fgMTT0XfK6uk3T2qLKpeYWOUBO1ENEdim6HQmFTOIgNyAdVcCipaedQSlD72ysfRXq2S1mzWzEw==
"@tiptap/extension-text-style@^2.0.3":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-text-style/-/extension-text-style-2.5.4.tgz#ff7f67f7eb8f035a8ca8d98b112948bc850c9364"
+ resolved "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-2.5.4.tgz"
integrity sha512-OwQ6rQrwVSCTicxJJ67C5Z+LQjZp9HyZDeEcrQgPsv/gtk6H69qo1jShHAdmYn4ck40CkuNyN6VKczd9VZf0+g==
"@tiptap/extension-text@^2.5.4":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-2.5.4.tgz#235638ad08975a321dae4f2a2c1e495f38bd3adb"
+ resolved "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.5.4.tgz"
integrity sha512-+3x/hYqhmCYbvedCcQzQHFtZ5MAcMOlKuczomZtygf8AfDfuQVrG1m4GoJyNzJdqxjN80/xq4e2vDVvqQxYTCw==
"@tiptap/extension-typography@^2.0.3":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/extension-typography/-/extension-typography-2.5.4.tgz#6b3615e047de4ae0574c258ae865a2a96187f79c"
+ resolved "https://registry.npmjs.org/@tiptap/extension-typography/-/extension-typography-2.5.4.tgz"
integrity sha512-LXctwoKdmWw9geXngQWGHcwEHIYLJ5v7GX3GuudN+oHhSV2MTGUTYZ2qv/RLIR9kvB0vcV9vTF98YJxEnjU5Fw==
"@tiptap/pm@^2.0.3":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/pm/-/pm-2.5.4.tgz#6d66cd8ab3bd696958a4a62f34d2032a82a28910"
+ resolved "https://registry.npmjs.org/@tiptap/pm/-/pm-2.5.4.tgz"
integrity sha512-oFIsuniptdUXn93x4aM2sVN3hYKo9Fj55zAkYrWhwxFYUYcPxd5ibra2we+wRK5TaiPu098wpC+yMSTZ/KKMpA==
dependencies:
prosemirror-changeset "^2.2.1"
@@ -446,7 +996,7 @@
"@tiptap/starter-kit@^2.0.3":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/starter-kit/-/starter-kit-2.5.4.tgz#81150a023e07f8c3a4c05e8fd3d0cfe0c4381df8"
+ resolved "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.5.4.tgz"
integrity sha512-IYnSETtBUSsy+Ece4kfVyzew+zyj7W9rP2Ronx0CbjeWQarfCAGxjuZ6uGLPB+tC5ZuMVt68Gyqb2y8GFes2Yw==
dependencies:
"@tiptap/core" "^2.5.4"
@@ -471,12 +1021,12 @@
"@tiptap/suggestion@^2.0.3":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/suggestion/-/suggestion-2.5.4.tgz#b5aad02c3408cc5bcdc5bc4539fc1f3c8d381671"
+ resolved "https://registry.npmjs.org/@tiptap/suggestion/-/suggestion-2.5.4.tgz"
integrity sha512-mf0gC237PFz5l/hFRIetZoXemLMUXtmTPRbHTgBzqkTfaiJhfWsZZ3VeQNh4hoQ5AGYxRHWb9+zgRNGsH4jAEw==
"@tiptap/vue-3@^2.0.3":
version "2.5.4"
- resolved "https://registry.yarnpkg.com/@tiptap/vue-3/-/vue-3-2.5.4.tgz#87f9bb39fed52237e0b5978100da78a951c1d3a1"
+ resolved "https://registry.npmjs.org/@tiptap/vue-3/-/vue-3-2.5.4.tgz"
integrity sha512-7pr1WnWfXiSPIzkGEM/8S10ANAfgZzfQ5MiAtszxKOHJjrndpj5W4OgXxPEht5sMaPj0eRbGIFOkgKqTNut1dQ==
dependencies:
"@tiptap/extension-bubble-menu" "^2.5.4"
@@ -487,6 +1037,20 @@
resolved "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz"
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==
+"@types/conventional-commits-parser@^5.0.0":
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.1.tgz#8cb81cf170853496cbc501a3b32dcf5e46ffb61a"
+ integrity sha512-7uz5EHdzz2TqoMfV7ee61Egf5y6NkcO4FB/1iCCQnbeiI1F3xzv3vK5dBCXUCLQgGYS+mUeigK1iKQzvED+QnQ==
+ dependencies:
+ "@types/node" "*"
+
+"@types/node@*":
+ version "22.10.2"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-22.10.2.tgz#a485426e6d1fdafc7b0d4c7b24e2c78182ddabb9"
+ integrity sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==
+ dependencies:
+ undici-types "~6.20.0"
+
"@types/parse-json@^4.0.0":
version "4.0.0"
resolved "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz"
@@ -494,12 +1058,12 @@
"@types/web-bluetooth@^0.0.20":
version "0.0.20"
- resolved "https://registry.yarnpkg.com/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz#f066abfcd1cbe66267cdbbf0de010d8a41b41597"
+ resolved "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.20.tgz"
integrity sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==
"@vueuse/core@^10.11.0", "@vueuse/core@^10.4.1":
version "10.11.0"
- resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-10.11.0.tgz#b042585a8bf98bb29c177b33999bd0e3fcd9e65d"
+ resolved "https://registry.npmjs.org/@vueuse/core/-/core-10.11.0.tgz"
integrity sha512-x3sD4Mkm7PJ+pcq3HX8PLPBadXCAlSDR/waK87dz0gQE+qJnaaFhc/dZVfJz+IUYzTMVGum2QlR7ImiJQN4s6g==
dependencies:
"@types/web-bluetooth" "^0.0.20"
@@ -509,16 +1073,24 @@
"@vueuse/metadata@10.11.0":
version "10.11.0"
- resolved "https://registry.yarnpkg.com/@vueuse/metadata/-/metadata-10.11.0.tgz#27be47cf115ee98e947a1bfcd0b1b5b35d785fb6"
+ resolved "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.11.0.tgz"
integrity sha512-kQX7l6l8dVWNqlqyN3ePW3KmjCQO3ZMgXuBMddIu83CmucrsBfXlH+JoviYyRBws/yLTQO8g3Pbw+bdIoVm4oQ==
"@vueuse/shared@10.11.0", "@vueuse/shared@^10.11.0":
version "10.11.0"
- resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-10.11.0.tgz#be09262b2c5857069ed3dadd1680f22c4cb6f984"
+ resolved "https://registry.npmjs.org/@vueuse/shared/-/shared-10.11.0.tgz"
integrity sha512-fyNoIXEq3PfX1L3NkNhtVQUSRtqYwJtJg+Bp9rIzculIZWHTkKSysujrOk2J+NrRulLTQH9+3gGSfYLWSEWU1A==
dependencies:
vue-demi ">=0.14.8"
+JSONStream@^1.3.5:
+ version "1.3.5"
+ resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0"
+ integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==
+ dependencies:
+ jsonparse "^1.2.0"
+ through ">=2.2.7 <3"
+
acorn-node@^1.6.1:
version "1.8.2"
resolved "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz"
@@ -538,6 +1110,21 @@ acorn@^7.0.0:
resolved "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz"
integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==
+ajv@^8.11.0:
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6"
+ integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==
+ dependencies:
+ fast-deep-equal "^3.1.3"
+ fast-uri "^3.0.1"
+ json-schema-traverse "^1.0.0"
+ require-from-string "^2.0.2"
+
+ansi-regex@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
+ integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
+
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz"
@@ -545,6 +1132,13 @@ ansi-styles@^3.2.1:
dependencies:
color-convert "^1.9.0"
+ansi-styles@^4.0.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
+ integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
+ dependencies:
+ color-convert "^2.0.1"
+
ansi-styles@^4.1.0:
version "4.2.1"
resolved "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz"
@@ -555,7 +1149,7 @@ ansi-styles@^4.1.0:
any-promise@^1.0.0:
version "1.3.0"
- resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
+ resolved "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz"
integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==
anymatch@~3.1.2:
@@ -573,21 +1167,31 @@ arg@^5.0.1:
arg@^5.0.2:
version "5.0.2"
- resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c"
+ 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.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
+ resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
aria-hidden@^1.2.4:
version "1.2.4"
- resolved "https://registry.yarnpkg.com/aria-hidden/-/aria-hidden-1.2.4.tgz#b78e383fdbc04d05762c78b4a25a501e736c4522"
+ resolved "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.4.tgz"
integrity sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==
dependencies:
tslib "^2.0.0"
+array-ify@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece"
+ integrity sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==
+
+array-timsort@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/array-timsort/-/array-timsort-1.0.3.tgz#3c9e4199e54fb2b9c3fe5976396a21614ef0d926"
+ integrity sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==
+
autoprefixer@^10.4.2:
version "10.4.2"
resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.2.tgz"
@@ -615,7 +1219,7 @@ autoprefixer@^9:
balanced-match@^1.0.0:
version "1.0.2"
- resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
+ resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
binary-extensions@^2.0.0:
@@ -625,15 +1229,15 @@ binary-extensions@^2.0.0:
brace-expansion@^1.1.7:
version "1.1.11"
- resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
+ 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"
-braces@^3.0.1, braces@^3.0.2, braces@~3.0.2:
+braces@^3.0.3, braces@~3.0.2:
version "3.0.3"
- resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
+ resolved "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz"
integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
dependencies:
fill-range "^7.1.1"
@@ -654,7 +1258,7 @@ bytes@^3.0.0:
resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz"
integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==
-callsites@^3.0.0:
+callsites@^3.0.0, callsites@^3.1.0:
version "3.1.0"
resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz"
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
@@ -669,6 +1273,13 @@ caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001286, caniuse-lite@^1.0.300012
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001382.tgz"
integrity sha512-2rtJwDmSZ716Pxm1wCtbPvHtbDWAreTPxXbkc5RkKglow3Ig/4GNGazDI9/BVnXbG/wnv6r3B5FEbkfg9OcTGg==
+chalk-template@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/chalk-template/-/chalk-template-1.1.0.tgz#ffc55db6dd745e9394b85327c8ac8466edb7a7b1"
+ integrity sha512-T2VJbcDuZQ0Tb2EWwSotMPJjgpy1/tGee1BTpUNsGZ/qgNjV2t7Mvu+d4600U564nbLesN1x2dPL+xii174Ekg==
+ dependencies:
+ chalk "^5.2.0"
+
chalk@^2.0.0, chalk@^2.4.1:
version "2.4.2"
resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz"
@@ -686,6 +1297,11 @@ chalk@^4.1.2:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
+chalk@^5.2.0, chalk@^5.3.0:
+ version "5.4.1"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.4.1.tgz#1b48bf0963ec158dce2aacf69c093ae2dd2092d8"
+ integrity sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==
+
chokidar@^3.5.2, chokidar@^3.5.3:
version "3.5.3"
resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz"
@@ -703,9 +1319,26 @@ chokidar@^3.5.2, chokidar@^3.5.3:
classnames@^2.2.5:
version "2.5.1"
- resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b"
+ resolved "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz"
integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==
+clear-module@^4.1.2:
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/clear-module/-/clear-module-4.1.2.tgz#5a58a5c9f8dccf363545ad7284cad3c887352a80"
+ integrity sha512-LWAxzHqdHsAZlPlEyJ2Poz6AIs384mPeqLVCru2p0BrP9G/kVGuhNyZYClLO6cXlnuJjzC8xtsJIuMjKqLXoAw==
+ dependencies:
+ parent-module "^2.0.0"
+ resolve-from "^5.0.0"
+
+cliui@^8.0.1:
+ version "8.0.1"
+ resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa"
+ integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==
+ dependencies:
+ string-width "^4.2.0"
+ strip-ansi "^6.0.1"
+ wrap-ansi "^7.0.0"
+
color-convert@^1.9.0:
version "1.9.3"
resolved "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz"
@@ -746,9 +1379,14 @@ color@^4.0.1:
color-convert "^2.0.1"
color-string "^1.6.0"
+commander@^12.1.0:
+ version "12.1.0"
+ resolved "https://registry.yarnpkg.com/commander/-/commander-12.1.0.tgz#01423b36f501259fdaac4d0e4d60c96c991585d3"
+ integrity sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==
+
commander@^4.0.0:
version "4.1.1"
- resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
+ resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz"
integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
commander@^6.0.0:
@@ -758,19 +1396,82 @@ commander@^6.0.0:
commander@^9.0.0:
version "9.5.0"
- resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30"
+ resolved "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz"
integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==
+comment-json@^4.2.5:
+ version "4.2.5"
+ resolved "https://registry.yarnpkg.com/comment-json/-/comment-json-4.2.5.tgz#482e085f759c2704b60bc6f97f55b8c01bc41e70"
+ integrity sha512-bKw/r35jR3HGt5PEPm1ljsQQGyCrR8sFGNiN5L+ykDHdpO8Smxkrkla9Yi6NkQyUrb8V54PGhfMs6NrIwtxtdw==
+ dependencies:
+ array-timsort "^1.0.3"
+ core-util-is "^1.0.3"
+ esprima "^4.0.1"
+ has-own-prop "^2.0.0"
+ repeat-string "^1.6.1"
+
+commitlint@^19.6.1:
+ version "19.6.1"
+ resolved "https://registry.yarnpkg.com/commitlint/-/commitlint-19.6.1.tgz#8fbfc2ee8cd62172360923679287841b536ee271"
+ integrity sha512-tU4or+Y2fDXepCZ44o8guEB9uwrRp4if4VupGH1CR+bsVS2zX6Gia4dndA7UPx8cWWw1tvRRJu5keA7RqfXf3w==
+ dependencies:
+ "@commitlint/cli" "^19.6.1"
+ "@commitlint/types" "^19.5.0"
+
+compare-func@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-2.0.0.tgz#fb65e75edbddfd2e568554e8b5b05fff7a51fcb3"
+ integrity sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==
+ dependencies:
+ array-ify "^1.0.0"
+ dot-prop "^5.1.0"
+
concat-map@0.0.1:
version "0.0.1"
- resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
+ resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
+conventional-changelog-angular@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz#5eec8edbff15aa9b1680a8dcfbd53e2d7eb2ba7a"
+ integrity sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==
+ dependencies:
+ compare-func "^2.0.0"
+
+conventional-changelog-conventionalcommits@^7.0.2:
+ version "7.0.2"
+ resolved "https://registry.yarnpkg.com/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz#aa5da0f1b2543094889e8cf7616ebe1a8f5c70d5"
+ integrity sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==
+ dependencies:
+ compare-func "^2.0.0"
+
+conventional-commits-parser@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz#57f3594b81ad54d40c1b4280f04554df28627d9a"
+ integrity sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==
+ dependencies:
+ JSONStream "^1.3.5"
+ is-text-path "^2.0.0"
+ meow "^12.0.1"
+ split2 "^4.0.0"
+
core-js@^3.1.3:
version "3.37.1"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.37.1.tgz#d21751ddb756518ac5a00e4d66499df981a62db9"
+ resolved "https://registry.npmjs.org/core-js/-/core-js-3.37.1.tgz"
integrity sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==
+core-util-is@^1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
+ integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
+
+cosmiconfig-typescript-loader@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.1.0.tgz#7f644503e1c2bff90aed2d29a637008f279646bb"
+ integrity sha512-tJ1w35ZRUiM5FeTzT7DtYWAFFv37ZLqSRkGi2oeCK1gPhvaWjkAtfXvLmvE1pRfxxp9aQo6ba/Pvg1dKj05D4g==
+ dependencies:
+ jiti "^2.4.1"
+
cosmiconfig@^7.0.1:
version "7.0.1"
resolved "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz"
@@ -782,11 +1483,137 @@ cosmiconfig@^7.0.1:
path-type "^4.0.0"
yaml "^1.10.0"
+cosmiconfig@^9.0.0:
+ version "9.0.0"
+ resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-9.0.0.tgz#34c3fc58287b915f3ae905ab6dc3de258b55ad9d"
+ integrity sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==
+ dependencies:
+ env-paths "^2.2.1"
+ import-fresh "^3.3.0"
+ js-yaml "^4.1.0"
+ parse-json "^5.2.0"
+
crelt@^1.0.0:
version "1.0.6"
- resolved "https://registry.yarnpkg.com/crelt/-/crelt-1.0.6.tgz#7cc898ea74e190fb6ef9dae57f8f81cf7302df72"
+ resolved "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz"
integrity sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==
+cspell-config-lib@8.17.1:
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/cspell-config-lib/-/cspell-config-lib-8.17.1.tgz#a87973b91d51bf23a2018042c25aeaaa8a4e69c0"
+ integrity sha512-x1S7QWprgUcwuwiJB1Ng0ZTBC4G50qP9qQyg/aroMkcdMsHfk26E8jUGRPNt4ftHFzS4YMhwtXuJQ9IgRUuNPA==
+ dependencies:
+ "@cspell/cspell-types" "8.17.1"
+ comment-json "^4.2.5"
+ yaml "^2.6.1"
+
+cspell-dictionary@8.17.1:
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/cspell-dictionary/-/cspell-dictionary-8.17.1.tgz#bfc9bfdbd3720d1425260a98091acffab7b03dd5"
+ integrity sha512-zSl9l3wii+x16yc2NVZl/+CMLeLBAiuEd5YoFkOYPcbTJnfPwdjMNcj71u7wBvNJ+qwbF+kGbutEt15yHW3NBw==
+ dependencies:
+ "@cspell/cspell-pipe" "8.17.1"
+ "@cspell/cspell-types" "8.17.1"
+ cspell-trie-lib "8.17.1"
+ fast-equals "^5.0.1"
+
+cspell-gitignore@8.17.1:
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/cspell-gitignore/-/cspell-gitignore-8.17.1.tgz#38f3213a40ba86480bb5f66a91198db6e0ef37c0"
+ integrity sha512-bk727Zf4FBCjm9Mwvyreyhgjwe+YhPQEW7PldkHiinKd+Irfez4s8GXLQb1EgV0UpvViqaqBqLmngjZdS30BTA==
+ dependencies:
+ "@cspell/url" "8.17.1"
+ cspell-glob "8.17.1"
+ cspell-io "8.17.1"
+ find-up-simple "^1.0.0"
+
+cspell-glob@8.17.1:
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/cspell-glob/-/cspell-glob-8.17.1.tgz#23d1be46b32fb4933487e4edff347d34db446f5a"
+ integrity sha512-cUwM5auSt0RvLX7UkP2GEArJRWc85l51B1voArl+3ZIKeMZwcJpJgN3qvImtF8yRTZwYeYCs1sgsihb179q+mg==
+ dependencies:
+ "@cspell/url" "8.17.1"
+ micromatch "^4.0.8"
+
+cspell-grammar@8.17.1:
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/cspell-grammar/-/cspell-grammar-8.17.1.tgz#8f6619fbfaebff6aeee63b13d17898b4d0c09136"
+ integrity sha512-H5tLcBuW7aUj9L0rR+FSbnWPEsWb8lWppHVidtqw9Ll1CUHWOZC9HTB2RdrhJZrsz/8DJbM2yNbok0Xt0VAfdw==
+ dependencies:
+ "@cspell/cspell-pipe" "8.17.1"
+ "@cspell/cspell-types" "8.17.1"
+
+cspell-io@8.17.1:
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/cspell-io/-/cspell-io-8.17.1.tgz#b91f1cac1c64a6fa2b61a388d0dc67437fcf3ada"
+ integrity sha512-liIOsblt7oVItifzRAbuxiYrwlgw1VOqKppMxVKtYoAn2VUuuEpjCj6jLWpoTqSszR/38o7ChsHY1LHakhJZmw==
+ dependencies:
+ "@cspell/cspell-service-bus" "8.17.1"
+ "@cspell/url" "8.17.1"
+
+cspell-lib@8.17.1:
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/cspell-lib/-/cspell-lib-8.17.1.tgz#21c76f1ea4e91c90245e55acddbf452d055a6607"
+ integrity sha512-66n83Q7bK5tnvkDH7869/pBY/65AKmZVfCOAlsbhJn3YMDbNHFCHR0d1oNMlqG+n65Aco89VGwYfXxImZY+/mA==
+ dependencies:
+ "@cspell/cspell-bundled-dicts" "8.17.1"
+ "@cspell/cspell-pipe" "8.17.1"
+ "@cspell/cspell-resolver" "8.17.1"
+ "@cspell/cspell-types" "8.17.1"
+ "@cspell/dynamic-import" "8.17.1"
+ "@cspell/filetypes" "8.17.1"
+ "@cspell/strong-weak-map" "8.17.1"
+ "@cspell/url" "8.17.1"
+ clear-module "^4.1.2"
+ comment-json "^4.2.5"
+ cspell-config-lib "8.17.1"
+ cspell-dictionary "8.17.1"
+ cspell-glob "8.17.1"
+ cspell-grammar "8.17.1"
+ cspell-io "8.17.1"
+ cspell-trie-lib "8.17.1"
+ env-paths "^3.0.0"
+ fast-equals "^5.0.1"
+ gensequence "^7.0.0"
+ import-fresh "^3.3.0"
+ resolve-from "^5.0.0"
+ vscode-languageserver-textdocument "^1.0.12"
+ vscode-uri "^3.0.8"
+ xdg-basedir "^5.1.0"
+
+cspell-trie-lib@8.17.1:
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/cspell-trie-lib/-/cspell-trie-lib-8.17.1.tgz#618e5cc671b0a24cf7ec27a9a9b834b197e17392"
+ integrity sha512-13WNa5s75VwOjlGzWprmfNbBFIfXyA7tYYrbV+LugKkznyNZJeJPojHouEudcLq3SYb2Q6tJ7qyWcuT5bR9qPA==
+ dependencies:
+ "@cspell/cspell-pipe" "8.17.1"
+ "@cspell/cspell-types" "8.17.1"
+ gensequence "^7.0.0"
+
+cspell@^8.17.1:
+ version "8.17.1"
+ resolved "https://registry.yarnpkg.com/cspell/-/cspell-8.17.1.tgz#be3c79a5b0b2e374ac0df8f921eb30ddca170110"
+ integrity sha512-D0lw8XTXrTycNzOn5DkfPJNUT00X53OgvFDm+0SzhBr1r+na8LEh3CnQ6zKYVU0fL0x8vU82vs4jmGjDho9mPg==
+ dependencies:
+ "@cspell/cspell-json-reporter" "8.17.1"
+ "@cspell/cspell-pipe" "8.17.1"
+ "@cspell/cspell-types" "8.17.1"
+ "@cspell/dynamic-import" "8.17.1"
+ "@cspell/url" "8.17.1"
+ chalk "^5.3.0"
+ chalk-template "^1.1.0"
+ commander "^12.1.0"
+ cspell-dictionary "8.17.1"
+ cspell-gitignore "8.17.1"
+ cspell-glob "8.17.1"
+ cspell-io "8.17.1"
+ cspell-lib "8.17.1"
+ fast-json-stable-stringify "^2.1.0"
+ file-entry-cache "^9.1.0"
+ get-stdin "^9.0.0"
+ semver "^7.6.3"
+ tinyglobby "^0.2.10"
+
css-color-names@^0.0.4:
version "0.0.4"
resolved "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz"
@@ -802,14 +1629,19 @@ cssesc@^3.0.0:
resolved "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz"
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
+dargs@^8.0.0:
+ version "8.1.0"
+ resolved "https://registry.yarnpkg.com/dargs/-/dargs-8.1.0.tgz#a34859ea509cbce45485e5aa356fef70bfcc7272"
+ integrity sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==
+
dayjs@^1.11.10:
version "1.11.10"
- resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.10.tgz#68acea85317a6e164457d6d6947564029a6a16a0"
+ resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz"
integrity sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==
debug@~4.3.1, debug@~4.3.2:
version "4.3.5"
- resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e"
+ resolved "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz"
integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==
dependencies:
ms "2.1.2"
@@ -821,7 +1653,7 @@ defined@^1.0.0:
defu@^6.1.4:
version "6.1.4"
- resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.4.tgz#4e0c9cf9ff68fe5f3d7f2765cc1a012dfdcb0479"
+ resolved "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz"
integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==
detective@^5.2.0:
@@ -843,14 +1675,26 @@ dlv@^1.1.3:
resolved "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz"
integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==
+dot-prop@^5.1.0:
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88"
+ integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==
+ dependencies:
+ is-obj "^2.0.0"
+
electron-to-chromium@^1.4.17:
version "1.4.65"
resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.65.tgz"
integrity sha512-0/d8Skk8sW3FxXP0Dd6MnBlrwx7Qo9cqQec3BlIAlvKnrmS3pHsIbaroEi+nd0kZkGpQ6apMEre7xndzjlEnLw==
+emoji-regex@^8.0.0:
+ version "8.0.0"
+ resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
+ integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
+
engine.io-client@~6.5.2:
version "6.5.4"
- resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-6.5.4.tgz#b8bc71ed3f25d0d51d587729262486b4b33bd0d0"
+ resolved "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.5.4.tgz"
integrity sha512-GeZeeRjpD2qf49cZQ0Wvh/8NJNfeXkXXcoGh+F77oEAgo9gUHwT1fCRxSNU+YEEaysOJTnsFHmM5oAcPy4ntvQ==
dependencies:
"@socket.io/component-emitter" "~3.1.0"
@@ -861,14 +1705,24 @@ engine.io-client@~6.5.2:
engine.io-parser@~5.2.1:
version "5.2.3"
- resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.2.3.tgz#00dc5b97b1f233a23c9398d0209504cf5f94d92f"
+ resolved "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz"
integrity sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==
entities@^4.4.0:
version "4.5.0"
- resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
+ resolved "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
+env-paths@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2"
+ integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==
+
+env-paths@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-3.0.0.tgz#2f1e89c2f6dbd3408e1b1711dd82d62e317f58da"
+ integrity sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==
+
error-ex@^1.3.1:
version "1.3.2"
resolved "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz"
@@ -888,14 +1742,24 @@ escape-string-regexp@^1.0.5:
escape-string-regexp@^4.0.0:
version "4.0.0"
- resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
+ resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
+esprima@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71"
+ integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==
+
fast-deep-equal@^3.1.3:
version "3.1.3"
- resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
+ resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
+fast-equals@^5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-5.0.1.tgz#a4eefe3c5d1c0d021aeed0bc10ba5e0c12ee405d"
+ integrity sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ==
+
fast-glob@^3.2.7:
version "3.2.11"
resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz"
@@ -909,7 +1773,7 @@ fast-glob@^3.2.7:
fast-glob@^3.3.0:
version "3.3.2"
- resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129"
+ resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz"
integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==
dependencies:
"@nodelib/fs.stat" "^2.0.2"
@@ -918,6 +1782,16 @@ fast-glob@^3.3.0:
merge2 "^1.3.0"
micromatch "^4.0.4"
+fast-json-stable-stringify@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
+ integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
+
+fast-uri@^3.0.1:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.3.tgz#892a1c91802d5d7860de728f18608a0573142241"
+ integrity sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==
+
fastq@^1.6.0:
version "1.6.1"
resolved "https://registry.npmjs.org/fastq/-/fastq-1.6.1.tgz"
@@ -925,21 +1799,60 @@ fastq@^1.6.0:
dependencies:
reusify "^1.0.4"
+fdir@^6.4.2:
+ version "6.4.2"
+ resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.2.tgz#ddaa7ce1831b161bc3657bb99cb36e1622702689"
+ integrity sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==
+
feather-icons@^4.28.0:
version "4.29.2"
- resolved "https://registry.yarnpkg.com/feather-icons/-/feather-icons-4.29.2.tgz#b03a47588a1c400f215e884504db1c18860d89f8"
+ resolved "https://registry.npmjs.org/feather-icons/-/feather-icons-4.29.2.tgz"
integrity sha512-0TaCFTnBTVCz6U+baY2UJNKne5ifGh7sMG4ZC2LoBWCZdIyPa+y6UiR4lEYGws1JOFWdee8KAsAIvu0VcXqiqA==
dependencies:
classnames "^2.2.5"
core-js "^3.1.3"
+file-entry-cache@^9.1.0:
+ version "9.1.0"
+ resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-9.1.0.tgz#2e66ad98ce93f49aed1b178c57b0b5741591e075"
+ integrity sha512-/pqPFG+FdxWQj+/WSuzXSDaNzxgTLr/OrR1QuqfEZzDakpdYE70PwUxL7BPUa8hpjbvY1+qvCl8k+8Tq34xJgg==
+ dependencies:
+ flat-cache "^5.0.0"
+
fill-range@^7.1.1:
version "7.1.1"
- resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
+ resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz"
integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
dependencies:
to-regex-range "^5.0.1"
+find-up-simple@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/find-up-simple/-/find-up-simple-1.0.0.tgz#21d035fde9fdbd56c8f4d2f63f32fd93a1cfc368"
+ integrity sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==
+
+find-up@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/find-up/-/find-up-7.0.0.tgz#e8dec1455f74f78d888ad65bf7ca13dd2b4e66fb"
+ integrity sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==
+ dependencies:
+ locate-path "^7.2.0"
+ path-exists "^5.0.0"
+ unicorn-magic "^0.1.0"
+
+flat-cache@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-5.0.0.tgz#26c4da7b0f288b408bb2b506b2cb66c240ddf062"
+ integrity sha512-JrqFmyUl2PnPi1OvLyTVHnQvwQ0S+e6lGSwu8OkAZlSaNIZciTY2H/cOOROxsBA1m/LZNHDsqAgDZt6akWcjsQ==
+ dependencies:
+ flatted "^3.3.1"
+ keyv "^4.5.4"
+
+flatted@^3.3.1:
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.2.tgz#adba1448a9841bec72b42c532ea23dbbedef1a27"
+ integrity sha512-AiwGJM8YcNOaobumgtng+6NHuOqC3A7MixFeDafM3X9cIUM+xUXoS5Vfgf+OihAYe20fxqNM9yPBXJzRtZ/4eA==
+
fraction.js@^4.1.2:
version "4.1.2"
resolved "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.2.tgz"
@@ -947,7 +1860,7 @@ fraction.js@^4.1.2:
frappe-ui@^0.1.70:
version "0.1.70"
- resolved "https://registry.yarnpkg.com/frappe-ui/-/frappe-ui-0.1.70.tgz#4cdf705d7f344ac1ab8dff7e579476a4d54ec9a2"
+ resolved "https://registry.npmjs.org/frappe-ui/-/frappe-ui-0.1.70.tgz"
integrity sha512-R8xrRbFm+Htx+GmsWtmfLij9GOojoFGibhqQqSFQb5DgBAjaIcr0JMieXV2Ze36EpzK2PqqUYxGDdQmQowknew==
dependencies:
"@headlessui/vue" "^1.7.14"
@@ -995,9 +1908,9 @@ fs.realpath@^1.0.0:
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
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==
+ version "2.3.3"
+ resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
+ integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
function-bind@^1.1.1:
version "1.1.1"
@@ -1006,14 +1919,38 @@ function-bind@^1.1.1:
function-bind@^1.1.2:
version "1.1.2"
- resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
+ resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz"
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
fuse.js@^6.6.2:
version "6.6.2"
- resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-6.6.2.tgz#fe463fed4b98c0226ac3da2856a415576dc9a111"
+ resolved "https://registry.npmjs.org/fuse.js/-/fuse.js-6.6.2.tgz"
integrity sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA==
+gensequence@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/gensequence/-/gensequence-7.0.0.tgz#bb6aedec8ff665e3a6c42f92823121e3a6ea7718"
+ integrity sha512-47Frx13aZh01afHJTB3zTtKIlFI6vWY+MYCN9Qpew6i52rfKjnhCF/l1YlC8UmEMvvntZZ6z4PiCcmyuedR2aQ==
+
+get-caller-file@^2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
+ integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
+
+get-stdin@^9.0.0:
+ version "9.0.0"
+ resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-9.0.0.tgz#3983ff82e03d56f1b2ea0d3e60325f39d703a575"
+ integrity sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==
+
+git-raw-commits@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-4.0.0.tgz#b212fd2bff9726d27c1283a1157e829490593285"
+ integrity sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==
+ dependencies:
+ dargs "^8.0.0"
+ meow "^12.0.1"
+ split2 "^4.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"
@@ -1040,6 +1977,13 @@ glob@7.1.6, glob@^7.0.0, glob@^7.1.2, glob@^7.1.3:
once "^1.3.0"
path-is-absolute "^1.0.0"
+global-directory@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/global-directory/-/global-directory-4.0.1.tgz#4d7ac7cfd2cb73f304c53b8810891748df5e361e"
+ integrity sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==
+ dependencies:
+ ini "4.1.1"
+
graceful-fs@^4.1.6, graceful-fs@^4.2.0:
version "4.2.3"
resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz"
@@ -1055,6 +1999,11 @@ has-flag@^4.0.0:
resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz"
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
+has-own-prop@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/has-own-prop/-/has-own-prop-2.0.0.tgz#f0f95d58f65804f5d218db32563bb85b8e0417af"
+ integrity sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==
+
has@^1.0.3:
version "1.0.3"
resolved "https://registry.npmjs.org/has/-/has-1.0.3.tgz"
@@ -1064,7 +2013,7 @@ has@^1.0.3:
hasown@^2.0.0:
version "2.0.0"
- resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c"
+ resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz"
integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==
dependencies:
function-bind "^1.1.2"
@@ -1091,7 +2040,7 @@ html-tags@^3.1.0:
idb-keyval@^6.2.0:
version "6.2.1"
- resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-6.2.1.tgz#94516d625346d16f56f3b33855da11bfded2db33"
+ resolved "https://registry.npmjs.org/idb-keyval/-/idb-keyval-6.2.1.tgz"
integrity sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==
import-cwd@^3.0.0:
@@ -1101,7 +2050,7 @@ import-cwd@^3.0.0:
dependencies:
import-from "^3.0.0"
-import-fresh@^3.2.1:
+import-fresh@^3.2.1, import-fresh@^3.3.0:
version "3.3.0"
resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz"
integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==
@@ -1116,6 +2065,11 @@ import-from@^3.0.0:
dependencies:
resolve-from "^5.0.0"
+import-meta-resolve@^4.0.0, import-meta-resolve@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz#f9db8bead9fafa61adb811db77a2bf22c5399706"
+ integrity sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==
+
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz"
@@ -1129,6 +2083,11 @@ inherits@2:
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
+ini@4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/ini/-/ini-4.1.1.tgz#d95b3d843b1e906e56d6747d5447904ff50ce7a1"
+ integrity sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==
+
is-arrayish@^0.2.1:
version "0.2.1"
resolved "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz"
@@ -1160,7 +2119,7 @@ is-color-stop@^1.1.0:
is-core-module@^2.13.0:
version "2.13.1"
- resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384"
+ 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"
@@ -1177,6 +2136,11 @@ is-extglob@^2.1.1:
resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz"
integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=
+is-fullwidth-code-point@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
+ integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
+
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"
@@ -1189,21 +2153,55 @@ is-number@^7.0.0:
resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
+is-obj@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982"
+ integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==
+
+is-text-path@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-2.0.0.tgz#b2484e2b720a633feb2e85b67dc193ff72c75636"
+ integrity sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==
+ dependencies:
+ text-extensions "^2.0.0"
+
jiti@^1.19.1:
version "1.21.0"
- resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d"
+ resolved "https://registry.npmjs.org/jiti/-/jiti-1.21.0.tgz"
integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==
+jiti@^2.4.1:
+ version "2.4.2"
+ resolved "https://registry.yarnpkg.com/jiti/-/jiti-2.4.2.tgz#d19b7732ebb6116b06e2038da74a55366faef560"
+ integrity sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==
+
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.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
+ integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
+ dependencies:
+ argparse "^2.0.1"
+
+json-buffer@3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
+ integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
+
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@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
+ integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
+
jsonfile@^6.0.1:
version "6.1.0"
resolved "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz"
@@ -1213,6 +2211,18 @@ jsonfile@^6.0.1:
optionalDependencies:
graceful-fs "^4.1.6"
+jsonparse@^1.2.0:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280"
+ integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==
+
+keyv@^4.5.4:
+ version "4.5.4"
+ resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93"
+ integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==
+ dependencies:
+ json-buffer "3.0.1"
+
libarchive.js@^1.3.0:
version "1.3.0"
resolved "https://registry.npmjs.org/libarchive.js/-/libarchive.js-1.3.0.tgz"
@@ -1225,12 +2235,12 @@ lilconfig@^2.0.3:
lilconfig@^2.1.0:
version "2.1.0"
- resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52"
+ resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz"
integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==
lilconfig@^3.0.0:
version "3.0.0"
- resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.0.0.tgz#f8067feb033b5b74dab4602a5f5029420be749bc"
+ resolved "https://registry.npmjs.org/lilconfig/-/lilconfig-3.0.0.tgz"
integrity sha512-K2U4W2Ff5ibV7j7ydLr+zLAkIg5JJ4lPn1Ltsdt+Tz/IjQ8buJ55pZAxoP34lqIiwtF9iAvtLv3JGv7CAyAg+g==
lines-and-columns@^1.1.6:
@@ -1240,16 +2250,28 @@ lines-and-columns@^1.1.6:
linkify-it@^5.0.0:
version "5.0.0"
- resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-5.0.0.tgz#9ef238bfa6dc70bd8e7f9572b52d369af569b421"
+ resolved "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz"
integrity sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==
dependencies:
uc.micro "^2.0.0"
linkifyjs@^4.1.0:
version "4.1.3"
- resolved "https://registry.yarnpkg.com/linkifyjs/-/linkifyjs-4.1.3.tgz#0edbc346428a7390a23ea2e5939f76112c9ae07f"
+ resolved "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.1.3.tgz"
integrity sha512-auMesunaJ8yfkHvK4gfg1K0SaKX/6Wn9g2Aac/NwX+l5VdmFZzo/hdPGxEOETj+ryRa4/fiOPjeeKURSAJx1sg==
+locate-path@^7.2.0:
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-7.2.0.tgz#69cb1779bd90b35ab1e771e1f2f89a202c2a8a8a"
+ integrity sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==
+ dependencies:
+ p-locate "^6.0.0"
+
+lodash.camelcase@^4.3.0:
+ version "4.3.0"
+ resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6"
+ 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"
@@ -1260,16 +2282,46 @@ lodash.isplainobject@^4.0.6:
resolved "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz"
integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
+lodash.kebabcase@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36"
+ integrity sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==
+
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.mergewith@^4.6.2:
+ version "4.6.2"
+ resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55"
+ integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==
+
+lodash.snakecase@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d"
+ integrity sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==
+
+lodash.startcase@^4.4.0:
+ version "4.4.0"
+ resolved "https://registry.yarnpkg.com/lodash.startcase/-/lodash.startcase-4.4.0.tgz#9436e34ed26093ed7ffae1936144350915d9add8"
+ integrity sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==
+
lodash.topath@^4.5.2:
version "4.5.2"
resolved "https://registry.npmjs.org/lodash.topath/-/lodash.topath-4.5.2.tgz"
integrity sha1-NhY1Hzu6YZlKCTGYlmC9AyVP0Ak=
+lodash.uniq@^4.5.0:
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
+ integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==
+
+lodash.upperfirst@^4.3.1:
+ version "4.3.1"
+ resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce"
+ integrity sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==
+
lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz"
@@ -1277,7 +2329,7 @@ lodash@^4.17.21:
markdown-it@^14.0.0:
version "14.1.0"
- resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-14.1.0.tgz#3c3c5992883c633db4714ccb4d7b5935d98b7d45"
+ resolved "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz"
integrity sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==
dependencies:
argparse "^2.0.1"
@@ -1289,28 +2341,25 @@ markdown-it@^14.0.0:
mdurl@^2.0.0:
version "2.0.0"
- resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-2.0.0.tgz#80676ec0433025dd3e17ee983d0fe8de5a2237e0"
+ resolved "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz"
integrity sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==
+meow@^12.0.1:
+ version "12.1.1"
+ resolved "https://registry.yarnpkg.com/meow/-/meow-12.1.1.tgz#e558dddbab12477b69b2e9a2728c327f191bace6"
+ integrity sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==
+
merge2@^1.3.0:
version "1.3.0"
resolved "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz"
integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==
-micromatch@^4.0.4:
- version "4.0.4"
- resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz"
- integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
- dependencies:
- braces "^3.0.1"
- picomatch "^2.2.3"
-
-micromatch@^4.0.5:
- version "4.0.5"
- resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
- integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
+micromatch@^4.0.4, micromatch@^4.0.5, micromatch@^4.0.8:
+ version "4.0.8"
+ resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz"
+ integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
dependencies:
- braces "^3.0.2"
+ braces "^3.0.3"
picomatch "^2.3.1"
mini-svg-data-uri@^1.2.3:
@@ -1320,15 +2369,15 @@ mini-svg-data-uri@^1.2.3:
minimatch@^3.0.4:
version "3.1.2"
- resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
+ resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"
-minimist@^1.1.1:
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
- integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
+minimist@^1.1.1, minimist@^1.2.8:
+ version "1.2.8"
+ resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz"
+ integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
modern-normalize@^1.1.0:
version "1.1.0"
@@ -1337,31 +2386,26 @@ modern-normalize@^1.1.0:
ms@2.1.2:
version "2.1.2"
- resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
+ 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.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
+ 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.2.0:
- version "3.2.0"
- resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz"
- integrity sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==
-
-nanoid@^3.3.6:
- version "3.3.7"
- resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
- integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==
+nanoid@^3.3.7:
+ version "3.3.8"
+ resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.8.tgz"
+ integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==
nanoid@^5.0.7:
version "5.0.7"
- resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-5.0.7.tgz#6452e8c5a816861fd9d2b898399f7e5fd6944cc6"
+ resolved "https://registry.npmjs.org/nanoid/-/nanoid-5.0.7.tgz"
integrity sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==
node-emoji@^1.11.0:
@@ -1403,7 +2447,7 @@ object-hash@^2.2.0:
object-hash@^3.0.0:
version "3.0.0"
- resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9"
+ resolved "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz"
integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==
once@^1.3.0:
@@ -1415,9 +2459,23 @@ once@^1.3.0:
orderedmap@^2.0.0:
version "2.1.1"
- resolved "https://registry.yarnpkg.com/orderedmap/-/orderedmap-2.1.1.tgz#61481269c44031c449915497bf5a4ad273c512d2"
+ resolved "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz"
integrity sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==
+p-limit@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644"
+ integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==
+ dependencies:
+ yocto-queue "^1.0.0"
+
+p-locate@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-6.0.0.tgz#3da9a49d4934b901089dca3302fa65dc5a05c04f"
+ integrity sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==
+ dependencies:
+ p-limit "^4.0.0"
+
parent-module@^1.0.0:
version "1.0.1"
resolved "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz"
@@ -1425,7 +2483,14 @@ parent-module@^1.0.0:
dependencies:
callsites "^3.0.0"
-parse-json@^5.0.0:
+parent-module@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-2.0.0.tgz#fa71f88ff1a50c27e15d8ff74e0e3a9523bf8708"
+ integrity sha512-uo0Z9JJeWzv8BG+tRcapBKNJ0dro9cLyczGzulS6EfeyAdeC9sbojtW6XwvYxJkEne9En+J2XEl4zyglVeIwFg==
+ dependencies:
+ callsites "^3.1.0"
+
+parse-json@^5.0.0, parse-json@^5.2.0:
version "5.2.0"
resolved "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz"
integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==
@@ -1435,6 +2500,11 @@ parse-json@^5.0.0:
json-parse-even-better-errors "^2.3.0"
lines-and-columns "^1.1.6"
+path-exists@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-5.0.0.tgz#a6aad9489200b21fab31e49cf09277e5116fb9e7"
+ integrity sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==
+
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"
@@ -1455,34 +2525,34 @@ picocolors@^0.2.1:
resolved "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz"
integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==
-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==
+picocolors@^1.0.0, picocolors@^1.1.1:
+ version "1.1.1"
+ resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz"
+ integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
picomatch@^2.0.4, picomatch@^2.2.1:
version "2.2.1"
resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz"
integrity sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==
-picomatch@^2.2.3:
- version "2.3.0"
- resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz"
- integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==
-
picomatch@^2.3.1:
version "2.3.1"
- resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
+ resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
+picomatch@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab"
+ integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==
+
pify@^2.3.0:
version "2.3.0"
- resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
+ resolved "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz"
integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==
pirates@^4.0.1:
version "4.0.6"
- resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9"
+ resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz"
integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==
postcss-functions@^3:
@@ -1497,7 +2567,7 @@ postcss-functions@^3:
postcss-import@^15.1.0:
version "15.1.0"
- resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-15.1.0.tgz#41c64ed8cc0e23735a9698b3249ffdbf704adc70"
+ 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"
@@ -1514,7 +2584,7 @@ postcss-js@^2:
postcss-js@^4.0.1:
version "4.0.1"
- resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2"
+ resolved "https://registry.npmjs.org/postcss-js/-/postcss-js-4.0.1.tgz"
integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==
dependencies:
camelcase-css "^2.0.1"
@@ -1530,7 +2600,7 @@ postcss-load-config@^3.1.0:
postcss-load-config@^4.0.1:
version "4.0.2"
- resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.2.tgz#7159dcf626118d33e299f485d6afe4aff7c4a3e3"
+ resolved "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-4.0.2.tgz"
integrity sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==
dependencies:
lilconfig "^3.0.0"
@@ -1546,14 +2616,14 @@ postcss-nested@^4:
postcss-nested@^6.0.1:
version "6.0.1"
- resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.0.1.tgz#f83dc9846ca16d2f4fa864f16e9d9f7d0961662c"
+ 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:
version "6.0.10"
- resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d"
+ 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"
@@ -1561,7 +2631,7 @@ postcss-selector-parser@6.0.10:
postcss-selector-parser@^6.0.11:
version "6.0.13"
- resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b"
+ 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"
@@ -1602,27 +2672,18 @@ postcss@^7, postcss@^7.0.18, postcss@^7.0.32:
picocolors "^0.2.1"
source-map "^0.6.1"
-postcss@^8.2.1, postcss@^8.4.6:
- version "8.4.6"
- resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.6.tgz"
- integrity sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==
- dependencies:
- nanoid "^3.2.0"
- picocolors "^1.0.0"
- source-map-js "^1.0.2"
-
-postcss@^8.4.23:
- version "8.4.31"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d"
- integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==
+postcss@^8.2.1, postcss@^8.4.23, postcss@^8.4.6:
+ version "8.4.49"
+ resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz"
+ integrity sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==
dependencies:
- nanoid "^3.3.6"
- picocolors "^1.0.0"
- source-map-js "^1.0.2"
+ nanoid "^3.3.7"
+ picocolors "^1.1.1"
+ source-map-js "^1.2.1"
prettier@^3.3.2:
version "3.3.3"
- resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.3.tgz#30c54fe0be0d8d12e6ae61dbb10109ea00d53105"
+ resolved "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz"
integrity sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==
pretty-hrtime@^1.0.3:
@@ -1632,21 +2693,21 @@ pretty-hrtime@^1.0.3:
prosemirror-changeset@^2.2.1:
version "2.2.1"
- resolved "https://registry.yarnpkg.com/prosemirror-changeset/-/prosemirror-changeset-2.2.1.tgz#dae94b63aec618fac7bb9061648e6e2a79988383"
+ resolved "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.2.1.tgz"
integrity sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==
dependencies:
prosemirror-transform "^1.0.0"
prosemirror-collab@^1.3.1:
version "1.3.1"
- resolved "https://registry.yarnpkg.com/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz#0e8c91e76e009b53457eb3b3051fb68dad029a33"
+ resolved "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz"
integrity sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==
dependencies:
prosemirror-state "^1.0.0"
prosemirror-commands@^1.0.0, prosemirror-commands@^1.5.2:
version "1.5.2"
- resolved "https://registry.yarnpkg.com/prosemirror-commands/-/prosemirror-commands-1.5.2.tgz#e94aeea52286f658cd984270de9b4c3fff580852"
+ resolved "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.5.2.tgz"
integrity sha512-hgLcPaakxH8tu6YvVAaILV2tXYsW3rAdDR8WNkeKGcgeMVQg3/TMhPdVoh7iAmfgVjZGtcOSjKiQaoeKjzd2mQ==
dependencies:
prosemirror-model "^1.0.0"
@@ -1655,7 +2716,7 @@ prosemirror-commands@^1.0.0, prosemirror-commands@^1.5.2:
prosemirror-dropcursor@^1.8.1:
version "1.8.1"
- resolved "https://registry.yarnpkg.com/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.1.tgz#49b9fb2f583e0d0f4021ff87db825faa2be2832d"
+ resolved "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.1.tgz"
integrity sha512-M30WJdJZLyXHi3N8vxN6Zh5O8ZBbQCz0gURTfPmTIBNQ5pxrdU7A58QkNqfa98YEjSAL1HUyyU34f6Pm5xBSGw==
dependencies:
prosemirror-state "^1.0.0"
@@ -1664,7 +2725,7 @@ prosemirror-dropcursor@^1.8.1:
prosemirror-gapcursor@^1.3.2:
version "1.3.2"
- resolved "https://registry.yarnpkg.com/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz#5fa336b83789c6199a7341c9493587e249215cb4"
+ resolved "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz"
integrity sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==
dependencies:
prosemirror-keymap "^1.0.0"
@@ -1674,7 +2735,7 @@ prosemirror-gapcursor@^1.3.2:
prosemirror-history@^1.0.0, prosemirror-history@^1.4.1:
version "1.4.1"
- resolved "https://registry.yarnpkg.com/prosemirror-history/-/prosemirror-history-1.4.1.tgz#cc370a46fb629e83a33946a0e12612e934ab8b98"
+ resolved "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.1.tgz"
integrity sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==
dependencies:
prosemirror-state "^1.2.2"
@@ -1684,7 +2745,7 @@ prosemirror-history@^1.0.0, prosemirror-history@^1.4.1:
prosemirror-inputrules@^1.4.0:
version "1.4.0"
- resolved "https://registry.yarnpkg.com/prosemirror-inputrules/-/prosemirror-inputrules-1.4.0.tgz#ef1519bb2cb0d1e0cec74bad1a97f1c1555068bb"
+ resolved "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.4.0.tgz"
integrity sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg==
dependencies:
prosemirror-state "^1.0.0"
@@ -1692,7 +2753,7 @@ prosemirror-inputrules@^1.4.0:
prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2, prosemirror-keymap@^1.2.2:
version "1.2.2"
- resolved "https://registry.yarnpkg.com/prosemirror-keymap/-/prosemirror-keymap-1.2.2.tgz#14a54763a29c7b2704f561088ccf3384d14eb77e"
+ resolved "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.2.tgz"
integrity sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ==
dependencies:
prosemirror-state "^1.0.0"
@@ -1700,7 +2761,7 @@ prosemirror-keymap@^1.0.0, prosemirror-keymap@^1.1.2, prosemirror-keymap@^1.2.2:
prosemirror-markdown@^1.13.0:
version "1.13.0"
- resolved "https://registry.yarnpkg.com/prosemirror-markdown/-/prosemirror-markdown-1.13.0.tgz#67ebfa40af48a22d1e4ed6cad2e29851eb61e649"
+ resolved "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.0.tgz"
integrity sha512-UziddX3ZYSYibgx8042hfGKmukq5Aljp2qoBiJRejD/8MH70siQNz5RB1TrdTPheqLMy4aCe4GYNF10/3lQS5g==
dependencies:
markdown-it "^14.0.0"
@@ -1708,7 +2769,7 @@ prosemirror-markdown@^1.13.0:
prosemirror-menu@^1.2.4:
version "1.2.4"
- resolved "https://registry.yarnpkg.com/prosemirror-menu/-/prosemirror-menu-1.2.4.tgz#3cfdc7c06d10f9fbd1bce29082c498bd11a0a79a"
+ resolved "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.4.tgz"
integrity sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA==
dependencies:
crelt "^1.0.0"
@@ -1718,21 +2779,21 @@ prosemirror-menu@^1.2.4:
prosemirror-model@^1.0.0, prosemirror-model@^1.19.0, prosemirror-model@^1.20.0, prosemirror-model@^1.21.0, prosemirror-model@^1.22.1, prosemirror-model@^1.8.1:
version "1.22.1"
- resolved "https://registry.yarnpkg.com/prosemirror-model/-/prosemirror-model-1.22.1.tgz#2ed7d7840e710172c559d5a9950e92b870d1e764"
+ resolved "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.22.1.tgz"
integrity sha512-gMrxal+F3higDFxCkBK5iQXckRVYvIu/3dopERJ6b20xfwZ9cbYvQvuldqaN+v/XytNPGyURYUpUU23kBRxWCQ==
dependencies:
orderedmap "^2.0.0"
prosemirror-schema-basic@^1.2.3:
version "1.2.3"
- resolved "https://registry.yarnpkg.com/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.3.tgz#649c349bb21c61a56febf9deb71ac68fca4cedf2"
+ resolved "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.3.tgz"
integrity sha512-h+H0OQwZVqMon1PNn0AG9cTfx513zgIG2DY00eJ00Yvgb3UD+GQ/VlWW5rcaxacpCGT1Yx8nuhwXk4+QbXUfJA==
dependencies:
prosemirror-model "^1.19.0"
prosemirror-schema-list@^1.4.1:
version "1.4.1"
- resolved "https://registry.yarnpkg.com/prosemirror-schema-list/-/prosemirror-schema-list-1.4.1.tgz#78b8d25531db48ca9688836dbde50e13ac19a4a1"
+ resolved "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.4.1.tgz"
integrity sha512-jbDyaP/6AFfDfu70VzySsD75Om2t3sXTOdl5+31Wlxlg62td1haUpty/ybajSfJ1pkGadlOfwQq9kgW5IMo1Rg==
dependencies:
prosemirror-model "^1.0.0"
@@ -1741,7 +2802,7 @@ prosemirror-schema-list@^1.4.1:
prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.1, prosemirror-state@^1.4.3:
version "1.4.3"
- resolved "https://registry.yarnpkg.com/prosemirror-state/-/prosemirror-state-1.4.3.tgz#94aecf3ffd54ec37e87aa7179d13508da181a080"
+ resolved "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz"
integrity sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==
dependencies:
prosemirror-model "^1.0.0"
@@ -1750,7 +2811,7 @@ prosemirror-state@^1.0.0, prosemirror-state@^1.2.2, prosemirror-state@^1.3.1, pr
prosemirror-tables@^1.3.7:
version "1.3.7"
- resolved "https://registry.yarnpkg.com/prosemirror-tables/-/prosemirror-tables-1.3.7.tgz#9d296bd432d2bc7dca90f14e5c3b5c5f61277f7a"
+ resolved "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.3.7.tgz"
integrity sha512-oEwX1wrziuxMtwFvdDWSFHVUWrFJWt929kVVfHvtTi8yvw+5ppxjXZkMG/fuTdFo+3DXyIPSKfid+Be1npKXDA==
dependencies:
prosemirror-keymap "^1.1.2"
@@ -1761,7 +2822,7 @@ prosemirror-tables@^1.3.7:
prosemirror-trailing-node@^2.0.8:
version "2.0.9"
- resolved "https://registry.yarnpkg.com/prosemirror-trailing-node/-/prosemirror-trailing-node-2.0.9.tgz#a087e6d1372e888cd3e57c977507b6b85dc658e4"
+ resolved "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-2.0.9.tgz"
integrity sha512-YvyIn3/UaLFlFKrlJB6cObvUhmwFNZVhy1Q8OpW/avoTbD/Y7H5EcjK4AZFKhmuS6/N6WkGgt7gWtBWDnmFvHg==
dependencies:
"@remirror/core-constants" "^2.0.2"
@@ -1769,14 +2830,14 @@ prosemirror-trailing-node@^2.0.8:
prosemirror-transform@^1.0.0, prosemirror-transform@^1.1.0, prosemirror-transform@^1.2.1, prosemirror-transform@^1.7.3, prosemirror-transform@^1.9.0:
version "1.9.0"
- resolved "https://registry.yarnpkg.com/prosemirror-transform/-/prosemirror-transform-1.9.0.tgz#81fd1fbd887929a95369e6dd3d240c23c19313f8"
+ resolved "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.9.0.tgz"
integrity sha512-5UXkr1LIRx3jmpXXNKDhv8OyAOeLTGuXNwdVfg8x27uASna/wQkr9p6fD3eupGOi4PLJfbezxTyi/7fSJypXHg==
dependencies:
prosemirror-model "^1.21.0"
prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, prosemirror-view@^1.27.0, prosemirror-view@^1.31.0, prosemirror-view@^1.33.8:
version "1.33.8"
- resolved "https://registry.yarnpkg.com/prosemirror-view/-/prosemirror-view-1.33.8.tgz#cfd76dff421730cbca0b6ea40ce36994daaeda41"
+ resolved "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.33.8.tgz"
integrity sha512-4PhMr/ufz2cdvFgpUAnZfs+0xij3RsFysreeG9V/utpwX7AJtYCDVyuRxzWoMJIEf4C7wVihuBNMPpFLPCiLQw==
dependencies:
prosemirror-model "^1.20.0"
@@ -1785,7 +2846,7 @@ prosemirror-view@^1.0.0, prosemirror-view@^1.1.0, prosemirror-view@^1.13.3, pros
punycode.js@^2.3.1:
version "2.3.1"
- resolved "https://registry.yarnpkg.com/punycode.js/-/punycode.js-2.3.1.tgz#6b53e56ad75588234e79f4affa90972c7dd8cdb7"
+ resolved "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz"
integrity sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==
purgecss@^4.0.3:
@@ -1805,7 +2866,7 @@ quick-lru@^5.1.1:
radix-vue@^1.5.3:
version "1.9.1"
- resolved "https://registry.yarnpkg.com/radix-vue/-/radix-vue-1.9.1.tgz#4aebb1fc89ba91709e524e8ddca8ad0965e5ad8f"
+ resolved "https://registry.npmjs.org/radix-vue/-/radix-vue-1.9.1.tgz"
integrity sha512-fObA+9l2ixNWBXRMj5mBZfmVv2znqIUph+0uo7QA/s7pDYSST2vGvxCbrg/xQGxWRwaQ8ejgo1wg2MzhHcbjLw==
dependencies:
"@floating-ui/dom" "^1.6.7"
@@ -1822,7 +2883,7 @@ radix-vue@^1.5.3:
read-cache@^1.0.0:
version "1.0.0"
- resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774"
+ resolved "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz"
integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==
dependencies:
pify "^2.3.0"
@@ -1842,6 +2903,21 @@ reduce-css-calc@^2.1.8:
css-unit-converter "^1.1.1"
postcss-value-parser "^3.3.0"
+repeat-string@^1.6.1:
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
+ integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==
+
+require-directory@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
+ integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
+
+require-from-string@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
+ integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
+
resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz"
@@ -1854,7 +2930,7 @@ resolve-from@^5.0.0:
resolve@^1.1.7, resolve@^1.22.2:
version "1.22.8"
- resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
+ resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz"
integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
dependencies:
is-core-module "^2.13.0"
@@ -1894,7 +2970,7 @@ rimraf@^3.0.0:
rope-sequence@^1.3.0:
version "1.3.4"
- resolved "https://registry.yarnpkg.com/rope-sequence/-/rope-sequence-1.3.4.tgz#df85711aaecd32f1e756f76e43a415171235d425"
+ resolved "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz"
integrity sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==
run-parallel@^1.1.9:
@@ -1902,9 +2978,14 @@ run-parallel@^1.1.9:
resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz"
integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==
+semver@^7.6.0, semver@^7.6.3:
+ version "7.6.3"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143"
+ integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==
+
showdown@^2.1.0:
version "2.1.0"
- resolved "https://registry.yarnpkg.com/showdown/-/showdown-2.1.0.tgz#1251f5ed8f773f0c0c7bfc8e6fd23581f9e545c5"
+ resolved "https://registry.npmjs.org/showdown/-/showdown-2.1.0.tgz"
integrity sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==
dependencies:
commander "^9.0.0"
@@ -1918,7 +2999,7 @@ simple-swizzle@^0.2.2:
socket.io-client@^4.5.1:
version "4.7.5"
- resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-4.7.5.tgz#919be76916989758bdc20eec63f7ee0ae45c05b7"
+ resolved "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.7.5.tgz"
integrity sha512-sJ/tqHOCe7Z50JCBCXrsY3I2k03iOiUe+tj1OmKeD2lXPiGH/RUCdTZFoqVyN7l1MnpIzPrGtLcijffmeouNlQ==
dependencies:
"@socket.io/component-emitter" "~3.1.0"
@@ -1928,25 +3009,46 @@ socket.io-client@^4.5.1:
socket.io-parser@~4.2.4:
version "4.2.4"
- resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.2.4.tgz#c806966cf7270601e47469ddeec30fbdfda44c83"
+ resolved "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz"
integrity sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==
dependencies:
"@socket.io/component-emitter" "~3.1.0"
debug "~4.3.1"
-source-map-js@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
- integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
+source-map-js@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz"
+ integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
source-map@^0.6.1:
version "0.6.1"
resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+split2@^4.0.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4"
+ integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==
+
+string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
+ 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"
+
+strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
+ integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
+ dependencies:
+ ansi-regex "^5.0.1"
+
sucrase@^3.32.0:
version "3.34.0"
- resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.34.0.tgz#1e0e2d8fcf07f8b9c3569067d92fbd8690fb576f"
+ resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.34.0.tgz"
integrity sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==
dependencies:
"@jridgewell/gen-mapping" "^0.3.2"
@@ -1978,7 +3080,7 @@ supports-preserve-symlinks-flag@^1.0.0:
tailwindcss@^3.2:
version "3.3.5"
- resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.3.5.tgz#22a59e2fbe0ecb6660809d9cc5f3976b077be3b8"
+ resolved "https://registry.npmjs.org/tailwindcss/-/tailwindcss-3.3.5.tgz"
integrity sha512-5SEZU4J7pxZgSkv7FP1zY8i2TIAOooNZ1e/OGtxIEv6GltpoiXUqWvLy89+a10qYTB1N5Ifkuw9lqQkN9sscvA==
dependencies:
"@alloc/quick-lru" "^5.2.0"
@@ -2004,23 +3106,46 @@ tailwindcss@^3.2:
resolve "^1.22.2"
sucrase "^3.32.0"
+text-extensions@^2.0.0:
+ version "2.4.0"
+ resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-2.4.0.tgz#a1cfcc50cf34da41bfd047cc744f804d1680ea34"
+ integrity sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==
+
thenify-all@^1.0.0:
version "1.6.0"
- resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
+ 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.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f"
+ resolved "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz"
integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==
dependencies:
any-promise "^1.0.0"
+"through@>=2.2.7 <3":
+ version "2.3.8"
+ resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
+ integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
+
+tinyexec@^0.3.0:
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-0.3.1.tgz#0ab0daf93b43e2c211212396bdb836b468c97c98"
+ integrity sha512-WiCJLEECkO18gwqIp6+hJg0//p23HXp4S+gGtAKu3mI2F2/sXC4FvHvXvB0zJVVaTPhx1/tOwdbRsa1sOBIKqQ==
+
+tinyglobby@^0.2.10:
+ version "0.2.10"
+ resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.10.tgz#e712cf2dc9b95a1f5c5bbd159720e15833977a0f"
+ integrity sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==
+ dependencies:
+ fdir "^6.4.2"
+ picomatch "^4.0.2"
+
tippy.js@^6.3.7:
version "6.3.7"
- resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.3.7.tgz#8ccfb651d642010ed9a32ff29b0e9e19c5b8c61c"
+ resolved "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz"
integrity sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==
dependencies:
"@popperjs/core" "^2.9.0"
@@ -2041,19 +3166,29 @@ to-regex-range@^5.0.1:
ts-interface-checker@^0.1.9:
version "0.1.13"
- resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699"
+ resolved "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz"
integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==
tslib@^2.0.0, tslib@^2.4.0:
version "2.6.3"
- resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0"
+ resolved "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz"
integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==
uc.micro@^2.0.0, uc.micro@^2.1.0:
version "2.1.0"
- resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-2.1.0.tgz#f8d3f7d0ec4c3dea35a7e3c8efa4cb8b45c9e7ee"
+ resolved "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz"
integrity sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==
+undici-types@~6.20.0:
+ version "6.20.0"
+ resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433"
+ integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==
+
+unicorn-magic@^0.1.0:
+ version "0.1.0"
+ resolved "https://registry.yarnpkg.com/unicorn-magic/-/unicorn-magic-0.1.0.tgz#1bb9a51c823aaf9d73a8bfcd3d1a23dde94b0ce4"
+ integrity sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==
+
universalify@^2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz"
@@ -2064,16 +3199,35 @@ util-deprecate@^1.0.2:
resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz"
integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
+vscode-languageserver-textdocument@^1.0.12:
+ version "1.0.12"
+ resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz#457ee04271ab38998a093c68c2342f53f6e4a631"
+ integrity sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==
+
+vscode-uri@^3.0.8:
+ version "3.0.8"
+ resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.8.tgz#1770938d3e72588659a172d0fd4642780083ff9f"
+ integrity sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==
+
vue-demi@>=0.13.0, vue-demi@>=0.14.8:
version "0.14.8"
- resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.14.8.tgz#00335e9317b45e4a68d3528aaf58e0cec3d5640a"
+ resolved "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.8.tgz"
integrity sha512-Uuqnk9YE9SsWeReYqK2alDI5YzciATE0r2SkA6iMAtuXvNTMNACJLJEXNXaEy94ECuBe4Sk6RzRU80kjdbIo1Q==
w3c-keyname@^2.2.0:
version "2.2.8"
- resolved "https://registry.yarnpkg.com/w3c-keyname/-/w3c-keyname-2.2.8.tgz#7b17c8c6883d4e8b86ac8aba79d39e880f8869c5"
+ resolved "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz"
integrity sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==
+wrap-ansi@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
+ integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
+ dependencies:
+ ansi-styles "^4.0.0"
+ string-width "^4.1.0"
+ strip-ansi "^6.0.0"
+
wrappy@1:
version "1.0.2"
resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz"
@@ -2081,12 +3235,17 @@ wrappy@1:
ws@~8.17.1:
version "8.17.1"
- resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.1.tgz#9293da530bb548febc95371d90f9c878727d919b"
+ resolved "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz"
integrity sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==
+xdg-basedir@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-5.1.0.tgz#1efba19425e73be1bc6f2a6ceb52a3d2c884c0c9"
+ integrity sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ==
+
xmlhttprequest-ssl@~2.0.0:
version "2.0.0"
- resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz#91360c86b914e67f44dce769180027c0da618c67"
+ resolved "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz"
integrity sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==
xtend@^4.0.2:
@@ -2094,6 +3253,11 @@ xtend@^4.0.2:
resolved "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
+y18n@^5.0.5:
+ version "5.0.8"
+ resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55"
+ integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
+
yaml@^1.10.0, yaml@^1.10.2:
version "1.10.2"
resolved "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz"
@@ -2101,5 +3265,33 @@ yaml@^1.10.0, yaml@^1.10.2:
yaml@^2.3.4:
version "2.3.4"
- resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.4.tgz#53fc1d514be80aabf386dc6001eb29bf3b7523b2"
+ resolved "https://registry.npmjs.org/yaml/-/yaml-2.3.4.tgz"
integrity sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA==
+
+yaml@^2.6.1:
+ version "2.6.1"
+ resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.6.1.tgz#42f2b1ba89203f374609572d5349fb8686500773"
+ integrity sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==
+
+yargs-parser@^21.1.1:
+ version "21.1.1"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
+ integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
+
+yargs@^17.0.0:
+ version "17.7.2"
+ resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
+ integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
+ dependencies:
+ cliui "^8.0.1"
+ escalade "^3.1.1"
+ get-caller-file "^2.0.5"
+ require-directory "^2.1.1"
+ string-width "^4.2.3"
+ y18n "^5.0.5"
+ yargs-parser "^21.1.1"
+
+yocto-queue@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.1.1.tgz#fef65ce3ac9f8a32ceac5a634f74e17e5b232110"
+ integrity sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==