Page MenuHomePhorge

No OneTemporary

Size
1 MB
Referenced Files
None
Subscribers
None
This file is larger than 256 KB, so syntax highlighting was skipped.
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 06fbf45f91..247218091d 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,223 +1,223 @@
# This file is a template, and might need editing before it works on your project.
# Official framework image. Look for the different tagged releases at:
# https://hub.docker.com/r/library/node/tags/
-image: node:18
+image: node:20
stages:
- check-changelog
- lint
- build
- test
- deploy
# https://git.pleroma.social/help/ci/yaml/workflow.md#switch-between-branch-pipelines-and-merge-request-pipelines
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
- if: $CI_COMMIT_BRANCH
check-changelog:
stage: check-changelog
image: alpine
rules:
- if: $CI_MERGE_REQUEST_SOURCE_PROJECT_PATH == 'pleroma/pleroma-fe' && $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^renovate/
when: never
- if: $CI_MERGE_REQUEST_SOURCE_PROJECT_PATH == 'pleroma/pleroma-fe' && $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == 'weblate'
when: never
- if: $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop"
before_script: ''
after_script: ''
cache: {}
script:
- apk add git
- sh ./tools/check-changelog
lint-eslint:
stage: lint
script:
- yarn
- yarn ci-eslint
lint-biome:
stage: lint
script:
- yarn
- yarn ci-biome
lint-stylelint:
stage: lint
script:
- yarn
- yarn ci-stylelint
test:
stage: test
tags:
- amd64
- himem
variables:
APT_CACHE_DIR: apt-cache
script:
- mkdir -pv $APT_CACHE_DIR && apt-get -qq update
- yarn
- yarn playwright install firefox
- yarn playwright install-deps
- yarn unit-ci
artifacts:
# When the test fails, upload screenshots for better context on why it fails
paths:
- test/**/__screenshots__
when: on_failure
e2e-pleroma:
stage: test
image: mcr.microsoft.com/playwright:v1.57.0-jammy
services:
- name: postgres:15-alpine
alias: db
- name: $PLEROMA_IMAGE
alias: pleroma
entrypoint: ["/bin/ash", "-c"]
command:
- |
set -eu
SEED_SENTINEL_PATH=/var/lib/pleroma/.e2e_seeded
CONFIG_OVERRIDE_PATH=/var/lib/pleroma/config.exs
echo '-- Waiting for database...'
while ! pg_isready -U ${DB_USER:-pleroma} -d postgres://${DB_HOST:-db}:${DB_PORT:-5432}/${DB_NAME:-pleroma} -t 1; do
sleep 1s
done
echo '-- Writing E2E config overrides...'
cat > $CONFIG_OVERRIDE_PATH <<EOF
import Config
config :pleroma, Pleroma.Captcha,
enabled: false
config :pleroma, :instance,
registrations_open: true,
account_activation_required: false,
approval_required: false
EOF
echo '-- Running migrations...'
/opt/pleroma/bin/pleroma_ctl migrate
echo '-- Starting!'
/opt/pleroma/bin/pleroma start &
PLEROMA_PID=$!
cleanup() {
if kill -0 $PLEROMA_PID 2>/dev/null; then
kill -TERM $PLEROMA_PID
wait $PLEROMA_PID || true
fi
}
trap cleanup INT TERM
echo '-- Waiting for API...'
api_ok=false
for _i in $(seq 1 120); do
if wget -qO- http://127.0.0.1:4000/api/v1/instance >/dev/null 2>&1; then
api_ok=true
break
fi
sleep 1s
done
if [ $api_ok != true ]; then
echo 'Timed out waiting for Pleroma API to become available'
exit 1
fi
if [ ! -f $SEED_SENTINEL_PATH ]; then
if [ -n ${E2E_ADMIN_USERNAME:-} ] && [ -n ${E2E_ADMIN_PASSWORD:-} ] && [ -n ${E2E_ADMIN_EMAIL:-} ]; then
echo '-- Seeding admin user' $E2E_ADMIN_USERNAME '...'
if ! /opt/pleroma/bin/pleroma_ctl user new $E2E_ADMIN_USERNAME $E2E_ADMIN_EMAIL --admin --password $E2E_ADMIN_PASSWORD -y; then
echo '-- User already exists or creation failed, ensuring admin + confirmed...'
/opt/pleroma/bin/pleroma_ctl user set $E2E_ADMIN_USERNAME --admin --confirmed
fi
else
echo '-- Skipping admin seeding (missing E2E_ADMIN_* env)'
fi
touch $SEED_SENTINEL_PATH
fi
wait $PLEROMA_PID
tags:
- amd64
- himem
variables:
PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "1"
FF_NETWORK_PER_BUILD: "true"
PLEROMA_IMAGE: git.pleroma.social:5050/pleroma/pleroma:stable
POSTGRES_USER: pleroma
POSTGRES_PASSWORD: pleroma
POSTGRES_DB: pleroma
DB_USER: pleroma
DB_PASS: pleroma
DB_NAME: pleroma
DB_HOST: db
DB_PORT: 5432
DOMAIN: localhost
INSTANCE_NAME: Pleroma E2E
E2E_ADMIN_USERNAME: admin
E2E_ADMIN_PASSWORD: adminadmin
E2E_ADMIN_EMAIL: admin@example.com
ADMIN_EMAIL: $E2E_ADMIN_EMAIL
NOTIFY_EMAIL: $E2E_ADMIN_EMAIL
VITE_PROXY_TARGET: http://pleroma:4000
VITE_PROXY_ORIGIN: http://localhost:4000
E2E_BASE_URL: http://localhost:8080
script:
- npm install -g yarn@1.22.22
- yarn --frozen-lockfile
- |
echo "-- Waiting for Pleroma API..."
api_ok="false"
for _i in $(seq 1 120); do
if wget -qO- http://pleroma:4000/api/v1/instance >/dev/null 2>&1; then
api_ok="true"
break
fi
sleep 1s
done
if [ "$api_ok" != "true" ]; then
echo "Timed out waiting for Pleroma API to become available"
exit 1
fi
- yarn e2e:pw
artifacts:
when: on_failure
paths:
- test/e2e-playwright/test-results
- test/e2e-playwright/playwright-report
build:
stage: build
tags:
- amd64
- himem
script:
- yarn
- yarn build
artifacts:
paths:
- dist/
docs-deploy:
stage: deploy
image: alpine:latest
only:
- develop@pleroma/pleroma-fe
before_script:
- apk add curl
script:
- curl -X POST -F"token=$DOCS_PIPELINE_TRIGGER" -F'ref=master' https://git.pleroma.social/api/v4/projects/673/trigger/pipeline
diff --git a/.node-version b/.node-version
index 08b7109d00..5bd6811705 100644
--- a/.node-version
+++ b/.node-version
@@ -1 +1 @@
-18.20.8
+20.19.0
diff --git a/.woodpecker/build.yaml b/.woodpecker/build.yaml
index 059fdb1ff3..af0bb98e34 100644
--- a/.woodpecker/build.yaml
+++ b/.woodpecker/build.yaml
@@ -1,43 +1,43 @@
when:
- event: pull_request
evaluate: 'CI_COMMIT_SOURCE_BRANCH != "weblate" && not(CI_COMMIT_SOURCE_BRANCH startsWith "renovate/")'
- event: push
branch: ${CI_REPO_DEFAULT_BRANCH}
- event: manual
branch: ${CI_REPO_DEFAULT_BRANCH}
depends_on:
- test
- test-e2e
labels:
platform: linux/amd64
memory: 'high'
steps:
build:
- image: docker.io/node:18-alpine
+ image: docker.io/node:20-alpine
commands:
- apk add --no-cache zip git
- yarn --frozen-lockfile
- yarn build
- if [ "${CI_PIPELINE_EVENT}" = "push" ] || [ "${CI_PIPELINE_EVENT}" = "manual" ]; then zip -9qr ${CI_REPO_DEFAULT_BRANCH}.zip dist/; fi
upload-artifacts:
image: docker.io/woodpeckercommunity/plugin-gitea-package:0.5.0
when:
- event: push
branch: ${CI_REPO_DEFAULT_BRANCH}
- event: manual
branch: ${CI_REPO_DEFAULT_BRANCH}
settings:
user:
from_secret: pleroma-ci-user
password:
from_secret: pleroma-ci-password
update: true
owner: 'pleroma'
package_name: 'pleroma-fe-builds'
package_version: ${CI_REPO_DEFAULT_BRANCH}
file_source: ./${CI_REPO_DEFAULT_BRANCH}.zip
file_name: latest.zip
diff --git a/.woodpecker/lint.yaml b/.woodpecker/lint.yaml
index 237135ee9e..257887338d 100644
--- a/.woodpecker/lint.yaml
+++ b/.woodpecker/lint.yaml
@@ -1,32 +1,32 @@
when:
- event: pull_request
evaluate: 'CI_COMMIT_SOURCE_BRANCH != "weblate" && not(CI_COMMIT_SOURCE_BRANCH startsWith "renovate/")'
- event: push
branch: ${CI_REPO_DEFAULT_BRANCH}
- event: manual
branch: ${CI_REPO_DEFAULT_BRANCH}
steps:
install-depends:
image: &node-image
- docker.io/node:18-alpine
+ docker.io/node:20-alpine
commands:
- yarn --frozen-lockfile
eslint:
image: *node-image
depends_on: install-depends
commands:
- yarn ci-eslint
biome:
image: *node-image
depends_on: install-depends
commands:
- yarn ci-biome
stylelint:
image: *node-image
depends_on: install-depends
commands:
- yarn ci-stylelint
diff --git a/build/sw_plugin.js b/build/sw_plugin.js
index 03c5978d7e..066c8da121 100644
--- a/build/sw_plugin.js
+++ b/build/sw_plugin.js
@@ -1,211 +1,144 @@
import { readFile } from 'node:fs/promises'
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
-import * as esbuild from 'esbuild'
+import { exactRegex } from '@rolldown/pluginutils'
import { build } from 'vite'
import {
generateServiceWorkerMessages,
i18nFiles,
} from './service_worker_messages.js'
const getSWMessagesAsText = async () => {
const messages = await generateServiceWorkerMessages()
return `export default ${JSON.stringify(messages, undefined, 2)}`
}
const projectRoot = dirname(dirname(fileURLToPath(import.meta.url)))
-const swEnvName = 'virtual:pleroma-fe/service_worker_env'
-const swEnvNameResolved = '\0' + swEnvName
-const getDevSwEnv = () => `self.serviceWorkerOption = { assets: [] };`
-const getProdSwEnv = ({ assets }) =>
- `self.serviceWorkerOption = { assets: ${JSON.stringify(assets)} };`
-
-export const devSwPlugin = ({ swSrc, swDest, transformSW, alias }) => {
- const swFullSrc = resolve(projectRoot, swSrc)
- const esbuildAlias = {}
- Object.entries(alias).forEach(([source, dest]) => {
- esbuildAlias[source] = dest.startsWith('/') ? projectRoot + dest : dest
- })
-
- return {
- name: 'dev-sw-plugin',
- apply: 'serve',
- configResolved() {
- /* no-op */
- },
- resolveId(id) {
- const name = id.startsWith('/') ? id.slice(1) : id
- if (name === swDest) {
- return swFullSrc
- } else if (name === swEnvName) {
- return swEnvNameResolved
- }
- return null
- },
- async load(id) {
- if (id === swFullSrc) {
- return readFile(swFullSrc, 'utf-8')
- } else if (id === swEnvNameResolved) {
- return getDevSwEnv()
- }
- return null
- },
- /**
- * vite does not bundle the service worker
- * during dev, and firefox does not support ESM as service worker
- * https://bugzilla.mozilla.org/show_bug.cgi?id=1360870
- */
- async transform(code, id) {
- if (id === swFullSrc && transformSW) {
- const res = await esbuild.build({
- entryPoints: [swSrc],
- bundle: true,
- write: false,
- outfile: 'sw-pleroma.js',
- alias: esbuildAlias,
- plugins: [
- {
- name: 'vite-like-root-resolve',
- setup(b) {
- b.onResolve({ filter: new RegExp(/^\//) }, (args) => ({
- path: resolve(projectRoot, args.path.slice(1)),
- }))
- },
- },
- {
- name: 'sw-messages',
- setup(b) {
- b.onResolve(
- { filter: new RegExp('^' + swMessagesName + '$') },
- (args) => ({
- path: args.path,
- namespace: 'sw-messages',
- }),
- )
- b.onLoad(
- { filter: /.*/, namespace: 'sw-messages' },
- async () => ({
- contents: await getSWMessagesAsText(),
- }),
- )
- },
- },
- {
- name: 'sw-env',
- setup(b) {
- b.onResolve(
- { filter: new RegExp('^' + swEnvName + '$') },
- (args) => ({
- path: args.path,
- namespace: 'sw-env',
- }),
- )
- b.onLoad({ filter: /.*/, namespace: 'sw-env' }, () => ({
- contents: getDevSwEnv(),
- }))
- },
- },
- ],
- })
- const text = res.outputFiles[0].text
- return text
- }
- },
- }
-}
-
// Idea taken from
// https://github.com/vite-pwa/vite-plugin-pwa/blob/main/src/plugins/build.ts
// rollup does not support compiling to iife if we want to code-split;
// however, we must compile the service worker to iife because of browser support.
// Run another vite build just for the service worker targeting iife at
// the end of the build.
export const buildSwPlugin = ({ swSrc, swDest }) => {
+ const swFullSrc = resolve(projectRoot, swSrc)
+ const swEnvName = 'virtual:pleroma-fe/service_worker_env'
+ const swEnvNameResolved = '\0' + swEnvName
+
let config
+
return {
name: 'build-sw-plugin',
enforce: 'post',
- apply: 'build',
configResolved(resolvedConfig) {
+ resolvedConfig
config = {
define: resolvedConfig.define,
resolve: resolvedConfig.resolve,
plugins: [swMessagesPlugin()],
publicDir: false,
build: {
...resolvedConfig.build,
- lib: {
- entry: swSrc,
- formats: ['iife'],
- name: 'sw_pleroma',
- },
emptyOutDir: false,
- rollupOptions: {
+ rolldownOptions: {
+ input: {
+ main: swSrc,
+ },
+ context: 'self',
output: {
entryFileNames: swDest,
+ codeSplitting: false,
+ format: 'iife',
},
},
},
configFile: false,
}
},
generateBundle: {
order: 'post',
sequential: true,
async handler(_, bundle) {
const assets = Object.keys(bundle)
.filter((name) => !/\.map$/.test(name))
.map((name) => '/' + name)
+
config.plugins.push({
name: 'build-sw-env-plugin',
- resolveId(id) {
- if (id === swEnvName) {
- return swEnvNameResolved
- }
- return null
+ mode: 'production',
+ resolveId: {
+ filter: { id: exactRegex(swEnvName) },
+ handler: () => swEnvNameResolved,
+ },
+ load: {
+ filter: { id: exactRegex(swEnvNameResolved) },
+ handler() {
+ return `self.serviceWorkerOption = { assets: ${JSON.stringify(assets)} };`
+ },
},
- load(id) {
- if (id === swEnvNameResolved) {
- return getProdSwEnv({ assets })
- }
- return null
+ })
+ },
+ },
+ resolveId: {
+ filter: { id: new RegExp(swDest) },
+ handler() {
+ return swFullSrc
+ },
+ },
+ load: {
+ filter: { id: new RegExp(swFullSrc) },
+ async handler() {
+ config.plugins.push({
+ name: 'dummy-sw-env',
+ mode: 'development',
+ resolveId: {
+ filter: { id: exactRegex(swEnvName) },
+ handler: () => swEnvNameResolved,
+ },
+ load: {
+ filter: { id: exactRegex(swEnvNameResolved) },
+ handler: () => 'self.serviceWorkerOption = { assets: [] }',
},
})
+
+ const swBundle = await build(config)
+ return swBundle.output[0]
},
},
closeBundle: {
order: 'post',
sequential: true,
async handler() {
+ if (process.env.VITEST) return
console.info('Building service worker for production')
await build(config)
},
},
}
}
const swMessagesName = 'virtual:pleroma-fe/service_worker_messages'
const swMessagesNameResolved = '\0' + swMessagesName
export const swMessagesPlugin = () => {
return {
name: 'sw-messages-plugin',
resolveId(id) {
if (id === swMessagesName) {
Object.values(i18nFiles).forEach((f) => {
this.addWatchFile(f)
})
return swMessagesNameResolved
} else {
return null
}
},
async load(id) {
if (id === swMessagesNameResolved) {
return await getSWMessagesAsText()
}
return null
},
}
}
diff --git a/changelog.d/fast.change b/changelog.d/fast.change
new file mode 100644
index 0000000000..1f0a89092c
--- /dev/null
+++ b/changelog.d/fast.change
@@ -0,0 +1 @@
+Migrated to Vite 8 and optimized our imports, more stuff is loaded on-demand, reducing the initial load time and transfer size
diff --git a/package.json b/package.json
index 85e79a1d32..c51d98b813 100644
--- a/package.json
+++ b/package.json
@@ -1,127 +1,129 @@
{
"name": "pleroma_fe",
"version": "2.10.1",
"description": "Pleroma frontend, the default frontend of Pleroma social network server",
"author": "Pleroma contributors <https://git.pleroma.social/pleroma/pleroma-fe/src/CONTRIBUTORS.md>",
"private": false,
"scripts": {
"dev": "node build/update-emoji.js && vite dev",
"build": "node build/update-emoji.js && vite build",
"unit": "node build/update-emoji.js && vitest --run",
"unit-ci": "node build/update-emoji.js && vitest --run --browser.headless",
"unit:watch": "node build/update-emoji.js && vitest",
"e2e:pw": "playwright test --config test/e2e-playwright/playwright.config.mjs",
"e2e": "sh ./tools/e2e/run.sh",
"test": "yarn run unit && yarn run e2e",
"ci-biome": "yarn exec biome check",
"ci-eslint": "yarn exec eslint",
"ci-stylelint": "yarn exec stylelint '**/*.scss' '**/*.vue'",
"lint": "yarn ci-biome; yarn ci-eslint; yarn ci-stylelint",
"lint-fix": "yarn exec eslint -- --fix; yarn exec stylelint '**/*.scss' '**/*.vue' --fix; biome check --write"
},
"dependencies": {
"@babel/runtime": "7.28.4",
"@chenfengyuan/vue-qrcode": "2.0.0",
"@fortawesome/fontawesome-svg-core": "7.1.0",
"@fortawesome/free-regular-svg-icons": "7.1.0",
"@fortawesome/free-solid-svg-icons": "7.1.0",
"@fortawesome/vue-fontawesome": "3.1.2",
"@kazvmoe-infra/pinch-zoom-element": "1.3.0",
"@kazvmoe-infra/unicode-emoji-json": "0.4.0",
"@ruffle-rs/ruffle": "0.1.0-nightly.2025.6.22",
"@vuelidate/core": "2.0.3",
"@vuelidate/validators": "2.0.4",
"@web3-storage/parse-link-header": "^3.1.0",
"body-scroll-lock": "3.1.5",
"chromatism": "3.0.0",
"click-outside-vue3": "4.0.1",
"cropperjs": "2.0.1",
"escape-html": "1.0.3",
"globals": "^16.0.0",
"hash-sum": "^2.0.0",
"js-cookie": "3.0.5",
"localforage": "1.10.0",
"parse-link-header": "2.0.0",
"phoenix": "1.8.1",
- "pinia": "^3.0.0",
+ "pinia": "^3.0.4",
"punycode.js": "2.3.1",
"qrcode": "1.5.4",
"querystring-es3": "0.2.1",
"url": "0.11.4",
"utf8": "3.0.0",
"uuid": "11.1.0",
"vue": "3.5.22",
"vue-i18n": "11",
"vue-router": "4.6.4",
"vue-virtual-scroller": "^2.0.0-beta.7",
"vuex": "4.1.0"
},
"devDependencies": {
"@babel/core": "7.28.5",
"@babel/eslint-parser": "7.28.5",
"@babel/plugin-transform-runtime": "7.28.5",
"@babel/preset-env": "7.28.5",
"@babel/register": "7.28.3",
"@biomejs/biome": "2.3.11",
"@pinia/testing": "1.0.3",
"@ungap/event-target": "0.2.4",
- "@vitejs/plugin-vue": "^5.2.1",
- "@vitejs/plugin-vue-jsx": "^4.1.1",
+ "@vitejs/devtools": "^0.3.1",
+ "@vitejs/plugin-vue": "^6.0.7",
+ "@vitejs/plugin-vue-jsx": "^5.1.5",
"@vitest/browser": "^3.0.7",
"@vitest/ui": "^3.0.7",
"@vue/babel-helper-vue-jsx-merge-props": "1.4.0",
"@vue/babel-plugin-jsx": "1.5.0",
"@vue/compiler-sfc": "3.5.22",
"@vue/test-utils": "2.4.6",
"autoprefixer": "10.4.21",
"babel-plugin-lodash": "3.3.4",
"chai": "5.3.3",
"chalk": "5.6.2",
"chromedriver": "135.0.4",
"connect-history-api-fallback": "2.0.0",
"cross-spawn": "7.0.6",
"custom-event-polyfill": "1.0.7",
"eslint": "9.39.2",
"eslint-config-standard": "17.1.0",
"eslint-formatter-friendly": "7.0.0",
"eslint-plugin-import": "2.32.0",
"eslint-plugin-n": "17.23.1",
"eslint-plugin-promise": "7.2.1",
"eslint-plugin-vue": "10.6.2",
"eventsource-polyfill": "0.9.6",
"express": "5.1.0",
"function-bind": "1.1.2",
"http-proxy-middleware": "3.0.5",
"iso-639-1": "3.1.5",
"lodash": "4.17.21",
"msw": "2.10.5",
"nightwatch": "3.12.2",
+ "oxc": "^1.0.1",
"playwright": "1.57.0",
"postcss": "8.5.6",
"postcss-html": "^1.5.0",
"postcss-scss": "^4.0.6",
- "sass": "1.93.2",
+ "sass-embedded": "^1.100.0",
"selenium-server": "3.141.59",
"semver": "7.7.3",
"serve-static": "2.2.0",
"shelljs": "0.10.0",
"sinon": "20.0.0",
"sinon-chai": "4.0.1",
"stylelint": "16.25.0",
"stylelint-config-html": "^1.1.0",
"stylelint-config-recommended": "^16.0.0",
"stylelint-config-recommended-scss": "^14.0.0",
"stylelint-config-recommended-vue": "^1.6.0",
"stylelint-config-standard": "38.0.0",
- "vite": "^6.1.0",
- "vite-plugin-eslint2": "^5.0.3",
- "vite-plugin-stylelint": "^6.0.0",
+ "vite": "^8.0.0",
+ "vite-plugin-eslint2": "^5.1.0",
+ "vite-plugin-stylelint": "^6.1.0",
"vitest": "^3.0.7",
"vue-eslint-parser": "10.2.0"
},
"type": "module",
"engines": {
"node": ">= 16.0.0"
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
}
diff --git a/src/App.js b/src/App.js
index a24ff42550..ea2271a754 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,298 +1,307 @@
import { throttle } from 'lodash'
import { mapState } from 'pinia'
import { defineAsyncComponent } from 'vue'
-import DesktopNav from './components/desktop_nav/desktop_nav.vue'
-import EditStatusModal from './components/edit_status_modal/edit_status_modal.vue'
-import FeaturesPanel from './components/features_panel/features_panel.vue'
-import GlobalNoticeList from './components/global_notice_list/global_notice_list.vue'
-import InstanceSpecificPanel from './components/instance_specific_panel/instance_specific_panel.vue'
-import MediaModal from './components/media_modal/media_modal.vue'
-import MobileNav from './components/mobile_nav/mobile_nav.vue'
-import MobilePostStatusButton from './components/mobile_post_status_button/mobile_post_status_button.vue'
-import NavPanel from './components/nav_panel/nav_panel.vue'
-import PostStatusModal from './components/post_status_modal/post_status_modal.vue'
-import ShoutPanel from './components/shout_panel/shout_panel.vue'
-import SideDrawer from './components/side_drawer/side_drawer.vue'
-import StatusHistoryModal from './components/status_history_modal/status_history_modal.vue'
-import UserPanel from './components/user_panel/user_panel.vue'
-import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
-import WhoToFollowPanel from './components/who_to_follow_panel/who_to_follow_panel.vue'
+import DesktopNav from 'src/components/desktop_nav/desktop_nav.vue'
+import FeaturesPanel from 'src/components/features_panel/features_panel.vue'
+import GlobalNoticeList from 'src/components/global_notice_list/global_notice_list.vue'
+import InstanceSpecificPanel from 'src/components/instance_specific_panel/instance_specific_panel.vue'
+import MobileNav from 'src/components/mobile_nav/mobile_nav.vue'
+import MobilePostStatusButton from 'src/components/mobile_post_status_button/mobile_post_status_button.vue'
+import NavPanel from 'src/components/nav_panel/nav_panel.vue'
+import UserPanel from 'src/components/user_panel/user_panel.vue'
import { getOrCreateServiceWorker } from './services/sw/sw'
import { windowHeight, windowWidth } from './services/window_utils/window_utils'
import { useEmojiStore } from 'src/stores/emoji.js'
import { useI18nStore } from 'src/stores/i18n.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useShoutStore } from 'src/stores/shout.js'
import messages from 'src/i18n/messages'
import localeService from 'src/services/locale/locale.service.js'
// Helper to unwrap reactive proxies
window.toValue = (x) => JSON.parse(JSON.stringify(x))
export default {
name: 'app',
components: {
UserPanel,
NavPanel,
Notifications: defineAsyncComponent(
- () => import('./components/notifications/notifications.vue'),
+ () => import('src/components/notifications/notifications.vue'),
),
InstanceSpecificPanel,
FeaturesPanel,
- WhoToFollowPanel,
- ShoutPanel,
- MediaModal,
- SideDrawer,
+ WhoToFollowPanel: defineAsyncComponent(
+ () =>
+ import('src/components/who_to_follow_panel/who_to_follow_panel.vue'),
+ ),
+ ShoutPanel: defineAsyncComponent(
+ () => import('src/components/shout_panel/shout_panel.vue'),
+ ),
+ MediaModal: defineAsyncComponent(
+ () => import('src/components/media_modal/media_modal.vue'),
+ ),
MobilePostStatusButton,
MobileNav,
DesktopNav,
SettingsModal: defineAsyncComponent(
- () => import('./components/settings_modal/settings_modal.vue'),
+ () => import('src/components/settings_modal/settings_modal.vue'),
),
UpdateNotification: defineAsyncComponent(
- () => import('./components/update_notification/update_notification.vue'),
+ () =>
+ import('src/components/update_notification/update_notification.vue'),
+ ),
+ PostStatusModal: defineAsyncComponent(
+ () => import('src/components/post_status_modal/post_status_modal.vue'),
+ ),
+ UserReportingModal: defineAsyncComponent(
+ () =>
+ import('src/components/user_reporting_modal/user_reporting_modal.vue'),
+ ),
+ EditStatusModal: defineAsyncComponent(
+ () => import('src/components/edit_status_modal/edit_status_modal.vue'),
+ ),
+ StatusHistoryModal: defineAsyncComponent(
+ () =>
+ import('src/components/status_history_modal/status_history_modal.vue'),
),
- UserReportingModal,
- PostStatusModal,
- EditStatusModal,
- StatusHistoryModal,
GlobalNoticeList,
},
data: () => ({
mobileActivePanel: 'timeline',
}),
provide() {
return {
allowNonSquareEmoji: useMergedConfigStore().mergedConfig.nonSquareEmoji,
}
},
watch: {
themeApplied() {
this.removeSplash()
},
currentTheme() {
this.setThemeBodyClass()
},
layoutType() {
document.getElementById('modal').classList = ['-' + this.layoutType]
},
},
created() {
// Load the locale from the storage
const value = useMergedConfigStore().mergedConfig.interfaceLanguage
useI18nStore().setLanguage(value)
useEmojiStore().loadUnicodeEmojiData(value)
document.getElementById('modal').classList = ['-' + this.layoutType]
// Create bound handlers
this.updateScrollState = throttle(this.scrollHandler, 200)
this.updateMobileState = throttle(this.resizeHandler, 200)
},
mounted() {
window.addEventListener('resize', this.updateMobileState)
this.scrollParent.addEventListener('scroll', this.updateScrollState)
if (this.themeApplied) {
this.setThemeBodyClass()
this.removeSplash()
}
getOrCreateServiceWorker()
},
unmounted() {
window.removeEventListener('resize', this.updateMobileState)
this.scrollParent.removeEventListener('scroll', this.updateScrollState)
},
computed: {
currentTheme() {
if (this.styleDataUsed) {
const styleMeta = this.styleDataUsed.find(
(x) => x.component === '@meta',
)
if (styleMeta !== undefined) {
return styleMeta.directives.name.replaceAll(' ', '-').toLowerCase()
}
}
return 'stock'
},
layoutModalClass() {
return '-' + this.layoutType
},
classes() {
return [
{
'-reverse': this.reverseLayout,
'-no-sticky-headers': this.noSticky,
'-has-new-post-button': this.newPostButtonShown,
},
'-' + this.layoutType,
]
},
navClasses() {
const { navbarColumnStretch } = useMergedConfigStore().mergedConfig
return [
'-' + this.layoutType,
...(navbarColumnStretch ? ['-column-stretch'] : []),
]
},
currentUser() {
return this.$store.state.users.currentUser
},
userBackground() {
return this.currentUser.background_image
},
foreignProfileBackground() {
return (
useMergedConfigStore().mergedConfig.allowForeignUserBackground &&
useInterfaceStore().foreignProfileBackground
)
},
instanceBackground() {
return useMergedConfigStore().mergedConfig.hideInstanceWallpaper
? null
: this.instanceBackgroundUrl
},
background() {
return (
this.foreignProfileBackground ||
this.userBackground ||
this.instanceBackground
)
},
bgStyle() {
if (this.background) {
return {
'--body-background-image': `url(${this.background})`,
}
}
},
shoutJoined() {
return useShoutStore().joined
},
isChats() {
return this.$route.name === 'chat' || this.$route.name === 'chats'
},
isListEdit() {
return this.$route.name === 'lists-edit'
},
newPostButtonShown() {
if (this.isChats) return false
if (this.isListEdit) return false
return (
useMergedConfigStore().mergedConfig.alwaysShowNewPostButton ||
this.layoutType === 'mobile'
)
},
shoutboxPosition() {
return (
useMergedConfigStore().mergedConfig.alwaysShowNewPostButton || false
)
},
hideShoutbox() {
return useMergedConfigStore().mergedConfig.hideShoutbox
},
reverseLayout() {
const { thirdColumnMode, sidebarRight: reverseSetting } =
useMergedConfigStore().mergedConfig
if (this.layoutType !== 'wide') {
return reverseSetting
} else {
return thirdColumnMode === 'notifications'
? reverseSetting
: !reverseSetting
}
},
noSticky() {
return useMergedConfigStore().mergedConfig.disableStickyHeaders
},
showScrollbars() {
return useMergedConfigStore().mergedConfig.showScrollbars
},
scrollParent() {
return window /* this.$refs.appContentRef */
},
showInstanceSpecificPanel() {
return (
this.instanceSpecificPanelPresent &&
!useMergedConfigStore().mergedConfig.hideISP
)
},
...mapState(useMergedConfigStore, ['mergedConfig']),
...mapState(useInterfaceStore, [
'themeApplied',
'styleDataUsed',
'layoutType',
]),
...mapState(useInstanceStore, ['styleDataUsed']),
...mapState(useInstanceCapabilitiesStore, [
'suggestionsEnabled',
'editingAvailable',
]),
...mapState(useInstanceStore, {
instanceBackgroundUrl: (store) => store.instanceIdentity.background,
showFeaturesPanel: (store) => store.instanceIdentity.showFeaturesPanel,
instanceSpecificPanelPresent: (store) =>
store.instanceIdentity.showInstanceSpecificPanel &&
store.instanceIdentity.instanceSpecificPanelContent,
}),
},
methods: {
resizeHandler() {
useInterfaceStore().setLayoutWidth(windowWidth())
useInterfaceStore().setLayoutHeight(windowHeight())
},
scrollHandler() {
const scrollPosition =
this.scrollParent === window
? window.scrollY
: this.scrollParent.scrollTop
if (scrollPosition != 0) {
this.$refs.appContentRef.classList.add(['-scrolled'])
} else {
this.$refs.appContentRef.classList.remove(['-scrolled'])
}
},
setThemeBodyClass() {
const themeName = this.currentTheme
const classList = Array.from(document.body.classList)
const oldTheme = classList.filter((c) => c.startsWith('theme-'))
if (themeName !== null && themeName !== '') {
const newTheme = `theme-${themeName.toLowerCase()}`
// remove old theme reference if there are any
if (oldTheme.length) {
document.body.classList.replace(oldTheme[0], newTheme)
} else {
document.body.classList.add(newTheme)
}
} else {
// remove theme reference if non-V3 theme is used
document.body.classList.remove(...oldTheme)
}
},
removeSplash() {
document.querySelector('#status').textContent = this.$t(
'splash.fun_' + Math.ceil(Math.random() * 4),
)
const splashscreenRoot = document.querySelector('#splash')
splashscreenRoot.addEventListener('transitionend', () => {
splashscreenRoot.remove()
})
setTimeout(() => {
splashscreenRoot.remove() // forcibly remove it, should fix my plasma browser widget t. HJ
}, 600)
splashscreenRoot.classList.add('hidden')
document.querySelector('#app').classList.remove('hidden')
},
},
}
diff --git a/src/boot/after_store.js b/src/boot/after_store.js
index a3d8701e57..fe65a73875 100644
--- a/src/boot/after_store.js
+++ b/src/boot/after_store.js
@@ -1,622 +1,629 @@
/* global process */
import vClickOutside from 'click-outside-vue3'
import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import VueVirtualScroller from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
+import RichContent from 'src/components/rich_content/rich_content.jsx'
+import Status from 'src/components/status/status.vue'
+import StillImage from 'src/components/still-image/still-image.vue'
+
import { config } from '@fortawesome/fontawesome-svg-core'
import {
FontAwesomeIcon,
FontAwesomeLayers,
} from '@fortawesome/vue-fontawesome'
config.autoAddCss = false
import App from '../App.vue'
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
import FaviconService from '../services/favicon_service/favicon_service.js'
import { applyStyleConfig } from '../services/style_setter/style_setter.js'
import { initServiceWorker, updateFocus } from '../services/sw/sw.js'
import {
windowHeight,
windowWidth,
} from '../services/window_utils/window_utils'
import routes from './routes'
import { useAnnouncementsStore } from 'src/stores/announcements'
import { useAuthFlowStore } from 'src/stores/auth_flow'
import { useEmojiStore } from 'src/stores/emoji.js'
import { useI18nStore } from 'src/stores/i18n'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useLocalConfigStore } from 'src/stores/local_config.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useOAuthStore } from 'src/stores/oauth'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { useUserHighlightStore } from 'src/stores/user_highlight.js'
import VBodyScrollLock from 'src/directives/body_scroll_lock'
import {
INSTANCE_DEFAULT_CONFIG_DEFINITIONS,
INSTANCE_IDENTITY_DEFAULT_DEFINITIONS,
INSTANCE_IDENTIY_EXTERNAL,
} from 'src/modules/default_config_state.js'
let staticInitialResults = null
const parsedInitialResults = () => {
if (!document.getElementById('initial-results')) {
return null
}
if (!staticInitialResults) {
staticInitialResults = JSON.parse(
document.getElementById('initial-results').textContent,
)
}
return staticInitialResults
}
const decodeUTF8Base64 = (data) => {
const rawData = atob(data)
const array = Uint8Array.from([...rawData].map((char) => char.charCodeAt(0)))
const text = new TextDecoder().decode(array)
return text
}
const preloadFetch = async (request) => {
const data = parsedInitialResults()
if (!data || !data[request]) {
return window.fetch(request)
}
const decoded = decodeUTF8Base64(data[request])
const requestData = JSON.parse(decoded)
return {
ok: true,
json: () => requestData,
text: () => requestData,
}
}
const getInstanceConfig = async ({ store }) => {
try {
const res = await preloadFetch('/api/v1/instance')
if (res.ok) {
const data = await res.json()
const textLimit = data.max_toot_chars
const vapidPublicKey = data.pleroma.vapid_public_key
useInstanceCapabilitiesStore().set(
'pleromaExtensionsAvailable',
data.pleroma,
)
useInstanceStore().set({
path: 'limits.textLimit',
value: textLimit,
})
useInstanceStore().set({
path: 'accountApprovalRequired',
value: data.approval_required,
})
useInstanceStore().set({
path: 'birthdayRequired',
value: !!data.pleroma?.metadata.birthday_required,
})
useInstanceStore().set({
path: 'birthdayMinAge',
value: data.pleroma?.metadata.birthday_min_age || 0,
})
if (vapidPublicKey) {
useInstanceStore().set({
path: 'vapidPublicKey',
value: vapidPublicKey,
})
}
} else {
throw res
}
} catch (error) {
console.error('Could not load instance config, potentially fatal')
console.error(error)
}
// We should check for scrobbles support here but it requires userId
// so instead we check for it where it's fetched (statuses.js)
}
const getBackendProvidedConfig = async () => {
try {
const res = await window.fetch('/api/pleroma/frontend_configurations')
if (res.ok) {
const data = await res.json()
return data.pleroma_fe
} else {
throw res
}
} catch (error) {
console.error(
'Could not load backend-provided frontend config, potentially fatal',
)
console.error(error)
}
}
const getStaticConfig = async () => {
try {
const res = await window.fetch('/static/config.json')
if (res.ok) {
return res.json()
} else {
throw res
}
} catch (error) {
console.warn(
'Failed to load static/config.json, continuing without it.',
error,
)
return {}
}
}
const setSettings = async ({ apiConfig, staticConfig, store }) => {
const overrides = window.___pleromafe_dev_overrides || {}
const env = window.___pleromafe_mode.NODE_ENV
// This takes static config and overrides properties that are present in apiConfig
let config = {}
if (overrides.staticConfigPreference && env === 'development') {
console.warn('OVERRIDING API CONFIG WITH STATIC CONFIG')
config = Object.assign({}, apiConfig, staticConfig)
} else {
config = Object.assign({}, staticConfig, apiConfig)
}
Object.keys(INSTANCE_IDENTITY_DEFAULT_DEFINITIONS).forEach((source) => {
if (source === 'name') return
if (INSTANCE_IDENTIY_EXTERNAL.has(source)) return
useInstanceStore().set({
value:
config[source] ?? INSTANCE_IDENTITY_DEFAULT_DEFINITIONS[source].default,
path: `instanceIdentity.${source}`,
})
})
Object.keys(INSTANCE_DEFAULT_CONFIG_DEFINITIONS).forEach((source) =>
useInstanceStore().set({
value:
config[source] ?? INSTANCE_DEFAULT_CONFIG_DEFINITIONS[source].default,
path: `prefsStorage.${source}`,
}),
)
useAuthFlowStore().setInitialStrategy(config.loginMethod)
}
const getTOS = async ({ store }) => {
try {
const res = await window.fetch('/static/terms-of-service.html')
if (res.ok) {
const html = await res.text()
useInstanceStore().set({ path: 'instanceIdentity.tos', value: html })
} else {
throw res
}
} catch (e) {
console.warn("Can't load TOS\n", e)
}
}
const getInstancePanel = async ({ store }) => {
try {
const res = await preloadFetch('/instance/panel.html')
if (res.ok) {
const html = await res.text()
useInstanceStore().set({
path: 'instanceIdentity.instanceSpecificPanelContent',
value: html,
})
} else {
throw res
}
} catch (e) {
console.warn("Can't load instance panel\n", e)
}
}
const getStickers = async ({ store }) => {
try {
const res = await window.fetch('/static/stickers.json')
if (res.ok) {
const values = await res.json()
const stickers = (
await Promise.all(
Object.entries(values).map(async ([name, path]) => {
const resPack = await window.fetch(path + 'pack.json')
let meta = {}
if (resPack.ok) {
meta = await resPack.json()
}
return {
pack: name,
path,
meta,
}
}),
)
).sort((a, b) => {
return a.meta.title.localeCompare(b.meta.title)
})
useEmojiStore().setStickers(stickers)
} else {
throw res
}
} catch (e) {
console.warn("Can't load stickers\n", e)
}
}
const getAppSecret = async ({ store }) => {
const oauth = useOAuthStore()
if (oauth.userToken) {
store.commit(
'setBackendInteractor',
backendInteractorService(oauth.getToken),
)
}
}
const resolveStaffAccounts = ({ store, accounts }) => {
const nicknames = accounts.map((uri) => uri.split('/').pop())
useInstanceStore().set({
path: 'staffAccounts',
value: nicknames,
})
}
const getNodeInfo = async ({ store }) => {
try {
let res = await preloadFetch('/nodeinfo/2.1.json')
if (!res.ok) res = await preloadFetch('/nodeinfo/2.0.json')
if (res.ok) {
const data = await res.json()
const metadata = data.metadata
const features = metadata.features
useInstanceStore().set({
path: 'instanceIdentity.name',
value: metadata.nodeName,
})
useInstanceStore().set({
path: 'registrationOpen',
value: data.openRegistrations,
})
useInstanceCapabilitiesStore().set(
'mediaProxyAvailable',
features.includes('media_proxy'),
)
useInstanceCapabilitiesStore().set(
'safeDM',
features.includes('safe_dm_mentions'),
)
useInstanceCapabilitiesStore().set(
'shoutAvailable',
features.includes('chat'),
)
useInstanceCapabilitiesStore().set(
'pleromaChatMessagesAvailable',
features.includes('pleroma_chat_messages'),
)
useInstanceCapabilitiesStore().set(
'pleromaCustomEmojiReactionsAvailable',
features.includes('pleroma_custom_emoji_reactions') ||
features.includes('custom_emoji_reactions'),
)
useInstanceCapabilitiesStore().set(
'pleromaBookmarkFoldersAvailable',
features.includes('pleroma:bookmark_folders'),
)
useInstanceCapabilitiesStore().set(
'gopherAvailable',
features.includes('gopher'),
)
useInstanceCapabilitiesStore().set(
'pollsAvailable',
features.includes('polls'),
)
useInstanceCapabilitiesStore().set(
'editingAvailable',
features.includes('editing'),
)
useInstanceCapabilitiesStore().set(
'mailerEnabled',
metadata.mailerEnabled,
)
useInstanceCapabilitiesStore().set(
'quotingAvailable',
features.includes('quote_posting'),
)
useInstanceCapabilitiesStore().set(
'groupActorAvailable',
features.includes('pleroma:group_actors'),
)
useInstanceCapabilitiesStore().set(
'blockExpiration',
features.includes('pleroma:block_expiration'),
)
useInstanceStore().set({
path: 'localBubbleInstances',
value: metadata.localBubbleInstances ?? [],
})
useInstanceCapabilitiesStore().set(
'localBubble',
(metadata.localBubbleInstances ?? []).length > 0,
)
useInstanceStore().set({
path: 'limits.pollLimits',
value: metadata.pollLimits,
})
const uploadLimits = metadata.uploadLimits
useInstanceStore().set({
path: 'limits.uploadlimit',
value: parseInt(uploadLimits.general),
})
useInstanceStore().set({
path: 'limits.avatarlimit',
value: parseInt(uploadLimits.avatar),
})
useInstanceStore().set({
path: 'limits.backgroundlimit',
value: parseInt(uploadLimits.background),
})
useInstanceStore().set({
path: 'limits.bannerlimit',
value: parseInt(uploadLimits.banner),
})
useInstanceStore().set({
path: 'limits.fieldsLimits',
value: metadata.fieldsLimits,
})
useInstanceStore().set({
path: 'restrictedNicknames',
value: metadata.restrictedNicknames,
})
useInstanceCapabilitiesStore().set('postFormats', metadata.postFormats)
const suggestions = metadata.suggestions
useInstanceCapabilitiesStore().set(
'suggestionsEnabled',
suggestions.enabled,
)
// this is unused, why?
useInstanceCapabilitiesStore().set('suggestionsWeb', suggestions.web)
const software = data.software
useInstanceStore().set({
path: 'backendVersion',
value: software.version,
})
useInstanceStore().set({
path: 'backendRepository',
value: software.repository,
})
const priv = metadata.private
useInstanceStore().set({ path: 'privateMode', value: priv })
const frontendVersion = window.___pleromafe_commit_hash
useInstanceStore().set({
path: 'frontendVersion',
value: frontendVersion,
})
const federation = metadata.federation
useInstanceCapabilitiesStore().set(
'tagPolicyAvailable',
typeof federation.mrf_policies === 'undefined'
? false
: metadata.federation.mrf_policies.includes('TagPolicy'),
)
useInstanceStore().set({
path: 'federationPolicy',
value: federation,
})
useInstanceStore().set({
path: 'federating',
value:
typeof federation.enabled === 'undefined' ? true : federation.enabled,
})
const accountActivationRequired = metadata.accountActivationRequired
useInstanceStore().set({
path: 'accountActivationRequired',
value: accountActivationRequired,
})
const accounts = metadata.staffAccounts
resolveStaffAccounts({ store, accounts })
} else {
throw res
}
} catch (e) {
console.warn('Could not load nodeinfo', e)
}
}
const setConfig = async ({ store }) => {
// apiConfig, staticConfig
const configInfos = await Promise.all([
getBackendProvidedConfig({ store }),
getStaticConfig(),
])
const apiConfig = configInfos[0]
const staticConfig = configInfos[1]
getAppSecret({ store })
await setSettings({ store, apiConfig, staticConfig })
}
const checkOAuthToken = async ({ store }) => {
const oauth = useOAuthStore()
if (oauth.getUserToken) {
return store.dispatch('loginUser', oauth.getUserToken)
}
return Promise.resolve()
}
const afterStoreSetup = async ({ pinia, store, storageError, i18n }) => {
const app = createApp(App)
// Must have app use pinia before we do anything that touches the store
// https://pinia.vuejs.org/core-concepts/plugins.html#Introduction
// "Plugins are only applied to stores created after the plugins themselves, and after pinia is passed to the app, otherwise they won't be applied."
app.use(pinia)
const waitForAllStoresToLoad = async () => {
// the stores that do not persist technically do not need to be awaited here,
// but that involves either hard-coding the stores in some place (prone to errors)
// or writing another vite plugin to analyze which stores needs persisting (++load time)
const allStores = import.meta.glob('../stores/*.js', { eager: true })
if (process.env.NODE_ENV === 'development') {
// do some checks to avoid common errors
if (!Object.keys(allStores).length) {
throw new Error(
'No stores are available. Check the code in src/boot/after_store.js',
)
}
}
await Promise.all(
Object.entries(allStores).map(async ([name, mod]) => {
const isStoreName = (name) => name.startsWith('use')
if (process.env.NODE_ENV === 'development') {
if (Object.keys(mod).filter(isStoreName).length !== 1) {
throw new Error(
'Each store file must export exactly one store as a named export. Check your code in src/stores/',
)
}
}
const storeFuncName = Object.keys(mod).find(isStoreName)
if (storeFuncName && typeof mod[storeFuncName] === 'function') {
const p = mod[storeFuncName]().$persistLoaded
if (!(p instanceof Promise)) {
throw new Error(
`${name} store's $persistLoaded is not a Promise. The persist plugin is not applied.`,
)
}
await p
} else {
throw new Error(
`Store module ${name} does not export a 'use...' function`,
)
}
}),
)
}
try {
await waitForAllStoresToLoad()
} catch (e) {
console.error('Cannot load stores:', e)
storageError = e
}
if (storageError) {
useInterfaceStore().pushGlobalNotice({
messageKey: 'errors.storage_unavailable',
level: 'error',
})
}
useInterfaceStore().setLayoutWidth(windowWidth())
useInterfaceStore().setLayoutHeight(windowHeight())
window.syncConfig = useSyncConfigStore()
window.mergedConfig = useMergedConfigStore()
window.localConfig = useLocalConfigStore()
window.highlightConfig = useUserHighlightStore()
FaviconService.initFaviconService()
initServiceWorker(store)
window.addEventListener('focus', () => updateFocus())
const overrides = window.___pleromafe_dev_overrides || {}
const server =
typeof overrides.target !== 'undefined'
? overrides.target
: window.location.origin
useInstanceStore().set({ path: 'server', value: server })
await setConfig({ store })
try {
await useInterfaceStore()
.applyTheme()
.catch((e) => {
console.error('Error setting theme', e)
})
} catch (e) {
window.splashError(e)
return Promise.reject(e)
}
applyStyleConfig(useMergedConfigStore().mergedConfig, i18n.global)
// Now we can try getting the server settings and logging in
// Most of these are preloaded into the index.html so blocking is minimized
await Promise.all([
checkOAuthToken({ store }),
getInstancePanel({ store }),
getNodeInfo({ store }),
getInstanceConfig({ store }),
]).catch((e) => Promise.reject(e))
// Start fetching things that don't need to block the UI
store.dispatch('fetchMutes')
store.dispatch('loadDrafts')
useAnnouncementsStore().startFetchingAnnouncements()
getTOS({ store })
getStickers({ store })
const router = createRouter({
history: createWebHistory(),
routes: routes(store),
scrollBehavior: (to, _from, savedPosition) => {
if (to.matched.some((m) => m.meta.dontScroll)) {
return false
}
return savedPosition || { left: 0, top: 0 }
},
})
useI18nStore().setI18n(i18n)
app.use(router)
app.use(store)
app.use(i18n)
// Little thing to get out of invalid theme state
window.resetThemes = () => {
useInterfaceStore().resetThemeV3()
useInterfaceStore().resetThemeV3Palette()
useInterfaceStore().resetThemeV2()
}
app.use(vClickOutside)
app.use(VBodyScrollLock)
app.use(VueVirtualScroller)
app.component('FAIcon', FontAwesomeIcon)
app.component('FALayers', FontAwesomeLayers)
+ app.component('Status', Status)
+ app.component('RichContent', RichContent)
+ app.component('StillImage', StillImage)
// remove after vue 3.3
app.config.unwrapInjectedRef = true
app.mount('#app')
return app
}
export default afterStoreSetup
diff --git a/src/boot/routes.js b/src/boot/routes.js
index 193daf4a72..4a075e955c 100644
--- a/src/boot/routes.js
+++ b/src/boot/routes.js
@@ -1,229 +1,308 @@
-import About from 'components/about/about.vue'
-import AnnouncementsPage from 'components/announcements_page/announcements_page.vue'
-import AuthForm from 'components/auth_form/auth_form.js'
-import BookmarkTimeline from 'components/bookmark_timeline/bookmark_timeline.vue'
-import BubbleTimeline from 'components/bubble_timeline/bubble_timeline.vue'
-import Chat from 'components/chat/chat.vue'
-import ChatList from 'components/chat_list/chat_list.vue'
-import ConversationPage from 'components/conversation-page/conversation-page.vue'
-import DMs from 'components/dm_timeline/dm_timeline.vue'
-import Drafts from 'components/drafts/drafts.vue'
-import FollowRequests from 'components/follow_requests/follow_requests.vue'
-import FriendsTimeline from 'components/friends_timeline/friends_timeline.vue'
-import Interactions from 'components/interactions/interactions.vue'
-import Lists from 'components/lists/lists.vue'
-import ListsEdit from 'components/lists_edit/lists_edit.vue'
-import ListsTimeline from 'components/lists_timeline/lists_timeline.vue'
-import Notifications from 'components/notifications/notifications.vue'
-import OAuthCallback from 'components/oauth_callback/oauth_callback.vue'
-import PasswordReset from 'components/password_reset/password_reset.vue'
-import PublicAndExternalTimeline from 'components/public_and_external_timeline/public_and_external_timeline.vue'
-import PublicTimeline from 'components/public_timeline/public_timeline.vue'
-import Registration from 'components/registration/registration.vue'
-import RemoteUserResolver from 'components/remote_user_resolver/remote_user_resolver.vue'
-import Search from 'components/search/search.vue'
-import ShoutPanel from 'components/shout_panel/shout_panel.vue'
-import TagTimeline from 'components/tag_timeline/tag_timeline.vue'
-import UserProfile from 'components/user_profile/user_profile.vue'
-import WhoToFollow from 'components/who_to_follow/who_to_follow.vue'
+import { defineAsyncComponent } from 'vue'
+import BookmarkTimeline from 'src/components/bookmark_timeline/bookmark_timeline.vue'
+import BubbleTimeline from 'src/components/bubble_timeline/bubble_timeline.vue'
+import ConversationPage from 'src/components/conversation-page/conversation-page.vue'
+import DMs from 'src/components/dm_timeline/dm_timeline.vue'
+import FriendsTimeline from 'src/components/friends_timeline/friends_timeline.vue'
import NavPanel from 'src/components/nav_panel/nav_panel.vue'
-import BookmarkFolderEdit from '../components/bookmark_folder_edit/bookmark_folder_edit.vue'
-import BookmarkFolders from '../components/bookmark_folders/bookmark_folders.vue'
-import QuotesTimeline from '../components/quotes_timeline/quotes_timeline.vue'
+import PublicAndExternalTimeline from 'src/components/public_and_external_timeline/public_and_external_timeline.vue'
+import PublicTimeline from 'src/components/public_timeline/public_timeline.vue'
+import QuotesTimeline from 'src/components/quotes_timeline/quotes_timeline.vue'
+import RemoteUserResolver from 'src/components/remote_user_resolver/remote_user_resolver.vue'
+import TagTimeline from 'src/components/tag_timeline/tag_timeline.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
export default (store) => {
const validateAuthenticatedRoute = (to, from, next) => {
if (store.state.users.currentUser) {
next()
} else {
next(
useInstanceStore().instanceIdentity.redirectRootNoLogin || '/main/all',
)
}
}
let routes = [
{
name: 'root',
path: '/',
redirect: () => {
return (
(store.state.users.currentUser
? useInstanceStore().instanceIdentity.redirectRootLogin
: useInstanceStore().instanceIdentity.redirectRootNoLogin) ||
'/main/all'
)
},
},
{
name: 'public-external-timeline',
path: '/main/all',
component: PublicAndExternalTimeline,
},
{
name: 'public-timeline',
path: '/main/public',
component: PublicTimeline,
},
{
name: 'friends',
path: '/main/friends',
component: FriendsTimeline,
beforeEnter: validateAuthenticatedRoute,
},
{ name: 'tag-timeline', path: '/tag/:tag', component: TagTimeline },
{ name: 'bookmarks', path: '/bookmarks', component: BookmarkTimeline },
{ name: 'bubble', path: '/bubble', component: BubbleTimeline },
{
name: 'conversation',
path: '/notice/:id',
component: ConversationPage,
meta: { dontScroll: true },
},
{ name: 'quotes', path: '/notice/:id/quotes', component: QuotesTimeline },
{
name: 'remote-user-profile-acct',
path: '/remote-users/:_(@)?:username([^/@]+)@:hostname([^/@]+)',
component: RemoteUserResolver,
beforeEnter: validateAuthenticatedRoute,
},
{
name: 'remote-user-profile',
path: '/remote-users/:hostname/:username',
component: RemoteUserResolver,
beforeEnter: validateAuthenticatedRoute,
},
{
name: 'external-user-profile',
path: '/users/$:id',
- component: UserProfile,
+ component: defineAsyncComponent(
+ () => import('src/components/user_profile/user_profile.vue'),
+ ),
},
{
name: 'interactions',
path: '/users/:username/interactions',
- component: Interactions,
+ component: defineAsyncComponent(
+ () => import('src/components/interactions/interactions.vue'),
+ ),
beforeEnter: validateAuthenticatedRoute,
},
{
name: 'dms',
path: '/users/:username/dms',
component: DMs,
beforeEnter: validateAuthenticatedRoute,
},
- { name: 'registration', path: '/registration', component: Registration },
+ {
+ name: 'registration',
+ path: '/registration',
+ component: defineAsyncComponent(
+ () => import('src/components/registration/registration.vue'),
+ ),
+ },
{
name: 'password-reset',
path: '/password-reset',
- component: PasswordReset,
+ component: defineAsyncComponent(
+ () => import('src/components/password_reset/password_reset.vue'),
+ ),
props: true,
},
{
name: 'registration-token',
path: '/registration/:token',
- component: Registration,
+ component: defineAsyncComponent(
+ () => import('src/components/registration/registration.vue'),
+ ),
},
{
name: 'friend-requests',
path: '/friend-requests',
- component: FollowRequests,
+ component: defineAsyncComponent(
+ () => import('src/components/follow_requests/follow_requests.vue'),
+ ),
beforeEnter: validateAuthenticatedRoute,
},
{
name: 'notifications',
path: '/:username/notifications',
- component: Notifications,
+ component: defineAsyncComponent(
+ () => import('src/components/notifications/notifications.vue'),
+ ),
props: () => ({ disableTeleport: true }),
beforeEnter: validateAuthenticatedRoute,
},
- { name: 'login', path: '/login', component: AuthForm },
+ {
+ name: 'login',
+ path: '/login',
+ component: defineAsyncComponent(
+ () => import('src/components/auth_form/auth_form.js'),
+ ),
+ },
{
name: 'shout-panel',
path: '/shout-panel',
- component: ShoutPanel,
+ component: defineAsyncComponent(
+ () => import('src/components/shout_panel/shout_panel.vue'),
+ ),
props: () => ({ floating: false }),
},
{
name: 'oauth-callback',
path: '/oauth-callback',
- component: OAuthCallback,
+ component: defineAsyncComponent(
+ () => import('src/components/oauth_callback/oauth_callback.vue'),
+ ),
props: (route) => ({ code: route.query.code }),
},
{
name: 'search',
path: '/search',
- component: Search,
+ component: defineAsyncComponent(
+ () => import('src/components/search/search.vue'),
+ ),
props: (route) => ({ query: route.query.query }),
},
{
name: 'who-to-follow',
path: '/who-to-follow',
- component: WhoToFollow,
+ component: defineAsyncComponent(
+ () => import('src/components/who_to_follow/who_to_follow.vue'),
+ ),
beforeEnter: validateAuthenticatedRoute,
},
- { name: 'about', path: '/about', component: About },
+ {
+ name: 'about',
+ path: '/about',
+ component: defineAsyncComponent(
+ () => import('src/components/about/about.vue'),
+ ),
+ },
{
name: 'announcements',
path: '/announcements',
- component: AnnouncementsPage,
+ component: defineAsyncComponent(
+ () =>
+ import('src/components/announcements_page/announcements_page.vue'),
+ ),
+ },
+ {
+ name: 'drafts',
+ path: '/drafts',
+ component: defineAsyncComponent(
+ () => import('src/components/drafts/drafts.vue'),
+ ),
+ },
+ {
+ name: 'user-profile',
+ path: '/users/:name',
+ component: defineAsyncComponent(
+ () => import('src/components/user_profile/user_profile.vue'),
+ ),
+ },
+ {
+ name: 'legacy-user-profile',
+ path: '/:name',
+ component: defineAsyncComponent(
+ () => import('src/components/user_profile/user_profile.vue'),
+ ),
+ },
+ {
+ name: 'lists',
+ path: '/lists',
+ component: defineAsyncComponent(
+ () => import('src/components/lists/lists.vue'),
+ ),
+ },
+ {
+ name: 'lists-timeline',
+ path: '/lists/:id',
+ component: defineAsyncComponent(
+ () => import('src/components/lists_timeline/lists_timeline.vue'),
+ ),
+ },
+ {
+ name: 'lists-edit',
+ path: '/lists/:id/edit',
+ component: defineAsyncComponent(
+ () => import('src/components/lists_edit/lists_edit.vue'),
+ ),
+ },
+ {
+ name: 'lists-new',
+ path: '/lists/new',
+ component: defineAsyncComponent(
+ () => import('src/components/lists_edit/lists_edit.vue'),
+ ),
},
- { name: 'drafts', path: '/drafts', component: Drafts },
- { name: 'user-profile', path: '/users/:name', component: UserProfile },
- { name: 'legacy-user-profile', path: '/:name', component: UserProfile },
- { name: 'lists', path: '/lists', component: Lists },
- { name: 'lists-timeline', path: '/lists/:id', component: ListsTimeline },
- { name: 'lists-edit', path: '/lists/:id/edit', component: ListsEdit },
- { name: 'lists-new', path: '/lists/new', component: ListsEdit },
{
name: 'edit-navigation',
path: '/nav-edit',
component: NavPanel,
props: () => ({ forceExpand: true, forceEditMode: true }),
beforeEnter: validateAuthenticatedRoute,
},
{
name: 'bookmark-folders',
path: '/bookmark_folders',
- component: BookmarkFolders,
+ component: defineAsyncComponent(
+ () => import('src/components/bookmark_folders/bookmark_folders.vue'),
+ ),
},
{
name: 'bookmark-folder-new',
path: '/bookmarks/new-folder',
- component: BookmarkFolderEdit,
+ component: defineAsyncComponent(
+ () =>
+ import(
+ 'src/components/bookmark_folder_edit/bookmark_folder_edit.vue'
+ ),
+ ),
},
{
name: 'bookmark-folder',
path: '/bookmarks/:id',
component: BookmarkTimeline,
},
{
name: 'bookmark-folder-edit',
path: '/bookmarks/:id/edit',
- component: BookmarkFolderEdit,
+ component: defineAsyncComponent(
+ () =>
+ import(
+ 'src/components/bookmark_folder_edit/bookmark_folder_edit.vue'
+ ),
+ ),
},
]
if (useInstanceCapabilitiesStore().pleromaChatMessagesAvailable) {
routes = routes.concat([
{
name: 'chat',
path: '/users/:username/chats/:recipient_id',
- component: Chat,
+ component: defineAsyncComponent(
+ () => import('src/components/chat/chat.vue'),
+ ),
meta: { dontScroll: false },
beforeEnter: validateAuthenticatedRoute,
},
{
name: 'chats',
path: '/users/:username/chats',
- component: ChatList,
+ component: defineAsyncComponent(
+ () => import('src/components/chat_list/chat_list.vue'),
+ ),
meta: { dontScroll: false },
beforeEnter: validateAuthenticatedRoute,
},
])
}
return routes
}
diff --git a/src/components/about/about.js b/src/components/about/about.js
index e6a1067fea..e293895d51 100644
--- a/src/components/about/about.js
+++ b/src/components/about/about.js
@@ -1,45 +1,45 @@
import { mapState } from 'pinia'
-import FeaturesPanel from '../features_panel/features_panel.vue'
-import InstanceSpecificPanel from '../instance_specific_panel/instance_specific_panel.vue'
-import MRFTransparencyPanel from '../mrf_transparency_panel/mrf_transparency_panel.vue'
-import StaffPanel from '../staff_panel/staff_panel.vue'
-import TermsOfServicePanel from '../terms_of_service_panel/terms_of_service_panel.vue'
+import FeaturesPanel from 'src/components/features_panel/features_panel.vue'
+import InstanceSpecificPanel from 'src/components/instance_specific_panel/instance_specific_panel.vue'
+import MRFTransparencyPanel from 'src/components/mrf_transparency_panel/mrf_transparency_panel.vue'
+import StaffPanel from 'src/components/staff_panel/staff_panel.vue'
+import TermsOfServicePanel from 'src/components/terms_of_service_panel/terms_of_service_panel.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
const pleromaFeCommitUrl =
'https://git.pleroma.social/pleroma/pleroma-fe/commit/'
const About = {
components: {
InstanceSpecificPanel,
FeaturesPanel,
TermsOfServicePanel,
StaffPanel,
MRFTransparencyPanel,
},
computed: {
showFeaturesPanel() {
return useInstanceStore().instanceIdentity.showFeaturesPanel
},
frontendVersionLink() {
return pleromaFeCommitUrl + this.frontendVersion
},
...mapState(useInstanceStore, [
'backendVersion',
'backendRepository',
'frontendVersion',
]),
showInstanceSpecificPanel() {
return (
useInstanceStore().instanceIdentity.showInstanceSpecificPanel &&
!useMergedConfigStore().mergedConfig.hideISP &&
useInstanceStore().instanceIdentity.instanceSpecificPanelContent
)
},
},
}
export default About
diff --git a/src/components/account_actions/account_actions.js b/src/components/account_actions/account_actions.js
index f204adbdea..9b4775b976 100644
--- a/src/components/account_actions/account_actions.js
+++ b/src/components/account_actions/account_actions.js
@@ -1,105 +1,111 @@
import { mapState } from 'pinia'
+import { defineAsyncComponent } from 'vue'
+import Popover from 'src/components/popover/popover.vue'
+import ProgressButton from 'src/components/progress_button/progress_button.vue'
import UserListMenu from 'src/components/user_list_menu/user_list_menu.vue'
-import UserTimedFilterModal from 'src/components/user_timed_filter_modal/user_timed_filter_modal.vue'
-import ConfirmModal from '../confirm_modal/confirm_modal.vue'
-import Popover from '../popover/popover.vue'
-import ProgressButton from '../progress_button/progress_button.vue'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useReportsStore } from 'src/stores/reports'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faEllipsisV } from '@fortawesome/free-solid-svg-icons'
library.add(faEllipsisV)
const AccountActions = {
props: ['user', 'relationship'],
data() {
return {
showingConfirmBlock: false,
showingConfirmRemoveFollower: false,
}
},
components: {
ProgressButton,
Popover,
UserListMenu,
- ConfirmModal,
- UserTimedFilterModal,
+ ConfirmModal: defineAsyncComponent(
+ () => import('src/components/confirm_modal/confirm_modal.vue'),
+ ),
+ UserTimedFilterModal: defineAsyncComponent(
+ () =>
+ import(
+ 'src/components/user_timed_filter_modal/user_timed_filter_modal.vue'
+ ),
+ ),
},
methods: {
showConfirmRemoveUserFromFollowers() {
this.showingConfirmRemoveFollower = true
},
hideConfirmRemoveUserFromFollowers() {
this.showingConfirmRemoveFollower = false
},
hideConfirmBlock() {
this.showingConfirmBlock = false
},
showRepeats() {
this.$store.dispatch('showReblogs', this.user.id)
},
hideRepeats() {
this.$store.dispatch('hideReblogs', this.user.id)
},
blockUser() {
if (this.$refs.timedBlockDialog) {
this.$refs.timedBlockDialog.optionallyPrompt()
} else {
if (!this.shouldConfirmBlock) {
this.doBlockUser()
} else {
this.showingConfirmBlock = true
}
}
},
doBlockUser() {
this.$store.dispatch('blockUser', { id: this.user.id })
this.hideConfirmBlock()
},
unblockUser() {
this.$store.dispatch('unblockUser', this.user.id)
},
removeUserFromFollowers() {
if (!this.shouldConfirmRemoveUserFromFollowers) {
this.doRemoveUserFromFollowers()
} else {
this.showConfirmRemoveUserFromFollowers()
}
},
doRemoveUserFromFollowers() {
this.$store.dispatch('removeUserFromFollowers', this.user.id)
this.hideConfirmRemoveUserFromFollowers()
},
reportUser() {
useReportsStore().openUserReportingModal({ userId: this.user.id })
},
openChat() {
this.$router.push({
name: 'chat',
params: {
username: this.$store.state.users.currentUser.screen_name,
recipient_id: this.user.id,
},
})
},
},
computed: {
shouldConfirmBlock() {
return useMergedConfigStore().mergedConfig.modalOnBlock
},
shouldConfirmRemoveUserFromFollowers() {
return useMergedConfigStore().mergedConfig.modalOnRemoveUserFromFollowers
},
...mapState(useInstanceCapabilitiesStore, [
'blockExpiration',
'pleromaChatMessagesAvailable',
]),
},
}
export default AccountActions
diff --git a/src/components/account_actions/account_actions.vue b/src/components/account_actions/account_actions.vue
index 94cb91ee0e..0c93872de6 100644
--- a/src/components/account_actions/account_actions.vue
+++ b/src/components/account_actions/account_actions.vue
@@ -1,161 +1,161 @@
<template>
<div class="AccountActions">
<Popover
trigger="click"
placement="bottom"
remove-padding
>
<template #content>
<div class="dropdown-menu">
<template v-if="relationship.following">
<div
v-if="relationship.showing_reblogs"
class="menu-item dropdown-item"
>
<button
class="main-button"
@click="hideRepeats"
>
{{ $t('user_card.hide_repeats') }}
</button>
</div>
<div
v-if="!relationship.showing_reblogs"
class="menu-item dropdown-item"
>
<button
class="main-button"
@click="showRepeats"
>
{{ $t('user_card.show_repeats') }}
</button>
</div>
<div
role="separator"
class="dropdown-divider"
/>
</template>
<UserListMenu :user="user" />
<div
v-if="relationship.followed_by"
class="menu-item dropdown-item"
>
<button
class="main-button"
@click="removeUserFromFollowers"
>
{{ $t('user_card.remove_follower') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
v-if="relationship.blocking"
class="main-button"
@click="unblockUser"
>
{{ $t('user_card.unblock') }}
</button>
<button
v-else
class="main-button"
@click="blockUser"
>
{{ $t('user_card.block') }}
</button>
</div>
<div class="menu-item dropdown-item">
<button
class="main-button"
@click="reportUser"
>
{{ $t('user_card.report') }}
</button>
</div>
<div
v-if="pleromaChatMessagesAvailable"
class="menu-item dropdown-item"
>
<button
class="main-button"
@click="openChat"
>
{{ $t('user_card.message') }}
</button>
</div>
</div>
</template>
<template #trigger>
<button class="button-unstyled ellipsis-button">
<FAIcon
class="icon"
icon="ellipsis-v"
/>
</button>
</template>
</Popover>
<teleport to="#modal">
- <confirm-modal
+ <ConfirmModal
v-if="showingConfirmBlock && !blockExpiration"
ref="blockDialog"
:title="$t('user_card.block_confirm_title')"
:confirm-text="$t('user_card.block_confirm_accept_button')"
:cancel-text="$t('user_card.block_confirm_cancel_button')"
@accepted="doBlockUser"
@cancelled="hideConfirmBlock"
>
<i18n-t
keypath="user_card.block_confirm"
tag="span"
scope="global"
>
<template #user>
<span
v-text="user.screen_name_ui"
/>
</template>
</i18n-t>
- </confirm-modal>
+ </ConfirmModal>
</teleport>
<teleport to="#modal">
- <confirm-modal
+ <ConfirmModal
v-if="showingConfirmRemoveFollower"
:title="$t('user_card.remove_follower_confirm_title')"
:confirm-text="$t('user_card.remove_follower_confirm_accept_button')"
:cancel-text="$t('user_card.remove_follower_confirm_cancel_button')"
@accepted="doRemoveUserFromFollowers"
@cancelled="hideConfirmRemoveUserFromFollowers"
>
<i18n-t
keypath="user_card.remove_follower_confirm"
tag="span"
scope="global"
>
<template #user>
<span
v-text="user.screen_name_ui"
/>
</template>
</i18n-t>
- </confirm-modal>
+ </ConfirmModal>
<UserTimedFilterModal
v-if="blockExpiration"
ref="timedBlockDialog"
:is-mute="false"
:user="user"
/>
</teleport>
</div>
</template>
<script src="./account_actions.js"></script>
<style lang="scss">
.AccountActions {
.ellipsis-button {
width: 2.5em;
margin: -0.5em 0;
padding: 0.5em 0;
text-align: center;
}
}
</style>
diff --git a/src/components/announcement/announcement.js b/src/components/announcement/announcement.js
index 13d55c159c..7f559f8fed 100644
--- a/src/components/announcement/announcement.js
+++ b/src/components/announcement/announcement.js
@@ -1,130 +1,128 @@
import { mapState } from 'vuex'
+import AnnouncementEditor from 'src/components/announcement_editor/announcement_editor.vue'
import localeService from '../../services/locale/locale.service.js'
-import AnnouncementEditor from '../announcement_editor/announcement_editor.vue'
-import RichContent from '../rich_content/rich_content.jsx'
import { useAnnouncementsStore } from 'src/stores/announcements.js'
const Announcement = {
components: {
AnnouncementEditor,
- RichContent,
},
data() {
return {
editing: false,
editedAnnouncement: {
content: '',
startsAt: undefined,
endsAt: undefined,
allDay: undefined,
},
editError: '',
}
},
props: {
announcement: Object,
},
computed: {
...mapState({
currentUser: (state) => state.users.currentUser,
}),
canEditAnnouncement() {
return (
this.currentUser &&
this.currentUser.privileges.includes(
'announcements_manage_announcements',
)
)
},
content() {
return this.announcement.content
},
isRead() {
return this.announcement.read
},
publishedAt() {
const time = this.announcement.published_at
if (!time) {
return
}
return this.formatTimeOrDate(
time,
localeService.internalToBrowserLocale(this.$i18n.locale),
)
},
startsAt() {
const time = this.announcement.starts_at
if (!time) {
return
}
return this.formatTimeOrDate(
time,
localeService.internalToBrowserLocale(this.$i18n.locale),
)
},
endsAt() {
const time = this.announcement.ends_at
if (!time) {
return
}
return this.formatTimeOrDate(
time,
localeService.internalToBrowserLocale(this.$i18n.locale),
)
},
inactive() {
return this.announcement.inactive
},
},
methods: {
markAsRead() {
if (!this.isRead) {
return useAnnouncementsStore().markAnnouncementAsRead(
this.announcement.id,
)
}
},
deleteAnnouncement() {
return useAnnouncementsStore().deleteAnnouncement(this.announcement.id)
},
formatTimeOrDate(time, locale) {
const d = new Date(time)
return this.announcement.all_day
? d.toLocaleDateString(locale)
: d.toLocaleString(locale)
},
enterEditMode() {
this.editedAnnouncement.content = this.announcement.pleroma.raw_content
this.editedAnnouncement.startsAt = this.announcement.starts_at
this.editedAnnouncement.endsAt = this.announcement.ends_at
this.editedAnnouncement.allDay = this.announcement.all_day
this.editing = true
},
submitEdit() {
useAnnouncementsStore()
.editAnnouncement({
id: this.announcement.id,
...this.editedAnnouncement,
})
.then(() => {
this.editing = false
})
.catch((error) => {
this.editError = error.error
})
},
cancelEdit() {
this.editing = false
},
clearError() {
this.editError = undefined
},
},
}
export default Announcement
diff --git a/src/components/announcement_editor/announcement_editor.js b/src/components/announcement_editor/announcement_editor.js
index 6d22ac1fda..c816083a4d 100644
--- a/src/components/announcement_editor/announcement_editor.js
+++ b/src/components/announcement_editor/announcement_editor.js
@@ -1,13 +1,13 @@
-import Checkbox from '../checkbox/checkbox.vue'
+import Checkbox from 'src/components/checkbox/checkbox.vue'
const AnnouncementEditor = {
components: {
Checkbox,
},
props: {
announcement: Object,
disabled: Boolean,
},
}
export default AnnouncementEditor
diff --git a/src/components/announcements_page/announcements_page.js b/src/components/announcements_page/announcements_page.js
index b8b1f000ab..3c73198c59 100644
--- a/src/components/announcements_page/announcements_page.js
+++ b/src/components/announcements_page/announcements_page.js
@@ -1,67 +1,67 @@
import { mapState } from 'vuex'
-import Announcement from '../announcement/announcement.vue'
-import AnnouncementEditor from '../announcement_editor/announcement_editor.vue'
+import Announcement from 'src/components/announcement/announcement.vue'
+import AnnouncementEditor from 'src/components/announcement_editor/announcement_editor.vue'
import { useAnnouncementsStore } from 'src/stores/announcements.js'
const AnnouncementsPage = {
components: {
Announcement,
AnnouncementEditor,
},
data() {
return {
newAnnouncement: {
content: '',
startsAt: undefined,
endsAt: undefined,
allDay: false,
},
posting: false,
error: undefined,
}
},
mounted() {
useAnnouncementsStore().fetchAnnouncements()
},
computed: {
...mapState({
currentUser: (state) => state.users.currentUser,
}),
announcements() {
return useAnnouncementsStore().announcements
},
canPostAnnouncement() {
return (
this.currentUser &&
this.currentUser.privileges.includes(
'announcements_manage_announcements',
)
)
},
},
methods: {
postAnnouncement() {
this.posting = true
useAnnouncementsStore()
.postAnnouncement(this.newAnnouncement)
.then(() => {
this.newAnnouncement.content = ''
this.startsAt = undefined
this.endsAt = undefined
})
.catch((error) => {
this.error = error.error
})
.finally(() => {
this.posting = false
})
},
clearError() {
this.error = undefined
},
},
}
export default AnnouncementsPage
diff --git a/src/components/attachment/attachment.js b/src/components/attachment/attachment.js
index d29d22f4a0..4b733258f7 100644
--- a/src/components/attachment/attachment.js
+++ b/src/components/attachment/attachment.js
@@ -1,217 +1,218 @@
import { mapState } from 'pinia'
+import { defineAsyncComponent } from 'vue'
+import Popover from 'src/components/popover/popover.vue'
+import VideoAttachment from 'src/components/video_attachment/video_attachment.vue'
import nsfwImage from '../../assets/nsfw.png'
-import Flash from '../flash/flash.vue'
-import Popover from '../popover/popover.vue'
-import StillImage from '../still-image/still-image.vue'
-import VideoAttachment from '../video_attachment/video_attachment.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useMediaViewerStore } from 'src/stores/media_viewer'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faAlignRight,
faFile,
faImage,
faMusic,
faPencilAlt,
faPlayCircle,
faSearchPlus,
faStop,
faTimes,
faTrashAlt,
faVideo,
} from '@fortawesome/free-solid-svg-icons'
library.add(
faFile,
faMusic,
faImage,
faVideo,
faPlayCircle,
faTimes,
faStop,
faSearchPlus,
faTrashAlt,
faPencilAlt,
faAlignRight,
)
const Attachment = {
props: [
'attachment',
'compact',
'description',
'hideDescription',
'nsfw',
'size',
'setMedia',
'remove',
'shiftUp',
'shiftDn',
'edit',
],
data() {
return {
localDescription: this.description || this.attachment.description,
nsfwImage:
useInstanceStore().instanceIdentity.nsfwCensorImage || nsfwImage,
hideNsfwLocal: useMergedConfigStore().mergedConfig.hideNsfw,
preloadImage: useMergedConfigStore().mergedConfig.preloadImage,
loading: false,
img: this.attachment.type === 'image' && document.createElement('img'),
modalOpen: false,
showHidden: false,
flashLoaded: false,
}
},
components: {
- Flash,
- StillImage,
- VideoAttachment,
+ Flash: defineAsyncComponent(() => import('src/components/flash/flash.vue')),
+
+ VideoAttachment: defineAsyncComponent(
+ () => import('src/components/video_attachment/video_attachment.vue'),
+ ),
Popover,
},
computed: {
classNames() {
return [
{
'-loading': this.loading,
'-nsfw-placeholder': this.hidden,
'-editable': this.edit !== undefined,
'-compact': this.compact,
},
'-type-' + this.attachment.type,
this.size && '-size-' + this.size,
`-${this.useContainFit ? 'contain' : 'cover'}-fit`,
]
},
usePlaceholder() {
return this.size === 'hide'
},
useContainFit() {
return this.mergedConfig.useContainFit
},
placeholderName() {
if (this.attachment.description === '' || !this.attachment.description) {
return this.attachment.type.toUpperCase()
}
return this.attachment.description
},
placeholderIconClass() {
if (this.attachment.type === 'image') return 'image'
if (this.attachment.type === 'video') return 'video'
if (this.attachment.type === 'audio') return 'music'
return 'file'
},
referrerpolicy() {
return useInstanceCapabilitiesStore().mediaProxyAvailable
? ''
: 'no-referrer'
},
hidden() {
return this.nsfw && this.hideNsfwLocal && !this.showHidden
},
isEmpty() {
return this.attachment.type === 'html' && !this.attachment.oembed
},
useModal() {
let modalTypes = []
switch (this.size) {
case 'hide':
case 'small':
modalTypes = ['image', 'video', 'audio', 'flash']
break
default:
modalTypes = this.mergedConfig.playVideosInModal
? ['image', 'video', 'flash']
: ['image']
break
}
return modalTypes.includes(this.attachment.type)
},
videoTag() {
return this.useModal ? 'button' : 'span'
},
...mapState(useMergedConfigStore, ['mergedConfig']),
},
watch: {
'attachment.description'(newVal) {
this.localDescription = newVal
},
localDescription(newVal) {
this.onEdit(newVal)
},
},
methods: {
linkClicked({ target }) {
if (target.tagName === 'A') {
window.open(target.href, '_blank')
}
},
openModal() {
if (this.useModal) {
this.$emit('setMedia')
useMediaViewerStore().setCurrentMedia(this.attachment)
} else if (this.attachment.type === 'unknown') {
window.open(this.attachment.url)
}
},
openModalForce() {
this.$emit('setMedia')
useMediaViewerStore().setCurrentMedia(this.attachment)
},
onEdit(event) {
this.edit && this.edit(this.attachment, event)
},
onRemove() {
this.remove && this.remove(this.attachment)
},
onShiftUp() {
this.shiftUp && this.shiftUp(this.attachment)
},
onShiftDn() {
this.shiftDn && this.shiftDn(this.attachment)
},
stopFlash() {
this.$refs.flash.closePlayer()
},
setFlashLoaded(event) {
this.flashLoaded = event
},
toggleHidden(event) {
if (
this.mergedConfig.useOneClickNsfw &&
!this.showHidden &&
(this.attachment.type !== 'video' ||
this.mergedConfig.playVideosInModal)
) {
this.openModal(event)
return
}
if (this.img && !this.preloadImage) {
if (this.img.onload) {
this.img.onload()
} else {
this.loading = true
this.img.src = this.attachment.url
this.img.onload = () => {
this.loading = false
this.showHidden = !this.showHidden
}
}
} else {
this.showHidden = !this.showHidden
}
},
onImageLoad(image) {
const width = image.naturalWidth
const height = image.naturalHeight
this.$emit('naturalSizeLoad', { id: this.attachment.id, width, height })
},
},
}
export default Attachment
diff --git a/src/components/auth_form/auth_form.js b/src/components/auth_form/auth_form.js
index 9e05095ca7..7d853d1197 100644
--- a/src/components/auth_form/auth_form.js
+++ b/src/components/auth_form/auth_form.js
@@ -1,34 +1,34 @@
import { mapState } from 'pinia'
import { h, resolveComponent } from 'vue'
-import LoginForm from '../login_form/login_form.vue'
-import MFARecoveryForm from '../mfa_form/recovery_form.vue'
-import MFATOTPForm from '../mfa_form/totp_form.vue'
+import LoginForm from 'src/components/login_form/login_form.vue'
+import MFARecoveryForm from 'src/components/mfa_form/recovery_form.vue'
+import MFATOTPForm from 'src/components/mfa_form/totp_form.vue'
import { useAuthFlowStore } from 'src/stores/auth_flow.js'
const AuthForm = {
name: 'AuthForm',
render() {
return h(resolveComponent(this.authForm))
},
computed: {
authForm() {
if (this.requiredTOTP) {
return 'MFATOTPForm'
}
if (this.requiredRecovery) {
return 'MFARecoveryForm'
}
return 'LoginForm'
},
...mapState(useAuthFlowStore, ['requiredTOTP', 'requiredRecovery']),
},
components: {
MFARecoveryForm,
MFATOTPForm,
LoginForm,
},
}
export default AuthForm
diff --git a/src/components/avatar_list/avatar_list.js b/src/components/avatar_list/avatar_list.js
index 830b64219d..7806fba813 100644
--- a/src/components/avatar_list/avatar_list.js
+++ b/src/components/avatar_list/avatar_list.js
@@ -1,28 +1,28 @@
-import UserAvatar from '../user_avatar/user_avatar.vue'
+import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
const AvatarList = {
props: ['users'],
computed: {
slicedUsers() {
return this.users ? this.users.slice(0, 15) : []
},
},
components: {
UserAvatar,
},
methods: {
userProfileLink(user) {
return generateProfileLink(
user.id,
user.screen_name,
useInstanceStore().restrictedNicknames,
)
},
},
}
export default AvatarList
diff --git a/src/components/basic_user_card/basic_user_card.js b/src/components/basic_user_card/basic_user_card.js
index 722d459f33..1c69f81b40 100644
--- a/src/components/basic_user_card/basic_user_card.js
+++ b/src/components/basic_user_card/basic_user_card.js
@@ -1,35 +1,34 @@
-import RichContent from 'src/components/rich_content/rich_content.jsx'
-import UserAvatar from '../user_avatar/user_avatar.vue'
-import UserLink from '../user_link/user_link.vue'
-import UserPopover from '../user_popover/user_popover.vue'
+import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
+import UserLink from 'src/components/user_link/user_link.vue'
+import UserPopover from 'src/components/user_popover/user_popover.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
const BasicUserCard = {
props: ['user'],
components: {
UserPopover,
UserAvatar,
- RichContent,
+
UserLink,
},
methods: {
userProfileLink(user) {
return generateProfileLink(
user.id,
user.screen_name,
useInstanceStore().restrictedNicknames,
)
},
},
computed: {
allowNonSquareEmoji() {
return useMergedConfigStore().mergedConfig.nonSquareEmoji
},
},
}
export default BasicUserCard
diff --git a/src/components/block_card/block_card.js b/src/components/block_card/block_card.js
index 967ce2a3cd..6484accffd 100644
--- a/src/components/block_card/block_card.js
+++ b/src/components/block_card/block_card.js
@@ -1,50 +1,50 @@
import { mapState } from 'pinia'
+import BasicUserCard from 'src/components/basic_user_card/basic_user_card.vue'
import UserTimedFilterModal from 'src/components/user_timed_filter_modal/user_timed_filter_modal.vue'
-import BasicUserCard from '../basic_user_card/basic_user_card.vue'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
const BlockCard = {
props: ['userId'],
computed: {
user() {
return this.$store.getters.findUser(this.userId)
},
relationship() {
return this.$store.getters.relationship(this.userId)
},
blocked() {
return this.relationship.blocking
},
blockExpiryAvailable() {
return Object.hasOwn(this.user, 'block_expires_at')
},
blockExpiry() {
return this.user.block_expires_at === false
? this.$t('user_card.block_expires_forever')
: this.$t('user_card.block_expires_at', [
new Date(this.user.mute_expires_at).toLocaleString(),
])
},
...mapState(useInstanceCapabilitiesStore, ['blockExpiration']),
},
components: {
BasicUserCard,
UserTimedFilterModal,
},
methods: {
unblockUser() {
this.$store.dispatch('unblockUser', this.user.id)
},
blockUser() {
if (this.blockExpiration) {
this.$refs.timedBlockDialog.optionallyPrompt()
} else {
this.$store.dispatch('blockUser', { id: this.user.id })
}
},
},
}
export default BlockCard
diff --git a/src/components/bookmark_folder_edit/bookmark_folder_edit.js b/src/components/bookmark_folder_edit/bookmark_folder_edit.js
index a036895bf1..43aa239b22 100644
--- a/src/components/bookmark_folder_edit/bookmark_folder_edit.js
+++ b/src/components/bookmark_folder_edit/bookmark_folder_edit.js
@@ -1,88 +1,88 @@
+import EmojiPicker from 'src/components/emoji_picker/emoji_picker.vue'
import apiService from '../../services/api/api.service'
-import EmojiPicker from '../emoji_picker/emoji_picker.vue'
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders.js'
import { useInterfaceStore } from 'src/stores/interface.js'
const BookmarkFolderEdit = {
data() {
return {
name: '',
nameDraft: '',
emoji: '',
emojiUrl: null,
emojiDraft: '',
emojiUrlDraft: null,
emojiPickerExpanded: false,
reallyDelete: false,
}
},
components: {
EmojiPicker,
},
created() {
if (!this.id) return
const credentials = this.$store.state.users.currentUser.credentials
apiService.fetchBookmarkFolders({ credentials }).then((folders) => {
const folder = folders.find((folder) => folder.id === this.id)
if (!folder) return
this.nameDraft = this.name = folder.name
this.emojiDraft = this.emoji = folder.emoji
this.emojiUrlDraft = this.emojiUrl = folder.emoji_url
})
},
computed: {
id() {
return this.$route.params.id
},
},
methods: {
selectEmoji(event) {
this.emojiDraft = event.insertion
this.emojiUrlDraft = event.insertionUrl
},
showEmojiPicker() {
if (!this.emojiPickerExpanded) {
this.$refs.picker.showPicker()
}
},
onShowPicker() {
this.emojiPickerExpanded = true
},
onClosePicker() {
this.emojiPickerExpanded = false
},
updateFolder() {
useBookmarkFoldersStore()
.updateBookmarkFolder({
folderId: this.id,
name: this.nameDraft,
emoji: this.emojiDraft,
})
.then(() => {
this.$router.push({ name: 'bookmark-folders' })
})
},
createFolder() {
useBookmarkFoldersStore()
.createBookmarkFolder({ name: this.nameDraft, emoji: this.emojiDraft })
.then(() => {
this.$router.push({ name: 'bookmark-folders' })
})
.catch((e) => {
useInterfaceStore().pushGlobalNotice({
messageKey: 'bookmark_folders.error',
messageArgs: [e.message],
level: 'error',
})
})
},
deleteFolder() {
useBookmarkFoldersStore().deleteBookmarkFolder({ folderId: this.id })
this.$router.push({ name: 'bookmark-folders' })
},
},
}
export default BookmarkFolderEdit
diff --git a/src/components/bookmark_folders/bookmark_folders.js b/src/components/bookmark_folders/bookmark_folders.js
index 1147fd3a55..9fd62dae08 100644
--- a/src/components/bookmark_folders/bookmark_folders.js
+++ b/src/components/bookmark_folders/bookmark_folders.js
@@ -1,29 +1,29 @@
-import BookmarkFolderCard from '../bookmark_folder_card/bookmark_folder_card.vue'
+import BookmarkFolderCard from 'src/components/bookmark_folder_card/bookmark_folder_card.vue'
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders.js'
const BookmarkFolders = {
data() {
return {
isNew: false,
}
},
components: {
BookmarkFolderCard,
},
computed: {
bookmarkFolders() {
return useBookmarkFoldersStore().allFolders
},
},
methods: {
cancelNewFolder() {
this.isNew = false
},
newFolder() {
this.isNew = true
},
},
}
export default BookmarkFolders
diff --git a/src/components/bookmark_timeline/bookmark_timeline.js b/src/components/bookmark_timeline/bookmark_timeline.js
index a241b6ac74..bf633c18c2 100644
--- a/src/components/bookmark_timeline/bookmark_timeline.js
+++ b/src/components/bookmark_timeline/bookmark_timeline.js
@@ -1,38 +1,38 @@
-import Timeline from '../timeline/timeline.vue'
+import Timeline from 'src/components/timeline/timeline.vue'
const Bookmarks = {
created() {
this.$store.commit('clearTimeline', { timeline: 'bookmarks' })
this.$store.dispatch('startFetchingTimeline', {
timeline: 'bookmarks',
bookmarkFolderId: this.folderId || null,
})
},
components: {
Timeline,
},
computed: {
folderId() {
return this.$route.params.id
},
timeline() {
return this.$store.state.statuses.timelines.bookmarks
},
},
watch: {
folderId() {
this.$store.commit('clearTimeline', { timeline: 'bookmarks' })
this.$store.dispatch('stopFetchingTimeline', 'bookmarks')
this.$store.dispatch('startFetchingTimeline', {
timeline: 'bookmarks',
bookmarkFolderId: this.folderId || null,
})
},
},
unmounted() {
this.$store.commit('clearTimeline', { timeline: 'bookmarks' })
this.$store.dispatch('stopFetchingTimeline', 'bookmarks')
},
}
export default Bookmarks
diff --git a/src/components/bubble_timeline/bubble_timeline.js b/src/components/bubble_timeline/bubble_timeline.js
index d3835e0e84..fcbc31ad23 100644
--- a/src/components/bubble_timeline/bubble_timeline.js
+++ b/src/components/bubble_timeline/bubble_timeline.js
@@ -1,20 +1,20 @@
-import Timeline from '../timeline/timeline.vue'
+import Timeline from 'src/components/timeline/timeline.vue'
const BubbleTimeline = {
components: {
Timeline,
},
computed: {
timeline() {
return this.$store.state.statuses.timelines.bubble
},
},
created() {
this.$store.dispatch('startFetchingTimeline', { timeline: 'bubble' })
},
unmounted() {
this.$store.dispatch('stopFetchingTimeline', 'bubble')
},
}
export default BubbleTimeline
diff --git a/src/components/chat/chat.js b/src/components/chat/chat.js
index caeb2aea70..7428c0dc71 100644
--- a/src/components/chat/chat.js
+++ b/src/components/chat/chat.js
@@ -1,419 +1,419 @@
-import _ from 'lodash'
+import { throttle } from 'lodash'
import { mapState as mapPiniaState } from 'pinia'
import { mapGetters, mapState } from 'vuex'
+import ChatMessage from 'src/components/chat_message/chat_message.vue'
+import ChatTitle from 'src/components/chat_title/chat_title.vue'
+import PostStatusForm from 'src/components/post_status_form/post_status_form.vue'
import { WSConnectionStatus } from '../../services/api/api.service.js'
import chatService from '../../services/chat_service/chat_service.js'
import { buildFakeMessage } from '../../services/chat_utils/chat_utils.js'
import { promiseInterval } from '../../services/promise_interval/promise_interval.js'
-import ChatMessage from '../chat_message/chat_message.vue'
-import ChatTitle from '../chat_title/chat_title.vue'
-import PostStatusForm from '../post_status_form/post_status_form.vue'
import {
getNewTopPosition,
getScrollPosition,
isBottomedOut,
isScrollable,
} from './chat_layout_utils.js'
import { useInterfaceStore } from 'src/stores/interface.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faChevronDown, faChevronLeft } from '@fortawesome/free-solid-svg-icons'
library.add(faChevronDown, faChevronLeft)
const BOTTOMED_OUT_OFFSET = 10
const JUMP_TO_BOTTOM_BUTTON_VISIBILITY_OFFSET = 10
const SAFE_RESIZE_TIME_OFFSET = 100
const MARK_AS_READ_DELAY = 1500
const MAX_RETRIES = 10
const Chat = {
components: {
ChatMessage,
ChatTitle,
PostStatusForm,
},
data() {
return {
jumpToBottomButtonVisible: false,
hoveredMessageChainId: undefined,
lastScrollPosition: {},
scrollableContainerHeight: '100%',
errorLoadingChat: false,
messageRetriers: {},
}
},
created() {
this.startFetching()
window.addEventListener('resize', this.handleResize)
},
mounted() {
window.addEventListener('scroll', this.handleScroll)
if (typeof document.hidden !== 'undefined') {
document.addEventListener(
'visibilitychange',
this.handleVisibilityChange,
false,
)
}
this.$nextTick(() => {
this.handleResize()
})
},
unmounted() {
window.removeEventListener('scroll', this.handleScroll)
window.removeEventListener('resize', this.handleResize)
if (typeof document.hidden !== 'undefined')
document.removeEventListener(
'visibilitychange',
this.handleVisibilityChange,
false,
)
this.$store.dispatch('clearCurrentChat')
},
computed: {
recipient() {
return this.currentChat && this.currentChat.account
},
recipientId() {
return this.$route.params.recipient_id
},
formPlaceholder() {
if (this.recipient) {
return this.$t('chats.message_user', {
nickname: this.recipient.screen_name_ui,
})
} else {
return ''
}
},
chatViewItems() {
return chatService.getView(this.currentChatMessageService)
},
newMessageCount() {
return (
this.currentChatMessageService &&
this.currentChatMessageService.newMessageCount
)
},
streamingEnabled() {
return (
this.mergedConfig.useStreamingApi &&
this.mastoUserSocketStatus === WSConnectionStatus.JOINED
)
},
...mapGetters([
'currentChat',
'currentChatMessageService',
'findOpenedChatByRecipientId',
'mergedConfig',
]),
...mapPiniaState(useInterfaceStore, {
mobileLayout: (store) => store.layoutType === 'mobile',
}),
...mapState({
backendInteractor: (state) => state.api.backendInteractor,
mastoUserSocketStatus: (state) => state.api.mastoUserSocketStatus,
currentUser: (state) => state.users.currentUser,
}),
},
watch: {
chatViewItems() {
// We don't want to scroll to the bottom on a new message when the user is viewing older messages.
// Therefore we need to know whether the scroll position was at the bottom before the DOM update.
const bottomedOutBeforeUpdate = this.bottomedOut(BOTTOMED_OUT_OFFSET)
this.$nextTick(() => {
if (bottomedOutBeforeUpdate) {
this.scrollDown()
}
})
},
$route: function () {
this.startFetching()
},
mastoUserSocketStatus(newValue) {
if (newValue === WSConnectionStatus.JOINED) {
this.fetchChat({ isFirstFetch: true })
}
},
},
methods: {
// Used to animate the avatar near the first message of the message chain when any message belonging to the chain is hovered
onMessageHover({ isHovered, messageChainId }) {
this.hoveredMessageChainId = isHovered ? messageChainId : undefined
},
onFilesDropped() {
this.$nextTick(() => {
this.handleResize()
})
},
handleVisibilityChange() {
this.$nextTick(() => {
if (!document.hidden && this.bottomedOut(BOTTOMED_OUT_OFFSET)) {
this.scrollDown({ forceRead: true })
}
})
},
// "Sticks" scroll to bottom instead of top, helps with OSK resizing the viewport
handleResize(opts = {}) {
const { delayed = false } = opts
if (delayed) {
setTimeout(() => {
this.handleResize({ ...opts, delayed: false })
}, SAFE_RESIZE_TIME_OFFSET)
return
}
this.$nextTick(() => {
const { offsetHeight = undefined } = getScrollPosition()
const diff = offsetHeight - this.lastScrollPosition.offsetHeight
if (diff !== 0 && !this.bottomedOut()) {
this.$nextTick(() => {
window.scrollBy({ top: -Math.trunc(diff) })
})
}
this.lastScrollPosition = getScrollPosition()
})
},
scrollDown(options = {}) {
const { behavior = 'auto', forceRead = false } = options
this.$nextTick(() => {
window.scrollTo({
top: document.documentElement.scrollHeight,
behavior,
})
})
if (forceRead) {
this.readChat()
}
},
readChat() {
if (
!(
this.currentChatMessageService && this.currentChatMessageService.maxId
)
) {
return
}
if (document.hidden) {
return
}
const lastReadId = this.currentChatMessageService.maxId
this.$store.dispatch('readChat', {
id: this.currentChat.id,
lastReadId,
})
},
bottomedOut(offset) {
return isBottomedOut(offset)
},
reachedTop() {
return window.scrollY <= 0
},
cullOlderCheck() {
window.setTimeout(() => {
if (this.bottomedOut(JUMP_TO_BOTTOM_BUTTON_VISIBILITY_OFFSET)) {
this.$store.dispatch(
'cullOlderMessages',
this.currentChatMessageService.chatId,
)
}
}, 5000)
},
- handleScroll: _.throttle(function () {
+ handleScroll: throttle(function () {
this.lastScrollPosition = getScrollPosition()
if (!this.currentChat) {
return
}
if (this.reachedTop()) {
this.fetchChat({ maxId: this.currentChatMessageService.minId })
} else if (this.bottomedOut(JUMP_TO_BOTTOM_BUTTON_VISIBILITY_OFFSET)) {
this.jumpToBottomButtonVisible = false
this.cullOlderCheck()
if (this.newMessageCount > 0) {
// Use a delay before marking as read to prevent situation where new messages
// arrive just as you're leaving the view and messages that you didn't actually
// get to see get marked as read.
window.setTimeout(() => {
// Don't mark as read if the element doesn't exist, user has left chat view
if (this.$el) this.readChat()
}, MARK_AS_READ_DELAY)
}
} else {
this.jumpToBottomButtonVisible = true
}
}, 200),
handleScrollUp(positionBeforeLoading) {
const positionAfterLoading = getScrollPosition()
window.scrollTo({
top: getNewTopPosition(positionBeforeLoading, positionAfterLoading),
})
},
fetchChat({ isFirstFetch = false, fetchLatest = false, maxId }) {
const chatMessageService = this.currentChatMessageService
if (!chatMessageService) {
return
}
if (fetchLatest && this.streamingEnabled) {
return
}
const chatId = chatMessageService.chatId
const fetchOlderMessages = !!maxId
const sinceId = fetchLatest && chatMessageService.maxId
return this.backendInteractor
.chatMessages({ id: chatId, maxId, sinceId })
.then((messages) => {
// Clear the current chat in case we're recovering from a ws connection loss.
if (isFirstFetch) {
chatService.clear(chatMessageService)
}
const positionBeforeUpdate = getScrollPosition()
this.$store
.dispatch('addChatMessages', { chatId, messages })
.then(() => {
this.$nextTick(() => {
if (fetchOlderMessages) {
this.handleScrollUp(positionBeforeUpdate)
}
// In vertical screens, the first batch of fetched messages may not always take the
// full height of the scrollable container.
// If this is the case, we want to fetch the messages until the scrollable container
// is fully populated so that the user has the ability to scroll up and load the history.
if (!isScrollable() && messages.length > 0) {
this.fetchChat({
maxId: this.currentChatMessageService.minId,
})
}
})
})
})
},
async startFetching() {
let chat = this.findOpenedChatByRecipientId(this.recipientId)
if (!chat) {
try {
chat = await this.backendInteractor.getOrCreateChat({
accountId: this.recipientId,
})
} catch (e) {
console.error('Error creating or getting a chat', e)
this.errorLoadingChat = true
}
}
if (chat) {
this.$nextTick(() => {
this.scrollDown({ forceRead: true })
})
this.$store.dispatch('addOpenedChat', { chat })
this.doStartFetching()
}
},
doStartFetching() {
this.$store.dispatch('startFetchingCurrentChat', {
fetcher: () =>
promiseInterval(() => this.fetchChat({ fetchLatest: true }), 5000),
})
this.fetchChat({ isFirstFetch: true })
},
handleAttachmentPosting() {
this.$nextTick(() => {
this.handleResize()
// When the posting form size changes because of a media attachment, we need an extra resize
// to account for the potential delay in the DOM update.
this.scrollDown({ forceRead: true })
})
},
sendMessage({ status, media, idempotencyKey }) {
const params = {
id: this.currentChat.id,
content: status,
idempotencyKey,
}
if (media[0]) {
params.mediaId = media[0].id
}
const fakeMessage = buildFakeMessage({
attachments: media,
chatId: this.currentChat.id,
content: status,
userId: this.currentUser.id,
idempotencyKey,
})
this.$store
.dispatch('addChatMessages', {
chatId: this.currentChat.id,
messages: [fakeMessage],
})
.then(() => {
this.handleAttachmentPosting()
})
return this.doSendMessage({
params,
fakeMessage,
retriesLeft: MAX_RETRIES,
})
},
doSendMessage({ params, fakeMessage, retriesLeft = MAX_RETRIES }) {
if (retriesLeft <= 0) return
this.backendInteractor
.sendChatMessage(params)
.then((data) => {
this.$store.dispatch('addChatMessages', {
chatId: this.currentChat.id,
updateMaxId: false,
messages: [{ ...data, fakeId: fakeMessage.id }],
})
return data
})
.catch((error) => {
console.error('Error sending message', error)
this.$store.dispatch('handleMessageError', {
chatId: this.currentChat.id,
fakeId: fakeMessage.id,
isRetry: retriesLeft !== MAX_RETRIES,
})
if (
(error.statusCode >= 500 && error.statusCode < 600) ||
error.message === 'Failed to fetch'
) {
this.messageRetriers[fakeMessage.id] = setTimeout(
() => {
this.doSendMessage({
params,
fakeMessage,
retriesLeft: retriesLeft - 1,
})
},
1000 * 2 ** (MAX_RETRIES - retriesLeft),
)
}
return {}
})
return Promise.resolve(fakeMessage)
},
goBack() {
this.$router.push({
name: 'chats',
params: { username: this.currentUser.screen_name },
})
},
},
}
export default Chat
diff --git a/src/components/chat_list/chat_list.js b/src/components/chat_list/chat_list.js
index 4c3194ae1c..597fcc7093 100644
--- a/src/components/chat_list/chat_list.js
+++ b/src/components/chat_list/chat_list.js
@@ -1,38 +1,38 @@
import { mapGetters, mapState } from 'vuex'
-import ChatListItem from '../chat_list_item/chat_list_item.vue'
-import ChatNew from '../chat_new/chat_new.vue'
-import List from '../list/list.vue'
+import ChatListItem from 'src/components/chat_list_item/chat_list_item.vue'
+import ChatNew from 'src/components/chat_new/chat_new.vue'
+import List from 'src/components/list/list.vue'
const ChatList = {
components: {
ChatListItem,
List,
ChatNew,
},
computed: {
...mapState({
currentUser: (state) => state.users.currentUser,
}),
...mapGetters(['sortedChatList']),
},
data() {
return {
isNew: false,
}
},
created() {
this.$store.dispatch('fetchChats', { latest: true })
},
methods: {
cancelNewChat() {
this.isNew = false
this.$store.dispatch('fetchChats', { latest: true })
},
newChat() {
this.isNew = true
},
},
}
export default ChatList
diff --git a/src/components/chat_list_item/chat_list_item.js b/src/components/chat_list_item/chat_list_item.js
index 74df26c1ff..3bbb93d609 100644
--- a/src/components/chat_list_item/chat_list_item.js
+++ b/src/components/chat_list_item/chat_list_item.js
@@ -1,71 +1,71 @@
import { mapState } from 'vuex'
-import AvatarList from '../avatar_list/avatar_list.vue'
-import ChatTitle from '../chat_title/chat_title.vue'
-import StatusBody from '../status_content/status_content.vue'
-import Timeago from '../timeago/timeago.vue'
-import UserAvatar from '../user_avatar/user_avatar.vue'
+import AvatarList from 'src/components/avatar_list/avatar_list.vue'
+import ChatTitle from 'src/components/chat_title/chat_title.vue'
+import StatusBody from 'src/components/status_content/status_content.vue'
+import Timeago from 'src/components/timeago/timeago.vue'
+import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
const ChatListItem = {
name: 'ChatListItem',
props: ['chat'],
components: {
UserAvatar,
AvatarList,
Timeago,
ChatTitle,
StatusBody,
},
computed: {
...mapState({
currentUser: (state) => state.users.currentUser,
}),
attachmentInfo() {
if (this.chat.lastMessage.attachments.length === 0) {
return
}
const types = this.chat.lastMessage.attachments.map((file) => file.type)
if (types.includes('video')) {
return this.$t('file_type.video')
} else if (types.includes('audio')) {
return this.$t('file_type.audio')
} else if (types.includes('image')) {
return this.$t('file_type.image')
} else {
return this.$t('file_type.file')
}
},
messageForStatusContent() {
const message = this.chat.lastMessage
const messageEmojis = message ? message.emojis : []
const isYou = message && message.account_id === this.currentUser.id
const content = message ? this.attachmentInfo || message.content : ''
const messagePreview = isYou
? `<i>${this.$t('chats.you')}</i> ${content}`
: content
return {
summary: '',
emojis: messageEmojis,
raw_html: messagePreview,
text: messagePreview,
attachments: [],
}
},
},
methods: {
openChat() {
if (this.chat.id) {
this.$router.push({
name: 'chat',
params: {
username: this.currentUser.screen_name,
recipient_id: this.chat.account.id,
},
})
}
},
},
}
export default ChatListItem
diff --git a/src/components/chat_message/chat_message.js b/src/components/chat_message/chat_message.js
index 1675f9ddd1..ba06172ed0 100644
--- a/src/components/chat_message/chat_message.js
+++ b/src/components/chat_message/chat_message.js
@@ -1,118 +1,117 @@
import { mapState as mapPiniaState } from 'pinia'
import { defineAsyncComponent } from 'vue'
import { mapGetters, mapState } from 'vuex'
-import Attachment from '../attachment/attachment.vue'
-import ChatMessageDate from '../chat_message_date/chat_message_date.vue'
-import Gallery from '../gallery/gallery.vue'
-import LinkPreview from '../link-preview/link-preview.vue'
-import Popover from '../popover/popover.vue'
-import StatusContent from '../status_content/status_content.vue'
-import UserAvatar from '../user_avatar/user_avatar.vue'
+import Attachment from 'src/components/attachment/attachment.vue'
+import ChatMessageDate from 'src/components/chat_message_date/chat_message_date.vue'
+import Gallery from 'src/components/gallery/gallery.vue'
+import LinkPreview from 'src/components/link-preview/link-preview.vue'
+import Popover from 'src/components/popover/popover.vue'
+import StatusContent from 'src/components/status_content/status_content.vue'
+import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
+import UserPopover from 'src/components/user_popover/user_popover.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faEllipsisH, faTimes } from '@fortawesome/free-solid-svg-icons'
library.add(faTimes, faEllipsisH)
const ChatMessage = {
name: 'ChatMessage',
props: [
'author',
'edited',
'noHeading',
'chatViewItem',
'hoveredMessageChain',
],
emits: ['hover'],
components: {
Popover,
Attachment,
StatusContent,
UserAvatar,
Gallery,
LinkPreview,
ChatMessageDate,
- UserPopover: defineAsyncComponent(
- () => import('../user_popover/user_popover.vue'),
- ),
+ UserPopover,
},
computed: {
// Returns HH:MM (hours and minutes) in local time.
createdAt() {
const time = this.chatViewItem.data.created_at
return time.toLocaleTimeString('en', {
hour: '2-digit',
minute: '2-digit',
hour12: false,
})
},
isCurrentUser() {
return this.message.account_id === this.currentUser.id
},
message() {
return this.chatViewItem.data
},
isMessage() {
return this.chatViewItem.type === 'message'
},
messageForStatusContent() {
return {
summary: '',
emojis: this.message.emojis,
raw_html: this.message.content || '',
text: this.message.content || '',
attachments: this.message.attachments,
}
},
hasAttachment() {
return this.message.attachments.length > 0
},
...mapPiniaState(useInterfaceStore, {
betterShadow: (store) => store.browserSupport.cssFilter,
}),
...mapState({
currentUser: (state) => state.users.currentUser,
restrictedNicknames: (state) => useInstanceStore().restrictedNicknames,
}),
popoverMarginStyle() {
if (this.isCurrentUser) {
return {}
} else {
return { left: 50 }
}
},
...mapPiniaState(useMergedConfigStore, ['mergedConfig', 'findUser']),
},
data() {
return {
hovered: false,
menuOpened: false,
}
},
methods: {
onHover(bool) {
this.$emit('hover', {
isHovered: bool,
messageChainId: this.chatViewItem.messageChainId,
})
},
async deleteMessage() {
const confirmed = window.confirm(this.$t('chats.delete_confirm'))
if (confirmed) {
await this.$store.dispatch('deleteChatMessage', {
messageId: this.chatViewItem.data.id,
chatId: this.chatViewItem.data.chat_id,
})
}
this.hovered = false
this.menuOpened = false
},
},
}
export default ChatMessage
diff --git a/src/components/chat_new/chat_new.js b/src/components/chat_new/chat_new.js
index 50e0f7a8f6..5ee2b610df 100644
--- a/src/components/chat_new/chat_new.js
+++ b/src/components/chat_new/chat_new.js
@@ -1,80 +1,80 @@
import { mapGetters, mapState } from 'vuex'
-import BasicUserCard from '../basic_user_card/basic_user_card.vue'
-import UserAvatar from '../user_avatar/user_avatar.vue'
+import BasicUserCard from 'src/components/basic_user_card/basic_user_card.vue'
+import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faChevronLeft, faSearch } from '@fortawesome/free-solid-svg-icons'
library.add(faSearch, faChevronLeft)
const chatNew = {
components: {
BasicUserCard,
UserAvatar,
},
data() {
return {
suggestions: [],
userIds: [],
loading: false,
query: '',
}
},
async created() {
const { chats } = await this.backendInteractor.chats()
chats.forEach((chat) => this.suggestions.push(chat.account))
},
computed: {
users() {
return this.userIds.map((userId) => this.findUser(userId))
},
availableUsers() {
if (this.query.length !== 0) {
return this.users
} else {
return this.suggestions
}
},
...mapState({
currentUser: (state) => state.users.currentUser,
backendInteractor: (state) => state.api.backendInteractor,
}),
...mapGetters(['findUser']),
},
methods: {
goBack() {
this.$emit('cancel')
},
goToChat(user) {
this.$router.push({ name: 'chat', params: { recipient_id: user.id } })
},
onInput() {
this.search(this.query)
},
addUser(user) {
this.selectedUserIds.push(user.id)
this.query = ''
},
removeUser(userId) {
this.selectedUserIds = this.selectedUserIds.filter((id) => id !== userId)
},
search(query) {
if (!query) {
this.loading = false
return
}
this.loading = true
this.userIds = []
this.$store
.dispatch('search', { q: query, resolve: true, type: 'accounts' })
.then((data) => {
this.loading = false
this.userIds = data.accounts.map((a) => a.id)
})
},
},
}
export default chatNew
diff --git a/src/components/chat_title/chat_title.js b/src/components/chat_title/chat_title.js
index 54a31a6fe6..52d4445b61 100644
--- a/src/components/chat_title/chat_title.js
+++ b/src/components/chat_title/chat_title.js
@@ -1,29 +1,27 @@
import { defineAsyncComponent } from 'vue'
-import RichContent from 'src/components/rich_content/rich_content.jsx'
-import UserAvatar from '../user_avatar/user_avatar.vue'
+import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
+import UserPopover from 'src/components/user_popover/user_popover.vue'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
export default {
name: 'ChatTitle',
components: {
UserAvatar,
- RichContent,
- UserPopover: defineAsyncComponent(
- () => import('../user_popover/user_popover.vue'),
- ),
+
+ UserPopover,
},
props: ['user', 'withAvatar'],
computed: {
title() {
return this.user ? this.user.screen_name_ui : ''
},
htmlTitle() {
return this.user ? this.user.name_html : ''
},
allowNonSquareEmoji() {
return useMergedConfigStore().mergedConfig.nonSquareEmoji
},
},
}
diff --git a/src/components/color_input/color_input.vue b/src/components/color_input/color_input.vue
index 07aed6b81f..208bdf2dca 100644
--- a/src/components/color_input/color_input.vue
+++ b/src/components/color_input/color_input.vue
@@ -1,159 +1,159 @@
<template>
<div
class="color-input style-control"
:class="{ disabled: !present || disabled, '-compact': compact }"
>
<label
:for="name"
class="label"
:class="{ faint: !present || disabled }"
>
{{ label }}
</label>
<Checkbox
v-if="typeof fallback !== 'undefined' && showOptionalCheckbox && !hideOptionalCheckbox"
:model-value="present"
:disabled="disabled"
class="opt"
@update:model-value="updateValue(typeof modelValue === 'undefined' ? fallback : undefined)"
/>
<div
class="input color-input-field"
:class="{ disabled: !present || disabled, unstyled }"
>
<input
:id="name + '-t'"
class="textColor unstyled"
:class="{ disabled: !present || disabled }"
type="text"
:value="modelValue ?? fallback"
:disabled="!present || disabled"
@input="updateValue($event.target.value)"
>
<div
v-if="validColor"
class="validIndicator"
:style="{backgroundColor: modelValue || fallback}"
/>
<div
v-else-if="transparentColor"
class="transparentIndicator"
/>
<div
v-else-if="computedColor"
class="computedIndicator"
:style="{backgroundColor: fallback}"
/>
<div
v-else
class="invalidIndicator"
/>
<label class="nativeColor">
<FAIcon icon="eye-dropper" />
<input
:id="name"
class="unstyled"
type="color"
:value="modelValue || fallback"
:disabled="!present || disabled"
:class="{ disabled: !present || disabled }"
@input="updateValue($event.target.value)"
>
</label>
</div>
</div>
</template>
<script>
import { throttle } from 'lodash'
+import Checkbox from 'src/components/checkbox/checkbox.vue'
import { hex2rgb } from '../../services/color_convert/color_convert.js'
-import Checkbox from '../checkbox/checkbox.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faEyeDropper } from '@fortawesome/free-solid-svg-icons'
library.add(faEyeDropper)
export default {
components: {
Checkbox,
},
props: {
// Name of color, used for identifying
name: {
required: true,
type: String,
},
// Readable label
label: {
required: false,
type: String,
default: '',
},
// use unstyled, uh, style
unstyled: {
required: false,
type: Boolean,
},
// Color value, should be required but vue cannot tell the difference
// between "property missing" and "property set to undefined"
modelValue: {
required: false,
type: String,
default: undefined,
},
// Color fallback to use when value is not defeind
fallback: {
required: false,
type: String,
default: undefined,
},
// Disable the control
disabled: {
required: false,
type: Boolean,
default: false,
},
// Show "optional" tickbox, for when value might become mandatory
showOptionalCheckbox: {
required: false,
type: Boolean,
default: true,
},
// Force "optional" tickbox to hide
hideOptionalCheckbox: {
required: false,
type: Boolean,
default: false,
},
compact: {
required: false,
type: Boolean,
},
},
emits: ['update:modelValue'],
computed: {
present() {
return typeof this.modelValue !== 'undefined'
},
validColor() {
return hex2rgb(this.modelValue || this.fallback)
},
transparentColor() {
return this.modelValue === 'transparent'
},
computedColor() {
return (
this.modelValue &&
(this.modelValue.startsWith('--') || this.modelValue.startsWith('$'))
)
},
},
methods: {
updateValue: throttle(function (value) {
this.$emit('update:modelValue', value)
}, 100),
},
}
</script>
<style lang="scss" src="./color_input.scss"></style>
diff --git a/src/components/confirm_modal/confirm_modal.js b/src/components/confirm_modal/confirm_modal.js
index affad7dcbc..08761177bb 100644
--- a/src/components/confirm_modal/confirm_modal.js
+++ b/src/components/confirm_modal/confirm_modal.js
@@ -1,40 +1,40 @@
-import DialogModal from '../dialog_modal/dialog_modal.vue'
+import DialogModal from 'src/components/dialog_modal/dialog_modal.vue'
/**
* This component emits the following events:
* cancelled, emitted when the action should not be performed;
* accepted, emitted when the action should be performed;
*
* The caller should close this dialog after receiving any of the two events.
*/
const ConfirmModal = {
components: {
DialogModal,
},
props: {
title: {
type: String,
},
cancelText: {
type: String,
},
confirmText: {
type: String,
},
confirmDanger: {
type: Boolean,
},
},
emits: ['cancelled', 'accepted'],
computed: {},
methods: {
onCancel() {
this.$emit('cancelled')
},
onAccept() {
this.$emit('accepted')
},
},
}
export default ConfirmModal
diff --git a/src/components/confirm_modal/mute_confirm.js b/src/components/confirm_modal/mute_confirm.js
index ffd3a3076e..c2f5ff8882 100644
--- a/src/components/confirm_modal/mute_confirm.js
+++ b/src/components/confirm_modal/mute_confirm.js
@@ -1,89 +1,92 @@
import { mapState } from 'pinia'
+import { defineAsyncComponent } from 'vue'
import Select from 'src/components/select/select.vue'
-import ConfirmModal from './confirm_modal.vue'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
export default {
props: ['type', 'user', 'status'],
emits: ['hide', 'show', 'muted'],
data: () => ({
showing: false,
}),
components: {
- ConfirmModal,
+ ConfirmModal: defineAsyncComponent(
+ () => import('src/components/confirm_modal/confirm_modal.vue'),
+ ),
+
Select,
},
computed: {
domain() {
return this.user.fqn.split('@')[1]
},
keypath() {
if (this.type === 'domain') {
return 'user_card.mute_domain_confirm'
} else if (this.type === 'conversation') {
return 'user_card.mute_conversation_confirm'
}
},
conversationIsMuted() {
return this.status.conversation_muted
},
domainIsMuted() {
return new Set(this.$store.state.users.currentUser.domainMutes).has(
this.domain,
)
},
shouldConfirm() {
switch (this.type) {
case 'domain': {
return this.mergedConfig.modalOnMuteDomain
}
default: {
// conversation
return this.mergedConfig.modalOnMuteConversation
}
}
},
...mapState(useMergedConfigStore, ['mergedConfig']),
},
methods: {
optionallyPrompt() {
if (this.shouldConfirm) {
this.show()
} else {
this.doMute()
}
},
show() {
this.showing = true
this.$emit('show')
},
hide() {
this.showing = false
this.$emit('hide')
},
doMute() {
switch (this.type) {
case 'domain': {
if (!this.domainIsMuted) {
this.$store.dispatch('muteDomain', this.domain)
} else {
this.$store.dispatch('unmuteDomain', this.domain)
}
break
}
case 'conversation': {
if (!this.conversationIsMuted) {
this.$store.dispatch('muteConversation', { id: this.status.id })
} else {
this.$store.dispatch('unmuteConversation', { id: this.status.id })
}
break
}
}
this.$emit('muted')
this.hide()
},
},
}
diff --git a/src/components/confirm_modal/mute_confirm.vue b/src/components/confirm_modal/mute_confirm.vue
index 7c754b0068..108a724771 100644
--- a/src/components/confirm_modal/mute_confirm.vue
+++ b/src/components/confirm_modal/mute_confirm.vue
@@ -1,31 +1,31 @@
<template>
- <confirm-modal
+ <ConfirmModal
v-if="showing"
:title="$t('user_card.mute_confirm_title')"
:confirm-text="$t('user_card.mute_confirm_accept_button')"
:cancel-text="$t('user_card.mute_confirm_cancel_button')"
@accepted="doMute"
@cancelled="hide"
>
<i18n-t
:keypath="keypath"
tag="div"
>
<template #domain>
<span v-text="domain" />
</template>
<template #user>
<span v-text="user.screen_name_ui" />
</template>
</i18n-t>
- </confirm-modal>
+ </ConfirmModal>
</template>
<script src="./mute_confirm.js" />
<style lang="scss">
.expiry-amount {
width: 4em;
text-align: right;
}
</style>
diff --git a/src/components/conversation-page/conversation-page.js b/src/components/conversation-page/conversation-page.js
index d4705303e9..84494332d1 100644
--- a/src/components/conversation-page/conversation-page.js
+++ b/src/components/conversation-page/conversation-page.js
@@ -1,14 +1,14 @@
-import Conversation from '../conversation/conversation.vue'
+import Conversation from 'src/components/conversation/conversation.vue'
const conversationPage = {
components: {
Conversation,
},
computed: {
statusId() {
return this.$route.params.id
},
},
}
export default conversationPage
diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js
index b0d3a304cf..da15c79d66 100644
--- a/src/components/conversation/conversation.js
+++ b/src/components/conversation/conversation.js
@@ -1,630 +1,628 @@
import { clone, filter, findIndex, get, reduce } from 'lodash'
import { mapState as mapPiniaState } from 'pinia'
import { mapState } from 'vuex'
+import QuickFilterSettings from 'src/components/quick_filter_settings/quick_filter_settings.vue'
+import QuickViewSettings from 'src/components/quick_view_settings/quick_view_settings.vue'
+import ThreadTree from 'src/components/thread_tree/thread_tree.vue'
import { WSConnectionStatus } from '../../services/api/api.service.js'
-import QuickFilterSettings from '../quick_filter_settings/quick_filter_settings.vue'
-import QuickViewSettings from '../quick_view_settings/quick_view_settings.vue'
-import Status from '../status/status.vue'
-import ThreadTree from '../thread_tree/thread_tree.vue'
import { useInterfaceStore } from 'src/stores/interface'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faAngleDoubleDown,
faAngleDoubleLeft,
faChevronLeft,
} from '@fortawesome/free-solid-svg-icons'
library.add(faAngleDoubleDown, faAngleDoubleLeft, faChevronLeft)
const sortById = (a, b) => {
const idA = a.type === 'retweet' ? a.retweeted_status.id : a.id
const idB = b.type === 'retweet' ? b.retweeted_status.id : b.id
const seqA = Number(idA)
const seqB = Number(idB)
const isSeqA = !Number.isNaN(seqA)
const isSeqB = !Number.isNaN(seqB)
if (isSeqA && isSeqB) {
return seqA < seqB ? -1 : 1
} else if (isSeqA && !isSeqB) {
return -1
} else if (!isSeqA && isSeqB) {
return 1
} else {
return idA < idB ? -1 : 1
}
}
const sortAndFilterConversation = (conversation, statusoid) => {
if (statusoid.type === 'retweet') {
conversation = filter(
conversation,
(status) =>
status.type === 'retweet' ||
status.id !== statusoid.retweeted_status.id,
)
} else {
conversation = filter(conversation, (status) => status.type !== 'retweet')
}
return conversation.filter((_) => _).sort(sortById)
}
const conversation = {
data() {
return {
highlight: null,
expanded: false,
threadDisplayStatusObject: {}, // id => 'showing' | 'hidden'
statusContentPropertiesObject: {},
inlineDivePosition: null,
loadStatusError: null,
}
},
props: [
'statusId',
'collapsable',
'isPage',
'pinnedStatusIdsObject',
'inProfile',
'profileUserId',
'virtualHidden',
],
created() {
if (this.isPage) {
this.fetchConversation()
}
},
computed: {
maxDepthToShowByDefault() {
// maxDepthInThread = max number of depths that is *visible*
// since our depth starts with 0 and "showing" means "showing children"
// there is a -2 here
const maxDepth = this.mergedConfig.maxDepthInThread - 2
return maxDepth >= 1 ? maxDepth : 1
},
streamingEnabled() {
return (
this.mergedConfig.useStreamingApi &&
this.mastoUserSocketStatus === WSConnectionStatus.JOINED
)
},
displayStyle() {
return this.mergedConfig.conversationDisplay
},
isTreeView() {
return !this.isLinearView
},
treeViewIsSimple() {
return !this.mergedConfig.conversationTreeAdvanced
},
isLinearView() {
return this.displayStyle === 'linear'
},
shouldFadeAncestors() {
return this.mergedConfig.conversationTreeFadeAncestors
},
otherRepliesButtonPosition() {
return this.mergedConfig.conversationOtherRepliesButton
},
showOtherRepliesButtonBelowStatus() {
return this.otherRepliesButtonPosition === 'below'
},
showOtherRepliesButtonInsideStatus() {
return this.otherRepliesButtonPosition === 'inside'
},
suspendable() {
if (this.isTreeView) {
return Object.entries(this.statusContentProperties).every(
([, prop]) => !prop.replying && prop.mediaPlaying.length === 0,
)
}
if (this.$refs.statusComponent && this.$refs.statusComponent[0]) {
return this.$refs.statusComponent.every((s) => s.suspendable)
} else {
return true
}
},
hideStatus() {
return this.virtualHidden && this.suspendable
},
status() {
return this.$store.state.statuses.allStatusesObject[this.statusId]
},
originalStatusId() {
if (this.status.retweeted_status) {
return this.status.retweeted_status.id
} else {
return this.statusId
}
},
conversationId() {
return this.getConversationId(this.statusId)
},
conversation() {
if (!this.status) {
return []
}
if (!this.isExpanded) {
return [this.status]
}
const conversation = clone(
this.$store.state.statuses.conversationsObject[this.conversationId],
)
const statusIndex = findIndex(conversation, { id: this.originalStatusId })
if (statusIndex !== -1) {
conversation[statusIndex] = this.status
}
return sortAndFilterConversation(conversation, this.status)
},
statusMap() {
return this.conversation.reduce((res, s) => {
res[s.id] = s
return res
}, {})
},
threadTree() {
const reverseLookupTable = this.conversation.reduce(
(table, status, index) => {
table[status.id] = index
return table
},
{},
)
const threads = this.conversation.reduce(
(a, cur) => {
const id = cur.id
a.forest[id] = this.getReplies(id).map((s) => s.id)
return a
},
{
forest: {},
},
)
const walk = (forest, topLevel, depth = 0, processed = {}) =>
topLevel
.map((id) => {
if (processed[id]) {
return []
}
processed[id] = true
return [
{
status: this.conversation[reverseLookupTable[id]],
id,
depth,
},
walk(forest, forest[id], depth + 1, processed),
].reduce((a, b) => a.concat(b), [])
})
.reduce((a, b) => a.concat(b), [])
const linearized = walk(
threads.forest,
this.topLevel.map((k) => k.id),
)
return linearized
},
replyIds() {
return this.conversation
.map((k) => k.id)
.reduce((res, id) => {
res[id] = (this.replies[id] || []).map((k) => k.id)
return res
}, {})
},
totalReplyCount() {
const sizes = {}
const subTreeSizeFor = (id) => {
if (sizes[id]) {
return sizes[id]
}
sizes[id] =
1 +
this.replyIds[id]
.map((cid) => subTreeSizeFor(cid))
.reduce((a, b) => a + b, 0)
return sizes[id]
}
this.conversation.map((k) => k.id).map(subTreeSizeFor)
return Object.keys(sizes).reduce((res, id) => {
res[id] = sizes[id] - 1 // exclude itself
return res
}, {})
},
totalReplyDepth() {
const depths = {}
const subTreeDepthFor = (id) => {
if (depths[id]) {
return depths[id]
}
depths[id] =
1 +
this.replyIds[id]
.map((cid) => subTreeDepthFor(cid))
.reduce((a, b) => (a > b ? a : b), 0)
return depths[id]
}
this.conversation.map((k) => k.id).map(subTreeDepthFor)
return Object.keys(depths).reduce((res, id) => {
res[id] = depths[id] - 1 // exclude itself
return res
}, {})
},
depths() {
return this.threadTree.reduce((a, k) => {
a[k.id] = k.depth
return a
}, {})
},
topLevel() {
const topLevel = this.conversation.reduce(
(tl, cur) =>
tl.filter(
(k) =>
this.getReplies(cur.id)
.map((v) => v.id)
.indexOf(k.id) === -1,
),
this.conversation,
)
return topLevel
},
otherTopLevelCount() {
return this.topLevel.length - 1
},
showingTopLevel() {
if (this.canDive && this.diveRoot) {
return [this.statusMap[this.diveRoot]]
}
return this.topLevel
},
diveRoot() {
const statusId = this.inlineDivePosition || this.statusId
const isTopLevel = !this.parentOf(statusId)
return isTopLevel ? null : statusId
},
diveDepth() {
return this.canDive && this.diveRoot ? this.depths[this.diveRoot] : 0
},
diveMode() {
return this.canDive && !!this.diveRoot
},
shouldShowAllConversationButton() {
// The "show all conversation" button tells the user that there exist
// other toplevel statuses, so do not show it if there is only a single root
return (
this.isTreeView &&
this.isExpanded &&
this.diveMode &&
this.topLevel.length > 1
)
},
shouldShowAncestors() {
return (
this.isTreeView &&
this.isExpanded &&
this.ancestorsOf(this.diveRoot).length
)
},
replies() {
let i = 1
return reduce(
this.conversation,
(result, { id, in_reply_to_status_id: irid }) => {
if (irid) {
result[irid] = result[irid] || []
result[irid].push({
name: `#${i}`,
id,
})
}
i++
return result
},
{},
)
},
isExpanded() {
return !!(this.expanded || this.isPage)
},
hiddenStyle() {
const height = (this.status && this.status.virtualHeight) || '120px'
return this.virtualHidden ? { height } : {}
},
threadDisplayStatus() {
return this.conversation.reduce((a, k) => {
const id = k.id
const depth = this.depths[id]
const status = (() => {
if (this.threadDisplayStatusObject[id]) {
return this.threadDisplayStatusObject[id]
}
if (depth - this.diveDepth <= this.maxDepthToShowByDefault) {
return 'showing'
} else {
return 'hidden'
}
})()
a[id] = status
return a
}, {})
},
statusContentProperties() {
return this.conversation.reduce((a, k) => {
const id = k.id
const props = (() => {
const def = {
showingTall: false,
expandingSubject: false,
showingLongSubject: false,
isReplying: false,
mediaPlaying: [],
}
if (this.statusContentPropertiesObject[id]) {
return {
...def,
...this.statusContentPropertiesObject[id],
}
}
return def
})()
a[id] = props
return a
}, {})
},
canDive() {
return this.isTreeView && this.isExpanded
},
maybeHighlight() {
return this.isExpanded ? this.highlight : null
},
...mapPiniaState(useMergedConfigStore, ['mergedConfig']),
...mapState({
mastoUserSocketStatus: (state) => state.api.mastoUserSocketStatus,
}),
...mapPiniaState(useInterfaceStore, {
mobileLayout: (store) => store.layoutType === 'mobile',
}),
},
components: {
- Status,
ThreadTree,
QuickFilterSettings,
QuickViewSettings,
},
watch: {
statusId(newVal, oldVal) {
const newConversationId = this.getConversationId(newVal)
const oldConversationId = this.getConversationId(oldVal)
if (
newConversationId &&
oldConversationId &&
newConversationId === oldConversationId
) {
this.setHighlight(this.originalStatusId)
} else {
this.fetchConversation()
}
},
expanded(value) {
if (value) {
this.fetchConversation()
} else {
this.resetDisplayState()
}
},
virtualHidden() {
this.$store.dispatch('setVirtualHeight', {
statusId: this.statusId,
height: `${this.$el.clientHeight}px`,
})
},
},
methods: {
fetchConversation() {
if (this.status) {
this.$store.state.api.backendInteractor
.fetchConversation({ id: this.statusId })
.then(({ ancestors, descendants }) => {
this.$store.dispatch('addNewStatuses', { statuses: ancestors })
this.$store.dispatch('addNewStatuses', { statuses: descendants })
this.setHighlight(this.originalStatusId)
})
} else {
this.loadStatusError = null
this.$store.state.api.backendInteractor
.fetchStatus({ id: this.statusId })
.then((status) => {
this.$store.dispatch('addNewStatuses', { statuses: [status] })
this.fetchConversation()
})
.catch((error) => {
this.loadStatusError = error
})
}
},
isFocused(id) {
return this.isExpanded && id === this.highlight
},
getReplies(id) {
return this.replies[id] || []
},
getHighlight() {
return this.isExpanded ? this.highlight : null
},
setHighlight(id) {
if (!id) return
this.highlight = id
if (!this.streamingEnabled) {
this.$store.dispatch('fetchStatus', id)
}
this.$store.dispatch('fetchFavsAndRepeats', id)
this.$store.dispatch('fetchEmojiReactionsBy', id)
},
toggleExpanded() {
this.expanded = !this.expanded
},
getConversationId(statusId) {
const status = this.$store.state.statuses.allStatusesObject[statusId]
return get(
status,
'retweeted_status.statusnet_conversation_id',
get(status, 'statusnet_conversation_id'),
)
},
setThreadDisplay(id, nextStatus) {
this.threadDisplayStatusObject = {
...this.threadDisplayStatusObject,
[id]: nextStatus,
}
},
toggleThreadDisplay(id) {
const curStatus = this.threadDisplayStatus[id]
const nextStatus = curStatus === 'showing' ? 'hidden' : 'showing'
this.setThreadDisplay(id, nextStatus)
},
setThreadDisplayRecursively(id, nextStatus) {
this.setThreadDisplay(id, nextStatus)
this.getReplies(id)
.map((k) => k.id)
.map((id) => this.setThreadDisplayRecursively(id, nextStatus))
},
showThreadRecursively(id) {
this.setThreadDisplayRecursively(id, 'showing')
},
setStatusContentProperty(id, name, value) {
this.statusContentPropertiesObject = {
...this.statusContentPropertiesObject,
[id]: {
...this.statusContentPropertiesObject[id],
[name]: value,
},
}
},
toggleStatusContentProperty(id, name) {
this.setStatusContentProperty(
id,
name,
!this.statusContentProperties[id][name],
)
},
leastVisibleAncestor(id) {
let cur = id
let parent = this.parentOf(cur)
while (cur) {
// if the parent is showing it means cur is visible
if (this.threadDisplayStatus[parent] === 'showing') {
return cur
}
parent = this.parentOf(parent)
cur = this.parentOf(cur)
}
// nothing found, fall back to toplevel
return this.topLevel[0] ? this.topLevel[0].id : undefined
},
diveIntoStatus(id) {
this.tryScrollTo(id)
},
diveToTopLevel() {
this.tryScrollTo(
this.topLevelAncestorOrSelfId(this.diveRoot) || this.topLevel[0].id,
)
},
// only used when we are not on a page
undive() {
this.inlineDivePosition = null
this.setHighlight(this.statusId)
},
tryScrollTo(id) {
if (!id) {
return
}
if (this.isPage) {
// set statusId
this.$router.push({ name: 'conversation', params: { id } })
} else {
this.inlineDivePosition = id
}
// Because the conversation can be unmounted when out of sight
// and mounted again when it comes into sight,
// the `mounted` or `created` function in `status` should not
// contain scrolling calls, as we do not want the page to jump
// when we scroll with an expanded conversation.
//
// Now the method is to rely solely on the `highlight` watcher
// in `status` components.
// In linear views, all statuses are rendered at all times, but
// in tree views, it is possible that a change in active status
// removes and adds status components (e.g. an originally child
// status becomes an ancestor status, and thus they will be
// different).
// Here, let the components be rendered first, in order to trigger
// the `highlight` watcher.
this.$nextTick(() => {
this.setHighlight(id)
})
},
goToCurrent() {
this.tryScrollTo(this.diveRoot || this.topLevel[0].id)
},
statusById(id) {
return this.statusMap[id]
},
parentOf(id) {
const status = this.statusById(id)
if (!status) {
return undefined
}
const { in_reply_to_status_id: parentId } = status
if (!this.statusMap[parentId]) {
return undefined
}
return parentId
},
parentOrSelf(id) {
return this.parentOf(id) || id
},
// Ancestors of some status, from top to bottom
ancestorsOf(id) {
const ancestors = []
let cur = this.parentOf(id)
while (cur) {
ancestors.unshift(this.statusMap[cur])
cur = this.parentOf(cur)
}
return ancestors
},
topLevelAncestorOrSelfId(id) {
let cur = id
let parent = this.parentOf(id)
while (parent) {
cur = this.parentOf(cur)
parent = this.parentOf(parent)
}
return cur
},
resetDisplayState() {
this.undive()
this.threadDisplayStatusObject = {}
},
},
}
export default conversation
diff --git a/src/components/desktop_nav/desktop_nav.js b/src/components/desktop_nav/desktop_nav.js
index 3382413a0a..df855500ac 100644
--- a/src/components/desktop_nav/desktop_nav.js
+++ b/src/components/desktop_nav/desktop_nav.js
@@ -1,130 +1,131 @@
import SearchBar from 'components/search_bar/search_bar.vue'
import { mapActions, mapState } from 'pinia'
-
-import ConfirmModal from '../confirm_modal/confirm_modal.vue'
+import { defineAsyncComponent } from 'vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faBell,
faBullhorn,
faCog,
faComments,
faHome,
faInfoCircle,
faSearch,
faSignInAlt,
faSignOutAlt,
faTachometerAlt,
faUserPlus,
} from '@fortawesome/free-solid-svg-icons'
library.add(
faSignInAlt,
faSignOutAlt,
faHome,
faComments,
faBell,
faUserPlus,
faBullhorn,
faSearch,
faTachometerAlt,
faCog,
faInfoCircle,
)
export default {
components: {
SearchBar,
- ConfirmModal,
+ ConfirmModal: defineAsyncComponent(
+ () => import('src/components/confirm_modal/confirm_modal.vue'),
+ ),
},
data: () => ({
searchBarHidden: true,
supportsMask:
window.CSS &&
window.CSS.supports &&
(window.CSS.supports('mask-size', 'contain') ||
window.CSS.supports('-webkit-mask-size', 'contain') ||
window.CSS.supports('-moz-mask-size', 'contain') ||
window.CSS.supports('-ms-mask-size', 'contain') ||
window.CSS.supports('-o-mask-size', 'contain')),
showingConfirmLogout: false,
}),
computed: {
enableMask() {
return this.supportsMask && this.logoMask
},
logoStyle() {
return {
visibility: this.enableMask ? 'hidden' : 'visible',
}
},
logoMaskStyle() {
return this.enableMask
? {
'mask-image': `url(${this.logo})`,
}
: {
'background-color': this.enableMask ? '' : 'transparent',
}
},
logoBgStyle() {
return Object.assign(
{
margin: `${this.logoMargin} 0`,
opacity: this.searchBarHidden ? 1 : 0,
},
this.enableMask
? {}
: {
'background-color': this.enableMask ? '' : 'transparent',
},
)
},
...mapState(useInstanceStore, ['privateMode']),
...mapState(useInstanceStore, {
logoMask: (store) => store.instanceIdentity.logoMask,
logo: (store) => store.instanceIdentity.logo,
logoLeft: (store) => store.instanceIdentity.logoLeft,
logoMargin: (store) => store.instanceIdentity.logoMargin,
sitename: (store) => store.instanceIdentity.name,
hideSitename: (store) => store.instanceIdentity.hideSitename,
}),
currentUser() {
return this.$store.state.users.currentUser
},
shouldConfirmLogout() {
return useMergedConfigStore().mergedConfig.modalOnLogout
},
},
methods: {
scrollToTop() {
window.scrollTo(0, 0)
},
showConfirmLogout() {
this.showingConfirmLogout = true
},
hideConfirmLogout() {
this.showingConfirmLogout = false
},
logout() {
if (!this.shouldConfirmLogout) {
this.doLogout()
} else {
this.showConfirmLogout()
}
},
doLogout() {
this.$router.replace('/main/public')
this.$store.dispatch('logout')
this.hideConfirmLogout()
},
onSearchBarToggled(hidden) {
this.searchBarHidden = hidden
},
...mapActions(useInterfaceStore, ['openSettingsModal']),
},
}
diff --git a/src/components/desktop_nav/desktop_nav.vue b/src/components/desktop_nav/desktop_nav.vue
index 8c7f589b68..477a7634dc 100644
--- a/src/components/desktop_nav/desktop_nav.vue
+++ b/src/components/desktop_nav/desktop_nav.vue
@@ -1,98 +1,98 @@
<template>
<nav
id="nav"
class="DesktopNav"
:class="{ '-logoLeft': logoLeft }"
@click="scrollToTop()"
>
<div class="inner-nav">
<div class="item sitename">
<router-link
v-if="!hideSitename"
class="site-name"
:to="{ name: 'root' }"
active-class="home"
>
{{ sitename }}
</router-link>
</div>
<router-link
class="logo"
:to="{ name: 'root' }"
:style="logoBgStyle"
:title="sitename"
>
<div
class="mask"
:style="logoMaskStyle"
/>
<img
:src="logo"
:style="logoStyle"
>
</router-link>
<div class="item right actions">
<SearchBar
v-if="currentUser || !privateMode"
@toggled="onSearchBarToggled"
@click.stop
/>
<template v-if="searchBarHidden">
<button
class="button-unstyled nav-icon"
:title="$t('nav.preferences')"
@click.stop="openSettingsModal('user')"
>
<FAIcon
fixed-width
class="fa-scale-110 fa-old-padding"
icon="cog"
/>
</button>
<button
v-if="currentUser && currentUser.role === 'admin'"
class="button-unstyled nav-icon"
target="_blank"
:title="$t('nav.administration')"
@click.stop="openSettingsModal('admin')"
>
<FAIcon
fixed-width
class="fa-scale-110 fa-old-padding"
icon="tachometer-alt"
/>
</button>
<span class="spacer" />
<button
v-if="currentUser"
class="button-unstyled nav-icon"
:title="$t('login.logout')"
@click.stop.prevent="logout"
>
<FAIcon
fixed-width
class="fa-scale-110 fa-old-padding"
icon="sign-out-alt"
/>
</button>
</template>
</div>
</div>
<teleport to="#modal">
- <confirm-modal
+ <ConfirmModal
v-if="showingConfirmLogout"
:title="$t('login.logout_confirm_title')"
:confirm-danger="true"
:confirm-text="$t('login.logout_confirm_accept_button')"
:cancel-text="$t('login.logout_confirm_cancel_button')"
@accepted="doLogout"
@cancelled="hideConfirmLogout"
>
{{ $t('login.logout_confirm') }}
- </confirm-modal>
+ </ConfirmModal>
</teleport>
</nav>
</template>
<script src="./desktop_nav.js"></script>
<style src="./desktop_nav.scss" lang="scss"></style>
diff --git a/src/components/dm_timeline/dm_timeline.js b/src/components/dm_timeline/dm_timeline.js
index c977efe304..d54044ff73 100644
--- a/src/components/dm_timeline/dm_timeline.js
+++ b/src/components/dm_timeline/dm_timeline.js
@@ -1,14 +1,14 @@
-import Timeline from '../timeline/timeline.vue'
+import Timeline from 'src/components/timeline/timeline.vue'
const DMs = {
computed: {
timeline() {
return this.$store.state.statuses.timelines.dms
},
},
components: {
Timeline,
},
}
export default DMs
diff --git a/src/components/domain_mute_card/domain_mute_card.js b/src/components/domain_mute_card/domain_mute_card.js
index 71da2684c1..d838966186 100644
--- a/src/components/domain_mute_card/domain_mute_card.js
+++ b/src/components/domain_mute_card/domain_mute_card.js
@@ -1,26 +1,26 @@
-import ProgressButton from '../progress_button/progress_button.vue'
+import ProgressButton from 'src/components/progress_button/progress_button.vue'
const DomainMuteCard = {
props: ['domain'],
components: {
ProgressButton,
},
computed: {
user() {
return this.$store.state.users.currentUser
},
muted() {
return this.user.domainMutes.includes(this.domain)
},
},
methods: {
unmuteDomain() {
return this.$store.dispatch('unmuteDomain', this.domain)
},
muteDomain() {
return this.$store.dispatch('muteDomain', this.domain)
},
},
}
export default DomainMuteCard
diff --git a/src/components/draft/draft.js b/src/components/draft/draft.js
index 45786614e2..529d3ddf1f 100644
--- a/src/components/draft/draft.js
+++ b/src/components/draft/draft.js
@@ -1,107 +1,110 @@
import { cloneDeep } from 'lodash'
+import { defineAsyncComponent } from 'vue'
-import ConfirmModal from 'src/components/confirm_modal/confirm_modal.vue'
-import EditStatusForm from 'src/components/edit_status_form/edit_status_form.vue'
import Gallery from 'src/components/gallery/gallery.vue'
import PostStatusForm from 'src/components/post_status_form/post_status_form.vue'
import StatusContent from 'src/components/status_content/status_content.vue'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faPollH } from '@fortawesome/free-solid-svg-icons'
library.add(faPollH)
const Draft = {
components: {
PostStatusForm,
- EditStatusForm,
- ConfirmModal,
+ EditStatusForm: defineAsyncComponent(
+ () => import('src/components/edit_status_form/edit_status_form.vue'),
+ ),
+ ConfirmModal: defineAsyncComponent(
+ () => import('src/components/confirm_modal/confirm_modal.vue'),
+ ),
StatusContent,
Gallery,
},
props: {
draft: {
type: Object,
required: true,
},
},
data() {
return {
referenceDraft: cloneDeep(this.draft),
editing: false,
showingConfirmDialog: false,
}
},
computed: {
relAttrs() {
if (this.draft.type === 'edit') {
return { statusId: this.draft.refId }
} else if (this.draft.type === 'reply') {
return { replyTo: this.draft.refId }
} else {
return {}
}
},
safeToSave() {
return (
this.draft.status ||
this.draft.files?.length ||
this.draft.hasPoll ||
this.draft.hasQuote
)
},
postStatusFormProps() {
return {
draftId: this.draft.id,
...this.relAttrs,
}
},
refStatus() {
return this.draft.refId
? this.$store.state.statuses.allStatusesObject[this.draft.refId]
: undefined
},
localCollapseSubjectDefault() {
return useMergedConfigStore().mergedConfig.collapseMessageWithSubject
},
nsfwClickthrough() {
if (!this.draft.nsfw) {
return false
}
if (this.draft.summary && this.localCollapseSubjectDefault) {
return false
}
return true
},
},
watch: {
editing(newVal) {
if (newVal) return
if (this.safeToSave) {
this.$store.dispatch('addOrSaveDraft', { draft: this.draft })
} else {
this.$store.dispatch('addOrSaveDraft', { draft: this.referenceDraft })
}
},
},
methods: {
toggleEditing() {
this.editing = !this.editing
},
abandon() {
this.showingConfirmDialog = true
},
doAbandon() {
this.$store.dispatch('abandonDraft', { id: this.draft.id }).then(() => {
this.hideConfirmDialog()
})
},
hideConfirmDialog() {
this.showingConfirmDialog = false
},
},
}
export default Draft
diff --git a/src/components/draft/draft.vue b/src/components/draft/draft.vue
index 433ebae316..c91675e35b 100644
--- a/src/components/draft/draft.vue
+++ b/src/components/draft/draft.vue
@@ -1,168 +1,168 @@
<template>
<article class="Draft">
<div
v-if="!editing"
class="status-content"
>
<div>
<i18n-t
v-if="draft.type === 'reply' || draft.type === 'edit'"
tag="span"
:keypath="draft.type === 'reply' ? 'drafts.replying' : 'drafts.editing'"
>
<template #statusLink>
<router-link
class="faint-link"
:to="{ name: 'conversation', params: { id: draft.refId } }"
>
{{ refStatus ? refStatus.external_url : $t('drafts.unavailable') }}
</router-link>
</template>
</i18n-t>
<StatusContent
v-if="draft.refId && refStatus"
class="status-content"
:status="refStatus"
:compact="true"
/>
</div>
<div class="status-preview">
<span class="status_content">
<p v-if="draft.spoilerText">
<i>
{{ draft.spoilerText }}:
</i>
</p>
<p v-if="draft.status">{{ draft.status }}</p>
<p
v-else
class="faint"
>{{ $t('drafts.empty') }}</p>
</span>
- <gallery
+ <Gallery
v-if="draft.files?.length !== 0"
class="attachments media-body"
:compact="true"
:nsfw="nsfwClickthrough"
:attachments="draft.files"
:limit="1"
size="small"
@play="$emit('mediaplay', attachment.id)"
@pause="$emit('mediapause', attachment.id)"
/>
<div
v-if="draft.poll.options"
class="poll-indicator-container"
:title="$t('drafts.poll_tooltip')"
>
<div class="poll-indicator">
<FAIcon
icon="poll-h"
size="3x"
/>
</div>
</div>
</div>
</div>
<div v-if="editing">
<PostStatusForm
v-if="draft.type !== 'edit'"
:hide-draft="true"
v-bind="postStatusFormProps"
/>
<EditStatusForm
v-else
:hide-draft="true"
:params="postStatusFormProps"
/>
</div>
<teleport to="#modal">
- <confirm-modal
+ <ConfirmModal
v-if="showingConfirmDialog"
:title="$t('drafts.abandon_confirm_title')"
:confirm-text="$t('drafts.abandon_confirm_accept_button')"
:cancel-text="$t('drafts.abandon_confirm_cancel_button')"
@accepted="doAbandon"
@cancelled="hideConfirmDialog"
>
{{ $t('drafts.abandon_confirm') }}
- </confirm-modal>
+ </ConfirmModal>
</teleport>
<div class="actions">
<button
class="btn button-default"
:aria-expanded="editing"
@click.prevent.stop="toggleEditing"
>
{{ editing ? $t('drafts.save') : $t('drafts.continue') }}
</button>
<button
class="btn button-default"
@click.prevent.stop="abandon"
>
{{ $t('drafts.abandon') }}
</button>
</div>
</article>
</template>
<script src="./draft.js"></script>
<style lang="scss">
.Draft {
position: relative;
.status-content {
padding: 0.5em;
margin: 0.5em 0;
}
.status-preview {
display: grid;
grid-template-columns: 1fr;
grid-auto-columns: 10em;
grid-auto-flow: column;
grid-gap: 0.5em;
align-items: start;
max-width: 100%;
p {
white-space: normal;
overflow-x: hidden;
}
.poll-indicator-container {
border-radius: var(--roundness);
display: grid;
place-items: center center;
align-self: start;
height: 0;
padding-bottom: 62.5%;
position: relative;
}
.poll-indicator {
box-sizing: border-box;
border: 1px solid var(--border);
position: absolute;
inset: 0;
display: grid;
place-items: center center;
width: 100%;
height: 100%;
}
}
.actions {
display: flex;
flex-direction: row;
justify-content: space-evenly;
.btn {
flex: 1;
margin-left: 1em;
margin-right: 1em;
}
}
}
</style>
diff --git a/src/components/draft_closer/draft_closer.js b/src/components/draft_closer/draft_closer.js
index 2648b40c5f..02c556922e 100644
--- a/src/components/draft_closer/draft_closer.js
+++ b/src/components/draft_closer/draft_closer.js
@@ -1,51 +1,53 @@
-import DialogModal from 'src/components/dialog_modal/dialog_modal.vue'
+import { defineAsyncComponent } from 'vue'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
const DraftCloser = {
data() {
return {
showing: false,
}
},
components: {
- DialogModal,
+ DialogModal: defineAsyncComponent(
+ () => import('src/components/dialog_modal/dialog_modal.vue'),
+ ),
},
emits: ['save', 'discard'],
computed: {
action() {
if (useMergedConfigStore().mergedConfig.autoSaveDraft) {
return 'save'
} else {
return useMergedConfigStore().mergedConfig.unsavedPostAction
}
},
shouldConfirm() {
return this.action === 'confirm'
},
},
methods: {
requestClose() {
if (this.shouldConfirm) {
this.showing = true
} else if (this.action === 'save') {
this.save()
} else {
this.discard()
}
},
save() {
this.$emit('save')
this.showing = false
},
discard() {
this.$emit('discard')
this.showing = false
},
cancel() {
this.showing = false
},
},
}
export default DraftCloser
diff --git a/src/components/draft_closer/draft_closer.vue b/src/components/draft_closer/draft_closer.vue
index 1afb1f44d0..bb8e5ec553 100644
--- a/src/components/draft_closer/draft_closer.vue
+++ b/src/components/draft_closer/draft_closer.vue
@@ -1,43 +1,43 @@
<template>
<teleport to="#modal">
- <dialog-modal
+ <DialogModal
v-if="showing"
v-body-scroll-lock="true"
class="confirm-modal"
:on-cancel="cancel"
>
<template #header>
<span>
{{ $t('post_status.close_confirm_title') }}
</span>
</template>
{{ $t('post_status.close_confirm') }}
<template #footer>
<button
class="btn button-default"
@click.prevent="save"
>
{{ $t('post_status.close_confirm_save_button') }}
</button>
<button
class="btn button-default"
@click.prevent="discard"
>
{{ $t('post_status.close_confirm_discard_button') }}
</button>
<button
class="btn button-default"
@click.prevent="cancel"
>
{{ $t('post_status.close_confirm_continue_composing_button') }}
</button>
</template>
- </dialog-modal>
+ </DialogModal>
</teleport>
</template>
<script src="./draft_closer.js"></script>
diff --git a/src/components/drafts/drafts.js b/src/components/drafts/drafts.js
index 87c22138bc..3d93edb144 100644
--- a/src/components/drafts/drafts.js
+++ b/src/components/drafts/drafts.js
@@ -1,36 +1,39 @@
-import ConfirmModal from 'src/components/confirm_modal/confirm_modal.vue'
+import { defineAsyncComponent } from 'vue'
+
import Draft from 'src/components/draft/draft.vue'
import List from 'src/components/list/list.vue'
const Drafts = {
components: {
Draft,
List,
- ConfirmModal,
+ ConfirmModal: defineAsyncComponent(
+ () => import('src/components/confirm_modal/confirm_modal.vue'),
+ ),
},
data() {
return {
showingConfirmDialog: false,
}
},
computed: {
drafts() {
return this.$store.getters.draftsArray
},
},
methods: {
abandonAll() {
this.showingConfirmDialog = true
},
doAbandonAll() {
this.$store
.dispatch('abandonAllDrafts')
.then(() => this.hideConfirmDialog())
},
hideConfirmDialog() {
this.showingConfirmDialog = false
},
},
}
export default Drafts
diff --git a/src/components/edit_status_form/edit_status_form.js b/src/components/edit_status_form/edit_status_form.js
index b8df927946..f7fd3d04dd 100644
--- a/src/components/edit_status_form/edit_status_form.js
+++ b/src/components/edit_status_form/edit_status_form.js
@@ -1,45 +1,45 @@
+import PostStatusForm from 'src/components/post_status_form/post_status_form.vue'
import statusPosterService from '../../services/status_poster/status_poster.service.js'
-import PostStatusForm from '../post_status_form/post_status_form.vue'
const EditStatusForm = {
components: {
PostStatusForm,
},
props: {
params: {
type: Object,
required: true,
},
},
methods: {
requestClose() {
this.$refs.postStatusForm.requestClose()
},
doEditStatus({ status, spoilerText, sensitive, media, contentType, poll }) {
const params = {
store: this.$store,
statusId: this.params.statusId,
status,
spoilerText,
sensitive,
poll,
media,
contentType,
}
return statusPosterService
.editStatus(params)
.then((data) => {
return data
})
.catch((err) => {
console.error('Error editing status', err)
return {
error: err.message,
}
})
},
},
}
export default EditStatusForm
diff --git a/src/components/edit_status_modal/edit_status_modal.js b/src/components/edit_status_modal/edit_status_modal.js
index 07836f1614..c3ba7e4cb3 100644
--- a/src/components/edit_status_modal/edit_status_modal.js
+++ b/src/components/edit_status_modal/edit_status_modal.js
@@ -1,59 +1,61 @@
-import get from 'lodash/get'
+import { get } from 'lodash'
+import { defineAsyncComponent } from 'vue'
-import EditStatusForm from '../edit_status_form/edit_status_form.vue'
-import Modal from '../modal/modal.vue'
+import Modal from 'src/components/modal/modal.vue'
import { useEditStatusStore } from 'src/stores/editStatus.js'
const EditStatusModal = {
components: {
- EditStatusForm,
+ EditStatusForm: defineAsyncComponent(
+ () => import('src/components/edit_status_form/edit_status_form.vue'),
+ ),
Modal,
},
data() {
return {
resettingForm: false,
}
},
computed: {
isLoggedIn() {
return !!this.$store.state.users.currentUser
},
modalActivated() {
return useEditStatusStore().modalActivated
},
isFormVisible() {
return this.isLoggedIn && !this.resettingForm && this.modalActivated
},
params() {
return useEditStatusStore().params || {}
},
},
watch: {
params(newVal, oldVal) {
if (get(newVal, 'statusId') !== get(oldVal, 'statusId')) {
this.resettingForm = true
this.$nextTick(() => {
this.resettingForm = false
})
}
},
isFormVisible(val) {
if (val) {
this.$nextTick(
() => this.$el && this.$el.querySelector('textarea').focus(),
)
}
},
},
methods: {
closeModal() {
this.$refs.editStatusForm.requestClose()
},
doCloseModal() {
useEditStatusStore().closeEditStatusModal()
},
},
}
export default EditStatusModal
diff --git a/src/components/emoji_input/emoji_input.vue b/src/components/emoji_input/emoji_input.vue
index 526f646ab5..8b69f3d9d3 100644
--- a/src/components/emoji_input/emoji_input.vue
+++ b/src/components/emoji_input/emoji_input.vue
@@ -1,235 +1,235 @@
<template>
<div
ref="root"
class="input emoji-input"
:class="{ '-with-picker': !hideEmojiButton, '-textarea': input?.tagName === 'TEXTAREA' }"
>
<slot
:id="'textbox-' + randomSeed"
:aria-owns="suggestionListId"
aria-autocomplete="both"
:aria-expanded="showSuggestions"
:aria-activedescendant="(!showSuggestions || highlighted === -1) ? '' : suggestionItemId(highlighted)"
/>
<!-- TODO: make the 'x' disappear if at the end maybe? -->
<div
ref="hiddenOverlay"
class="hidden-overlay"
:style="overlayStyle"
:aria-hidden="true"
>
<span>{{ preText }}</span>
<span
ref="hiddenOverlayCaret"
class="caret"
>x</span>
<span>{{ postText }}</span>
</div>
<screen-reader-notice
ref="screenReaderNotice"
aria-live="assertive"
/>
<template v-if="enableEmojiPicker">
<button
v-if="!hideEmojiButton"
class="button-unstyled emoji-picker-icon"
type="button"
:title="$t('emoji.add_emoji')"
@click.prevent="togglePicker"
>
- <FAIcon :icon="['far', 'smile-beam']" />
+ <FAIcon :icon="['far', 'face-smile-beam']" />
</button>
<EmojiPicker
v-if="enableEmojiPicker"
ref="picker"
:enable-sticker-picker="enableStickerPicker"
class="emoji-picker-panel"
@emoji="insert"
@sticker-uploaded="onStickerUploaded"
@sticker-upload-failed="onStickerUploadFailed"
@show="onPickerShown"
@close="onPickerClosed"
/>
</template>
<Popover
ref="suggestorPopover"
class="autocomplete-panel"
placement="bottom"
:hide-trigger="true"
>
<template #content>
<div
:id="suggestionListId"
ref="panel-body"
class="autocomplete-panel-body"
role="listbox"
>
<div
v-for="(suggestion, index) in suggestions"
:id="suggestionItemId(index)"
:key="index"
class="menu-item autocomplete-item"
role="option"
:class="{ '-active': index === highlighted }"
:aria-label="autoCompleteItemLabel(suggestion)"
:aria-selected="index === highlighted"
@click.stop.prevent="onClick($event, suggestion)"
>
<span class="image">
<img
v-if="suggestion.img"
:src="suggestion.img"
>
<span v-else>{{ suggestion.replacement }}</span>
</span>
<div class="label">
<span
v-if="suggestion.user"
class="displayText"
>
{{ suggestion.displayText }}<UnicodeDomainIndicator
:user="suggestion.user"
:at="false"
/>
</span>
<span
v-if="!suggestion.user"
class="displayText"
>
{{ maybeLocalizedEmojiName(suggestion) }}
</span>
<span class="detailText">{{ suggestion.detailText }}</span>
</div>
</div>
</div>
</template>
</Popover>
</div>
</template>
<script src="./emoji_input.js"></script>
<style lang="scss">
.input.emoji-input {
padding: 0;
display: flex;
flex-direction: column;
position: relative;
.emoji-picker-icon {
position: absolute;
bottom: 0;
right: 0;
height: 100%;
padding: 0 0.2em;
font-size: 1.3em;
cursor: pointer;
line-height: 1.2em;
&:hover i {
color: var(--text);
}
}
&.-textarea {
.emoji-picker-icon {
height: auto;
padding: 0.2em;
}
}
.emoji-picker-panel {
position: absolute;
z-index: 20;
margin-top: 0.2em;
&.hide {
display: none;
}
}
input,
textarea {
flex: 1 0 auto;
color: inherit;
/* stylelint-disable-next-line declaration-no-important */
background: none !important;
box-shadow: none;
border: none;
outline: none;
}
&.-with-picker {
textarea,
input {
padding-right: 2.4em;
}
}
.hidden-overlay {
opacity: 0;
pointer-events: none;
position: absolute;
inset: 0;
overflow: hidden;
/* DEBUG STUFF */
color: red;
/* set opacity to non-zero to see the overlay */
.caret {
width: 0;
margin-right: calc(-1ch - 1px);
border: 1px solid red;
}
}
}
.autocomplete {
&-panel {
position: absolute;
}
&-item.menu-item {
display: flex;
padding-top: 0;
padding-bottom: 0;
.image {
width: calc(var(--__line-height) + var(--__vertical-gap) * 2);
height: calc(var(--__line-height) + var(--__vertical-gap) * 2);
line-height: var(--__line-height);
text-align: center;
margin-right: var(--__horizontal-gap);
img {
width: calc(var(--__line-height) + var(--__vertical-gap) * 2);
height: calc(var(--__line-height) + var(--__vertical-gap) * 2);
object-fit: contain;
}
span {
font-size: var(--__line-height);
line-height: var(--__line-height);
}
}
.label {
display: flex;
flex-direction: column;
justify-content: center;
margin: 0 0.1em 0 0.2em;
.displayText {
line-height: 1.5;
}
.detailText {
font-size: 0.6em;
line-height: 0.6em;
}
}
}
}
</style>
diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js
index 36b669622e..bc2bb092bc 100644
--- a/src/components/emoji_picker/emoji_picker.js
+++ b/src/components/emoji_picker/emoji_picker.js
@@ -1,445 +1,444 @@
import { chunk, debounce, trim } from 'lodash'
import { defineAsyncComponent } from 'vue'
+import Checkbox from 'src/components/checkbox/checkbox.vue'
import Popover from 'src/components/popover/popover.vue'
import { ensureFinalFallback } from '../../i18n/languages.js'
-import Checkbox from '../checkbox/checkbox.vue'
-import StillImage from '../still-image/still-image.vue'
import { useEmojiStore } from 'src/stores/emoji.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faBasketballBall,
faBoxOpen,
faBus,
faCode,
faFlag,
faIceCream,
faLightbulb,
faPaw,
faSmile,
faSmileBeam,
faStickyNote,
faUser,
} from '@fortawesome/free-solid-svg-icons'
library.add(
faBoxOpen,
faStickyNote,
faSmileBeam,
faSmile,
faUser,
faPaw,
faIceCream,
faBus,
faBasketballBall,
faLightbulb,
faCode,
faFlag,
)
const UNICODE_EMOJI_GROUP_ICON = {
'smileys-and-emotion': 'smile',
'people-and-body': 'user',
'animals-and-nature': 'paw',
'food-and-drink': 'ice-cream',
'travel-and-places': 'bus',
activities: 'basketball-ball',
objects: 'lightbulb',
symbols: 'code',
flags: 'flag',
}
const maybeLocalizedKeywords = (emoji, languages, nameLocalizer) => {
const res = [emoji.displayText, nameLocalizer(emoji)]
if (emoji.annotations) {
languages.forEach((lang) => {
const keywords = emoji.annotations[lang]?.keywords || []
const name = emoji.annotations[lang]?.name
res.push(...keywords.concat([name]).filter((k) => k))
})
}
return res
}
const filterByKeyword = (list, keyword = '', languages, nameLocalizer) => {
if (keyword === '') return list
const keywordLowercase = keyword.toLowerCase()
const orderedEmojiList = []
for (const emoji of list) {
const indices = maybeLocalizedKeywords(emoji, languages, nameLocalizer)
.map((k) => k.toLowerCase().indexOf(keywordLowercase))
.filter((k) => k > -1)
const indexOfKeyword = indices.length ? Math.min(...indices) : -1
if (indexOfKeyword > -1) {
if (!Array.isArray(orderedEmojiList[indexOfKeyword])) {
orderedEmojiList[indexOfKeyword] = []
}
orderedEmojiList[indexOfKeyword].push(emoji)
}
}
return orderedEmojiList.flat()
}
const getOffset = (elem) => {
const style = elem.style.transform
const res = /translateY\((\d+)px\)/.exec(style)
if (!res) {
return 0
}
return res[1]
}
const toHeaderId = (id) => {
return id.replace(/^row-\d+-/, '')
}
const EmojiPicker = {
props: {
enableStickerPicker: {
required: false,
type: Boolean,
default: true,
},
hideCustomEmoji: {
required: false,
type: Boolean,
default: false,
},
},
inject: {
popoversZLayer: {
default: '',
},
},
data() {
return {
keyword: '',
activeGroup: 'custom',
showingStickers: false,
groupsScrolledClass: 'scrolled-top',
keepOpen: false,
customEmojiTimeout: null,
hideCustomEmojiInPicker: false,
// Lazy-load only after the first time `showing` becomes true.
contentLoaded: false,
popoverShown: false,
groupRefs: {},
emojiRefs: {},
filteredEmojiGroups: [],
emojiSize: 0,
width: 0,
}
},
components: {
StickerPicker: defineAsyncComponent(
- () => import('../sticker_picker/sticker_picker.vue'),
+ () => import('src/components/sticker_picker/sticker_picker.vue'),
),
Checkbox,
- StillImage,
+
Popover,
},
methods: {
groupScroll(e) {
e.currentTarget.scrollLeft += e.deltaY + e.deltaX
},
updateEmojiSize() {
const css = window.getComputedStyle(this.$refs.popover.$el)
const fontSize = css.getPropertyValue('font-size') || '1rem'
const emojiSize = css.getPropertyValue('--emojiSize') || '2.2rem'
const fontSizeUnit = fontSize.replace(/[0-9,.]+/, '').trim()
const fontSizeValue = Number(fontSize.replace(/[^0-9,.]+/, ''))
const emojiSizeUnit = emojiSize.replace(/[0-9,.]+/, '').trim()
const emojiSizeValue = Number(emojiSize.replace(/[^0-9,.]+/, ''))
let fontSizeMultiplier
if (fontSizeUnit.endsWith('em')) {
fontSizeMultiplier = fontSizeValue
} else {
fontSizeMultiplier = fontSizeValue / 14
}
let emojiSizeReal
if (emojiSizeUnit.endsWith('em')) {
emojiSizeReal = emojiSizeValue * fontSizeMultiplier * 14
} else {
emojiSizeReal = emojiSizeValue
}
const fullEmojiSize = emojiSizeReal + 2 * 0.2 * fontSizeMultiplier * 14
this.emojiSize = fullEmojiSize
},
togglePicker() {
if (this.popoverShown) {
this.hidePicker()
} else {
this.showPicker()
}
},
showPicker() {
this.$refs.popover.showPopover()
this.$nextTick(() => {
this.onShowing()
})
},
hidePicker() {
this.$refs.popover.hidePopover()
},
setAnchorEl(el) {
this.$refs.popover.setAnchorEl(el)
},
setGroupRef(name) {
return (el) => {
this.groupRefs[name] = el
}
},
onPopoverShown() {
this.popoverShown = true
},
onPopoverClosed() {
this.popoverShown = false
},
onStickerUploaded(e) {
this.$emit('sticker-uploaded', e)
},
onStickerUploadFailed(e) {
this.$emit('sticker-upload-failed', e)
},
onEmoji(emoji) {
const value = emoji.imageUrl
? `:${emoji.displayText}:`
: emoji.replacement
if (!this.keepOpen) {
this.$refs.popover.hidePopover()
}
this.$emit('emoji', {
insertion: value,
insertionUrl: emoji.imageUrl,
keepOpen: this.keepOpen,
})
},
onScroll(startIndex, endIndex, visibleStartIndex, visibleEndIndex) {
const target = this.$refs['emoji-groups'].$el
this.scrolledGroup(target, visibleStartIndex, visibleEndIndex)
},
scrolledGroup(target, start, end) {
const top = target.scrollTop + 5
this.$nextTick(() => {
this.emojiItems.slice(start, end + 1).forEach((group) => {
const headerId = toHeaderId(group.id)
const ref = this.groupRefs['group-' + group.id]
if (!ref) {
return
}
const elem = ref.$el.parentElement
if (!elem) {
return
}
if (elem && getOffset(elem) <= top) {
this.activeGroup = headerId
}
})
this.scrollHeader()
})
},
scrollHeader() {
// Scroll the active tab's header into view
const headerRef = this.groupRefs['group-header-' + this.activeGroup]
const left = headerRef.offsetLeft
const right = left + headerRef.offsetWidth
const headerCont = this.$refs.header
const currentScroll = headerCont.scrollLeft
const currentScrollRight = currentScroll + headerCont.clientWidth
const setScroll = (s) => {
headerCont.scrollLeft = s
}
const margin = 7 // .emoji-tabs-item: padding
if (left - margin < currentScroll) {
setScroll(left - margin)
} else if (right + margin > currentScrollRight) {
setScroll(right + margin - headerCont.clientWidth)
}
},
highlight(groupId) {
this.setShowStickers(false)
const indexInList = this.emojiItems.findIndex((k) => k.id === groupId)
this.$refs['emoji-groups'].scrollToItem(indexInList)
},
updateScrolledClass(target) {
if (target.scrollTop <= 5) {
this.groupsScrolledClass = 'scrolled-top'
} else if (target.scrollTop >= target.scrollTopMax - 5) {
this.groupsScrolledClass = 'scrolled-bottom'
} else {
this.groupsScrolledClass = 'scrolled-middle'
}
},
toggleStickers() {
this.showingStickers = !this.showingStickers
},
setShowStickers(value) {
this.showingStickers = value
},
filterByKeyword(list, keyword) {
return filterByKeyword(
list,
keyword,
this.languages,
this.maybeLocalizedEmojiName,
)
},
onShowing() {
const oldContentLoaded = this.contentLoaded
this.updateEmojiSize()
this.recalculateItemPerRow()
this.$nextTick(() => {
this.$refs.search.focus()
})
this.contentLoaded = true
this.filteredEmojiGroups = this.getFilteredEmojiGroups()
if (!oldContentLoaded) {
this.$nextTick(() => {
if (this.defaultGroup) {
this.highlight(this.defaultGroup)
}
})
}
},
getFilteredEmojiGroups() {
return this.allEmojiGroups
.map((group) => ({
...group,
emojis: this.filterByKeyword(group.emojis, trim(this.keyword)),
}))
.filter((group) => group.emojis.length > 0)
},
recalculateItemPerRow() {
this.$nextTick(() => {
if (!this.$refs['emoji-groups']) {
return
}
this.width = this.$refs['emoji-groups'].$el.clientWidth
})
},
},
watch: {
keyword() {
this.onScroll()
this.debouncedHandleKeywordChange()
},
allCustomGroups() {
this.filteredEmojiGroups = this.getFilteredEmojiGroups()
},
},
computed: {
minItemSize() {
return this.emojiSize
},
// used to watch it
fontSize() {
this.$nextTick(() => {
this.updateEmojiSize()
})
return useMergedConfigStore().mergedConfig.fontSize
},
emojiHeight() {
return this.emojiSize
},
itemPerRow() {
return this.width ? Math.floor(this.width / this.emojiSize) : 6
},
activeGroupView() {
return this.showingStickers ? '' : this.activeGroup
},
stickersAvailable() {
if (useEmojiStore().stickers) {
return useEmojiStore().stickers.length > 0
}
return 0
},
allCustomGroups() {
if (this.hideCustomEmoji || this.hideCustomEmojiInPicker) {
return {}
}
const emojis = useEmojiStore().groupedCustomEmojis
if (emojis.unpacked) {
emojis.unpacked.text = this.$t('emoji.unpacked')
}
return emojis
},
defaultGroup() {
return Object.keys(this.allCustomGroups)[0]
},
unicodeEmojiGroups() {
return useEmojiStore().standardEmojiGroupList.map((group) => ({
id: `standard-${group.id}`,
text: this.$t(`emoji.unicode_groups.${group.id}`),
icon: UNICODE_EMOJI_GROUP_ICON[group.id],
emojis: group.emojis,
}))
},
allEmojiGroups() {
return Object.entries(this.allCustomGroups)
.map(([, v]) => v)
.concat(this.unicodeEmojiGroups)
},
stickerPickerEnabled() {
return (useEmojiStore().stickers || []).length !== 0
},
debouncedHandleKeywordChange() {
return debounce(() => {
this.filteredEmojiGroups = this.getFilteredEmojiGroups()
}, 500)
},
emojiItems() {
return this.filteredEmojiGroups
.map((group) =>
chunk(group.emojis, this.itemPerRow).map((items, index) => ({
...group,
id: index === 0 ? group.id : `row-${index}-${group.id}`,
emojis: items,
isFirstRow: index === 0,
})),
)
.reduce((a, c) => a.concat(c), [])
},
languages() {
return ensureFinalFallback(
useMergedConfigStore().mergedConfig.interfaceLanguage,
)
},
maybeLocalizedEmojiName() {
return (emoji) => {
if (!emoji.annotations) {
return emoji.displayText
}
if (emoji.displayTextI18n) {
return this.$t(emoji.displayTextI18n.key, emoji.displayTextI18n.args)
}
for (const lang of this.languages) {
if (emoji.annotations[lang]?.name) {
return emoji.annotations[lang].name
}
}
return emoji.displayText
}
},
isInModal() {
return this.popoversZLayer === 'modals'
},
},
}
export default EmojiPicker
diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue
index 67f40c9450..06e5976c43 100644
--- a/src/components/emoji_picker/emoji_picker.vue
+++ b/src/components/emoji_picker/emoji_picker.vue
@@ -1,179 +1,179 @@
<template>
<Popover
ref="popover"
trigger="click"
popover-class="emoji-picker popover-default"
:hide-trigger="true"
placement="bottom"
@show="onPopoverShown"
@close="onPopoverClosed"
>
<template #content>
<div
class="heading"
>
<div class="emoji-search">
<input
ref="search"
v-model="keyword"
type="text"
class="input form-control"
:placeholder="$t('emoji.search_emoji')"
@input="$event.target.composing = false"
>
</div>
<!--
Body scroll lock needs to be on every scrollable element on safari iOS.
Here we tell it to enable scrolling for this element.
See https://github.com/willmcpo/body-scroll-lock#vanilla-js
-->
<span
ref="header"
v-body-scroll-lock="isInModal"
class="emoji-tabs"
@wheel.prevent="groupScroll"
>
<span
v-for="group in filteredEmojiGroups"
:ref="setGroupRef('group-header-' + group.id)"
:key="group.id"
class="button-unstyled emoji-tabs-item"
:class="{
toggled: activeGroupView === group.id
}"
:title="group.text"
role="button"
@click.prevent="highlight(group.id)"
>
<span
v-if="group.image"
class="emoji-picker-header-image"
>
- <still-image
+ <StillImage
:alt="group.text"
:src="group.image"
/>
</span>
<FAIcon
v-else
:icon="group.icon"
fixed-width
/>
</span>
</span>
<span
v-if="stickerPickerEnabled"
class="additional-tabs"
>
<span
class="button-unstyled stickers-tab-icon additional-tabs-item"
:class="{toggled: showingStickers}"
:title="$t('emoji.stickers')"
@click.prevent="toggleStickers"
>
<FAIcon
icon="sticky-note"
fixed-width
/>
</span>
</span>
</div>
<div
v-if="contentLoaded"
class="content"
>
<div
class="emoji-content"
:class="{hidden: showingStickers}"
>
<!-- Enables scrolling for this element on safari iOS. See comments for header. -->
<DynamicScroller
ref="emoji-groups"
v-body-scroll-lock="isInModal"
class="emoji-groups"
:class="groupsScrolledClass"
:min-item-size="minItemSize"
:buffer="minItemSize"
:items="emojiItems"
:emit-update="true"
@update="onScroll"
@visible="recalculateItemPerRow"
@resize="recalculateItemPerRow"
>
<template #default="{ item: group, index, active }">
<DynamicScrollerItem
:ref="setGroupRef('group-' + group.id)"
:item="group"
:active="active"
:data-index="index"
:size-dependencies="[group.emojis.length]"
>
<div
class="emoji-group"
:class="{ ['first-row']: group.isFirstRow }"
:style="{ '--__amount': itemPerRow }"
>
<h6
v-if="group.isFirstRow"
class="emoji-group-title"
>
{{ group.text }}
</h6>
<span
v-for="emoji in group.emojis"
:key="group.id + emoji.displayText"
:title="maybeLocalizedEmojiName(emoji)"
class="emoji-item"
role="button"
@click.stop.prevent="onEmoji(emoji)"
>
<span
v-if="!emoji.imageUrl"
class="emoji-picker-emoji -unicode"
>{{ emoji.replacement }}</span>
- <still-image
+ <StillImage
v-else
class="emoji-picker-emoji -custom"
loading="lazy"
:alt="maybeLocalizedEmojiName(emoji)"
:src="emoji.imageUrl"
:data-emoji-name="group.id + emoji.displayText"
/>
</span>
</div>
</DynamicScrollerItem>
</template>
</DynamicScroller>
<div class="keep-open">
<Checkbox v-model="keepOpen">
{{ $t('emoji.keep_open') }}
</Checkbox>
</div>
<div
v-if="!hideCustomEmoji"
class="hide-custom-emoji"
>
<Checkbox
v-model="hideCustomEmojiInPicker"
@change="onShowing"
>
{{ $t('emoji.hide_custom_emoji') }}
</Checkbox>
</div>
</div>
<div
v-if="showingStickers"
class="stickers-content"
>
<sticker-picker
@uploaded="onStickerUploaded"
@upload-failed="onStickerUploadFailed"
/>
</div>
</div>
</template>
</Popover>
</template>
<script src="./emoji_picker.js"></script>
<style lang="scss" src="./emoji_picker.scss"></style>
diff --git a/src/components/emoji_reactions/emoji_reactions.js b/src/components/emoji_reactions/emoji_reactions.js
index e22336138e..acb5404c0e 100644
--- a/src/components/emoji_reactions/emoji_reactions.js
+++ b/src/components/emoji_reactions/emoji_reactions.js
@@ -1,107 +1,105 @@
-import StillImage from 'src/components/still-image/still-image.vue'
-import UserAvatar from '../user_avatar/user_avatar.vue'
-import UserListPopover from '../user_list_popover/user_list_popover.vue'
+import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
+import UserListPopover from 'src/components/user_list_popover/user_list_popover.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faCheck, faMinus, faPlus } from '@fortawesome/free-solid-svg-icons'
library.add(faPlus, faMinus, faCheck)
const EMOJI_REACTION_COUNT_CUTOFF = 12
const EmojiReactions = {
name: 'EmojiReactions',
components: {
UserAvatar,
UserListPopover,
- StillImage,
},
props: ['status'],
data: () => ({
showAll: false,
}),
computed: {
tooManyReactions() {
return this.status.emoji_reactions.length > EMOJI_REACTION_COUNT_CUTOFF
},
emojiReactions() {
return this.showAll
? this.status.emoji_reactions
: this.status.emoji_reactions.slice(0, EMOJI_REACTION_COUNT_CUTOFF)
},
showMoreString() {
return `+${this.status.emoji_reactions.length - EMOJI_REACTION_COUNT_CUTOFF}`
},
accountsForEmoji() {
return this.status.emoji_reactions.reduce((acc, reaction) => {
acc[reaction.name] = reaction.accounts || []
return acc
}, {})
},
loggedIn() {
return !!this.$store.state.users.currentUser
},
remoteInteractionLink() {
return useInstanceStore().getRemoteInteractionLink({
statusId: this.status.id,
})
},
allowNonSquareEmoji() {
return useMergedConfigStore().mergedConfig.nonSquareEmoji
},
},
methods: {
toggleShowAll() {
this.showAll = !this.showAll
},
reactedWith(emoji) {
return this.status.emoji_reactions.find((r) => r.name === emoji).me
},
async fetchEmojiReactionsByIfMissing() {
const hasNoAccounts = this.status.emoji_reactions.find((r) => !r.accounts)
if (hasNoAccounts) {
return await this.$store.dispatch(
'fetchEmojiReactionsBy',
this.status.id,
)
}
},
reactWith(emoji) {
this.$store.dispatch('reactWithEmoji', { id: this.status.id, emoji })
},
unreact(emoji) {
this.$store.dispatch('unreactWithEmoji', { id: this.status.id, emoji })
},
async emojiOnClick(emoji) {
if (!this.loggedIn) return
await this.fetchEmojiReactionsByIfMissing()
if (this.reactedWith(emoji)) {
this.unreact(emoji)
} else {
this.reactWith(emoji)
}
},
counterTriggerAttrs(reaction) {
return {
class: [
'emoji-reaction-count-button',
{
'-picked-reaction': this.reactedWith(reaction.name),
toggled: this.reactedWith(reaction.name),
},
],
'aria-label': this.$t(
'status.reaction_count_label',
{ num: reaction.count },
reaction.count,
),
}
},
},
}
export default EmojiReactions
diff --git a/src/components/follow_button/follow_button.js b/src/components/follow_button/follow_button.js
index 644f95f859..3fecc025f0 100644
--- a/src/components/follow_button/follow_button.js
+++ b/src/components/follow_button/follow_button.js
@@ -1,89 +1,92 @@
+import { defineAsyncComponent } from 'vue'
+
import {
requestFollow,
requestUnfollow,
} from '../../services/follow_manipulate/follow_manipulate'
-import ConfirmModal from '../confirm_modal/confirm_modal.vue'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
export default {
props: ['relationship', 'user', 'labelFollowing', 'buttonClass'],
components: {
- ConfirmModal,
+ ConfirmModal: defineAsyncComponent(
+ () => import('src/components/confirm_modal/confirm_modal.vue'),
+ ),
},
data() {
return {
inProgress: false,
showingConfirmUnfollow: false,
}
},
computed: {
shouldConfirmUnfollow() {
return useMergedConfigStore().mergedConfig.modalOnUnfollow
},
isPressed() {
return this.inProgress || this.relationship.following
},
title() {
if (this.inProgress || this.relationship.following) {
return this.$t('user_card.follow_unfollow')
} else if (this.relationship.requested) {
return this.$t('user_card.follow_cancel')
} else {
return this.$t('user_card.follow')
}
},
label() {
if (this.inProgress) {
return this.$t('user_card.follow_progress')
} else if (this.relationship.following) {
return this.labelFollowing || this.$t('user_card.following')
} else if (this.relationship.requested) {
return this.$t('user_card.follow_sent')
} else {
return this.$t('user_card.follow')
}
},
disabled() {
return this.inProgress || this.user.deactivated
},
},
methods: {
showConfirmUnfollow() {
this.showingConfirmUnfollow = true
},
hideConfirmUnfollow() {
this.showingConfirmUnfollow = false
},
onClick() {
this.relationship.following || this.relationship.requested
? this.unfollow()
: this.follow()
},
follow() {
this.inProgress = true
requestFollow(this.relationship.id, this.$store).then(() => {
this.inProgress = false
})
},
unfollow() {
if (this.shouldConfirmUnfollow) {
this.showConfirmUnfollow()
} else {
this.doUnfollow()
}
},
doUnfollow() {
const store = this.$store
this.inProgress = true
requestUnfollow(this.relationship.id, store).then(() => {
this.inProgress = false
store.commit('removeStatus', {
timeline: 'friends',
userId: this.relationship.id,
})
})
this.hideConfirmUnfollow()
},
},
}
diff --git a/src/components/follow_button/follow_button.vue b/src/components/follow_button/follow_button.vue
index 3606b68be8..ba0cda46dd 100644
--- a/src/components/follow_button/follow_button.vue
+++ b/src/components/follow_button/follow_button.vue
@@ -1,35 +1,35 @@
<template>
<button
class="btn button-default follow-button"
:class="{ toggled: isPressed }"
:disabled="disabled"
:title="title"
@click="onClick"
>
{{ label }}
<teleport to="#modal">
- <confirm-modal
+ <ConfirmModal
v-if="showingConfirmUnfollow"
:title="$t('user_card.unfollow_confirm_title')"
:confirm-text="$t('user_card.unfollow_confirm_accept_button')"
:cancel-text="$t('user_card.unfollow_confirm_cancel_button')"
@accepted="doUnfollow"
@cancelled="hideConfirmUnfollow"
>
<i18n-t
scope="global"
keypath="user_card.unfollow_confirm"
tag="span"
>
<template #user>
<span
v-text="user.screen_name_ui"
/>
</template>
</i18n-t>
- </confirm-modal>
+ </ConfirmModal>
</teleport>
</button>
</template>
<script src="./follow_button.js"></script>
diff --git a/src/components/follow_card/follow_card.js b/src/components/follow_card/follow_card.js
index e4c84dcddf..8fffbf7309 100644
--- a/src/components/follow_card/follow_card.js
+++ b/src/components/follow_card/follow_card.js
@@ -1,27 +1,27 @@
-import BasicUserCard from '../basic_user_card/basic_user_card.vue'
-import FollowButton from '../follow_button/follow_button.vue'
-import RemoteFollow from '../remote_follow/remote_follow.vue'
-import RemoveFollowerButton from '../remove_follower_button/remove_follower_button.vue'
+import BasicUserCard from 'src/components/basic_user_card/basic_user_card.vue'
+import FollowButton from 'src/components/follow_button/follow_button.vue'
+import RemoteFollow from 'src/components/remote_follow/remote_follow.vue'
+import RemoveFollowerButton from 'src/components/remove_follower_button/remove_follower_button.vue'
const FollowCard = {
props: ['user', 'noFollowsYou'],
components: {
BasicUserCard,
RemoteFollow,
FollowButton,
RemoveFollowerButton,
},
computed: {
isMe() {
return this.$store.state.users.currentUser.id === this.user.id
},
loggedIn() {
return this.$store.state.users.currentUser
},
relationship() {
return this.$store.getters.relationship(this.user.id)
},
},
}
export default FollowCard
diff --git a/src/components/follow_request_card/follow_request_card.js b/src/components/follow_request_card/follow_request_card.js
index a6ffcd28be..44658e985c 100644
--- a/src/components/follow_request_card/follow_request_card.js
+++ b/src/components/follow_request_card/follow_request_card.js
@@ -1,92 +1,95 @@
+import { defineAsyncComponent } from 'vue'
+
import { notificationsFromStore } from '../../services/notification_utils/notification_utils.js'
import BasicUserCard from '../basic_user_card/basic_user_card.vue'
-import ConfirmModal from '../confirm_modal/confirm_modal.vue'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
const FollowRequestCard = {
props: ['user'],
components: {
BasicUserCard,
- ConfirmModal,
+ ConfirmModal: defineAsyncComponent(
+ () => import('src/components/confirm_modal/confirm_modal.vue'),
+ ),
},
data() {
return {
showingApproveConfirmDialog: false,
showingDenyConfirmDialog: false,
}
},
methods: {
findFollowRequestNotificationId() {
const notif = notificationsFromStore(this.$store).find(
(notif) =>
notif.from_profile.id === this.user.id &&
notif.type === 'follow_request',
)
return notif && notif.id
},
showApproveConfirmDialog() {
this.showingApproveConfirmDialog = true
},
hideApproveConfirmDialog() {
this.showingApproveConfirmDialog = false
},
showDenyConfirmDialog() {
this.showingDenyConfirmDialog = true
},
hideDenyConfirmDialog() {
this.showingDenyConfirmDialog = false
},
approveUser() {
if (this.shouldConfirmApprove) {
this.showApproveConfirmDialog()
} else {
this.doApprove()
}
},
doApprove() {
this.$store.state.api.backendInteractor.approveUser({ id: this.user.id })
this.$store.dispatch('removeFollowRequest', this.user)
const notifId = this.findFollowRequestNotificationId()
this.$store.dispatch('markSingleNotificationAsSeen', { id: notifId })
this.$store.dispatch('updateNotification', {
id: notifId,
updater: (notification) => {
notification.type = 'follow'
},
})
this.hideApproveConfirmDialog()
},
denyUser() {
if (this.shouldConfirmDeny) {
this.showDenyConfirmDialog()
} else {
this.doDeny()
}
},
doDeny() {
const notifId = this.findFollowRequestNotificationId()
this.$store.state.api.backendInteractor
.denyUser({ id: this.user.id })
.then(() => {
this.$store.dispatch('dismissNotificationLocal', { id: notifId })
this.$store.dispatch('removeFollowRequest', this.user)
})
this.hideDenyConfirmDialog()
},
},
computed: {
mergedConfig() {
return useMergedConfigStore().mergedConfig
},
shouldConfirmApprove() {
return this.mergedConfig.modalOnApproveFollow
},
shouldConfirmDeny() {
return this.mergedConfig.modalOnDenyFollow
},
},
}
export default FollowRequestCard
diff --git a/src/components/follow_request_card/follow_request_card.vue b/src/components/follow_request_card/follow_request_card.vue
index 55b651120b..64b1850943 100644
--- a/src/components/follow_request_card/follow_request_card.vue
+++ b/src/components/follow_request_card/follow_request_card.vue
@@ -1,61 +1,61 @@
<template>
<basic-user-card :user="user">
<div class="follow-request-card-content-container">
<button
class="btn button-default"
@click="approveUser"
>
{{ $t('user_card.approve') }}
</button>
<button
class="btn button-default"
@click="denyUser"
>
{{ $t('user_card.deny') }}
</button>
</div>
<teleport to="#modal">
- <confirm-modal
+ <ConfirmModal
v-if="showingApproveConfirmDialog"
:title="$t('user_card.approve_confirm_title')"
:confirm-text="$t('user_card.approve_confirm_accept_button')"
:cancel-text="$t('user_card.approve_confirm_cancel_button')"
@accepted="doApprove"
@cancelled="hideApproveConfirmDialog"
>
{{ $t('user_card.approve_confirm', { user: user.screen_name_ui }) }}
- </confirm-modal>
- <confirm-modal
+ </ConfirmModal>
+ <ConfirmModal
v-if="showingDenyConfirmDialog"
:title="$t('user_card.deny_confirm_title')"
:confirm-text="$t('user_card.deny_confirm_accept_button')"
:cancel-text="$t('user_card.deny_confirm_cancel_button')"
@accepted="doDeny"
@cancelled="hideDenyConfirmDialog"
>
{{ $t('user_card.deny_confirm', { user: user.screen_name_ui }) }}
- </confirm-modal>
+ </ConfirmModal>
</teleport>
</basic-user-card>
</template>
<script src="./follow_request_card.js"></script>
<style lang="scss">
.follow-request-card-content-container {
display: flex;
flex-flow: row wrap;
button {
margin-top: 0.5em;
margin-right: 0.5em;
flex: 1 1;
max-width: 12em;
min-width: 8em;
&:last-child {
margin-right: 0;
}
}
}
</style>
diff --git a/src/components/follow_requests/follow_requests.js b/src/components/follow_requests/follow_requests.js
index 7dbecee533..513298afc2 100644
--- a/src/components/follow_requests/follow_requests.js
+++ b/src/components/follow_requests/follow_requests.js
@@ -1,14 +1,14 @@
-import FollowRequestCard from '../follow_request_card/follow_request_card.vue'
+import FollowRequestCard from 'src/components/follow_request_card/follow_request_card.vue'
const FollowRequests = {
components: {
FollowRequestCard,
},
computed: {
requests() {
return this.$store.state.api.followRequests
},
},
}
export default FollowRequests
diff --git a/src/components/font_control/font_control.js b/src/components/font_control/font_control.js
index 81c46ec89a..697d83ee21 100644
--- a/src/components/font_control/font_control.js
+++ b/src/components/font_control/font_control.js
@@ -1,57 +1,57 @@
import Checkbox from 'src/components/checkbox/checkbox.vue'
import Popover from 'src/components/popover/popover.vue'
+import Select from 'src/components/select/select.vue'
import LocalSettingIndicator from 'src/components/settings_modal/helpers/local_setting_indicator.vue'
-import Select from '../select/select.vue'
import { useInterfaceStore } from 'src/stores/interface.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faExclamationTriangle,
faFont,
faKeyboard,
} from '@fortawesome/free-solid-svg-icons'
library.add(faExclamationTriangle, faKeyboard, faFont)
export default {
components: {
Select,
Checkbox,
Popover,
LocalSettingIndicator,
},
props: ['name', 'label', 'modelValue', 'fallback', 'options', 'no-inherit'],
mounted() {
useInterfaceStore().queryLocalFonts()
},
emits: ['update:modelValue'],
data() {
return {
manualEntry: false,
availableOptions: [
this.noInherit ? '' : 'inherit',
'serif',
'sans-serif',
'monospace',
...(this.options || []),
].filter((_) => _),
}
},
methods: {
toggleManualEntry() {
this.manualEntry = !this.manualEntry
},
},
computed: {
present() {
return this.modelValue != null
},
localFontsList() {
return useInterfaceStore().localFonts
},
localFontsSize() {
return useInterfaceStore().localFonts?.length
},
},
}
diff --git a/src/components/friends_timeline/friends_timeline.js b/src/components/friends_timeline/friends_timeline.js
index c0c032a8f4..b6bee73054 100644
--- a/src/components/friends_timeline/friends_timeline.js
+++ b/src/components/friends_timeline/friends_timeline.js
@@ -1,14 +1,14 @@
-import Timeline from '../timeline/timeline.vue'
+import Timeline from 'src/components/timeline/timeline.vue'
const FriendsTimeline = {
components: {
Timeline,
},
computed: {
timeline() {
return this.$store.state.statuses.timelines.friends
},
},
}
export default FriendsTimeline
diff --git a/src/components/gallery/gallery.js b/src/components/gallery/gallery.js
index 03a5aab11d..252a32bf69 100644
--- a/src/components/gallery/gallery.js
+++ b/src/components/gallery/gallery.js
@@ -1,151 +1,151 @@
import { set, sumBy } from 'lodash'
-import Attachment from '../attachment/attachment.vue'
+import Attachment from 'src/components/attachment/attachment.vue'
import { useMediaViewerStore } from 'src/stores/media_viewer.js'
const displayTypes = new Set(['image', 'video', 'flash'])
const Gallery = {
props: [
'attachments',
'compact',
'limitRows',
'descriptions',
'limit',
'nsfw',
'setMedia',
'size',
'editable',
'removeAttachment',
'shiftUpAttachment',
'shiftDnAttachment',
'editAttachment',
'grid',
],
data() {
return {
sizes: {},
hidingLong: true,
}
},
components: { Attachment },
computed: {
rows() {
if (!this.attachments) {
return []
}
const attachments =
this.limit > 0
? this.attachments.slice(0, this.limit)
: this.attachments
if (this.size === 'hide') {
return attachments.map((item) => ({ minimal: true, items: [item] }))
}
const rows = this.grid
? [{ grid: true, items: attachments }]
: attachments
.reduce(
(acc, attachment, i) => {
const peek = attachments[i + 1]
const nextEnd = peek == null
const nextWide = !nextEnd && !displayTypes.has(peek?.type)
// Inserting new row
if (attachment.type === 'audio') {
return [
...acc,
{ audio: true, items: [attachment] },
{ items: [] },
]
}
if (!displayTypes.has(attachment.type)) {
return [
...acc,
{ minimal: true, items: [attachment] },
{ items: [] },
]
}
const maxPerRow = 3
const currentRow = acc[acc.length - 1]
const previousRow = acc[acc.length - 2]
if (currentRow.items.length >= maxPerRow) {
if (nextWide || nextEnd) {
if (previousRow?.items.length > 1) {
currentRow.items.push(attachment)
return [...acc, { items: [] }]
} else {
const last = currentRow.items.splice(-1)[0]
return [...acc, { items: [last, attachment] }]
}
} else {
return [...acc, { items: [attachment] }]
}
} else {
currentRow.items.push(attachment)
}
return acc
},
[{ items: [] }],
)
.filter((_) => _.items.length > 0)
return rows
},
attachmentsDimensionalScore() {
return this.rows.reduce((acc, row) => {
let size = 0
if (row.minimal) {
size += 1 / 8
} else if (row.audio) {
size += 1 / 4
} else {
size += 1 / (row.items.length + 0.6)
}
return acc + size
}, 0)
},
tooManyAttachments() {
if (this.editable || this.size === 'small') {
return false
} else if (this.size === 'hide') {
return this.attachments.length > 8
} else {
return this.attachmentsDimensionalScore > 1
}
},
},
methods: {
onNaturalSizeLoad({ id, width, height }) {
set(this.sizes, id, { width, height })
},
rowStyle(row) {
if (row.audio) {
return { 'padding-bottom': '25%' } // fixed reduced height for audio
} else if (!row.minimal && !row.grid) {
return { 'padding-bottom': `${100 / (row.items.length + 0.6)}%` }
}
},
itemStyle(id, row) {
const total = sumBy(row, (item) => this.getAspectRatio(item.id))
return { flex: `${this.getAspectRatio(id) / total} 1 0%` }
},
getAspectRatio(id) {
const size = this.sizes[id]
return size ? size.width / size.height : 1
},
toggleHidingLong(event) {
this.hidingLong = event
},
openGallery() {
useMediaViewerStore().setMedia(this.attachments)
useMediaViewerStore().setCurrentMedia(this.attachments[0])
},
onMedia() {
useMediaViewerStore().setMedia(this.attachments)
},
},
}
export default Gallery
diff --git a/src/components/interactions/interactions.js b/src/components/interactions/interactions.js
index 87e9e1b879..142a5fc8ad 100644
--- a/src/components/interactions/interactions.js
+++ b/src/components/interactions/interactions.js
@@ -1,36 +1,36 @@
+import Notifications from 'src/components/notifications/notifications.vue'
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
-import Notifications from '../notifications/notifications.vue'
const tabModeDict = {
mentions: ['mention'],
statuses: ['status'],
'likes+repeats': ['repeat', 'like'],
follows: ['follow'],
reactions: ['pleroma:emoji_reaction'],
reports: ['pleroma:report'],
moves: ['move'],
}
const Interactions = {
data() {
return {
allowFollowingMove:
this.$store.state.users.currentUser.allow_following_move,
filterMode: tabModeDict.mentions,
canSeeReports: this.$store.state.users.currentUser.privileges.includes(
'reports_manage_reports',
),
}
},
methods: {
onModeSwitch(key) {
this.filterMode = tabModeDict[key]
},
},
components: {
Notifications,
TabSwitcher,
},
}
export default Interactions
diff --git a/src/components/interface_language_switcher/interface_language_switcher.js b/src/components/interface_language_switcher/interface_language_switcher.js
index becf5677f1..bcf22fe9b2 100644
--- a/src/components/interface_language_switcher/interface_language_switcher.js
+++ b/src/components/interface_language_switcher/interface_language_switcher.js
@@ -1,61 +1,61 @@
import { v4 as uuidv4 } from 'uuid'
+import Select from 'src/components/select/select.vue'
import localeService from '../../services/locale/locale.service.js'
-import Select from '../select/select.vue'
export default {
components: {
Select,
},
props: {
// List of languages (or just one language)
modelValue: {
type: [Array, String],
required: true,
},
// Is this setting stored in user profile (true) or elsewhere (false)
// Doesn't affect storage, just shows an icon if true
profile: {
type: Boolean,
default: false,
},
},
emits: ['update:modelValue'],
computed: {
languages() {
return localeService.languages
},
uniqueId() {
return uuidv4()
},
controlledLanguage: {
get: function () {
return Array.isArray(this.modelValue)
? this.modelValue
: [this.modelValue]
},
set: function (val) {
this.$emit('update:modelValue', val)
},
},
},
methods: {
getLanguageName(code) {
return localeService.getLanguageName(code)
},
addLanguage() {
this.controlledLanguage = [...this.controlledLanguage, '']
},
setLanguageAt(index, val) {
const lang = [...this.controlledLanguage]
lang[index] = val
this.controlledLanguage = lang
},
removeLanguageAt(index) {
const lang = [...this.controlledLanguage]
lang.splice(index, 1)
this.controlledLanguage = lang
},
},
}
diff --git a/src/components/lists/lists.js b/src/components/lists/lists.js
index ae58960f52..9dcb7636c3 100644
--- a/src/components/lists/lists.js
+++ b/src/components/lists/lists.js
@@ -1,29 +1,29 @@
-import ListsCard from '../lists_card/lists_card.vue'
+import ListsCard from 'src/components/lists_card/lists_card.vue'
import { useListsStore } from 'src/stores/lists.js'
const Lists = {
data() {
return {
isNew: false,
}
},
components: {
ListsCard,
},
computed: {
lists() {
return useListsStore().allLists
},
},
methods: {
cancelNewList() {
this.isNew = false
},
newList() {
this.isNew = true
},
},
}
export default Lists
diff --git a/src/components/lists_edit/lists_edit.js b/src/components/lists_edit/lists_edit.js
index 483a9c02a4..d7a8525a82 100644
--- a/src/components/lists_edit/lists_edit.js
+++ b/src/components/lists_edit/lists_edit.js
@@ -1,151 +1,151 @@
import { mapState as mapPiniaState } from 'pinia'
import { mapGetters, mapState } from 'vuex'
+import BasicUserCard from 'src/components/basic_user_card/basic_user_card.vue'
+import ListsUserSearch from 'src/components/lists_user_search/lists_user_search.vue'
import PanelLoading from 'src/components/panel_loading/panel_loading.vue'
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
-import BasicUserCard from '../basic_user_card/basic_user_card.vue'
-import ListsUserSearch from '../lists_user_search/lists_user_search.vue'
-import UserAvatar from '../user_avatar/user_avatar.vue'
+import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useListsStore } from 'src/stores/lists.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faChevronLeft, faSearch } from '@fortawesome/free-solid-svg-icons'
library.add(faSearch, faChevronLeft)
const ListsNew = {
components: {
BasicUserCard,
UserAvatar,
ListsUserSearch,
TabSwitcher,
PanelLoading,
},
data() {
return {
title: '',
titleDraft: '',
membersUserIds: [],
removedUserIds: new Set([]), // users we added for members, to undo
searchUserIds: [],
addedUserIds: new Set([]), // users we added from search, to undo
searchLoading: false,
reallyDelete: false,
}
},
created() {
if (!this.id) return
useListsStore()
.fetchList({ listId: this.id })
.then(() => {
this.title = this.findListTitle(this.id)
this.titleDraft = this.title
})
useListsStore()
.fetchListAccounts({ listId: this.id })
.then(() => {
this.membersUserIds = this.findListAccounts(this.id)
this.membersUserIds.forEach((userId) => {
this.$store.dispatch('fetchUserIfMissing', userId)
})
})
},
computed: {
id() {
return this.$route.params.id
},
membersUsers() {
return [...this.membersUserIds, ...this.addedUserIds]
.map((userId) => this.findUser(userId))
.filter((user) => user)
},
searchUsers() {
return this.searchUserIds
.map((userId) => this.findUser(userId))
.filter((user) => user)
},
...mapState({
currentUser: (state) => state.users.currentUser,
}),
...mapPiniaState(useListsStore, ['findListTitle', 'findListAccounts']),
...mapGetters(['findUser']),
},
methods: {
onInput() {
this.search(this.query)
},
toggleRemoveMember(user) {
if (this.removedUserIds.has(user.id)) {
this.id && this.addUser(user)
this.removedUserIds.delete(user.id)
} else {
this.id && this.removeUser(user.id)
this.removedUserIds.add(user.id)
}
},
toggleAddFromSearch(user) {
if (this.addedUserIds.has(user.id)) {
this.id && this.removeUser(user.id)
this.addedUserIds.delete(user.id)
} else {
this.id && this.addUser(user)
this.addedUserIds.add(user.id)
}
},
isRemoved(user) {
return this.removedUserIds.has(user.id)
},
isAdded(user) {
return this.addedUserIds.has(user.id)
},
addUser(user) {
useListsStore().addListAccount({ accountId: user.id, listId: this.id })
},
removeUser(userId) {
useListsStore().removeListAccount({ accountId: userId, listId: this.id })
},
onSearchLoading() {
this.searchLoading = true
},
onSearchLoadingDone() {
this.searchLoading = false
},
onSearchResults(results) {
this.searchLoading = false
this.searchUserIds = results
},
updateListTitle() {
useListsStore().setList({ listId: this.id, title: this.titleDraft })
this.title = this.findListTitle(this.id)
},
createList() {
useListsStore()
.createList({ title: this.titleDraft })
.then((list) => {
useListsStore().setListAccounts({
listId: list.id,
accountIds: [...this.addedUserIds],
})
return list.id
})
.then((listId) => {
this.$router.push({ name: 'lists-timeline', params: { id: listId } })
})
.catch((e) => {
useInterfaceStore().pushGlobalNotice({
messageKey: 'lists.error',
messageArgs: [e.message],
level: 'error',
})
})
},
deleteList() {
useListsStore().deleteList({ listId: this.id })
this.$router.push({ name: 'lists' })
},
},
}
export default ListsNew
diff --git a/src/components/lists_timeline/lists_timeline.js b/src/components/lists_timeline/lists_timeline.js
index 3d2cafa731..a06220a373 100644
--- a/src/components/lists_timeline/lists_timeline.js
+++ b/src/components/lists_timeline/lists_timeline.js
@@ -1,47 +1,47 @@
-import Timeline from '../timeline/timeline.vue'
+import Timeline from 'src/components/timeline/timeline.vue'
import { useListsStore } from 'src/stores/lists.js'
const ListsTimeline = {
data() {
return {
listId: null,
}
},
components: {
Timeline,
},
computed: {
timeline() {
return this.$store.state.statuses.timelines.list
},
},
watch: {
$route: function (route) {
if (route.name === 'lists-timeline' && route.params.id !== this.listId) {
this.listId = route.params.id
this.$store.dispatch('stopFetchingTimeline', 'list')
this.$store.commit('clearTimeline', { timeline: 'list' })
useListsStore().fetchList({ listId: this.listId })
this.$store.dispatch('startFetchingTimeline', {
timeline: 'list',
listId: this.listId,
})
}
},
},
created() {
this.listId = this.$route.params.id
useListsStore().fetchList({ listId: this.listId })
this.$store.dispatch('startFetchingTimeline', {
timeline: 'list',
listId: this.listId,
})
},
unmounted() {
this.$store.dispatch('stopFetchingTimeline', 'list')
this.$store.commit('clearTimeline', { timeline: 'list' })
},
}
export default ListsTimeline
diff --git a/src/components/lists_user_search/lists_user_search.js b/src/components/lists_user_search/lists_user_search.js
index 699e6c1567..aed3f1ce77 100644
--- a/src/components/lists_user_search/lists_user_search.js
+++ b/src/components/lists_user_search/lists_user_search.js
@@ -1,56 +1,56 @@
import { debounce } from 'lodash'
-import Checkbox from '../checkbox/checkbox.vue'
+import Checkbox from 'src/components/checkbox/checkbox.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faChevronLeft, faSearch } from '@fortawesome/free-solid-svg-icons'
library.add(faSearch, faChevronLeft)
const ListsUserSearch = {
components: {
Checkbox,
},
emits: ['loading', 'loadingDone', 'results'],
data() {
return {
loading: false,
query: '',
followingOnly: true,
}
},
methods: {
onInput: debounce(function () {
this.search(this.query)
}, 2000),
search(query) {
if (!query) {
this.loading = false
return
}
this.loading = true
this.$emit('loading')
this.userIds = []
this.$store
.dispatch('search', {
q: query,
resolve: true,
type: 'accounts',
following: this.followingOnly,
})
.then((data) => {
this.$emit(
'results',
data.accounts.map((a) => a.id),
)
})
.finally(() => {
this.loading = false
this.$emit('loadingDone')
})
},
},
}
export default ListsUserSearch
diff --git a/src/components/media_modal/media_modal.js b/src/components/media_modal/media_modal.js
index 0808b8cd61..ad53b6e31d 100644
--- a/src/components/media_modal/media_modal.js
+++ b/src/components/media_modal/media_modal.js
@@ -1,157 +1,160 @@
-import Flash from 'src/components/flash/flash.vue'
+import { defineAsyncComponent } from 'vue'
+
+import Modal from 'src/components/modal/modal.vue'
+import StillImage from 'src/components/still-image/still-image.vue'
import GestureService from '../../services/gesture_service/gesture_service'
-import Modal from '../modal/modal.vue'
-import PinchZoom from '../pinch_zoom/pinch_zoom.vue'
-import StillImage from '../still-image/still-image.vue'
-import SwipeClick from '../swipe_click/swipe_click.vue'
-import VideoAttachment from '../video_attachment/video_attachment.vue'
import { useMediaViewerStore } from 'src/stores/media_viewer.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faChevronLeft,
faChevronRight,
faCircleNotch,
faTimes,
} from '@fortawesome/free-solid-svg-icons'
library.add(faChevronLeft, faChevronRight, faCircleNotch, faTimes)
const MediaModal = {
components: {
- StillImage,
- VideoAttachment,
- PinchZoom,
- SwipeClick,
+ VideoAttachment: defineAsyncComponent(
+ () => import('src/components/video_attachment/video_attachment.vue'),
+ ),
+ PinchZoom: defineAsyncComponent(
+ () => import('src/components/pinch_zoom/pinch_zoom.vue'),
+ ),
+ SwipeClick: defineAsyncComponent(
+ () => import('src/components/swipe_click/swipe_click.vue'),
+ ),
Modal,
- Flash,
+ Flash: defineAsyncComponent(() => import('src/components/flash/flash.vue')),
},
data() {
return {
loading: false,
swipeDirection: GestureService.DIRECTION_LEFT,
swipeThreshold: () => {
const considerableMoveRatio = 1 / 4
return window.innerWidth * considerableMoveRatio
},
pinchZoomMinScale: 1,
pinchZoomScaleResetLimit: 1.2,
}
},
computed: {
showing() {
return useMediaViewerStore().activated
},
media() {
return useMediaViewerStore().media
},
description() {
return this.currentMedia.description
},
currentIndex() {
return useMediaViewerStore().currentIndex
},
currentMedia() {
return this.media[this.currentIndex]
},
canNavigate() {
return this.media.length > 1
},
swipeDisableClickThreshold() {
// If there is only one media, allow more mouse movements to close the modal
// because there is less chance that the user wants to switch to another image
return () => (this.canNavigate ? 1 : 30)
},
},
methods: {
hide() {
// HACK: Closing immediately via a touch will cause the click
// to be processed on the content below the overlay
const transitionTime = 100 // ms
setTimeout(() => {
useMediaViewerStore().closeMediaViewer()
}, transitionTime)
},
hideIfNotSwiped(event) {
// If we have swiped over SwipeClick, do not trigger hide
const comp = this.$refs.swipeClick
if (!comp) {
this.hide()
} else {
comp.$gesture.click(event)
}
},
goPrev() {
if (this.canNavigate) {
const prevIndex =
this.currentIndex === 0
? this.media.length - 1
: this.currentIndex - 1
const newMedia = this.media[prevIndex]
if (newMedia.type === 'image') {
this.loading = true
}
useMediaViewerStore().setCurrentMedia(newMedia)
}
},
goNext() {
if (this.canNavigate) {
const nextIndex =
this.currentIndex === this.media.length - 1
? 0
: this.currentIndex + 1
const newMedia = this.media[nextIndex]
if (newMedia.type === 'image') {
this.loading = true
}
useMediaViewerStore().setCurrentMedia(newMedia)
}
},
onImageLoaded() {
this.loading = false
},
handleSwipePreview(offsets) {
this.$refs.pinchZoom.setTransform({ scale: 1, x: offsets[0], y: 0 })
},
handleSwipeEnd(sign) {
this.$refs.pinchZoom.setTransform({ scale: 1, x: 0, y: 0 })
if (sign > 0) {
this.goNext()
} else if (sign < 0) {
this.goPrev()
}
},
handleKeyupEvent(e) {
if (this.showing && e.keyCode === 27) {
// escape
this.hide()
}
},
handleKeydownEvent(e) {
if (!this.showing) {
return
}
if (e.keyCode === 39) {
// arrow right
this.goNext()
} else if (e.keyCode === 37) {
// arrow left
this.goPrev()
}
},
},
mounted() {
window.addEventListener('popstate', this.hide)
document.addEventListener('keyup', this.handleKeyupEvent)
document.addEventListener('keydown', this.handleKeydownEvent)
},
unmounted() {
window.removeEventListener('popstate', this.hide)
document.removeEventListener('keyup', this.handleKeyupEvent)
document.removeEventListener('keydown', this.handleKeydownEvent)
},
}
export default MediaModal
diff --git a/src/components/mention_link/mention_link.js b/src/components/mention_link/mention_link.js
index 5edc89516a..877e83c121 100644
--- a/src/components/mention_link/mention_link.js
+++ b/src/components/mention_link/mention_link.js
@@ -1,171 +1,170 @@
import { mapState as mapPiniaState } from 'pinia'
import { defineAsyncComponent } from 'vue'
import { mapGetters, mapState } from 'vuex'
+import UnicodeDomainIndicator from 'src/components/unicode_domain_indicator/unicode_domain_indicator.vue'
+import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
+import UserPopover from 'src/components/user_popover/user_popover.vue'
import {
highlightClass,
highlightStyle,
} from '../../services/user_highlighter/user_highlighter.js'
-import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue'
-import UserAvatar from '../user_avatar/user_avatar.vue'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useUserHighlightStore } from 'src/stores/user_highlight.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faAt } from '@fortawesome/free-solid-svg-icons'
library.add(faAt)
const MentionLink = {
name: 'MentionLink',
components: {
UserAvatar,
UnicodeDomainIndicator,
- UserPopover: defineAsyncComponent(
- () => import('../user_popover/user_popover.vue'),
- ),
+ UserPopover,
},
props: {
url: {
required: true,
type: String,
},
content: {
required: true,
type: String,
},
userId: {
required: false,
type: String,
},
userScreenName: {
required: false,
type: String,
},
},
data() {
return {
hasSelection: false,
}
},
methods: {
onClick() {
if (this.shouldShowTooltip) return
const link = generateProfileLink(
this.userId || this.user.id,
this.userScreenName || this.user.screen_name,
)
this.$router.push(link)
},
handleSelection() {
if (this.$refs.full) {
this.hasSelection = document
.getSelection()
.containsNode(this.$refs.full, true)
}
},
},
mounted() {
document.addEventListener('selectionchange', this.handleSelection)
},
unmounted() {
document.removeEventListener('selectionchange', this.handleSelection)
},
computed: {
user() {
return (
this.url && this.$store && this.$store.getters.findUserByUrl(this.url)
)
},
isYou() {
// FIXME why user !== currentUser???
return this.user && this.user.id === this.currentUser.id
},
userName() {
return this.user && this.userNameFullUi.split('@')[0]
},
serverName() {
// XXX assumed that domain does not contain @
return (
this.user &&
(this.userNameFullUi.split('@')[1] ||
this.$store.getters.instanceDomain)
)
},
userNameFull() {
return this.user && this.user.screen_name
},
userNameFullUi() {
return this.user && this.user.screen_name_ui
},
highlightData() {
return this.highlight[this.user?.screen_name]
},
highlightType() {
return this.highlightData && '-' + this.highlightData.type
},
highlightClass() {
return this.highlightData && highlightClass(this.user)
},
style() {
if (this.highlightData) {
const {
backgroundColor,
backgroundPosition,
backgroundImage,
...rest
} = highlightStyle(this.highlightData)
return rest
}
},
classnames() {
return [
{
'-you': this.isYou && this.shouldBoldenYou,
'-highlighted': !!this.highlightData,
'-has-selection': this.hasSelection,
},
this.highlightType,
]
},
isRemote() {
return this.userName !== this.userNameFull
},
shouldShowFullUserName() {
const conf = this.mergedConfig.mentionLinkDisplay
if (conf === 'short') {
return false
} else if (conf === 'full') {
return true
} else {
// full_for_remote
return this.isRemote
}
},
shouldShowTooltip() {
return this.mergedConfig.mentionLinkShowTooltip
},
shouldShowAvatar() {
return this.mergedConfig.mentionLinkShowAvatar
},
shouldShowYous() {
return this.mergedConfig.mentionLinkShowYous
},
shouldBoldenYou() {
return this.mergedConfig.mentionLinkBoldenYou
},
shouldFadeDomain() {
return this.mergedConfig.mentionLinkFadeDomain
},
...mapPiniaState(useMergedConfigStore, ['mergedConfig']),
...mapPiniaState(useUserHighlightStore, ['highlight']),
...mapState({
currentUser: (state) => state.users.currentUser,
}),
},
}
export default MentionLink
diff --git a/src/components/mentions/mentions.js b/src/components/mentions/mentions.js
index 10167ac776..48e06a950c 100644
--- a/src/components/mentions/mentions.js
+++ b/src/components/mentions/mentions.js
@@ -1,14 +1,14 @@
-import Timeline from '../timeline/timeline.vue'
+import Timeline from 'src/components/timeline/timeline.vue'
const Mentions = {
computed: {
timeline() {
return this.$store.state.statuses.timelines.mentions
},
},
components: {
Timeline,
},
}
export default Mentions
diff --git a/src/components/mobile_nav/mobile_nav.js b/src/components/mobile_nav/mobile_nav.js
index f47cef893a..41cc4f457a 100644
--- a/src/components/mobile_nav/mobile_nav.js
+++ b/src/components/mobile_nav/mobile_nav.js
@@ -1,164 +1,169 @@
import { mapState } from 'pinia'
+import { defineAsyncComponent } from 'vue'
import { mapGetters } from 'vuex'
import NavigationPins from 'src/components/navigation/navigation_pins.vue'
import GestureService from '../../services/gesture_service/gesture_service'
import {
countExtraNotifications,
unseenNotificationsFromStore,
} from '../../services/notification_utils/notification_utils'
-import ConfirmModal from '../confirm_modal/confirm_modal.vue'
-import Notifications from '../notifications/notifications.vue'
-import SideDrawer from '../side_drawer/side_drawer.vue'
import { useAnnouncementsStore } from 'src/stores/announcements.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faArrowUp,
faBars,
faBell,
faCheckDouble,
faMinus,
faTimes,
} from '@fortawesome/free-solid-svg-icons'
library.add(faTimes, faBell, faBars, faArrowUp, faMinus, faCheckDouble)
const MobileNav = {
components: {
- SideDrawer,
- Notifications,
+ SideDrawer: defineAsyncComponent(
+ () => import('src/components/side_drawer/side_drawer.vue'),
+ ),
+ Notifications: defineAsyncComponent(
+ () => import('src/components/notifications/notifications.vue'),
+ ),
NavigationPins,
- ConfirmModal,
+ ConfirmModal: defineAsyncComponent(
+ () => import('src/components/confirm_modal/confirm_modal.vue'),
+ ),
},
data: () => ({
notificationsCloseGesture: undefined,
notificationsOpen: false,
notificationsAtTop: true,
showingConfirmLogout: false,
}),
created() {
this.notificationsCloseGesture = GestureService.swipeGesture(
GestureService.DIRECTION_RIGHT,
() => this.closeMobileNotifications(true),
50,
)
},
computed: {
currentUser() {
return this.$store.state.users.currentUser
},
unseenNotifications() {
return unseenNotificationsFromStore(
this.$store,
useMergedConfigStore().mergedConfig.notificationVisibility,
useMergedConfigStore().mergedConfig.ignoreInactionableSeen,
)
},
unseenNotificationsCount() {
return (
this.unseenNotifications.length +
countExtraNotifications(
this.$store,
useMergedConfigStore().mergedConfig,
+ useAnnouncementsStore().unreadAnnouncementCount,
)
)
},
unseenCount() {
return this.unseenNotifications.length
},
unseenCountBadgeText() {
return `${this.unseenCount ? this.unseenCount : ''}`
},
hideSitename() {
return useInstanceStore().hideSitename
},
sitename() {
return useInstanceStore().name
},
isChat() {
return this.$route.name === 'chat'
},
...mapState(useAnnouncementsStore, ['unreadAnnouncementCount']),
...mapState(useMergedConfigStore, {
pinnedItems: (store) =>
new Set(store.prefsStorage.collections.pinnedNavItems).has('chats'),
}),
shouldConfirmLogout() {
return useMergedConfigStore().mergedConfig.modalOnLogout
},
closingDrawerMarksAsSeen() {
return useMergedConfigStore().mergedConfig.closingDrawerMarksAsSeen
},
...mapGetters(['unreadChatCount']),
},
methods: {
toggleMobileSidebar() {
this.$refs.sideDrawer.toggleDrawer()
},
openMobileNotifications() {
this.notificationsOpen = true
},
closeMobileNotifications(markRead) {
if (this.notificationsOpen) {
// make sure to mark notifs seen only when the notifs were open and not
// from close-calls.
this.notificationsOpen = false
if (markRead && this.closingDrawerMarksAsSeen) {
this.markNotificationsAsSeen()
}
}
},
notificationsTouchStart(e) {
GestureService.beginSwipe(e, this.notificationsCloseGesture)
},
notificationsTouchMove(e) {
GestureService.updateSwipe(e, this.notificationsCloseGesture)
},
scrollToTop() {
window.scrollTo(0, 0)
},
scrollMobileNotificationsToTop() {
this.$refs.mobileNotifications.scrollTo(0, 0)
},
showConfirmLogout() {
this.showingConfirmLogout = true
},
hideConfirmLogout() {
this.showingConfirmLogout = false
},
logout() {
if (!this.shouldConfirmLogout) {
this.doLogout()
} else {
this.showConfirmLogout()
}
},
doLogout() {
this.$router.replace('/main/public')
this.$store.dispatch('logout')
this.hideConfirmLogout()
},
markNotificationsAsSeen() {
this.$store.dispatch('markNotificationsAsSeen')
},
onScroll({ target: { scrollTop, clientHeight, scrollHeight } }) {
this.notificationsAtTop = scrollTop > 0
if (scrollTop + clientHeight >= scrollHeight) {
this.$refs.notifications.fetchOlderNotifications()
}
},
},
watch: {
$route() {
// handles closing notificaitons when you press any router-link on the
// notifications.
this.closeMobileNotifications()
},
},
}
export default MobileNav
diff --git a/src/components/mobile_nav/mobile_nav.vue b/src/components/mobile_nav/mobile_nav.vue
index 0eb8c986ef..09009782aa 100644
--- a/src/components/mobile_nav/mobile_nav.vue
+++ b/src/components/mobile_nav/mobile_nav.vue
@@ -1,259 +1,259 @@
<template>
<div
class="MobileNav"
>
<nav
id="nav"
class="mobile-nav"
@click="scrollToTop()"
>
<div class="item">
<button
class="button-unstyled mobile-nav-button"
:title="$t('nav.mobile_sidebar')"
:aria-expanaded="$refs.sideDrawer && !$refs.sideDrawer.closed"
@click.stop.prevent="toggleMobileSidebar()"
>
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="bars"
/>
<div
v-if="(unreadChatCount && !chatsPinned) || unreadAnnouncementCount"
class="badge -dot -notification"
/>
</button>
<NavigationPins class="pins" />
</div> <div class="item right">
<button
v-if="currentUser"
class="button-unstyled mobile-nav-button"
:title="unseenNotificationsCount ? $t('nav.mobile_notifications_unread_active') : $t('nav.mobile_notifications')"
@click.stop.prevent="openMobileNotifications()"
>
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="bell"
/>
<div
v-if="unseenNotificationsCount"
class="badge -dot -notification"
/>
</button>
</div>
</nav>
<aside
v-if="currentUser"
class="mobile-notifications-drawer mobile-drawer"
:class="{ '-closed': !notificationsOpen }"
@touchstart.stop="notificationsTouchStart"
@touchmove.stop="notificationsTouchMove"
>
<div class="panel-heading mobile-notifications-header">
<h1 class="title">
{{ $t('notifications.notifications') }}
<span
v-if="unseenCountBadgeText"
class="badge -notification unseen-count"
>{{ unseenCountBadgeText }}</span>
</h1>
<span class="spacer" />
<button
v-if="notificationsAtTop"
class="button-unstyled mobile-nav-button"
:title="$t('general.scroll_to_top')"
@click.stop.prevent="scrollMobileNotificationsToTop"
>
<FALayers class="fa-scale-110 fa-old-padding-layer">
<FAIcon icon="arrow-up" />
<FAIcon
icon="minus"
transform="up-7"
/>
</FALayers>
</button>
<button
v-if="!closingDrawerMarksAsSeen"
class="button-unstyled mobile-nav-button"
:title="$t('nav.mobile_notifications_mark_as_seen')"
@click.stop.prevent="markNotificationsAsSeen()"
>
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="check-double"
/>
</button>
<button
class="button-unstyled mobile-nav-button"
:title="$t('nav.mobile_notifications_close')"
@click.stop.prevent="closeMobileNotifications(true)"
>
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="times"
/>
</button>
</div>
<div
id="mobile-notifications"
ref="mobileNotifications"
class="mobile-notifications"
@scroll="onScroll"
/>
</aside>
<SideDrawer
ref="sideDrawer"
:logout="logout"
/>
<teleport to="#modal">
- <confirm-modal
+ <ConfirmModal
v-if="showingConfirmLogout"
:title="$t('login.logout_confirm_title')"
:confirm-danger="true"
:confirm-text="$t('login.logout_confirm_accept_button')"
:cancel-text="$t('login.logout_confirm_cancel_button')"
@accepted="doLogout"
@cancelled="hideConfirmLogout"
>
{{ $t('login.logout_confirm') }}
- </confirm-modal>
+ </ConfirmModal>
</teleport>
</div>
</template>
<script src="./mobile_nav.js"></script>
<style lang="scss">
.MobileNav {
z-index: var(--ZI_navbar);
.mobile-nav {
display: grid;
line-height: var(--navbar-height);
grid-template-rows: var(--navbar-height);
grid-template-columns: 2fr auto;
width: 100%;
box-sizing: border-box;
a {
color: var(--link);
}
}
.mobile-inner-nav {
width: 100%;
display: flex;
align-items: center;
}
.mobile-nav-button {
display: inline-block;
text-align: center;
padding: 0 1em;
position: relative;
cursor: pointer;
}
.site-name {
padding: 0 0.3em;
display: inline-block;
}
.item {
/* moslty just to get rid of extra whitespaces */
display: flex;
}
.mobile-notifications-drawer {
width: 100%;
height: 100vh;
overflow-x: hidden;
position: fixed;
top: 0;
left: 0;
box-shadow: var(--shadow);
transition-property: transform;
transition-duration: 0.25s;
transform: translateX(0);
z-index: var(--ZI_navbar);
-webkit-overflow-scrolling: touch;
background: var(--background);
&.-closed {
transform: translateX(100%);
box-shadow: none;
}
}
.mobile-notifications-header {
display: flex;
align-items: center;
justify-content: space-between;
z-index: calc(var(--ZI_navbar) + 100);
width: 100%;
height: 3.5em;
line-height: 3.5em;
position: absolute;
box-shadow: var(--shadow);
.spacer {
flex: 1;
}
.title {
font-size: 1.3em;
margin-left: 0.6em;
white-space: nowrap;
overflow-x: hidden;
text-overflow: ellipsis;
}
}
.pins {
flex: 1;
.pinned-item {
flex-grow: 1;
}
}
.mobile-notifications {
margin-top: 3.5em;
width: 100vw;
height: calc(100vh - var(--navbar-height));
overflow: hidden scroll;
.notifications {
padding: 0;
border-radius: 0;
box-shadow: none;
.panel {
border-radius: 0;
margin: 0;
box-shadow: none;
}
.panel::after {
border-radius: 0;
}
.panel .panel-heading {
border-radius: 0;
box-shadow: none;
}
}
}
.confirm-modal.dark-overlay {
&::before {
z-index: 3000;
}
.dialog-modal.panel {
z-index: 3001;
}
}
}
</style>
diff --git a/src/components/moderation_tools/moderation_tools.js b/src/components/moderation_tools/moderation_tools.js
index 4149fd6d02..d31002fadd 100644
--- a/src/components/moderation_tools/moderation_tools.js
+++ b/src/components/moderation_tools/moderation_tools.js
@@ -1,151 +1,151 @@
-import DialogModal from '../dialog_modal/dialog_modal.vue'
-import Popover from '../popover/popover.vue'
+import DialogModal from 'src/components/dialog_modal/dialog_modal.vue'
+import Popover from 'src/components/popover/popover.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faChevronDown } from '@fortawesome/free-solid-svg-icons'
library.add(faChevronDown)
const FORCE_NSFW = 'mrf_tag:media-force-nsfw'
const STRIP_MEDIA = 'mrf_tag:media-strip'
const FORCE_UNLISTED = 'mrf_tag:force-unlisted'
const DISABLE_REMOTE_SUBSCRIPTION = 'mrf_tag:disable-remote-subscription'
const DISABLE_ANY_SUBSCRIPTION = 'mrf_tag:disable-any-subscription'
const SANDBOX = 'mrf_tag:sandbox'
const QUARANTINE = 'mrf_tag:quarantine'
const ModerationTools = {
props: ['user'],
data() {
return {
tags: {
FORCE_NSFW,
STRIP_MEDIA,
FORCE_UNLISTED,
DISABLE_REMOTE_SUBSCRIPTION,
DISABLE_ANY_SUBSCRIPTION,
SANDBOX,
QUARANTINE,
},
showDeleteUserDialog: false,
toggled: false,
}
},
components: {
DialogModal,
Popover,
},
computed: {
tagsSet() {
return new Set(this.user.tags)
},
canGrantRole() {
return (
this.user.is_local &&
!this.user.deactivated &&
this.$store.state.users.currentUser.role === 'admin'
)
},
canChangeActivationState() {
return this.privileged('users_manage_activation_state')
},
canDeleteAccount() {
return this.privileged('users_delete')
},
canUseTagPolicy() {
return (
useInstanceCapabilitiesStore().tagPolicyAvailable &&
this.privileged('users_manage_tags')
)
},
},
methods: {
hasTag(tagName) {
return this.tagsSet.has(tagName)
},
privileged(privilege) {
return this.$store.state.users.currentUser.privileges.includes(privilege)
},
toggleTag(tag) {
const store = this.$store
if (this.tagsSet.has(tag)) {
store.state.api.backendInteractor
.untagUser({ user: this.user, tag })
.then((response) => {
if (!response.ok) {
return
}
store.commit('untagUser', { user: this.user, tag })
})
} else {
store.state.api.backendInteractor
.tagUser({ user: this.user, tag })
.then((response) => {
if (!response.ok) {
return
}
store.commit('tagUser', { user: this.user, tag })
})
}
},
toggleRight(right) {
const store = this.$store
if (this.user.rights[right]) {
store.state.api.backendInteractor
.deleteRight({ user: this.user, right })
.then((response) => {
if (!response.ok) {
return
}
store.commit('updateRight', {
user: this.user,
right,
value: false,
})
})
} else {
store.state.api.backendInteractor
.addRight({ user: this.user, right })
.then((response) => {
if (!response.ok) {
return
}
store.commit('updateRight', { user: this.user, right, value: true })
})
}
},
toggleActivationStatus() {
this.$store.dispatch('toggleActivationStatus', { user: this.user })
},
deleteUserDialog(show) {
this.showDeleteUserDialog = show
},
deleteUser() {
const store = this.$store
const user = this.user
const { id, name } = user
store.state.api.backendInteractor.deleteUser({ user }).then(() => {
this.$store.dispatch(
'markStatusesAsDeleted',
(status) => user.id === status.user.id,
)
const isProfile =
this.$route.name === 'external-user-profile' ||
this.$route.name === 'user-profile'
const isTargetUser =
this.$route.params.name === name || this.$route.params.id === id
if (isProfile && isTargetUser) {
window.history.back()
}
})
},
setToggled(value) {
this.toggled = value
},
},
}
export default ModerationTools
diff --git a/src/components/mute_card/mute_card.js b/src/components/mute_card/mute_card.js
index d5226ef06f..0d247930af 100644
--- a/src/components/mute_card/mute_card.js
+++ b/src/components/mute_card/mute_card.js
@@ -1,41 +1,41 @@
+import BasicUserCard from 'src/components/basic_user_card/basic_user_card.vue'
import UserTimedFilterModal from 'src/components/user_timed_filter_modal/user_timed_filter_modal.vue'
-import BasicUserCard from '../basic_user_card/basic_user_card.vue'
const MuteCard = {
props: ['userId'],
computed: {
user() {
return this.$store.getters.findUser(this.userId)
},
relationship() {
return this.$store.getters.relationship(this.userId)
},
muted() {
return this.relationship.muting
},
muteExpiryAvailable() {
return Object.hasOwn(this.user, 'mute_expires_at')
},
muteExpiry() {
return this.user.mute_expires_at === false
? this.$t('user_card.mute_expires_forever')
: this.$t('user_card.mute_expires_at', [
new Date(this.user.mute_expires_at).toLocaleString(),
])
},
},
components: {
BasicUserCard,
UserTimedFilterModal,
},
methods: {
unmuteUser() {
this.$store.dispatch('unmuteUser', this.userId)
},
muteUser() {
this.$refs.timedMuteDialog.optionallyPrompt()
},
},
}
export default MuteCard
diff --git a/src/components/navigation/navigation_pins.js b/src/components/navigation/navigation_pins.js
index 85f6fafeeb..c3649e4b38 100644
--- a/src/components/navigation/navigation_pins.js
+++ b/src/components/navigation/navigation_pins.js
@@ -1,130 +1,127 @@
import { mapState as mapPiniaState } from 'pinia'
import { mapState } from 'vuex'
import {
filterNavigation,
getBookmarkFolderEntries,
getListEntries,
} from 'src/components/navigation/filter.js'
import {
ROOT_ITEMS,
routeTo,
TIMELINES,
} from 'src/components/navigation/navigation.js'
-import StillImage from 'src/components/still-image/still-image.vue'
import { useAnnouncementsStore } from 'src/stores/announcements'
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useListsStore } from 'src/stores/lists'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faBell,
faBookmark,
faCity,
faComments,
faEnvelope,
faGlobe,
faInfoCircle,
faList,
faStream,
faUsers,
} from '@fortawesome/free-solid-svg-icons'
library.add(
faUsers,
faGlobe,
faCity,
faBookmark,
faEnvelope,
faComments,
faBell,
faInfoCircle,
faStream,
faList,
)
const NavPanel = {
props: ['limit'],
methods: {
getRouteTo(item) {
return routeTo(item, this.currentUser)
},
},
- components: {
- StillImage,
- },
+ components: {},
computed: {
getters() {
return this.$store.getters
},
...mapPiniaState(useListsStore, {
lists: getListEntries,
}),
...mapPiniaState(useAnnouncementsStore, {
supportsAnnouncements: (store) => store.supportsAnnouncements,
}),
...mapPiniaState(useBookmarkFoldersStore, {
bookmarks: getBookmarkFolderEntries,
}),
...mapPiniaState(useSyncConfigStore, {
pinnedItems: (store) =>
new Set(store.prefsStorage.collections.pinnedNavItems),
}),
...mapPiniaState(useInstanceStore, ['privateMode', 'federating']),
...mapPiniaState(useInstanceCapabilitiesStore, [
'pleromaChatMessagesAvailable',
'localBubble',
]),
...mapState({
currentUser: (state) => state.users.currentUser,
followRequestCount: (state) => state.api.followRequests.length,
}),
pinnedList() {
if (!this.currentUser) {
return filterNavigation(
[
{ ...TIMELINES.public, name: 'public' },
{ ...TIMELINES.twkn, name: 'twkn' },
{ ...ROOT_ITEMS.about, name: 'about' },
],
{
hasChats: this.pleromaChatMessagesAvailable,
hasAnnouncements: this.supportsAnnouncements,
isFederating: this.federating,
isPrivate: this.privateMode,
currentUser: this.currentUser,
supportsBubbleTimeline: this.localBubble,
supportsBookmarkFolders: this.bookmarks,
},
)
}
return filterNavigation(
[
...Object.entries({ ...TIMELINES })
.filter(([k]) => this.pinnedItems.has(k))
.map(([k, v]) => ({ ...v, name: k })),
...this.lists.filter((k) => this.pinnedItems.has(k.name)),
...this.bookmarks.filter((k) => this.pinnedItems.has(k.name)),
...Object.entries({ ...ROOT_ITEMS })
.filter(([k]) => this.pinnedItems.has(k))
.map(([k, v]) => ({ ...v, name: k })),
],
{
hasChats: this.pleromaChatMessagesAvailable,
hasAnnouncements: this.supportsAnnouncements,
supportsBubbleTimeline: this.localBubble,
supportsBookmarkFolders: this.bookmarks,
isFederating: this.federating,
isPrivate: this.privateMode,
currentUser: this.currentUser,
},
).slice(0, this.limit)
},
},
}
export default NavPanel
diff --git a/src/components/notification/notification.js b/src/components/notification/notification.js
index fc4ffc518b..856850920f 100644
--- a/src/components/notification/notification.js
+++ b/src/components/notification/notification.js
@@ -1,228 +1,226 @@
+import { defineAsyncComponent } from 'vue'
import { mapState } from 'vuex'
-import RichContent from 'src/components/rich_content/rich_content.jsx'
+import Report from 'src/components/report/report.vue'
+import StatusContent from 'src/components/status_content/status_content.vue'
+import Timeago from 'src/components/timeago/timeago.vue'
+import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
+import UserLink from 'src/components/user_link/user_link.vue'
+import UserPopover from 'src/components/user_popover/user_popover.vue'
import { isStatusNotification } from '../../services/notification_utils/notification_utils.js'
import {
highlightClass,
highlightStyle,
} from '../../services/user_highlighter/user_highlighter.js'
-import ConfirmModal from '../confirm_modal/confirm_modal.vue'
-import Report from '../report/report.vue'
-import Status from '../status/status.vue'
-import StatusContent from '../status_content/status_content.vue'
-import Timeago from '../timeago/timeago.vue'
-import UserAvatar from '../user_avatar/user_avatar.vue'
-import UserCard from '../user_card/user_card.vue'
-import UserLink from '../user_link/user_link.vue'
-import UserPopover from '../user_popover/user_popover.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useUserHighlightStore } from 'src/stores/user_highlight.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faCheck,
faCompressAlt,
faExpandAlt,
faEyeSlash,
faRetweet,
faStar,
faSuitcaseRolling,
faTimes,
faUser,
faUserPlus,
} from '@fortawesome/free-solid-svg-icons'
library.add(
faCheck,
faTimes,
faStar,
faRetweet,
faUserPlus,
faUser,
faEyeSlash,
faSuitcaseRolling,
faExpandAlt,
faCompressAlt,
)
const Notification = {
data() {
return {
selecting: false,
statusExpanded: false,
unmuted: false,
showingApproveConfirmDialog: false,
showingDenyConfirmDialog: false,
}
},
props: ['notification'],
emits: ['interacted'],
components: {
StatusContent,
UserAvatar,
- UserCard,
Timeago,
- Status,
+
Report,
- RichContent,
+
UserPopover,
UserLink,
- ConfirmModal,
+ ConfirmModal: defineAsyncComponent(
+ () => import('src/components/confirm_modal/confirm_modal.vue'),
+ ),
},
mounted() {
document.addEventListener('selectionchange', this.onContentSelect)
},
unmounted() {
document.removeEventListener('selectionchange', this.onContentSelect)
},
methods: {
toggleStatusExpanded() {
if (!this.expandable) return
this.statusExpanded = !this.statusExpanded
},
onContentSelect() {
const { isCollapsed, anchorNode, offsetNode } = document.getSelection()
if (isCollapsed) {
this.selecting = false
return
}
const within =
this.$refs.root.contains(anchorNode) ||
this.$refs.root.contains(offsetNode)
if (within) {
this.selecting = true
} else {
this.selecting = false
}
},
onContentClick(e) {
if (
!this.selecting &&
!e.target.closest('a') &&
!e.target.closest('button')
) {
this.toggleStatusExpanded()
}
},
generateUserProfileLink(user) {
return generateProfileLink(
user.id,
user.screen_name,
useInstanceStore().restrictedNicknames,
)
},
getUser(notification) {
return this.$store.state.users.usersObject[notification.from_profile.id]
},
interacted() {
this.$emit('interacted')
},
toggleMute() {
this.unmuted = !this.unmuted
},
showApproveConfirmDialog() {
this.showingApproveConfirmDialog = true
},
hideApproveConfirmDialog() {
this.showingApproveConfirmDialog = false
},
showDenyConfirmDialog() {
this.showingDenyConfirmDialog = true
},
hideDenyConfirmDialog() {
this.showingDenyConfirmDialog = false
},
approveUser() {
if (this.shouldConfirmApprove) {
this.showApproveConfirmDialog()
} else {
this.doApprove()
}
},
doApprove() {
this.$store.state.api.backendInteractor.approveUser({ id: this.user.id })
this.$store.dispatch('removeFollowRequest', this.user)
this.$store.dispatch('markSingleNotificationAsSeen', {
id: this.notification.id,
})
this.$store.dispatch('updateNotification', {
id: this.notification.id,
updater: (notification) => {
notification.type = 'follow'
},
})
this.hideApproveConfirmDialog()
},
denyUser() {
if (this.shouldConfirmDeny) {
this.showDenyConfirmDialog()
} else {
this.doDeny()
}
},
doDeny() {
this.$store.state.api.backendInteractor
.denyUser({ id: this.user.id })
.then(() => {
this.$store.dispatch('dismissNotificationLocal', {
id: this.notification.id,
})
this.$store.dispatch('removeFollowRequest', this.user)
})
this.hideDenyConfirmDialog()
},
},
computed: {
userClass() {
return highlightClass(this.notification.from_profile)
},
userStyle() {
const user = this.notification.from_profile.screen_name
return highlightStyle(useUserHighlightStore().get(user))
},
expandable() {
return new Set(['like', 'pleroma:emoji_reaction', 'repeat', 'poll']).has(
this.notification.type,
)
},
user() {
return this.$store.getters.findUser(this.notification.from_profile.id)
},
userProfileLink() {
return this.generateUserProfileLink(this.user)
},
targetUser() {
return this.$store.getters.findUser(this.notification.target.id)
},
targetUserProfileLink() {
return this.generateUserProfileLink(this.targetUser)
},
needMute() {
return this.$store.getters.relationship(this.user.id).muting
},
isStatusNotification() {
return isStatusNotification(this.notification.type)
},
mergedConfig() {
return useMergedConfigStore().mergedConfig
},
allowNonSquareEmoji() {
return this.mergedConfig.nonSquareEmoji
},
shouldConfirmApprove() {
return this.mergedConfig.modalOnApproveFollow
},
shouldConfirmDeny() {
return this.mergedConfig.modalOnDenyFollow
},
...mapState({
currentUser: (state) => state.users.currentUser,
}),
},
}
export default Notification
diff --git a/src/components/notification/notification.vue b/src/components/notification/notification.vue
index fbe45eceb1..39bd154263 100644
--- a/src/components/notification/notification.vue
+++ b/src/components/notification/notification.vue
@@ -1,295 +1,295 @@
<template>
<article
v-if="notification.type === 'mention' || notification.type === 'status'"
ref="root"
>
<Status
class="Notification"
:compact="true"
:statusoid="notification.status"
@click="interacted"
/>
</article>
<article
v-else
ref="root"
class="NotificationParent"
:class="{ '-expandable': expandable }"
>
<div
v-if="needMute && !unmuted"
:id="'notif-' +notification.id"
:aria-expanded="statusExpanded"
:aria-controls="'notif-' +notification.id"
class="Notification container -muted"
>
<small>
<user-link
:user="notification.from_profile"
:at="false"
/>
</small>
<button
class="button-unstyled unmute"
@click.prevent="toggleMute"
>
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="eye-slash"
/>
</button>
</div>
<div
v-else
class="Notification non-mention"
:class="[userClass, { highlighted: userStyle }, '-type--' + notification.type]"
:style="[ userStyle ]"
>
<a
class="avatar-container"
:href="$router.resolve(userProfileLink).href"
@click.prevent
>
<UserPopover
:user-id="notification.from_profile.id"
:overlay-centers="true"
>
<UserAvatar
class="post-avatar"
:compact="true"
:user="notification.from_profile"
/>
</UserPopover>
</a>
<div class="notification-right">
<span class="notification-details">
<div class="name-and-action">
<!-- eslint-disable vue/no-v-html -->
<bdi v-if="!!notification.from_profile.name_html">
<RichContent
class="username"
:title="'@'+notification.from_profile.screen_name_ui"
:html="notification.from_profile.name_html"
:emoji="notification.from_profile.emoji"
:allow-non-square-emoji="allowNonSquareEmoji"
:is-local="notification.from_profile.is_local"
/>
</bdi>
<!-- eslint-enable vue/no-v-html -->
<span
v-else
class="username"
:title="'@'+notification.from_profile.screen_name_ui"
>
{{ notification.from_profile.name }}
</span>
{{ ' ' }}
<span v-if="notification.type === 'like'">
<FAIcon
class="type-icon"
icon="star"
/>
{{ ' ' }}
<small>{{ $t('notifications.favorited_you') }}</small>
</span>
<span v-if="notification.type === 'repeat'">
<FAIcon
class="type-icon"
icon="retweet"
:title="$t('tool_tip.repeat')"
/>
{{ ' ' }}
<small>{{ $t('notifications.repeated_you') }}</small>
</span>
<span v-if="notification.type === 'follow'">
<FAIcon
class="type-icon"
icon="user-plus"
/>
{{ ' ' }}
<small>{{ $t('notifications.followed_you') }}</small>
</span>
<span v-if="notification.type === 'follow_request'">
<FAIcon
class="type-icon"
icon="user"
/>
{{ ' ' }}
<small>{{ $t('notifications.follow_request') }}</small>
</span>
<span v-if="notification.type === 'move'">
<FAIcon
class="type-icon"
icon="suitcase-rolling"
/>
{{ ' ' }}
<small>{{ $t('notifications.migrated_to') }}</small>
</span>
<span v-if="notification.type === 'pleroma:emoji_reaction'">
<small>
<i18n-t
scope="global"
keypath="notifications.reacted_with"
>
<img
v-if="notification.emoji_url"
class="emoji-reaction-emoji emoji-reaction-emoji-image"
:src="notification.emoji_url"
:alt="notification.emoji"
:title="notification.emoji"
:class="{ ['-wide']: allowNonSquareEmoji }"
>
<span
v-else
class="emoji-reaction-emoji"
>{{ notification.emoji }}</span>
</i18n-t>
</small>
</span>
<span v-if="notification.type === 'pleroma:report'">
<small>{{ $t('notifications.submitted_report') }}</small>
</span>
<span v-if="notification.type === 'poll'">
<FAIcon
class="type-icon"
icon="poll-h"
/>
{{ ' ' }}
<small>{{ $t('notifications.poll_ended') }}</small>
</span>
</div>
<div
v-if="isStatusNotification"
class="timeago"
>
<router-link
v-if="notification.status"
:to="{ name: 'conversation', params: { id: notification.status.id } }"
class="timeago-link faint"
>
<Timeago
:time="notification.created_at"
:auto-update="240"
/>
</router-link>
<button
class="button-unstyled expand-icon"
:title="$t('tool_tip.toggle_expand')"
:aria-expanded="statusExpanded"
@click.prevent="toggleStatusExpanded"
>
<FAIcon
class="fa-scale-110"
fixed-width
:icon="statusExpanded ? 'compress-alt' : 'expand-alt'"
/>
</button>
</div>
<div
v-else
class="timeago"
>
<span class="faint">
<Timeago
:time="notification.created_at"
:auto-update="240"
/>
</span>
</div>
<button
v-if="needMute"
class="button-unstyled"
:title="$t('tool_tip.toggle_mute')"
:aria-expanded="!unmuted"
@click.prevent="toggleMute"
>
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="eye-slash"
/>
</button>
</span>
<div
v-if="notification.type === 'follow' || notification.type === 'follow_request'"
class="follow-text"
>
<user-link
class="follow-name"
:user="notification.from_profile"
/>
<div
v-if="notification.type === 'follow_request'"
style="white-space: nowrap;"
>
<button
class="button-unstyled"
:title="$t('tool_tip.accept_follow_request')"
@click="approveUser()"
>
<FAIcon
icon="check"
class="fa-scale-110 fa-old-padding follow-request-accept"
/>
</button>
<button
class="button-unstyled"
:title="$t('tool_tip.reject_follow_request')"
@click="denyUser()"
>
<FAIcon
icon="times"
class="fa-scale-110 fa-old-padding follow-request-reject"
/>
</button>
</div>
</div>
<div
v-else-if="notification.type === 'move'"
class="move-text"
>
<user-link
:user="notification.target"
/>
</div>
<Report
v-else-if="notification.type === 'pleroma:report'"
:report-id="notification.report.id"
/>
<template v-else>
<StatusContent
class="status-content"
:compact="!statusExpanded"
:status="notification.status"
:collapse="!statusExpanded"
@click="onContentClick"
/>
</template>
</div>
</div>
<teleport to="#modal">
- <confirm-modal
+ <ConfirmModal
v-if="showingApproveConfirmDialog"
:title="$t('user_card.approve_confirm_title')"
:confirm-text="$t('user_card.approve_confirm_accept_button')"
:cancel-text="$t('user_card.approve_confirm_cancel_button')"
@accepted="doApprove"
@cancelled="hideApproveConfirmDialog"
>
{{ $t('user_card.approve_confirm', { user: user.screen_name_ui }) }}
- </confirm-modal>
- <confirm-modal
+ </ConfirmModal>
+ <ConfirmModal
v-if="showingDenyConfirmDialog"
:title="$t('user_card.deny_confirm_title')"
:confirm-text="$t('user_card.deny_confirm_accept_button')"
:cancel-text="$t('user_card.deny_confirm_cancel_button')"
@accepted="doDeny"
@cancelled="hideDenyConfirmDialog"
>
{{ $t('user_card.deny_confirm', { user: user.screen_name_ui }) }}
- </confirm-modal>
+ </ConfirmModal>
</teleport>
</article>
</template>
<script src="./notification.js"></script>
<style src="./notification.scss" lang="scss"></style>
diff --git a/src/components/notifications/notification_filters.vue b/src/components/notifications/notification_filters.vue
index 9232930dfd..27e1bb179c 100644
--- a/src/components/notifications/notification_filters.vue
+++ b/src/components/notifications/notification_filters.vue
@@ -1,138 +1,138 @@
<template>
<Popover
trigger="click"
class="NotificationFilters"
placement="bottom"
:bound-to="{ x: 'container' }"
>
<template #content>
<div class="dropdown-menu">
<div class="menu-item dropdown-item -icon">
<button
class="main-button"
@click="toggleNotificationFilter('likes')"
>
<span
class="input menu-checkbox"
:class="{ 'menu-checkbox-checked': filters.likes }"
/>{{ $t('settings.notification_visibility_likes') }}
</button>
</div>
<div class="menu-item dropdown-item -icon">
<button
class="main-button"
@click="toggleNotificationFilter('repeats')"
>
<span
class="input menu-checkbox"
:class="{ 'menu-checkbox-checked': filters.repeats }"
/>{{ $t('settings.notification_visibility_repeats') }}
</button>
</div>
<div class="menu-item dropdown-item -icon">
<button
class="main-button"
@click="toggleNotificationFilter('follows')"
>
<span
class="input menu-checkbox"
:class="{ 'menu-checkbox-checked': filters.follows }"
/>{{ $t('settings.notification_visibility_follows') }}
</button>
</div>
<div class="menu-item dropdown-item -icon">
<button
class="main-button"
@click="toggleNotificationFilter('mentions')"
>
<span
class="input menu-checkbox"
:class="{ 'menu-checkbox-checked': filters.mentions }"
/>{{ $t('settings.notification_visibility_mentions') }}
</button>
</div>
<div class="menu-item dropdown-item -icon">
<button
class="main-button"
@click="toggleNotificationFilter('statuses')"
>
<span
class="input menu-checkbox"
:class="{ 'menu-checkbox-checked': filters.statuses }"
/>{{ $t('settings.notification_visibility_statuses') }}
</button>
</div>
<div class="menu-item dropdown-item -icon">
<button
class="main-button"
@click="toggleNotificationFilter('emojiReactions')"
>
<span
class="input menu-checkbox"
:class="{ 'menu-checkbox-checked': filters.emojiReactions }"
/>{{ $t('settings.notification_visibility_emoji_reactions') }}
</button>
</div>
<div class="menu-item dropdown-item -icon">
<button
class="main-button"
@click="toggleNotificationFilter('moves')"
>
<span
class="input menu-checkbox"
:class="{ 'menu-checkbox-checked': filters.moves }"
/>{{ $t('settings.notification_visibility_moves') }}
</button>
</div>
<div class="menu-item dropdown-item -icon">
<button
class="main-button"
@click="toggleNotificationFilter('polls')"
>
<span
class="input menu-checkbox"
:class="{ 'menu-checkbox-checked': filters.polls }"
/>{{ $t('settings.notification_visibility_polls') }}
</button>
</div>
</div>
</template>
<template #trigger>
<button class="filter-trigger-button button-unstyled">
<FAIcon icon="filter" />
</button>
</template>
</Popover>
</template>
<script>
-import Popover from '../popover/popover.vue'
+import Popover from 'src/components/popover/popover.vue'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faFilter } from '@fortawesome/free-solid-svg-icons'
library.add(faFilter)
export default {
components: { Popover },
computed: {
filters() {
return useMergedConfigStore().mergedConfig.notificationVisibility
},
},
methods: {
toggleNotificationFilter(type) {
useSyncConfigStore().setSimplePrefAndSave({
path: 'notificationVisibility',
value: {
...this.filters,
[type]: !this.filters[type],
},
})
},
},
}
</script>
diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js
index 96263d93b2..49349b1272 100644
--- a/src/components/notifications/notifications.js
+++ b/src/components/notifications/notifications.js
@@ -1,271 +1,272 @@
import { mapState } from 'pinia'
import { computed } from 'vue'
import { mapGetters } from 'vuex'
+import ExtraNotifications from 'src/components/extra_notifications/extra_notifications.vue'
+import Notification from 'src/components/notification/notification.vue'
import FaviconService from '../../services/favicon_service/favicon_service.js'
import {
ACTIONABLE_NOTIFICATION_TYPES,
countExtraNotifications,
filteredNotificationsFromStore,
notificationsFromStore,
unseenNotificationsFromStore,
} from '../../services/notification_utils/notification_utils.js'
import notificationsFetcher from '../../services/notifications_fetcher/notifications_fetcher.service.js'
-import ExtraNotifications from '../extra_notifications/extra_notifications.vue'
-import Notification from '../notification/notification.vue'
import NotificationFilters from './notification_filters.vue'
import { useAnnouncementsStore } from 'src/stores/announcements.js'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faArrowUp,
faCircleNotch,
faMinus,
} from '@fortawesome/free-solid-svg-icons'
library.add(faCircleNotch, faArrowUp, faMinus)
const DEFAULT_SEEN_TO_DISPLAY_COUNT = 30
const Notifications = {
components: {
Notification,
NotificationFilters,
ExtraNotifications,
},
props: {
// Disables panel styles, unread mark, potentially other notification-related actions
// meant for "Interactions" timeline
minimalMode: Boolean,
// Custom filter mode, an array of strings, possible values 'mention', 'status', 'repeat', 'like', 'follow', used to override global filter for use in "Interactions" timeline
filterMode: Array,
// Do not show extra notifications
noExtra: {
type: Boolean,
default: false,
},
// Disable teleporting (i.e. for /users/user/notifications)
disableTeleport: Boolean,
},
data() {
return {
showScrollTop: false,
bottomedOut: false,
// How many seen notifications to display in the list. The more there are,
// the heavier the page becomes. This count is increased when loading
// older notifications, and cut back to default whenever hitting "Read!".
seenToDisplayCount: DEFAULT_SEEN_TO_DISPLAY_COUNT,
}
},
provide() {
return {
popoversZLayer: computed(() => this.popoversZLayer),
}
},
computed: {
mainClass() {
return this.minimalMode ? '' : 'panel panel-default'
},
notifications() {
return notificationsFromStore(this.$store)
},
error() {
return this.$store.state.notifications.error
},
unseenNotifications() {
return unseenNotificationsFromStore(
this.$store,
useMergedConfigStore().mergedConfig.notificationVisibility,
useMergedConfigStore().mergedConfig.ignoreInactionableSeen,
)
},
filteredNotifications() {
if (this.unseenAtTop) {
return [
...filteredNotificationsFromStore(
this.$store,
useMergedConfigStore().mergedConfig.notificationVisibility,
).filter((n) => this.shouldShowUnseen(n)),
...filteredNotificationsFromStore(
this.$store,
useMergedConfigStore().mergedConfig.notificationVisibility,
).filter((n) => !this.shouldShowUnseen(n)),
]
} else {
return filteredNotificationsFromStore(
this.$store,
useMergedConfigStore().mergedConfig.notificationVisibility,
this.filterMode,
)
}
},
unseenCountBadgeText() {
return `${this.unseenCount ? this.unseenCount : ''}${this.extraNotificationsCount ? '*' : ''}`
},
unseenCount() {
return this.unseenNotifications.length
},
ignoreInactionableSeen() {
return useMergedConfigStore().mergedConfig.ignoreInactionableSeen
},
extraNotificationsCount() {
return countExtraNotifications(
this.$store,
useMergedConfigStore().mergedConfig,
+ useAnnouncementsStore().unreadAnnouncementCount,
)
},
unseenCountTitle() {
return (
this.unseenNotifications.length +
this.unreadChatCount +
this.unreadAnnouncementCount
)
},
loading() {
return this.$store.state.notifications.loading
},
noHeading() {
const { layoutType } = useInterfaceStore()
return this.minimalMode || layoutType === 'mobile'
},
teleportTarget() {
const { layoutType } = useInterfaceStore()
const map = {
wide: '#notifs-column',
mobile: '#mobile-notifications',
}
return map[layoutType] || '#notifs-sidebar'
},
popoversZLayer() {
const { layoutType } = useInterfaceStore()
return layoutType === 'mobile' ? 'navbar' : null
},
notificationsToDisplay() {
return this.filteredNotifications.slice(
0,
this.unseenCount + this.seenToDisplayCount,
)
},
noSticky() {
return useMergedConfigStore().mergedConfig.disableStickyHeaders
},
unseenAtTop() {
return useMergedConfigStore().mergedConfig.unseenAtTop
},
showExtraNotifications() {
return !this.noExtra
},
...mapState(useAnnouncementsStore, ['unreadAnnouncementCount']),
...mapGetters(['unreadChatCount']),
},
mounted() {
this.scrollerRef = this.$refs.root.closest('.column.-scrollable')
if (!this.scrollerRef) {
this.scrollerRef = this.$refs.root.closest('.mobile-notifications')
}
if (!this.scrollerRef) {
this.scrollerRef = this.$refs.root.closest('.column.main')
}
this.scrollerRef.addEventListener('scroll', this.updateScrollPosition)
},
unmounted() {
if (!this.scrollerRef) return
this.scrollerRef.removeEventListener('scroll', this.updateScrollPosition)
},
watch: {
unseenCountTitle(count) {
if (count > 0) {
FaviconService.drawFaviconBadge()
useInterfaceStore().setPageTitle(`(${count})`)
} else {
FaviconService.clearFaviconBadge()
useInterfaceStore().setPageTitle('')
}
},
teleportTarget() {
// handle scroller change
this.$nextTick(() => {
this.scrollerRef.removeEventListener(
'scroll',
this.updateScrollPosition,
)
this.scrollerRef = this.$refs.root.closest('.column.-scrollable')
if (!this.scrollerRef) {
this.scrollerRef = this.$refs.root.closest('.mobile-notifications')
}
this.scrollerRef.addEventListener('scroll', this.updateScrollPosition)
this.updateScrollPosition()
})
},
},
methods: {
scrollToTop() {
const scrollable = this.scrollerRef
scrollable.scrollTo({ top: this.$refs.root.offsetTop })
},
updateScrollPosition() {
this.showScrollTop =
this.$refs.root.offsetTop < this.scrollerRef.scrollTop
},
shouldShowUnseen(notification) {
if (notification.seen) return false
const actionable = ACTIONABLE_NOTIFICATION_TYPES.has(notification.type)
return this.ignoreInactionableSeen ? actionable : true
},
/* "Interacted" really refers to "actionable" notifications that require user input,
* everything else (likes/repeats/reacts) cannot be acted and therefore we just clear
* the "seen" status upon any clicks on them
*/
notificationClicked(notification) {
const { id } = notification
this.$store.dispatch('notificationClicked', { id })
},
notificationInteracted(notification) {
const { id } = notification
this.$store.dispatch('markSingleNotificationAsSeen', { id })
},
markAsSeen() {
this.$store.dispatch('markNotificationsAsSeen')
this.seenToDisplayCount = DEFAULT_SEEN_TO_DISPLAY_COUNT
},
fetchOlderNotifications() {
if (this.loading) {
return
}
const seenCount = this.filteredNotifications.length - this.unseenCount
if (this.seenToDisplayCount < seenCount) {
this.seenToDisplayCount = Math.min(
this.seenToDisplayCount + 20,
seenCount,
)
return
} else if (this.seenToDisplayCount > seenCount) {
this.seenToDisplayCount = seenCount
}
const store = this.$store
const credentials = store.state.users.currentUser.credentials
store.commit('setNotificationsLoading', { value: true })
notificationsFetcher
.fetchAndUpdate({
store,
credentials,
older: true,
})
.then((notifs) => {
store.commit('setNotificationsLoading', { value: false })
if (notifs.length === 0) {
this.bottomedOut = true
}
this.seenToDisplayCount += notifs.length
})
},
},
}
export default Notifications
diff --git a/src/components/opacity_input/opacity_input.vue b/src/components/opacity_input/opacity_input.vue
index b8012741f8..761aeb2169 100644
--- a/src/components/opacity_input/opacity_input.vue
+++ b/src/components/opacity_input/opacity_input.vue
@@ -1,49 +1,49 @@
<template>
<div
class="opacity-control style-control"
:class="{ disabled: !present || disabled }"
>
<label
:for="name"
class="label"
:class="{ faint: !present || disabled }"
>
{{ label || $t('settings.style.themes3.editor.opacity') }}
</label>
<Checkbox
v-if="typeof fallback !== 'undefined'"
:model-value="present"
:disabled="disabled"
class="opt"
@update:model-value="$emit('update:modelValue', !present ? fallback : undefined)"
/>
<input
:id="name"
class="input input-number"
type="number"
:value="modelValue || fallback"
:disabled="!present || disabled"
:class="{ disabled: !present || disabled }"
max="1"
min="0"
step=".05"
@input="$emit('update:modelValue', $event.target.value)"
>
</div>
</template>
<script>
-import Checkbox from '../checkbox/checkbox.vue'
+import Checkbox from 'src/components/checkbox/checkbox.vue'
export default {
components: {
Checkbox,
},
props: ['name', 'label', 'modelValue', 'fallback', 'disabled'],
emits: ['update:modelValue'],
computed: {
present() {
return typeof this.modelValue !== 'undefined'
},
},
}
</script>
diff --git a/src/components/poll/poll.js b/src/components/poll/poll.js
index 5033726f39..3ea9a18902 100644
--- a/src/components/poll/poll.js
+++ b/src/components/poll/poll.js
@@ -1,124 +1,123 @@
import Checkbox from 'components/checkbox/checkbox.vue'
-import RichContent from 'components/rich_content/rich_content.jsx'
import Timeago from 'components/timeago/timeago.vue'
import genRandomSeed from '../../services/random_seed/random_seed.service.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { usePollsStore } from 'src/stores/polls.js'
export default {
name: 'Poll',
props: ['basePoll', 'emoji'],
components: {
Timeago,
- RichContent,
+
Checkbox,
},
data() {
return {
loading: false,
choices: [],
randomSeed: genRandomSeed(),
}
},
created() {
if (!usePollsStore().pollsObject[this.pollId]) {
usePollsStore().mergeOrAddPoll(this.basePoll)
}
usePollsStore().trackPoll(this.pollId)
},
unmounted() {
usePollsStore().untrackPoll(this.pollId)
},
computed: {
pollId() {
return this.basePoll.id
},
poll() {
const storePoll = usePollsStore().pollsObject[this.pollId]
return storePoll || {}
},
options() {
return (this.poll && this.poll.options) || []
},
expiresAt() {
return (this.poll && this.poll.expires_at) || null
},
expired() {
return (this.poll && this.poll.expired) || false
},
expirationLabel() {
if (useMergedConfigStore().mergedConfig.useAbsoluteTimeFormat) {
return this.expired ? 'polls.expired_at' : 'polls.expires_at'
} else {
return this.expired ? 'polls.expired' : 'polls.expires_in'
}
},
allowNonSquareEmoji() {
return useMergedConfigStore().mergedConfig.nonSquareEmoji
},
loggedIn() {
return this.$store.state.users.currentUser
},
showResults() {
return this.poll.voted || this.expired || !this.loggedIn
},
totalVotesCount() {
return this.poll.votes_count
},
containerClass() {
return {
loading: this.loading,
}
},
choiceIndices() {
// Convert array of booleans into an array of indices of the
// items that were 'true', so [true, false, false, true] becomes
// [0, 3].
return this.choices
.map((entry, index) => entry && index)
.filter((value) => typeof value === 'number')
},
isDisabled() {
const noChoice = this.choiceIndices.length === 0
return this.loading || noChoice
},
},
methods: {
percentageForOption(count) {
return this.totalVotesCount === 0
? 0
: Math.round((count / this.totalVotesCount) * 100)
},
resultTitle(option) {
return `${option.votes_count}/${this.totalVotesCount} ${this.$t('polls.votes')}`
},
activateOption(index, value) {
let result
if (this.poll.multiple) {
result = this.choices || this.options.map(() => false)
} else {
result = this.options.map(() => false)
}
result[index] = value
this.choices = result
},
optionId(index) {
return `poll${this.poll.id}-${index}`
},
vote() {
if (this.choiceIndices.length === 0) return
this.loading = true
usePollsStore()
.votePoll({
id: this.statusId,
pollId: this.poll.id,
choices: this.choiceIndices,
})
.then(() => {
this.loading = false
})
},
},
}
diff --git a/src/components/poll/poll_form.js b/src/components/poll/poll_form.js
index 1e132312f0..e89935c7e1 100644
--- a/src/components/poll/poll_form.js
+++ b/src/components/poll/poll_form.js
@@ -1,141 +1,141 @@
-import Select from '../select/select.vue'
+import Select from 'src/components/select/select.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import * as DateUtils from 'src/services/date_utils/date_utils.js'
import { pollFallback } from 'src/services/poll/poll.service.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faPlus, faTimes } from '@fortawesome/free-solid-svg-icons'
library.add(faTimes, faPlus)
export default {
components: {
Select,
},
name: 'PollForm',
props: {
visible: {},
params: {
type: Object,
required: true,
},
},
computed: {
pollType: {
get() {
return pollFallback(this.params, 'pollType')
},
set(newVal) {
this.params.pollType = newVal
},
},
options() {
const hasOptions = !!this.params.options
if (!hasOptions) {
this.params.options = pollFallback(this.params, 'options')
}
return this.params.options
},
expiryAmount: {
get() {
return pollFallback(this.params, 'expiryAmount')
},
set(newVal) {
this.params.expiryAmount = newVal
},
},
expiryUnit: {
get() {
return pollFallback(this.params, 'expiryUnit')
},
set(newVal) {
this.params.expiryUnit = newVal
},
},
pollLimits() {
return useInstanceStore().limits.pollLimits
},
maxOptions() {
return this.pollLimits.max_options
},
maxLength() {
return this.pollLimits.max_option_chars
},
expiryUnits() {
const allUnits = ['minutes', 'hours', 'days']
const expiry = this.convertExpiryFromUnit
return allUnits.filter(
(unit) => this.pollLimits.max_expiration >= expiry(unit, 1),
)
},
minExpirationInCurrentUnit() {
return Math.ceil(
this.convertExpiryToUnit(
this.expiryUnit,
this.pollLimits.min_expiration,
),
)
},
maxExpirationInCurrentUnit() {
return Math.floor(
this.convertExpiryToUnit(
this.expiryUnit,
this.pollLimits.max_expiration,
),
)
},
},
methods: {
clear() {
this.pollType = 'single'
this.options = ['', '']
this.expiryAmount = 10
this.expiryUnit = 'minutes'
},
nextOption(index) {
const element = this.$el.querySelector(`#poll-${index + 1}`)
if (element) {
element.focus()
} else {
// Try adding an option and try focusing on it
const addedOption = this.addOption()
if (addedOption) {
this.$nextTick(function () {
this.nextOption(index)
})
}
}
},
addOption() {
if (this.options.length < this.maxOptions) {
this.options.push('')
return true
}
return false
},
deleteOption(index) {
if (this.options.length > 2) {
this.options.splice(index, 1)
}
},
convertExpiryToUnit(unit, amount) {
// Note: we want seconds and not milliseconds
return DateUtils.secondsToUnit(unit, amount)
},
convertExpiryFromUnit(unit, amount) {
return DateUtils.unitToSeconds(unit, amount)
},
expiryAmountChange() {
this.expiryAmount = Math.max(
this.minExpirationInCurrentUnit,
this.expiryAmount,
)
this.expiryAmount = Math.min(
this.maxExpirationInCurrentUnit,
this.expiryAmount,
)
},
},
}
diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js
index 1e9c624f44..7eb129430e 100644
--- a/src/components/post_status_form/post_status_form.js
+++ b/src/components/post_status_form/post_status_form.js
@@ -1,997 +1,1000 @@
import { debounce, map, reject, uniqBy } from 'lodash'
import { mapActions, mapState } from 'pinia'
+import { defineAsyncComponent } from 'vue'
import { mapGetters } from 'vuex'
+import Attachment from 'src/components/attachment/attachment.vue'
+import Checkbox from 'src/components/checkbox/checkbox.vue'
import DraftCloser from 'src/components/draft_closer/draft_closer.vue'
+import EmojiInput from 'src/components/emoji_input/emoji_input.vue'
+import suggestor from 'src/components/emoji_input/suggestor.js'
import Gallery from 'src/components/gallery/gallery.vue'
+import MediaUpload from 'src/components/media_upload/media_upload.vue'
import Popover from 'src/components/popover/popover.vue'
+import ScopeSelector from 'src/components/scope_selector/scope_selector.vue'
+import Select from 'src/components/select/select.vue'
+import StatusContent from 'src/components/status_content/status_content.vue'
import { propsToNative } from '../../services/attributes_helper/attributes_helper.service.js'
import { findOffset } from '../../services/offset_finder/offset_finder.service.js'
import genRandomSeed from '../../services/random_seed/random_seed.service.js'
import statusPoster from '../../services/status_poster/status_poster.service.js'
-import Attachment from '../attachment/attachment.vue'
-import Checkbox from '../checkbox/checkbox.vue'
-import EmojiInput from '../emoji_input/emoji_input.vue'
-import suggestor from '../emoji_input/suggestor.js'
-import MediaUpload from '../media_upload/media_upload.vue'
-import PollForm from '../poll/poll_form.vue'
-import QuoteForm from '../quote/quote_form.vue'
-import ScopeSelector from '../scope_selector/scope_selector.vue'
-import Select from '../select/select.vue'
-import StatusContent from '../status_content/status_content.vue'
import { useEmojiStore } from 'src/stores/emoji.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useMediaViewerStore } from 'src/stores/media_viewer.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { pollFormToMasto } from 'src/services/poll/poll.service.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faBan,
faChevronDown,
faChevronLeft,
faChevronRight,
faCircleNotch,
faPollH,
faQuoteRight,
faSmileBeam,
faTimes,
faUpload,
} from '@fortawesome/free-solid-svg-icons'
library.add(
faSmileBeam,
faPollH,
faUpload,
faQuoteRight,
faBan,
faTimes,
faCircleNotch,
faChevronDown,
faChevronLeft,
faChevronRight,
)
const buildMentionsString = ({ user, attentions = [] }, currentUser) => {
let allAttentions = [...attentions]
allAttentions.unshift(user)
allAttentions = uniqBy(allAttentions, 'id')
allAttentions = reject(allAttentions, { id: currentUser.id })
const mentions = map(allAttentions, (attention) => {
return `@${attention.screen_name}`
})
return mentions.length > 0 ? mentions.join(' ') + ' ' : ''
}
// Converts a string with px to a number like '2px' -> 2
const pxStringToNumber = (str) => {
return Number(str.substring(0, str.length - 2))
}
const typeAndRefId = ({ replyTo, profileMention, statusId }) => {
if (replyTo) {
return ['reply', replyTo]
} else if (profileMention) {
return ['mention', profileMention]
} else if (statusId) {
return ['edit', statusId]
} else {
return ['new', '']
}
}
const PostStatusForm = {
props: [
'statusId',
'statusText',
'statusIsSensitive',
'statusPoll',
'statusFiles',
'statusMediaDescriptions',
'statusScope',
'statusContentType',
'replyTo',
'repliedUser',
'attentions',
'copyMessageScope',
'subject',
'disableSubject',
'disableScopeSelector',
'disableVisibilitySelector',
'disableNotice',
'disableLockWarning',
'disablePolls',
'disableQuotes',
'disableSensitivityCheckbox',
'disableSubmit',
'disablePreview',
'disableDraft',
'hideDraft',
'closeable',
'placeholder',
'maxHeight',
'postHandler',
'preserveFocus',
'autoFocus',
'fileLimit',
'submitOnEnter',
'emojiPickerPlacement',
'optimisticPosting',
'profileMention',
'draftId',
],
emits: [
'posted',
'draft-done',
'resize',
'mediaplay',
'mediapause',
'can-close',
'update',
],
components: {
MediaUpload,
EmojiInput,
- PollForm,
- QuoteForm,
+ PollForm: defineAsyncComponent(
+ () => import('src/components/poll/poll_form.vue'),
+ ),
+ QuoteForm: defineAsyncComponent(
+ () => import('src/components/quote/quote_form.vue'),
+ ),
ScopeSelector,
Checkbox,
Select,
Attachment,
StatusContent,
Gallery,
DraftCloser,
Popover,
},
mounted() {
this.updateIdempotencyKey()
this.resize(this.$refs.textarea)
if (this.replyTo) {
const textLength = this.$refs.textarea.value.length
this.$refs.textarea.setSelectionRange(textLength, textLength)
}
if (this.replyTo || this.autoFocus) {
this.$refs.textarea.focus()
}
},
data() {
const preset = this.$route.query.message
let statusText = preset || ''
const { scopeCopy } = useMergedConfigStore().mergedConfig
const [statusType, refId] = typeAndRefId({
replyTo: this.replyTo,
profileMention: this.profileMention && this.repliedUser?.id,
statusId: this.statusId,
})
// If we are starting a new post, do not associate it with old drafts
let statusParams =
!this.disableDraft && (this.draftId || statusType !== 'new')
? this.getDraft(statusType, refId)
: null
if (!statusParams) {
if (statusType === 'reply' || statusType === 'mention') {
const currentUser = this.$store.state.users.currentUser
statusText = buildMentionsString(
{ user: this.repliedUser, attentions: this.attentions },
currentUser,
)
}
const scope =
(this.copyMessageScope && scopeCopy) ||
this.copyMessageScope === 'direct'
? this.copyMessageScope
: this.$store.state.users.currentUser.default_scope
const { postContentType: contentType, sensitiveByDefault } =
useMergedConfigStore().mergedConfig
statusParams = {
type: statusType,
refId,
spoilerText: this.subject || '',
status: statusText,
nsfw: !!sensitiveByDefault,
files: [],
poll: {},
hasPoll: false,
hasQuote: false,
quote: {
id: '',
url: '',
thread: false,
},
mediaDescriptions: {},
visibility: scope,
contentType,
quoting: false,
}
if (statusType === 'edit') {
const statusContentType = this.statusContentType || contentType
statusParams = {
type: statusType,
refId,
spoilerText: this.subject || '',
status: this.statusText || '',
nsfw: this.statusIsSensitive || !!sensitiveByDefault,
files: this.statusFiles || [],
poll: this.statusPoll || {},
hasPoll: false,
hasQuote: false,
quote: {
id: '',
url: '',
thread: false,
},
mediaDescriptions: this.statusMediaDescriptions || {},
visibility: this.statusScope || scope,
contentType: statusContentType,
}
}
}
return {
randomSeed: genRandomSeed(),
dropFiles: [],
uploadingFiles: false,
error: null,
posting: false,
highlighted: 0,
newStatus: statusParams,
caret: 0,
showDropIcon: 'hide',
dropStopTimeout: null,
preview: null,
previewLoading: false,
emojiInputShown: false,
idempotencyKey: '',
saveInhibited: true,
saveable: false,
}
},
computed: {
users() {
return this.$store.state.users.users
},
userDefaultScope() {
return this.$store.state.users.currentUser.default_scope
},
showAllScopes() {
return !this.mergedConfig.minimalScopesMode
},
hideExtraActions() {
return this.disableDraft || this.hideDraft
},
emojiUserSuggestor() {
return suggestor({
emoji: [
...useEmojiStore().standardEmojiList,
...useEmojiStore().customEmoji,
],
store: this.$store,
})
},
emojiSuggestor() {
return suggestor({
emoji: [
...useEmojiStore().standardEmojiList,
...useEmojiStore().customEmoji,
],
})
},
emoji() {
return useEmojiStore().standardEmojiList
},
customEmoji() {
return useEmojiStore().customEmoji
},
statusLength() {
return this.newStatus.status.length
},
spoilerTextLength() {
return this.newStatus.spoilerText.length
},
statusLengthLimit() {
return useInstanceStore().limits.textLimit
},
hasStatusLengthLimit() {
return this.statusLengthLimit > 0
},
charactersLeft() {
return (
this.statusLengthLimit - (this.statusLength + this.spoilerTextLength)
)
},
isOverLengthLimit() {
return this.hasStatusLengthLimit && this.charactersLeft < 0
},
minimalScopesMode() {
return useInstanceStore().minimalScopesMode
},
alwaysShowSubject() {
return this.mergedConfig.alwaysShowSubjectInput
},
postFormats() {
return useInstanceCapabilitiesStore().postFormats || []
},
safeDMEnabled() {
return useInstanceCapabilitiesStore().safeDM
},
pollsAvailable() {
return (
useInstanceCapabilitiesStore().pollsAvailable &&
useInstanceStore().limits.pollLimits.max_options >= 2 &&
this.disablePolls !== true
)
},
hideScopeNotice() {
return (
this.disableNotice ||
useMergedConfigStore().mergedConfig.hideScopeNotice
)
},
pollContentError() {
return (
this.pollFormVisible && this.newStatus.poll && this.newStatus.poll.error
)
},
showPreview() {
return !this.disablePreview && (!!this.preview || this.previewLoading)
},
emptyStatus() {
return (
this.newStatus.status.trim() === '' && this.newStatus.files.length === 0
)
},
uploadFileLimitReached() {
return this.newStatus.files.length >= this.fileLimit
},
isEdit() {
return typeof this.statusId !== 'undefined' && this.statusId.trim() !== ''
},
quotingAvailable() {
if (!useInstanceCapabilitiesStore().quotingAvailable) {
return false
}
return this.disableQuotes !== true
},
isReply() {
return this.newStatus.type === 'reply'
},
quotable() {
return this.quotingAvailable && this.replyTo
},
quoteThreadToggled: {
get() {
return this.newStatus.hasQuote && this.newStatus.quote.thread
},
set(value) {
this.newStatus.hasQuote = value
this.newStatus.quote.thread = value
this.newStatus.quote.id = value ? this.replyTo : ''
},
},
defaultQuotable() {
if (
!this.quotingAvailable ||
!this.isReply ||
!useMergedConfigStore().mergedConfig.quoteReply
) {
return false
}
const repliedStatus =
this.$store.state.statuses.allStatusesObject[this.replyTo]
if (!repliedStatus) {
return false
}
if (
repliedStatus.visibility === 'public' ||
repliedStatus.visibility === 'unlisted' ||
repliedStatus.visibility === 'local'
) {
return true
} else if (repliedStatus.visibility === 'private') {
return repliedStatus.user.id === this.$store.state.users.currentUser.id
}
return false
},
inReplyStatusId() {
return !this.newStatus.hasQuote ||
!this.newStatus.quote.thread ||
!this.newStatus.quote.id
? this.replyTo
: undefined
},
quoteId() {
return this.newStatus.hasQuote ? this.newStatus.quote.id : undefined
},
debouncedMaybeAutoSaveDraft() {
return debounce(this.maybeAutoSaveDraft, 3000)
},
pollFormVisible() {
return this.newStatus.hasPoll
},
quoteFormVisible() {
return this.newStatus.hasQuote && !this.newStatus.quote.thread
},
shouldAutoSaveDraft() {
return useMergedConfigStore().mergedConfig.autoSaveDraft
},
autoSaveState() {
if (this.saveable) {
return this.$t('post_status.auto_save_saving')
} else if (this.newStatus.id) {
return this.$t('post_status.auto_save_saved')
} else {
return this.$t('post_status.auto_save_nothing_new')
}
},
safeToSaveDraft() {
return (
(this.newStatus.status ||
this.newStatus.spoilerText ||
this.newStatus.files?.length ||
this.newStatus.hasPoll ||
this.newStatus.hasQuote) &&
this.saveable
)
},
hasEmptyDraft() {
return (
this.newStatus.id &&
!(
this.newStatus.status ||
this.newStatus.spoilerText ||
this.newStatus.files?.length ||
this.newStatus.hasPoll ||
this.newStatus.hasQuote
)
)
},
...mapState(useMergedConfigStore, ['mergedConfig']),
...mapState(useInterfaceStore, {
mobileLayout: (store) => store.mobileLayout,
}),
},
watch: {
newStatus: {
deep: true,
handler() {
this.statusChanged()
},
},
saveable(val) {
// https://developer.mozilla.org/en-US/docs/Web/API/Window/beforeunload_event#usage_notes
// MDN says we'd better add the beforeunload event listener only when needed, and remove it when it's no longer needed
if (val) {
this.addBeforeUnloadListener()
} else {
this.removeBeforeUnloadListener()
}
},
},
beforeUnmount() {
this.maybeAutoSaveDraft()
this.removeBeforeUnloadListener()
},
methods: {
...mapActions(useMediaViewerStore, ['increment']),
statusChanged() {
this.autoPreview()
this.updateIdempotencyKey()
this.debouncedMaybeAutoSaveDraft()
this.saveable = true
this.saveInhibited = false
},
clearStatus() {
const newStatus = this.newStatus
this.saveInhibited = true
this.newStatus = {
status: '',
spoilerText: '',
files: [],
visibility: newStatus.visibility,
contentType: newStatus.contentType,
poll: {},
hasPoll: false,
hasQuote: false,
quote: {},
mediaDescriptions: {},
}
this.$refs.mediaUpload && this.$refs.mediaUpload.clearFile()
this.clearPollForm()
this.clearQuoteForm()
if (this.preserveFocus) {
this.$nextTick(() => {
this.$refs.textarea.focus()
})
}
const el = this.$el.querySelector('textarea')
el.style.height = 'auto'
el.style.height = undefined
this.error = null
if (this.preview) this.previewStatus()
this.saveable = false
},
async postStatus(event, newStatus) {
if (this.posting && !this.optimisticPosting) {
return
}
if (this.disableSubmit) {
return
}
if (this.emojiInputShown) {
return
}
if (this.submitOnEnter) {
event.stopPropagation()
event.preventDefault()
}
if (
this.optimisticPosting &&
(this.emptyStatus || this.isOverLengthLimit)
) {
return
}
if (this.emptyStatus) {
this.error = this.$t('post_status.empty_status_error')
return
}
const poll = newStatus.hasPoll ? pollFormToMasto(newStatus.poll) : {}
if (this.pollContentError) {
this.error = this.pollContentError
return
}
this.posting = true
try {
await this.setAllMediaDescriptions()
} catch {
this.error = this.$t('post_status.media_description_error')
this.posting = false
return
}
const postingOptions = {
status: newStatus.status,
spoilerText: newStatus.spoilerText || null,
visibility: newStatus.visibility,
sensitive: newStatus.nsfw,
media: newStatus.files,
store: this.$store,
inReplyToStatusId: this.inReplyStatusId,
quoteId: this.quoteId,
contentType: newStatus.contentType,
poll,
idempotencyKey: this.idempotencyKey,
}
const postHandler = this.postHandler
? this.postHandler
: statusPoster.postStatus
postHandler(postingOptions).then((data) => {
if (!data.error) {
this.abandonDraft()
this.clearStatus()
this.$emit('posted', data)
} else {
this.error = data.error
}
this.posting = false
})
},
previewStatus() {
if (this.emptyStatus && this.newStatus.spoilerText.trim() === '') {
this.preview = { error: this.$t('post_status.preview_empty') }
this.previewLoading = false
return
}
const newStatus = this.newStatus
this.previewLoading = true
statusPoster
.postStatus({
status: newStatus.status,
spoilerText: newStatus.spoilerText || null,
visibility: newStatus.visibility,
sensitive: newStatus.nsfw,
media: [],
store: this.$store,
inReplyToStatusId: this.inReplyStatusId,
quoteId: this.quoteId,
contentType: newStatus.contentType,
poll: {},
preview: true,
})
.then((data) => {
// Don't apply preview if not loading, because it means
// user has closed the preview manually.
if (!this.previewLoading) return
if (!data.error) {
this.preview = data
} else {
this.preview = { error: data.error }
}
})
.catch((error) => {
this.preview = { error }
})
.finally(() => {
this.previewLoading = false
})
},
debouncePreviewStatus: debounce(function () {
this.previewStatus()
}, 500),
autoPreview() {
if (!this.preview) return
this.previewLoading = true
this.debouncePreviewStatus()
},
closePreview() {
this.preview = null
this.previewLoading = false
},
togglePreview() {
if (this.showPreview) {
this.closePreview()
} else {
this.previewStatus()
}
},
addMediaFile(fileInfo) {
this.newStatus.files.push(fileInfo)
this.$emit('resize', { delayed: true })
},
removeMediaFile(fileInfo) {
const index = this.newStatus.files.indexOf(fileInfo)
this.newStatus.files.splice(index, 1)
this.$emit('resize')
},
editAttachment(fileInfo, newText) {
this.newStatus.mediaDescriptions[fileInfo.id] = newText
},
shiftUpMediaFile(fileInfo) {
const { files } = this.newStatus
const index = this.newStatus.files.indexOf(fileInfo)
files.splice(index, 1)
files.splice(index - 1, 0, fileInfo)
},
shiftDnMediaFile(fileInfo) {
const { files } = this.newStatus
const index = this.newStatus.files.indexOf(fileInfo)
files.splice(index, 1)
files.splice(index + 1, 0, fileInfo)
},
uploadFailed(errString, templateArgs) {
templateArgs = templateArgs || {}
this.error =
this.$t('upload.error.base') +
' ' +
this.$t('upload.error.' + errString, templateArgs)
},
startedUploadingFiles() {
this.uploadingFiles = true
},
finishedUploadingFiles() {
this.$emit('resize')
this.uploadingFiles = false
},
paste(e) {
this.autoPreview()
this.resize(e)
if (e.clipboardData.files.length > 0) {
// prevent pasting of file as text
e.preventDefault()
// Strangely, files property gets emptied after event propagation
// Trying to wrap it in array doesn't work. Plus I doubt it's possible
// to hold more than one file in clipboard.
this.dropFiles = [e.clipboardData.files[0]]
}
},
fileDrop(e) {
if (e.dataTransfer && e.dataTransfer.types.includes('Files')) {
e.preventDefault() // allow dropping text like before
this.dropFiles = e.dataTransfer.files
clearTimeout(this.dropStopTimeout)
this.showDropIcon = 'hide'
}
},
fileDragStop() {
// The false-setting is done with delay because just using leave-events
// directly caused unwanted flickering, this is not perfect either but
// much less noticable.
clearTimeout(this.dropStopTimeout)
this.showDropIcon = 'fade'
this.dropStopTimeout = setTimeout(() => (this.showDropIcon = 'hide'), 500)
},
fileDrag(e) {
e.dataTransfer.dropEffect = this.uploadFileLimitReached ? 'none' : 'copy'
if (e.dataTransfer && e.dataTransfer.types.includes('Files')) {
clearTimeout(this.dropStopTimeout)
this.showDropIcon = 'show'
}
},
onEmojiInputInput() {
this.$nextTick(() => {
this.resize(this.$refs.textarea)
})
},
resize(e) {
const target = e.target || e
if (!(target instanceof window.Element)) {
return
}
// Reset to default height for empty form, nothing else to do here.
if (target.value === '') {
target.style.height = null
this.$emit('resize')
return
}
const formRef = this.$refs.form
const bottomRef = this.$refs.bottom
/* Scroller is either `window` (replies in TL), sidebar (main post form,
* replies in notifs) or mobile post form. Note that getting and setting
* scroll is different for `Window` and `Element`s
*/
const bottomBottomPaddingStr =
window.getComputedStyle(bottomRef)['padding-bottom']
const bottomBottomPadding = pxStringToNumber(bottomBottomPaddingStr)
const scrollerRef =
this.$el.closest('.column.-scrollable') ||
this.$el.closest('.post-form-modal-view') ||
window
// Getting info about padding we have to account for, removing 'px' part
const topPaddingStr = window.getComputedStyle(target)['padding-top']
const bottomPaddingStr = window.getComputedStyle(target)['padding-bottom']
const topPadding = pxStringToNumber(topPaddingStr)
const bottomPadding = pxStringToNumber(bottomPaddingStr)
const vertPadding = topPadding + bottomPadding
const oldHeight = pxStringToNumber(target.style.height)
/* Explanation:
*
* https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight
* scrollHeight returns element's scrollable content height, i.e. visible
* element + overscrolled parts of it. We use it to determine when text
* inside the textarea exceeded its height, so we can set height to prevent
* overscroll, i.e. make textarea grow with the text. HOWEVER, since we
* explicitly set new height, scrollHeight won't go below that, so we can't
* SHRINK the textarea when there's extra space. To workaround that we set
* height to 'auto' which makes textarea tiny again, so that scrollHeight
* will match text height again. HOWEVER, shrinking textarea can screw with
* the scroll since there might be not enough padding around form-bottom to even
* warrant a scroll, so it will jump to 0 and refuse to move anywhere,
* so we check current scroll position before shrinking and then restore it
* with needed delta.
*/
// this part has to be BEFORE the content size update
const currentScroll =
scrollerRef === window ? scrollerRef.scrollY : scrollerRef.scrollTop
const scrollerHeight =
scrollerRef === window
? scrollerRef.innerHeight
: scrollerRef.offsetHeight
const scrollerBottomBorder = currentScroll + scrollerHeight
// BEGIN content size update
target.style.height = 'auto'
const heightWithoutPadding = Math.floor(target.scrollHeight - vertPadding)
let newHeight = this.maxHeight
? Math.min(heightWithoutPadding, this.maxHeight)
: heightWithoutPadding
// This is a bit of a hack to combat target.scrollHeight being different on every other input
// on some browsers for whatever reason. Don't change the height if difference is 1px or less.
if (Math.abs(newHeight - oldHeight) <= 1) {
newHeight = oldHeight
}
target.style.height = `${newHeight}px`
this.$emit('resize', newHeight)
// END content size update
// We check where the bottom border of form-bottom element is, this uses findOffset
// to find offset relative to scrollable container (scroller)
const bottomBottomBorder =
bottomRef.offsetHeight +
findOffset(bottomRef, scrollerRef).top +
bottomBottomPadding
const isBottomObstructed = scrollerBottomBorder < bottomBottomBorder
const isFormBiggerThanScroller = scrollerHeight < formRef.offsetHeight
const bottomChangeDelta = bottomBottomBorder - scrollerBottomBorder
// The intention is basically this;
// Keep form-bottom always visible so that submit button is in view EXCEPT
// if form element bigger than scroller and caret isn't at the end, so that
// if you scroll up and edit middle of text you won't get scrolled back to bottom
const shouldScrollToBottom =
isBottomObstructed &&
!(
isFormBiggerThanScroller &&
this.$refs.textarea.selectionStart !==
this.$refs.textarea.value.length
)
const totalDelta = shouldScrollToBottom ? bottomChangeDelta : 0
const targetScroll = Math.round(currentScroll + totalDelta)
if (scrollerRef === window) {
scrollerRef.scroll(0, targetScroll)
} else {
scrollerRef.scrollTop = targetScroll
}
},
clearError() {
this.error = null
},
changeVis(visibility) {
this.newStatus.visibility = visibility
},
togglePollForm() {
this.newStatus.hasPoll = !this.newStatus.hasPoll
},
setPoll(poll) {
this.newStatus.poll = poll
},
clearPollForm() {
if (this.$refs.pollForm) {
this.$refs.pollForm.clear()
}
},
clearQuoteForm() {
if (this.$refs.quoteForm) {
this.$refs.quoteForm.clear()
}
},
toggleQuoteForm() {
this.newStatus.hasQuote = !this.newStatus.hasQuote
this.newStatus.quote = {}
this.newStatus.quote.thread = false
this.newStatus.quote.id = null
this.newStatus.quote.url = ''
},
dismissScopeNotice() {
useSyncConfigStore().setSimplePrefAndSave({
path: 'hideScopeNotice',
value: true,
})
},
setMediaDescription(id) {
const description = this.newStatus.mediaDescriptions[id]
if (!description || description.trim() === '') return
return statusPoster.setMediaDescription({
store: this.$store,
id,
description,
})
},
setAllMediaDescriptions() {
const ids = this.newStatus.files.map((file) => file.id)
return Promise.all(ids.map((id) => this.setMediaDescription(id)))
},
handleEmojiInputShow(value) {
this.emojiInputShown = value
},
updateIdempotencyKey() {
this.idempotencyKey = Date.now().toString()
},
openProfileTab() {
useInterfaceStore().openSettingsModalTab('profile')
},
propsToNative(props) {
return propsToNative(props)
},
saveDraft() {
if (!this.disableDraft && !this.saveInhibited) {
if (this.safeToSaveDraft) {
return this.$store
.dispatch('addOrSaveDraft', { draft: this.newStatus })
.then((id) => {
if (this.newStatus.id !== id) {
this.newStatus.id = id
}
this.saveable = false
if (!this.shouldAutoSaveDraft) {
this.clearStatus()
this.$emit('draft-done')
}
})
} else if (this.hasEmptyDraft) {
// There is a draft, but there is nothing in it, clear it
return this.abandonDraft().then(() => {
this.saveable = false
if (!this.shouldAutoSaveDraft) {
this.clearStatus()
this.$emit('draft-done')
}
})
}
}
return Promise.resolve()
},
maybeAutoSaveDraft() {
if (this.shouldAutoSaveDraft) {
this.saveDraft(false)
}
},
abandonDraft() {
return this.$store.dispatch('abandonDraft', { id: this.newStatus.id })
},
getDraft(statusType, refId) {
const maybeDraft = this.$store.state.drafts.drafts[this.draftId]
if (this.draftId && maybeDraft) {
return maybeDraft
} else {
const existingDrafts = this.$store.getters.draftsByTypeAndRefId(
statusType,
refId,
)
if (existingDrafts.length) {
return existingDrafts[0]
}
}
// No draft available, fall back
},
requestClose() {
if (!this.saveable) {
this.$emit('can-close')
} else {
this.$refs.draftCloser.requestClose()
}
},
saveAndCloseDraft() {
this.saveDraft().then(() => {
this.$emit('can-close')
})
},
discardAndCloseDraft() {
this.abandonDraft().then(() => {
this.$emit('can-close')
})
},
addBeforeUnloadListener() {
this._beforeUnloadListener ||= () => {
this.saveDraft()
}
window.addEventListener('beforeunload', this._beforeUnloadListener)
},
removeBeforeUnloadListener() {
if (this._beforeUnloadListener) {
window.removeEventListener('beforeunload', this._beforeUnloadListener)
}
},
},
}
export default PostStatusForm
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index d37d0a90fa..a5e6ffb6d8 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -1,434 +1,434 @@
<template>
<div
ref="form"
class="post-status-form"
>
<form
autocomplete="off"
@submit.prevent
@dragover.prevent="fileDrag"
>
<div class="form-group">
<div
v-if="!$store.state.users.currentUser.locked && newStatus.visibility == 'private' && !disableLockWarning"
class="visibility-notice notice-dismissible"
>
<i18n-t
keypath="post_status.account_not_locked_warning"
tag="p"
class=""
scope="global"
>
<button
class="button-unstyled -link"
@click="openProfileTab"
>
{{ $t('post_status.account_not_locked_warning_link') }}
</button>
</i18n-t>
</div>
<p
v-if="!hideScopeNotice && newStatus.visibility === 'public'"
class="visibility-notice notice-dismissible"
>
<span>{{ $t('post_status.scope_notice.public') }}</span>
<a
class="fa-scale-110 fa-old-padding dismiss"
:title="$t('post_status.scope_notice_dismiss')"
role="button"
tabindex="0"
@click.prevent="dismissScopeNotice()"
>
<FAIcon icon="times" />
</a>
</p>
<p
v-else-if="!hideScopeNotice && newStatus.visibility === 'unlisted'"
class="visibility-notice notice-dismissible"
>
<span>{{ $t('post_status.scope_notice.unlisted') }}</span>
<a
class="fa-scale-110 fa-old-padding dismiss"
:title="$t('post_status.scope_notice_dismiss')"
role="button"
tabindex="0"
@click.prevent="dismissScopeNotice()"
>
<FAIcon icon="times" />
</a>
</p>
<p
v-else-if="!hideScopeNotice && newStatus.visibility === 'private' && $store.state.users.currentUser.locked"
class="visibility-notice notice-dismissible"
>
<span>{{ $t('post_status.scope_notice.private') }}</span>
<a
class="fa-scale-110 fa-old-padding dismiss"
:title="$t('post_status.scope_notice_dismiss')"
role="button"
tabindex="0"
@click.prevent="dismissScopeNotice()"
>
<FAIcon icon="times" />
</a>
</p>
<p
v-else-if="newStatus.visibility === 'direct'"
class="visibility-notice notice-dismissible"
>
<span v-if="safeDMEnabled">{{ $t('post_status.direct_warning_to_first_only') }}</span>
<span v-else>{{ $t('post_status.direct_warning_to_all') }}</span>
</p>
<div
v-if="isEdit"
class="visibility-notice edit-warning"
>
<p>{{ $t('post_status.edit_remote_warning') }}</p>
<p>{{ $t('post_status.edit_unsupported_warning') }}</p>
</div>
<div
v-if="!disablePreview"
class="preview-heading"
>
<a
class="preview-toggle faint"
@click.stop.prevent="togglePreview"
>
{{ $t('post_status.preview') }}
<FAIcon :icon="showPreview ? 'chevron-left' : 'chevron-right'" />
</a>
<div
v-show="previewLoading"
class="preview-spinner"
>
<FAIcon
class="fa-old-padding"
spin
icon="circle-notch"
/>
</div>
<div
v-if="quotable"
role="radiogroup"
class="reply-or-quote-selector"
>
<Checkbox
v-model="quoteThreadToggled"
:radio="true"
:disabled="quoteFormVisible"
>
{{ $t('post_status.quote_option') }}
</Checkbox>
<Checkbox
role="radio"
:radio="true"
:model-value="!quoteThreadToggled"
:disabled="quoteFormVisible"
@update:model-value="e => quoteThreadToggled = !e"
>
{{ $t('post_status.reply_option') }}
</Checkbox>
</div>
</div>
<div
v-if="showPreview"
class="preview-container"
>
<div
v-if="!preview"
class="preview-status"
>
{{ $t('general.loading') }}
</div>
<div
v-else-if="preview.error"
class="preview-status preview-error"
>
{{ preview.error }}
</div>
<StatusContent
v-else
:status="preview"
class="preview-status"
/>
</div>
<div class="input inputs-wrapper">
<EmojiInput
v-if="!disableSubject && (newStatus.spoilerText || alwaysShowSubject)"
v-model="newStatus.spoilerText"
enable-emoji-picker
:suggest="emojiSuggestor"
class="input form-control subject-input unstyled"
>
<template #default="inputProps">
<input
v-model="newStatus.spoilerText"
type="text"
:placeholder="$t('post_status.content_warning')"
:disabled="posting && !optimisticPosting"
v-bind="propsToNative(inputProps)"
size="1"
class="input form-post-subject unstyled"
>
</template>
</EmojiInput>
<EmojiInput
ref="emoji-input"
v-model="newStatus.status"
:suggest="emojiUserSuggestor"
:placement="emojiPickerPlacement"
class="input form-control main-input unstyled"
enable-sticker-picker
enable-emoji-picker
:newline-on-ctrl-enter="submitOnEnter"
@input="onEmojiInputInput"
@sticker-uploaded="addMediaFile"
@sticker-upload-failed="uploadFailed"
@shown="handleEmojiInputShow"
>
<template #default="inputProps">
<textarea
ref="textarea"
v-model="newStatus.status"
:placeholder="placeholder || $t('post_status.default')"
rows="1"
cols="1"
:disabled="posting && !optimisticPosting"
class="input form-post-body"
:class="{ 'scrollable-form': !!maxHeight }"
v-bind="propsToNative(inputProps)"
@keydown.exact.enter="submitOnEnter && postStatus($event, newStatus)"
@keydown.meta.enter="postStatus($event, newStatus)"
@keydown.ctrl.enter="!submitOnEnter && postStatus($event, newStatus)"
@input="resize"
@compositionupdate="resize"
@paste="paste"
/>
<p
v-if="hasStatusLengthLimit"
class="character-counter faint"
:class="{ error: isOverLengthLimit }"
>
{{ charactersLeft }}
</p>
</template>
</EmojiInput>
</div>
<div
v-if="!disableScopeSelector"
class="visibility-tray"
>
<scope-selector
v-if="!disableVisibilitySelector"
:show-all="showAllScopes"
:user-default="userDefaultScope"
:original-scope="copyMessageScope"
:initial-scope="newStatus.visibility"
:on-scope-change="changeVis"
/>
<div
v-if="postFormats.length > 1"
class="text-format"
>
<Select
v-model="newStatus.contentType"
class="input form-control unstyled"
:attrs="{ 'aria-label': $t('post_status.content_type_selection') }"
unstyled="true"
>
<option
v-for="postFormat in postFormats"
:key="postFormat"
:value="postFormat"
>
{{ $t(`post_status.content_type["${postFormat}"]`) }}
</option>
</Select>
</div>
<div
v-if="postFormats.length === 1 && postFormats[0] !== 'text/plain'"
class="text-format"
>
<span class="only-format">
{{ $t(`post_status.content_type["${postFormats[0]}"]`) }}
</span>
</div>
</div>
</div>
<PollForm
v-if="pollsAvailable"
ref="pollForm"
:visible="pollFormVisible"
:params="newStatus.poll"
/>
<QuoteForm
v-if="quotingAvailable"
:id="newStatus.quote.id"
ref="quoteForm"
:visible="quoteFormVisible"
:url="newStatus.quote.url"
@update:url="url => newStatus.quote.url = url"
@update:id="id => newStatus.quote.id = id"
/>
<span
v-if="!disableDraft && shouldAutoSaveDraft"
class="auto-save-status"
>
{{ autoSaveState }}
</span>
<div
ref="bottom"
class="form-bottom"
>
<div class="form-bottom-left">
<media-upload
ref="mediaUpload"
class="bottom-left-button media-upload-icon"
:drop-files="dropFiles"
:disabled="uploadFileLimitReached"
@uploading="startedUploadingFiles"
@uploaded="addMediaFile"
@upload-failed="uploadFailed"
@all-uploaded="finishedUploadingFiles"
/>
<button
v-if="pollsAvailable"
class="bottom-left-button poll-icon button-unstyled"
:class="{ toggled: pollFormVisible }"
:title="$t('polls.add_poll')"
@click="togglePollForm"
>
<FAIcon icon="poll-h" />
</button>
<button
v-if="quotingAvailable"
class="bottom-left-button quote-icon button-unstyled"
:disabled="quoteThreadToggled"
:class="{ toggled: quoteFormVisible }"
:title="$t('tool_tip.add_quote')"
@click="toggleQuoteForm"
>
<FAIcon icon="quote-right" />
</button>
</div>
<div class="btn-group post-button-group">
<button
class="btn button-default post-button"
:disabled="isOverLengthLimit || posting || uploadingFiles || disableSubmit"
@click.stop.prevent="postStatus($event, newStatus)"
>
<template v-if="posting">
{{ $t('post_status.posting') }}
</template>
<template v-else>
{{ $t('post_status.post') }}
</template>
</button>
<Popover
v-if="!hideExtraActions"
class="more-post-actions"
:normal-button="true"
trigger="click"
placement="bottom"
:offset="{ y: 5 }"
:trigger-attrs="{ 'aria-label': $t('post_status.more_post_actions') }"
>
<template #trigger>
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="chevron-down"
/>
</template>
<template #content="{close}">
<div
class="dropdown-menu"
role="menu"
>
<div
class="menu-item dropdown-item"
:class="{ disabled: !safeToSaveDraft }"
>
<button
v-if="!hideDraft || !disableDraft"
class="main-button"
role="menu"
:disabled="!safeToSaveDraft"
@click.prevent="saveDraft"
@click="close"
>
<template v-if="closeable">
{{ $t('post_status.save_to_drafts_and_close_button') }}
</template>
<template v-else>
{{ $t('post_status.save_to_drafts_button') }}
</template>
</button>
</div>
</div>
</template>
</Popover>
</div>
</div>
<div
v-show="showDropIcon !== 'hide'"
:style="{ animation: showDropIcon === 'show' ? 'fade-in 0.25s' : 'fade-out 0.5s' }"
class="drop-indicator"
@dragleave="fileDragStop"
@drop.stop="fileDrop"
>
<FAIcon :icon="uploadFileLimitReached ? 'ban' : 'upload'" />
</div>
<div
v-if="error"
class="alert error -dismissible"
>
<span>
{{ error }}
</span>
<button
class="button-unstyled"
@click="clearError"
>
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="times"
/>
</button>
</div>
- <gallery
+ <Gallery
v-if="newStatus.files && newStatus.files.length > 0"
class="attachments"
:grid="true"
:nsfw="false"
:attachments="newStatus.files"
:descriptions="newStatus.mediaDescriptions"
:set-media="() => setMedia()"
:editable="true"
:edit-attachment="editAttachment"
:remove-attachment="removeMediaFile"
:shift-up-attachment="newStatus.files.length > 1 && shiftUpMediaFile"
:shift-dn-attachment="newStatus.files.length > 1 && shiftDnMediaFile"
@play="$emit('mediaplay', attachment.id)"
@pause="$emit('mediapause', attachment.id)"
/>
<div
v-if="newStatus.files.length > 0 && !disableSensitivityCheckbox"
class="upload_settings"
>
<Checkbox v-model="newStatus.nsfw">
{{ $t('post_status.attachments_sensitive') }}
</Checkbox>
</div>
</form>
<DraftCloser
ref="draftCloser"
@save="saveAndCloseDraft"
@discard="discardAndCloseDraft"
/>
</div>
</template>
<script src="./post_status_form.js"></script>
<style src="./post_status_form.scss" lang="scss"></style>
diff --git a/src/components/post_status_modal/post_status_modal.js b/src/components/post_status_modal/post_status_modal.js
index 0fe51791e2..6011281cf8 100644
--- a/src/components/post_status_modal/post_status_modal.js
+++ b/src/components/post_status_modal/post_status_modal.js
@@ -1,60 +1,61 @@
-import get from 'lodash/get'
+import { get } from 'lodash'
+import { defineAsyncComponent } from 'vue'
-import Modal from '../modal/modal.vue'
-import PostStatusForm from '../post_status_form/post_status_form.vue'
+import Modal from 'src/components/modal/modal.vue'
+import PostStatusForm from 'src/components/post_status_form/post_status_form.vue'
import { usePostStatusStore } from 'src/stores/post_status.js'
const PostStatusModal = {
components: {
PostStatusForm,
Modal,
},
data() {
return {
resettingForm: false,
}
},
computed: {
isLoggedIn() {
return !!this.$store.state.users.currentUser
},
modalActivated() {
return usePostStatusStore().modalActivated
},
isFormVisible() {
return this.isLoggedIn && !this.resettingForm && this.modalActivated
},
params() {
return usePostStatusStore().params || {}
},
},
watch: {
params(newVal, oldVal) {
if (get(newVal, 'repliedUser.id') !== get(oldVal, 'repliedUser.id')) {
this.resettingForm = true
this.$nextTick(() => {
this.resettingForm = false
})
}
},
isFormVisible(val) {
if (val) {
this.$nextTick(
() => this.$el && this.$el.querySelector('textarea').focus(),
)
}
},
},
methods: {
closeModal() {
usePostStatusStore().closePostStatusModal()
},
resetAndClose() {
usePostStatusStore().resetPostStatusModal()
usePostStatusStore().closePostStatusModal()
},
},
}
export default PostStatusModal
diff --git a/src/components/public_and_external_timeline/public_and_external_timeline.js b/src/components/public_and_external_timeline/public_and_external_timeline.js
index b6e53a4cfa..6dc8df02a1 100644
--- a/src/components/public_and_external_timeline/public_and_external_timeline.js
+++ b/src/components/public_and_external_timeline/public_and_external_timeline.js
@@ -1,22 +1,22 @@
-import Timeline from '../timeline/timeline.vue'
+import Timeline from 'src/components/timeline/timeline.vue'
const PublicAndExternalTimeline = {
components: {
Timeline,
},
computed: {
timeline() {
return this.$store.state.statuses.timelines.publicAndExternal
},
},
created() {
this.$store.dispatch('startFetchingTimeline', {
timeline: 'publicAndExternal',
})
},
unmounted() {
this.$store.dispatch('stopFetchingTimeline', 'publicAndExternal')
},
}
export default PublicAndExternalTimeline
diff --git a/src/components/public_timeline/public_timeline.js b/src/components/public_timeline/public_timeline.js
index b9d136e29e..bbeae47af1 100644
--- a/src/components/public_timeline/public_timeline.js
+++ b/src/components/public_timeline/public_timeline.js
@@ -1,20 +1,20 @@
-import Timeline from '../timeline/timeline.vue'
+import Timeline from 'src/components/timeline/timeline.vue'
const PublicTimeline = {
components: {
Timeline,
},
computed: {
timeline() {
return this.$store.state.statuses.timelines.public
},
},
created() {
this.$store.dispatch('startFetchingTimeline', { timeline: 'public' })
},
unmounted() {
this.$store.dispatch('stopFetchingTimeline', 'public')
},
}
export default PublicTimeline
diff --git a/src/components/quick_filter_settings/quick_filter_settings.js b/src/components/quick_filter_settings/quick_filter_settings.js
index 4127f3f309..6c27f7e0a7 100644
--- a/src/components/quick_filter_settings/quick_filter_settings.js
+++ b/src/components/quick_filter_settings/quick_filter_settings.js
@@ -1,137 +1,137 @@
import { mapState } from 'pinia'
-import Popover from '../popover/popover.vue'
+import Popover from 'src/components/popover/popover.vue'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useLocalConfigStore } from 'src/stores/local_config.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faFilter, faFont, faWrench } from '@fortawesome/free-solid-svg-icons'
library.add(faFilter, faFont, faWrench)
const QuickFilterSettings = {
props: {
conversation: Boolean,
nested: Boolean,
},
components: {
Popover,
},
methods: {
setReplyVisibility(visibility) {
useSyncConfigStore().setSimplePrefAndSave({
path: 'replyVisibility',
value: visibility,
})
this.$store.dispatch('queueFlushAll')
},
openTab(tab) {
useInterfaceStore().openSettingsModalTab(tab)
},
},
computed: {
...mapState(useMergedConfigStore, ['mergedConfig']),
...mapState(useInterfaceStore, {
mobileLayout: (state) => state.layoutType === 'mobile',
}),
triggerAttrs() {
if (this.mobileLayout) {
return {}
} else {
return {
title: this.$t('timeline.quick_filter_settings'),
}
}
},
mainClass() {
if (this.mobileLayout) {
return 'main-button'
} else {
return 'dropdown-item'
}
},
loggedIn() {
return !!this.$store.state.users.currentUser
},
replyVisibilitySelf: {
get() {
return this.mergedConfig.replyVisibility === 'self'
},
set() {
this.setReplyVisibility('self')
},
},
replyVisibilityFollowing: {
get() {
return this.mergedConfig.replyVisibility === 'following'
},
set() {
this.setReplyVisibility('following')
},
},
replyVisibilityAll: {
get() {
return this.mergedConfig.replyVisibility === 'all'
},
set() {
this.setReplyVisibility('all')
},
},
hideMedia: {
get() {
return (
this.mergedConfig.hideAttachments ||
this.mergedConfig.hideAttachmentsInConv
)
},
set(value) {
useLocalConfigStore().set({
path: 'hideAttachments',
value,
})
useLocalConfigStore().set({
path: 'hideAttachmentsInConv',
value,
})
},
},
hideMutedPosts: {
get() {
return this.mergedConfig.hideFilteredStatuses
},
set(value) {
useSyncConfigStore().setSimplePrefAndSave({
path: 'hideFilteredStatuses',
value,
})
},
},
muteBotStatuses: {
get() {
return this.mergedConfig.muteBotStatuses
},
set(value) {
useSyncConfigStore().setSimplePrefAndSave({
path: 'muteBotStatuses',
value,
})
},
},
muteSensitiveStatuses: {
get() {
return this.mergedConfig.muteSensitiveStatuses
},
set(value) {
useSyncConfigStore().setSimplePrefAndSave({
path: 'muteSensitiveStatuses',
value,
})
},
},
},
}
export default QuickFilterSettings
diff --git a/src/components/quote/quote.js b/src/components/quote/quote.js
index 168d5094de..3b771b3f28 100644
--- a/src/components/quote/quote.js
+++ b/src/components/quote/quote.js
@@ -1,101 +1,99 @@
import { defineAsyncComponent } from 'vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faCircleNotch } from '@fortawesome/free-solid-svg-icons'
library.add(faCircleNotch)
export default {
- components: {
- Status: defineAsyncComponent(() => import('../status/status.vue')),
- },
+ components: {},
name: 'Quote',
props: {
visible: {
type: Boolean,
},
loading: {
type: Boolean,
},
statusId: {
type: String,
},
statusUrl: {
type: String,
},
statusVisible: {
type: Boolean,
},
initiallyExpanded: {
type: Boolean,
},
},
data() {
return {
displayQuote: this.initiallyExpanded,
fetchAttempted: false,
fetching: false,
error: null,
}
},
created() {
this.maybeFetchStatus()
},
watch: {
statusId() {
this.maybeFetchStatus()
},
},
computed: {
quotedStatus() {
return this.statusId
? this.$store.state.statuses.allStatusesObject[this.statusId]
: undefined
},
shouldDisplayQuote() {
return this.displayQuote && this.quotedStatus
},
hasVisibleQuote() {
return (
this.statusUrl &&
this.statusVisible &&
(this.showSpinner || this.quotedStatus)
)
},
hasInvisibleQuote() {
return this.statusUrl && !this.statusVisible
},
showSpinner() {
return this.loading || this.fetching
},
},
methods: {
toggleDisplayQuote() {
this.displayQuote = !this.displayQuote
this.maybeFetchStatus()
},
maybeFetchStatus() {
if (this.statusId && this.displayQuote && !this.quotedStatus) {
this.fetchStatus()
}
},
fetchStatus() {
this.fetchAttempted = true
this.fetching = true
this.$emit('loading', true)
this.$store
.dispatch('fetchStatus', this.statusId)
.then(() => {
this.displayQuote = true
})
.catch((error) => {
this.error = error
this.$emit('error', error)
})
.finally(() => {
this.fetching = false
this.$emit('loading', false)
})
},
},
}
diff --git a/src/components/quote/quote_form.js b/src/components/quote/quote_form.js
index 4f580be444..cffae123bc 100644
--- a/src/components/quote/quote_form.js
+++ b/src/components/quote/quote_form.js
@@ -1,120 +1,120 @@
import { debounce } from 'lodash'
-import Checkbox from '../checkbox/checkbox.vue'
+import Checkbox from 'src/components/checkbox/checkbox.vue'
import Quote from './quote.vue'
import { useInstanceStore } from 'src/stores/instance.js'
export default {
components: {
Quote,
Checkbox,
},
name: 'QuoteForm',
props: {
visible: {
type: Boolean,
},
url: {
type: String,
required: false,
default: '',
},
id: {
type: String,
required: false,
default: '',
},
},
data() {
return {
text: this.url,
loading: false,
error: false,
debounceSetQuote: debounce((value) => {
this.fetchStatus(value)
}, 1000),
}
},
created() {
if (this.url && !this.id) {
this.fetchStatus(this.url)
} else if (this.id) {
this.text =
window.location.protocol +
'//' +
this.instanceHost +
'/notice/' +
this.id
}
},
computed: {
instanceHost() {
return new URL(useInstanceStore().server).host
},
noticeRegex() {
return new RegExp(
`^([^/:]*:?//|)(${window.location.host}|${this.instanceHost})/notice/(.*)$`,
)
},
quoteVisible() {
return (!!this.id || this.loading) && !this.error
},
},
watch: {
text(value) {
this.debounceSetQuote(value)
this.$emit('update:url', value)
},
visible(value) {
if (value && this.url) {
this.fetchStatus(this.url)
}
},
},
methods: {
clear() {
this.text = this.url
this.loading = false
this.error = false
},
setLoading(value) {
this.loading = value
},
handleError(error) {
this.id = null
this.error = !!error
},
fetchStatus(value) {
this.error = false
const notice = this.noticeRegex.exec(value)
if (notice && notice.length === 4) {
this.$emit('update:id', notice[3])
} else if (value) {
this.loading = true
this.$store
.dispatch('search', {
q: value,
resolve: true,
offset: 0,
limit: 1,
type: 'statuses',
})
.then((data) => {
if (data && data.statuses && data.statuses.length === 1) {
this.$emit('update:id', data.statuses[0].id)
} else {
this.handleError(true)
}
})
.catch(this.handleError)
.finally(() => {
this.loading = false
})
} else {
this.$emit('update:id', null)
}
},
},
}
diff --git a/src/components/quotes_timeline/quotes_timeline.js b/src/components/quotes_timeline/quotes_timeline.js
index b9b3e8f104..f92f109be6 100644
--- a/src/components/quotes_timeline/quotes_timeline.js
+++ b/src/components/quotes_timeline/quotes_timeline.js
@@ -1,36 +1,36 @@
-import Timeline from '../timeline/timeline.vue'
+import Timeline from 'src/components/timeline/timeline.vue'
const QuotesTimeline = {
created() {
this.$store.commit('clearTimeline', { timeline: 'quotes' })
this.$store.dispatch('startFetchingTimeline', {
timeline: 'quotes',
statusId: this.statusId,
})
},
components: {
Timeline,
},
computed: {
statusId() {
return this.$route.params.id
},
timeline() {
return this.$store.state.statuses.timelines.quotes
},
},
watch: {
statusId() {
this.$store.commit('clearTimeline', { timeline: 'quotes' })
this.$store.dispatch('startFetchingTimeline', {
timeline: 'quotes',
statusId: this.statusId,
})
},
},
unmounted() {
this.$store.dispatch('stopFetchingTimeline', 'quotes')
},
}
export default QuotesTimeline
diff --git a/src/components/registration/registration.js b/src/components/registration/registration.js
index 9058963c66..60f0fd16bb 100644
--- a/src/components/registration/registration.js
+++ b/src/components/registration/registration.js
@@ -1,162 +1,162 @@
import useVuelidate from '@vuelidate/core'
import { required, requiredIf, sameAs } from '@vuelidate/validators'
import { mapState as mapPiniaState } from 'pinia'
import { mapActions, mapState } from 'vuex'
+import InterfaceLanguageSwitcher from 'src/components/interface_language_switcher/interface_language_switcher.vue'
+import TermsOfServicePanel from 'src/components/terms_of_service_panel/terms_of_service_panel.vue'
import localeService from '../../services/locale/locale.service.js'
-import InterfaceLanguageSwitcher from '../interface_language_switcher/interface_language_switcher.vue'
-import TermsOfServicePanel from '../terms_of_service_panel/terms_of_service_panel.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { DAY } from 'src/services/date_utils/date_utils.js'
const registration = {
setup() {
return { v$: useVuelidate() }
},
data: () => ({
user: {
email: '',
fullname: '',
username: '',
password: '',
confirm: '',
birthday: '',
reason: '',
language: [''],
},
captcha: {},
}),
components: {
InterfaceLanguageSwitcher,
TermsOfServicePanel,
},
validations() {
return {
user: {
email: { required: requiredIf(() => this.accountActivationRequired) },
username: { required },
fullname: { required },
password: { required },
confirm: {
required,
sameAs: sameAs(this.user.password),
},
birthday: {
required: requiredIf(() => this.birthdayRequired),
maxValue: (value) => {
return (
!this.birthdayRequired ||
new Date(value).getTime() <= this.birthdayMin.getTime()
)
},
},
reason: { required: requiredIf(() => this.accountApprovalRequired) },
language: {},
},
}
},
created() {
if ((!this.registrationOpen && !this.token) || this.signedIn) {
this.$router.push({ name: 'root' })
}
this.setCaptcha()
},
computed: {
token() {
return this.$route.params.token
},
bioPlaceholder() {
return this.replaceNewlines(this.$t('registration.bio_placeholder'))
},
reasonPlaceholder() {
return this.replaceNewlines(this.$t('registration.reason_placeholder'))
},
birthdayMin() {
const minAge = this.birthdayMinAge
const today = new Date()
today.setUTCMilliseconds(0)
today.setUTCSeconds(0)
today.setUTCMinutes(0)
today.setUTCHours(0)
const minDate = new Date()
minDate.setTime(today.getTime() - minAge * DAY)
return minDate
},
birthdayMinAttr() {
return this.birthdayMin.toJSON().replace(/T.+$/, '')
},
birthdayMinFormatted() {
const browserLocale = localeService.internalToBrowserLocale(
this.$i18n.locale,
)
return (
this.user.birthday &&
new Date(Date.parse(this.birthdayMin)).toLocaleDateString(
browserLocale,
{ timeZone: 'UTC', day: 'numeric', month: 'long', year: 'numeric' },
)
)
},
...mapPiniaState(useInstanceStore, {
registrationOpen: (store) => store.registrationOpen,
embeddedToS: (store) => store.embeddedToS,
termsOfService: (store) => store.tos,
accountActivationRequired: (store) => store.accountActivationRequired,
accountApprovalRequired: (store) => store.accountApprovalRequired,
birthdayRequired: (store) => store.birthdayRequired,
birthdayMinAge: (store) => store.birthdayMinAge,
}),
...mapState({
signedIn: (state) => !!state.users.currentUser,
isPending: (state) => state.users.signUpPending,
serverValidationErrors: (state) => state.users.signUpErrors,
signUpNotice: (state) => state.users.signUpNotice,
hasSignUpNotice: (state) => !!state.users.signUpNotice.message,
}),
},
methods: {
...mapActions(['signUp', 'getCaptcha']),
async submit() {
this.user.nickname = this.user.username
this.user.token = this.token
this.user.captcha_solution = this.captcha.solution
this.user.captcha_token = this.captcha.token
this.user.captcha_answer_data = this.captcha.answer_data
if (this.user.language) {
this.user.language = localeService.internalToBackendLocaleMulti(
this.user.language.filter((k) => k),
)
}
this.v$.$touch()
if (!this.v$.$invalid) {
try {
const status = await this.signUp(this.user)
if (status === 'ok') {
this.$router.push({ name: 'friends' })
}
// If status is not 'ok' (i.e. it needs further actions to be done
// before you can login), display sign up notice, do not switch anywhere
} catch (error) {
console.warn('Registration failed: ', error)
this.setCaptcha()
}
}
},
setCaptcha() {
this.getCaptcha().then((cpt) => {
this.captcha = cpt
})
},
replaceNewlines(str) {
return str.replace(/\s*\n\s*/g, ' \n')
},
},
}
export default registration
diff --git a/src/components/remove_follower_button/remove_follower_button.js b/src/components/remove_follower_button/remove_follower_button.js
index bd5aa6d5b4..cbe92dce16 100644
--- a/src/components/remove_follower_button/remove_follower_button.js
+++ b/src/components/remove_follower_button/remove_follower_button.js
@@ -1,52 +1,54 @@
-import ConfirmModal from '../confirm_modal/confirm_modal.vue'
+import { defineAsyncComponent } from 'vue'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
export default {
props: ['user', 'relationship'],
data() {
return {
inProgress: false,
showingConfirmRemoveFollower: false,
}
},
components: {
- ConfirmModal,
+ ConfirmModal: defineAsyncComponent(
+ () => import('src/components/confirm_modal/confirm_modal.vue'),
+ ),
},
computed: {
label() {
if (this.inProgress) {
return this.$t('user_card.follow_progress')
} else {
return this.$t('user_card.remove_follower')
}
},
shouldConfirmRemoveUserFromFollowers() {
return useMergedConfigStore().mergedConfig.modalOnRemoveUserFromFollowers
},
},
methods: {
showConfirmRemoveUserFromFollowers() {
this.showingConfirmRemoveFollower = true
},
hideConfirmRemoveUserFromFollowers() {
this.showingConfirmRemoveFollower = false
},
onClick() {
if (!this.shouldConfirmRemoveUserFromFollowers) {
this.doRemoveUserFromFollowers()
} else {
this.showConfirmRemoveUserFromFollowers()
}
},
doRemoveUserFromFollowers() {
this.inProgress = true
this.$store
.dispatch('removeUserFromFollowers', this.relationship.id)
.then(() => {
this.inProgress = false
})
this.hideConfirmRemoveUserFromFollowers()
},
},
}
diff --git a/src/components/remove_follower_button/remove_follower_button.vue b/src/components/remove_follower_button/remove_follower_button.vue
index 3054770d9b..93eaf66c49 100644
--- a/src/components/remove_follower_button/remove_follower_button.vue
+++ b/src/components/remove_follower_button/remove_follower_button.vue
@@ -1,35 +1,35 @@
<template>
<button
class="btn button-default follow-button"
:class="{ toggled: inProgress }"
:disabled="inProgress"
:title="$t('user_card.remove_follower')"
@click="onClick"
>
{{ label }}
<teleport to="#modal">
- <confirm-modal
+ <ConfirmModal
v-if="showingConfirmRemoveFollower"
:title="$t('user_card.remove_follower_confirm_title')"
:confirm-text="$t('user_card.remove_follower_confirm_accept_button')"
:cancel-text="$t('user_card.remove_follower_confirm_cancel_button')"
@accepted="doRemoveUserFromFollowers"
@cancelled="hideConfirmRemoveUserFromFollowers"
>
<i18n-t
scope="global"
keypath="user_card.remove_follower_confirm"
tag="span"
>
<template #user>
<span
v-text="user.screen_name_ui"
/>
</template>
</i18n-t>
- </confirm-modal>
+ </ConfirmModal>
</teleport>
</button>
</template>
<script src="./remove_follower_button.js"></script>
diff --git a/src/components/report/report.js b/src/components/report/report.js
index fcfb83c3a9..e9d14c515f 100644
--- a/src/components/report/report.js
+++ b/src/components/report/report.js
@@ -1,46 +1,44 @@
-import RichContent from 'src/components/rich_content/rich_content.jsx'
-import Select from '../select/select.vue'
-import StatusContent from '../status_content/status_content.vue'
-import Timeago from '../timeago/timeago.vue'
+import Select from 'src/components/select/select.vue'
+import StatusContent from 'src/components/status_content/status_content.vue'
+import Timeago from 'src/components/timeago/timeago.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useReportsStore } from 'src/stores/reports.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
const Report = {
props: ['reportId'],
components: {
Select,
StatusContent,
Timeago,
- RichContent,
},
computed: {
report() {
return useReportsStore().reports[this.reportId] || {}
},
state: {
get: function () {
return this.report.state
},
set: function (val) {
this.setReportState(val)
},
},
},
methods: {
generateUserProfileLink(user) {
return generateProfileLink(
user.id,
user.screen_name,
useInstanceStore().restrictedNicknames,
)
},
setReportState(state) {
return useReportsStore().setReportState({ id: this.report.id, state })
},
},
}
export default Report
diff --git a/src/components/roundness_input/roundness_input.vue b/src/components/roundness_input/roundness_input.vue
index 04b623e86e..caf21763b2 100644
--- a/src/components/roundness_input/roundness_input.vue
+++ b/src/components/roundness_input/roundness_input.vue
@@ -1,49 +1,49 @@
<template>
<div
class="roundness-control style-control"
:class="{ disabled: !present || disabled }"
>
<label
:for="name"
class="label"
:class="{ faint: !present || disabled }"
>
{{ label }}
</label>
<Checkbox
v-if="typeof fallback !== 'undefined'"
:model-value="present"
:disabled="disabled"
class="opt"
@update:model-value="$emit('update:modelValue', !present ? fallback : undefined)"
/>
<input
:id="name"
class="input input-number"
type="number"
:value="modelValue || fallback"
:disabled="!present || disabled"
:class="{ disabled: !present || disabled }"
max="999"
min="0"
step="1"
@input="$emit('update:modelValue', $event.target.value)"
>
</div>
</template>
<script>
-import Checkbox from '../checkbox/checkbox.vue'
+import Checkbox from 'src/components/checkbox/checkbox.vue'
export default {
components: {
Checkbox,
},
props: ['name', 'label', 'modelValue', 'fallback', 'disabled'],
emits: ['update:modelValue'],
computed: {
present() {
return typeof this.modelValue !== 'undefined'
},
},
}
</script>
diff --git a/src/components/search/search.js b/src/components/search/search.js
index b8812d0acd..0a1f779bb9 100644
--- a/src/components/search/search.js
+++ b/src/components/search/search.js
@@ -1,132 +1,130 @@
-import { uniqBy } from 'lodash'
-import map from 'lodash/map'
+import { map, uniqBy } from 'lodash'
+import Conversation from 'src/components/conversation/conversation.vue'
+import FollowCard from 'src/components/follow_card/follow_card.vue'
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
-import Conversation from '../conversation/conversation.vue'
-import FollowCard from '../follow_card/follow_card.vue'
-import Status from '../status/status.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faCircleNotch, faSearch } from '@fortawesome/free-solid-svg-icons'
library.add(faCircleNotch, faSearch)
const Search = {
components: {
FollowCard,
Conversation,
- Status,
+
TabSwitcher,
},
props: ['query'],
data() {
return {
loaded: false,
loading: false,
searchTerm: this.query || '',
userIds: [],
statuses: [],
hashtags: [],
currenResultTab: 'statuses',
statusesOffset: 0,
lastStatusFetchCount: 0,
lastQuery: '',
}
},
computed: {
users() {
return this.userIds.map((userId) => this.$store.getters.findUser(userId))
},
visibleStatuses() {
const allStatusesObject = this.$store.state.statuses.allStatusesObject
return this.statuses.filter(
(status) =>
allStatusesObject[status.id] && !allStatusesObject[status.id].deleted,
)
},
},
mounted() {
this.search(this.query)
},
watch: {
query(newValue) {
this.searchTerm = newValue
this.search(newValue)
},
},
methods: {
newQuery(query) {
this.$router.push({ name: 'search', query: { query } })
this.$refs.searchInput.focus()
},
search(query, searchType = null) {
if (!query) {
this.loading = false
return
}
this.loading = true
this.$refs.searchInput.blur()
if (this.lastQuery !== query) {
this.userIds = []
this.hashtags = []
this.statuses = []
this.statusesOffset = 0
this.lastStatusFetchCount = 0
}
this.$store
.dispatch('search', {
q: query,
resolve: true,
offset: this.statusesOffset,
type: searchType,
})
.then((data) => {
this.loading = false
const oldLength = this.statuses.length
// Always append to old results. If new results are empty, this doesn't change anything
this.userIds = this.userIds.concat(map(data.accounts, 'id'))
this.statuses = uniqBy(this.statuses.concat(data.statuses), 'id')
this.hashtags = this.hashtags.concat(data.hashtags)
this.currenResultTab = this.getActiveTab()
this.loaded = true
// Offset from whatever we already have
this.statusesOffset = this.statuses.length
// Because the amount of new statuses can actually be zero, compare to old lenght instead
this.lastStatusFetchCount = this.statuses.length - oldLength
this.lastQuery = query
})
},
resultCount(tabName) {
const length = this[tabName].length
return length === 0 ? '' : ` (${length})`
},
onResultTabSwitch(key) {
this.currenResultTab = key
},
getActiveTab() {
if (this.visibleStatuses.length > 0) {
return 'statuses'
} else if (this.users.length > 0) {
return 'people'
} else if (this.hashtags.length > 0) {
return 'hashtags'
}
return 'statuses'
},
lastHistoryRecord(hashtag) {
return hashtag.history && hashtag.history[0]
},
},
}
export default Search
diff --git a/src/components/selectable_list/selectable_list.js b/src/components/selectable_list/selectable_list.js
index b08a3e9a55..b82b3d40c6 100644
--- a/src/components/selectable_list/selectable_list.js
+++ b/src/components/selectable_list/selectable_list.js
@@ -1,66 +1,66 @@
-import Checkbox from '../checkbox/checkbox.vue'
-import List from '../list/list.vue'
+import Checkbox from 'src/components/checkbox/checkbox.vue'
+import List from 'src/components/list/list.vue'
const SelectableList = {
components: {
List,
Checkbox,
},
props: {
items: {
type: Array,
default: () => [],
},
getKey: {
type: Function,
default: (item) => item.id,
},
},
data() {
return {
selected: [],
}
},
computed: {
allKeys() {
return this.items.map(this.getKey)
},
filteredSelected() {
return this.allKeys.filter((key) => this.selected.indexOf(key) !== -1)
},
allSelected() {
return this.filteredSelected.length === this.items.length
},
noneSelected() {
return this.filteredSelected.length === 0
},
someSelected() {
return !this.allSelected && !this.noneSelected
},
},
methods: {
isSelected(item) {
return this.filteredSelected.indexOf(this.getKey(item)) !== -1
},
toggle(checked, item) {
const key = this.getKey(item)
const oldChecked = this.isSelected(key)
if (checked !== oldChecked) {
if (checked) {
this.selected.push(key)
} else {
this.selected.splice(this.selected.indexOf(key), 1)
}
}
},
toggleAll(value) {
if (value) {
this.selected = this.allKeys.slice(0)
} else {
this.selected = []
}
},
},
}
export default SelectableList
diff --git a/src/components/settings_modal/admin_tabs/emoji_tab.js b/src/components/settings_modal/admin_tabs/emoji_tab.js
index 78f71934bb..98c0cb4674 100644
--- a/src/components/settings_modal/admin_tabs/emoji_tab.js
+++ b/src/components/settings_modal/admin_tabs/emoji_tab.js
@@ -1,314 +1,317 @@
import Checkbox from 'components/checkbox/checkbox.vue'
-import ConfirmModal from 'components/confirm_modal/confirm_modal.vue'
import Popover from 'components/popover/popover.vue'
import Select from 'components/select/select.vue'
import StillImage from 'components/still-image/still-image.vue'
import { assign, clone } from 'lodash'
+import { defineAsyncComponent } from 'vue'
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
import EmojiEditingPopover from '../helpers/emoji_editing_popover.vue'
import ModifiedIndicator from '../helpers/modified_indicator.vue'
import SharedComputedObject from '../helpers/shared_computed_object.js'
import StringSetting from '../helpers/string_setting.vue'
import { useEmojiStore } from 'src/stores/emoji.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faArrowsRotate,
faDownload,
faFolderOpen,
faServer,
} from '@fortawesome/free-solid-svg-icons'
library.add(faArrowsRotate, faFolderOpen, faDownload, faServer)
const EmojiTab = {
components: {
TabSwitcher,
StringSetting,
Checkbox,
StillImage,
Select,
Popover,
- ConfirmModal,
+ ConfirmModal: defineAsyncComponent(
+ () => import('src/components/confirm_modal/confirm_modal.vue'),
+ ),
+
ModifiedIndicator,
EmojiEditingPopover,
},
data() {
return {
knownLocalPacks: {},
knownRemotePacks: {},
editedMetadata: {},
packName: '',
newPackName: '',
deleteModalVisible: false,
remotePackInstance: '',
remotePackDownloadAs: '',
remotePackURL: '',
remotePackFile: null,
}
},
provide() {
return { emojiAddr: this.emojiAddr }
},
computed: {
...SharedComputedObject(),
pack() {
return this.packName !== '' ? this.knownPacks[this.packName] : undefined
},
packMeta() {
if (this.packName === '') return {}
if (this.editedMetadata[this.packName] === undefined) {
this.editedMetadata[this.packName] = clone(this.pack.pack)
}
return this.editedMetadata[this.packName]
},
knownPacks() {
// Copy the object itself but not the children, so they are still passed by reference and modified
const result = clone(this.knownLocalPacks)
for (const instName in this.knownRemotePacks) {
for (const instPack in this.knownRemotePacks[instName]) {
result[`${instPack}@${instName}`] =
this.knownRemotePacks[instName][instPack]
}
}
return result
},
downloadWillReplaceLocal() {
return (
(this.remotePackDownloadAs.trim() === '' &&
this.pack.remote &&
this.pack.remote.baseName in this.knownLocalPacks) ||
this.remotePackDownloadAs in this.knownLocalPacks
)
},
},
methods: {
reloadEmoji() {
this.$store.state.api.backendInteractor.reloadEmoji()
},
importFromFS() {
this.$store.state.api.backendInteractor.importEmojiFromFS()
},
emojiAddr(name) {
if (this.pack.remote !== undefined) {
// Remote pack
return `${this.pack.remote.instance}/emoji/${encodeURIComponent(this.pack.remote.baseName)}/${name}`
} else {
return `${useInstanceStore().server}/emoji/${encodeURIComponent(this.packName)}/${name}`
}
},
createEmojiPack() {
this.$store.state.api.backendInteractor
.createEmojiPack({ name: this.newPackName })
.then((resp) => resp.json())
.then((resp) => {
if (resp === 'ok') {
return this.refreshPackList()
} else {
this.displayError(resp.error)
return Promise.reject(resp)
}
})
.then(() => {
this.packName = this.newPackName
this.newPackName = ''
})
},
deleteEmojiPack() {
this.$store.state.api.backendInteractor
.deleteEmojiPack({ name: this.packName })
.then((resp) => resp.json())
.then((resp) => {
if (resp === 'ok') {
return this.refreshPackList()
} else {
this.displayError(resp.error)
return Promise.reject(resp)
}
})
.then(() => {
delete this.editedMetadata[this.packName]
this.deleteModalVisible = false
this.packName = ''
})
},
metaEdited(prop) {
if (!this.pack) return
const def = this.pack.pack[prop] || ''
const edited = this.packMeta[prop] || ''
return edited !== def
},
savePackMetadata() {
this.$store.state.api.backendInteractor
.saveEmojiPackMetadata({ name: this.packName, newData: this.packMeta })
.then((resp) => resp.json())
.then((resp) => {
if (resp.error !== undefined) {
this.displayError(resp.error)
return
}
// Update actual pack data
this.pack.pack = resp
// Delete edited pack data, should auto-update itself
delete this.editedMetadata[this.packName]
})
},
updatePackFiles(newFiles, packName) {
this.knownPacks[packName].files = newFiles
this.sortPackFiles(packName)
},
refreshPackList() {
useEmojiStore()
.getAdminPacks(
this.remotePackInstance,
this.$store.state.api.backendInteractor.listEmojiPacks,
)
.then((allPacks) => {
this.knownLocalPacks = allPacks
for (const name of Object.keys(this.knownLocalPacks)) {
this.sortPackFiles(name)
}
})
},
listRemotePacks() {
useEmojiStore()
.getAdminPacks(
this.remotePackInstance,
this.$store.state.api.backendInteractor.listRemoteEmojiPacks,
)
.then((allPacks) => {
let inst = this.remotePackInstance
if (!inst.startsWith('http')) {
inst = 'https://' + inst
}
const instUrl = new URL(inst)
inst = instUrl.host
for (const packName in allPacks) {
allPacks[packName].remote = {
baseName: packName,
instance: instUrl.origin,
}
}
this.knownRemotePacks[inst] = allPacks
for (const pack in this.knownRemotePacks[inst]) {
this.sortPackFiles(`${pack}@${inst}`)
}
})
.catch((data) => {
this.displayError(data)
})
},
downloadRemotePack() {
if (this.remotePackDownloadAs.trim() === '') {
this.remotePackDownloadAs = this.pack.remote.baseName
}
this.$store.state.api.backendInteractor
.downloadRemoteEmojiPack({
instance: this.pack.remote.instance,
packName: this.pack.remote.baseName,
as: this.remotePackDownloadAs,
})
.then((data) => data.json())
.then((resp) => {
if (resp === 'ok') {
return this.refreshPackList()
} else {
this.displayError(resp.error)
return Promise.reject(resp)
}
})
.then(() => {
this.packName = this.remotePackDownloadAs
this.remotePackDownloadAs = ''
})
},
downloadRemoteURLPack() {
this.$store.state.api.backendInteractor
.downloadRemoteEmojiPackZIP({
url: this.remotePackURL,
packName: this.newPackName,
})
.then((data) => data.json())
.then((resp) => {
if (resp === 'ok') {
return this.refreshPackList()
} else {
this.displayError(resp.error)
return Promise.reject(resp)
}
})
.then(() => {
this.packName = this.newPackName
this.newPackName = ''
this.remotePackURL = ''
})
},
downloadRemoteFilePack() {
this.$store.state.api.backendInteractor
.downloadRemoteEmojiPackZIP({
file: this.remotePackFile[0],
packName: this.newPackName,
})
.then((data) => data.json())
.then((resp) => {
if (resp === 'ok') {
return this.refreshPackList()
} else {
this.displayError(resp.error)
return Promise.reject(resp)
}
})
.then(() => {
this.packName = this.newPackName
this.newPackName = ''
this.remotePackURL = ''
})
},
displayError(msg) {
useInterfaceStore().pushGlobalNotice({
messageKey: 'admin_dash.emoji.error',
messageArgs: [msg],
level: 'error',
})
},
sortPackFiles(nameOfPack) {
// Sort by key
const sorted = Object.keys(this.knownPacks[nameOfPack].files)
.sort()
.reduce((acc, key) => {
if (key.length === 0) return acc
acc[key] = this.knownPacks[nameOfPack].files[key]
return acc
}, {})
this.knownPacks[nameOfPack].files = sorted
},
},
mounted() {
this.refreshPackList()
},
}
export default EmojiTab
diff --git a/src/components/settings_modal/helpers/emoji_editing_popover.vue b/src/components/settings_modal/helpers/emoji_editing_popover.vue
index 9fdcdd2338..7078d24882 100644
--- a/src/components/settings_modal/helpers/emoji_editing_popover.vue
+++ b/src/components/settings_modal/helpers/emoji_editing_popover.vue
@@ -1,333 +1,340 @@
<template>
<Popover
ref="emojiPopover"
trigger="click"
:placement="placement"
bound-to-selector=".emoji-list"
popover-class="emoji-tab-edit-popover popover-default"
:bound-to="{ x: 'container' }"
:offset="{ y: 5 }"
:class="{'emoji-unsaved': isEdited}"
>
<template #trigger>
<slot name="trigger" />
</template>
<template #content>
<h3>
{{ title }}
</h3>
<StillImage
v-if="emojiPreview"
class="emoji"
:src="emojiPreview"
/>
<div
v-else
class="emoji"
/>
<div
v-if="newUpload"
class="emoji-tab-popover-new-upload"
>
<h4>{{ $t('admin_dash.emoji.emoji_source') }}</h4>
<div class="emoji-tab-popover-input">
<input
type="file"
accept="image/*"
class="emoji-tab-popover-file input"
@change="uploadFile = $event.target.files"
>
</div>
<div class="emoji-tab-popover-input ">
<input
v-model="uploadURL"
:placeholder="$t('admin_dash.emoji.upload_url')"
class="emoji-data-input input"
>
</div>
</div>
<div>
<div class="emoji-tab-popover-input">
<label>
{{ $t('admin_dash.emoji.shortcode') }}
<input
v-model="editedShortcode"
class="emoji-data-input input"
:placeholder="$t('admin_dash.emoji.new_shortcode')"
>
</label>
</div>
<div class="emoji-tab-popover-input">
<label>
{{ $t('admin_dash.emoji.filename') }}
<input
v-model="editedFile"
class="emoji-data-input input"
:placeholder="$t('admin_dash.emoji.new_filename')"
>
</label>
</div>
<div
v-if="remote !== undefined"
class="emoji-tab-popover-input"
>
<label>
{{ $t('admin_dash.emoji.copy_to') }}
<SelectComponent
v-model="copyToPack"
class="form-control"
>
<option
value=""
disabled
hidden
>
{{ $t('admin_dash.emoji.emoji_pack') }}
</option>
<option
v-for="(pack, listPackName) in knownLocalPacks"
:key="listPackName"
:label="listPackName"
>
{{ listPackName }}
</option>
</SelectComponent>
</label>
</div>
<!--
For local emojis, disable the button if nothing was edited.
For remote emojis, also disable it if a local pack is not selected.
Remote emojis are processed by the same function that uploads new ones, as that is effectively what it does
-->
<button
class="button button-default btn"
type="button"
:disabled="saveButtonDisabled"
@click="(newUpload || remote !== undefined) ? uploadEmoji() : saveEditedEmoji()"
>
{{ $t('admin_dash.emoji.save') }}
</button>
<template v-if="!newUpload && remote === undefined">
<button
class="button button-default btn emoji-tab-popover-button"
type="button"
@click="deleteModalVisible = true"
>
{{ $t('admin_dash.emoji.delete') }}
</button>
<button
class="button button-default btn emoji-tab-popover-button"
type="button"
@click="revertEmoji"
>
{{ $t('admin_dash.emoji.revert') }}
</button>
<ConfirmModal
v-if="deleteModalVisible"
:title="$t('admin_dash.emoji.delete_title')"
:cancel-text="$t('status.delete_confirm_cancel_button')"
:confirm-text="$t('status.delete_confirm_accept_button')"
@cancelled="deleteModalVisible = false"
@accepted="deleteEmoji"
>
{{ $t('admin_dash.emoji.delete_confirm', [shortcode]) }}
</ConfirmModal>
</template>
</div>
</template>
</Popover>
</template>
<script>
-import ConfirmModal from 'components/confirm_modal/confirm_modal.vue'
import Popover from 'components/popover/popover.vue'
import SelectComponent from 'components/select/select.vue'
-import StillImage from 'components/still-image/still-image.vue'
+import { defineAsyncComponent } from 'vue'
export default {
- components: { Popover, ConfirmModal, StillImage, SelectComponent },
+ components: {
+ Popover,
+ ConfirmModal: defineAsyncComponent(
+ () => import('src/components/confirm_modal/confirm_modal.vue'),
+ ),
+
+ SelectComponent,
+ },
+
inject: ['emojiAddr'],
props: {
placement: {
type: String,
required: true,
},
newUpload: Boolean,
title: {
type: String,
required: true,
},
packName: {
type: String,
required: true,
},
shortcode: {
type: String,
// Only exists when this is not a new upload
default: '',
},
file: {
type: String,
// Only exists when this is not a new upload
default: '',
},
// Only exists for emojis from remote packs
remote: {
type: Object,
default: undefined,
},
knownLocalPacks: {
type: Object,
default: undefined,
},
},
emits: ['updatePackFiles', 'displayError'],
data() {
return {
uploadFile: [],
uploadURL: '',
editedShortcode: this.shortcode,
editedFile: this.file,
deleteModalVisible: false,
copyToPack: '',
}
},
computed: {
emojiPreview() {
if (this.newUpload && this.uploadFile.length > 0) {
return URL.createObjectURL(this.uploadFile[0])
} else if (this.newUpload && this.uploadURL !== '') {
return this.uploadURL
} else if (!this.newUpload) {
return this.emojiAddr(this.file)
}
return null
},
isEdited() {
return (
!this.newUpload &&
(this.editedShortcode !== this.shortcode ||
this.editedFile !== this.file)
)
},
saveButtonDisabled() {
if (this.remote === undefined)
return this.newUpload
? this.uploadURL === '' && this.uploadFile.length == 0
: !this.isEdited
else return this.copyToPack === ''
},
},
methods: {
saveEditedEmoji() {
if (!this.isEdited) return
this.$store.state.api.backendInteractor
.updateEmojiFile({
packName: this.packName,
shortcode: this.shortcode,
newShortcode: this.editedShortcode,
newFilename: this.editedFile,
force: false,
})
.then((resp) => {
if (resp.error !== undefined) {
this.$emit('displayError', resp.error)
return Promise.reject(resp.error)
}
return resp.json()
})
.then((resp) => this.$emit('updatePackFiles', resp))
},
uploadEmoji() {
let packName = this.remote === undefined ? this.packName : this.copyToPack
this.$store.state.api.backendInteractor
.addNewEmojiFile({
packName: packName,
file:
this.remote === undefined
? this.uploadURL !== ''
? this.uploadURL
: this.uploadFile[0]
: this.emojiAddr(this.file),
shortcode: this.editedShortcode,
filename: this.editedFile,
})
.then((resp) => resp.json())
.then((resp) => {
if (resp.error !== undefined) {
this.$emit('displayError', resp.error)
return
}
this.$emit('updatePackFiles', resp, packName)
this.$refs.emojiPopover.hidePopover()
this.editedFile = ''
this.editedShortcode = ''
this.uploadFile = []
})
},
revertEmoji() {
this.editedFile = this.file
this.editedShortcode = this.shortcode
},
deleteEmoji() {
this.deleteModalVisible = false
this.$store.state.api.backendInteractor
.deleteEmojiFile({ packName: this.packName, shortcode: this.shortcode })
.then((resp) => resp.json())
.then((resp) => {
if (resp.error !== undefined) {
this.$emit('displayError', resp.error)
return
}
this.$emit('updatePackFiles', resp, this.packName)
})
},
},
}
</script>
<style lang="scss">
.emoji-tab-edit-popover {
padding-left: 0.5em;
padding-right: 0.5em;
padding-bottom: 0.5em;
.emoji-tab-popover-new-upload {
margin-bottom: 2em;
}
.emoji {
width: 2.3em;
height: 2.3em;
}
.Select {
display: inline-block;
}
h4 {
margin-bottom: 1em;
margin-top: 1em;
}
}
</style>
diff --git a/src/components/settings_modal/settings_modal.js b/src/components/settings_modal/settings_modal.js
index 5c157e068b..e2df79c261 100644
--- a/src/components/settings_modal/settings_modal.js
+++ b/src/components/settings_modal/settings_modal.js
@@ -1,272 +1,275 @@
import { cloneDeep, isEqual } from 'lodash'
import { mapActions, mapState } from 'pinia'
+import { defineAsyncComponent } from 'vue'
import AsyncComponentError from 'src/components/async_component_error/async_component_error.vue'
import Checkbox from 'src/components/checkbox/checkbox.vue'
-import ConfirmModal from 'src/components/confirm_modal/confirm_modal.vue'
import Modal from 'src/components/modal/modal.vue'
import PanelLoading from 'src/components/panel_loading/panel_loading.vue'
-import Popover from '../popover/popover.vue'
+import Popover from 'src/components/popover/popover.vue'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useLocalConfigStore } from 'src/stores/local_config.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
import {
LOCAL_ONLY_KEYS,
ROOT_CONFIG,
ROOT_CONFIG_DEFINITIONS,
validateSetting,
} from 'src/modules/default_config_state.js'
import {
newExporter,
newImporter,
} from 'src/services/export_import/export_import.js'
import getResettableAsyncComponent from 'src/services/resettable_async_component.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faWindowMinimize } from '@fortawesome/free-regular-svg-icons'
import {
faChevronDown,
faFileDownload,
faFileUpload,
faTimes,
} from '@fortawesome/free-solid-svg-icons'
const PLEROMAFE_SETTINGS_MAJOR_VERSION = 1
const PLEROMAFE_SETTINGS_MINOR_VERSION = 0
library.add(
faTimes,
faWindowMinimize,
faFileUpload,
faFileDownload,
faChevronDown,
)
const SettingsModal = {
data() {
return {
dataImporter: newImporter({
validator: this.importValidator,
onImport: this.onImport,
onImportFailure: this.onImportFailure,
}),
dataThemeExporter: newExporter({
filename: 'pleromafe_settings.full',
getExportedObject: () => this.generateExport(true),
}),
dataExporter: newExporter({
filename: 'pleromafe_settings',
getExportedObject: () => this.generateExport(),
}),
}
},
components: {
Modal,
Popover,
Checkbox,
- ConfirmModal,
+ ConfirmModal: defineAsyncComponent(
+ () => import('src/components/confirm_modal/confirm_modal.vue'),
+ ),
+
SettingsModalUserContent: getResettableAsyncComponent(
() => import('./settings_modal_user_content.vue'),
{
loadingComponent: PanelLoading,
errorComponent: AsyncComponentError,
delay: 0,
},
),
SettingsModalAdminContent: getResettableAsyncComponent(
() => import('./settings_modal_admin_content.vue'),
{
loadingComponent: PanelLoading,
errorComponent: AsyncComponentError,
delay: 0,
},
),
},
methods: {
closeModal() {
useInterfaceStore().closeSettingsModal()
},
peekModal() {
useInterfaceStore().togglePeekSettingsModal()
},
importValidator(data) {
if (!Array.isArray(data._pleroma_settings_version)) {
return {
messageKey: 'settings.file_import_export.invalid_file',
}
}
const [major, minor] = data._pleroma_settings_version
if (major > PLEROMAFE_SETTINGS_MAJOR_VERSION) {
return {
messageKey: 'settings.file_export_import.errors.file_too_new',
messageArgs: {
fileMajor: major,
feMajor: PLEROMAFE_SETTINGS_MAJOR_VERSION,
},
}
}
if (major < PLEROMAFE_SETTINGS_MAJOR_VERSION) {
return {
messageKey: 'settings.file_export_import.errors.file_too_old',
messageArgs: {
fileMajor: major,
feMajor: PLEROMAFE_SETTINGS_MAJOR_VERSION,
},
}
}
if (minor > PLEROMAFE_SETTINGS_MINOR_VERSION) {
useInterfaceStore().pushGlobalNotice({
level: 'warning',
messageKey: 'settings.file_export_import.errors.file_slightly_new',
})
}
return true
},
onImportFailure(result) {
if (result.error) {
useInterfaceStore().pushGlobalNotice({
messageKey: 'settings.invalid_settings_imported',
level: 'error',
})
} else {
useInterfaceStore().pushGlobalNotice({
...result.validationResult,
level: 'error',
})
}
},
onImport(input) {
if (!input) return
const { _pleroma_settings_version, ...data } = input
Object.entries(data).forEach(([path, value]) => {
const definition = ROOT_CONFIG_DEFINITIONS[path]
const finalValue = validateSetting({
path,
value,
definition,
throwError: false,
defaultState: ROOT_CONFIG,
})
if (finalValue === undefined) return
if (LOCAL_ONLY_KEYS.has(path)) {
useLocalConfigStore().set({ path, value: finalValue })
} else {
if (path.startsWith('muteFilters')) {
Object.keys(
useMergedConfigStore().mergedConfig.muteFilters,
).forEach((key) => {
useSyncConfigStore().unsetPreference({
path: `simple.${path}.${key}`,
})
})
Object.entries(value).forEach(([key, filter]) => {
useSyncConfigStore().setPreference({
path: `simple.${path}.${key}`,
value: filter,
})
})
} else {
if (finalValue !== undefined) {
useSyncConfigStore().setPreference({
path: `simple.${path}`,
value: finalValue,
})
}
}
}
})
useSyncConfigStore().pushSyncConfig()
},
restore() {
this.dataImporter.importData()
},
backup() {
this.dataExporter.exportData()
},
backupWithTheme() {
this.dataThemeExporter.exportData()
},
generateExport(theme = false) {
const config = useMergedConfigStore().mergedConfigWithoutDefaults
let sample = config
if (!theme) {
const ignoreList = new Set([
'theme',
'customTheme',
'customThemeSource',
'colors',
'style',
'styleCustomData',
'palette',
'paletteCustomData',
'themeChecksum',
])
sample = Object.fromEntries(
Object.entries(sample).filter(
([key, value]) => !ignoreList.has(key) && value !== undefined,
),
)
}
const clone = cloneDeep(sample)
clone._pleroma_settings_version = [
PLEROMAFE_SETTINGS_MAJOR_VERSION,
PLEROMAFE_SETTINGS_MINOR_VERSION,
]
return clone
},
resetAdminDraft() {
this.$store.commit('resetAdminDraft')
},
pushAdminDraft() {
this.$store.dispatch('pushAdminDraft')
},
...mapActions(useInterfaceStore, [
'temporaryChangesRevert',
'temporaryChangesConfirm',
]),
},
computed: {
...mapState(useInterfaceStore, {
temporaryChangesCountdown: (store) => store.temporaryChangesCountdown,
currentSaveStateNotice: (store) => store.settings.currentSaveStateNotice,
modalActivated: (store) => store.settingsModalState !== 'hidden',
modalMode: (store) => store.settingsModalMode,
modalOpenedOnceUser: (store) => store.settingsModalLoadedUser,
modalOpenedOnceAdmin: (store) => store.settingsModalLoadedAdmin,
modalPeeked: (store) => store.settingsModalState === 'minimized',
}),
expertLevel: {
get() {
return useMergedConfigStore().mergedConfig.expertLevel > 0
},
set(value) {
useSyncConfigStore().setSimplePrefAndSave({
path: 'expertLevel',
value: value ? 1 : 0,
})
},
},
adminDraftAny() {
return !isEqual(
this.$store.state.adminSettings.config,
this.$store.state.adminSettings.draft,
)
},
},
}
export default SettingsModal
diff --git a/src/components/settings_modal/tabs/mutes_and_blocks_tab.js b/src/components/settings_modal/tabs/mutes_and_blocks_tab.js
index cb198619f4..3b82bbb4c4 100644
--- a/src/components/settings_modal/tabs/mutes_and_blocks_tab.js
+++ b/src/components/settings_modal/tabs/mutes_and_blocks_tab.js
@@ -1,155 +1,153 @@
-import get from 'lodash/get'
-import map from 'lodash/map'
-import reject from 'lodash/reject'
+import { get, map, reject } from 'lodash'
import withLoadMore from 'src/components/../hocs/with_load_more/with_load_more'
import withSubscription from 'src/components/../hocs/with_subscription/with_subscription'
import Autosuggest from 'src/components/autosuggest/autosuggest.vue'
import BlockCard from 'src/components/block_card/block_card.vue'
import Checkbox from 'src/components/checkbox/checkbox.vue'
import DomainMuteCard from 'src/components/domain_mute_card/domain_mute_card.vue'
import MuteCard from 'src/components/mute_card/mute_card.vue'
import ProgressButton from 'src/components/progress_button/progress_button.vue'
import SelectableList from 'src/components/selectable_list/selectable_list.vue'
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
import { useInstanceStore } from 'src/stores/instance.js'
import { useOAuthTokensStore } from 'src/stores/oauth_tokens.js'
const BlockList = withLoadMore({
fetch: (props, $store) => $store.dispatch('fetchBlocks'),
select: (props, $store) =>
get($store.state.users.currentUser, 'blockIds', []),
destroy: () => {
/* no-op */
},
childPropName: 'items',
})(SelectableList)
const MuteList = withLoadMore({
fetch: (props, $store) => $store.dispatch('fetchMutes'),
select: (props, $store) => get($store.state.users.currentUser, 'muteIds', []),
destroy: () => {
/* no-op */
},
childPropName: 'items',
})(SelectableList)
const DomainMuteList = withSubscription({
fetch: (props, $store) => $store.dispatch('fetchDomainMutes'),
select: (props, $store) =>
get($store.state.users.currentUser, 'domainMutes', []),
childPropName: 'items',
})(SelectableList)
const MutesAndBlocks = {
data() {
return {
activeTab: 'profile',
}
},
created() {
useOAuthTokensStore().fetchTokens()
useInstanceStore().getKnownDomains()
},
components: {
TabSwitcher,
BlockList,
MuteList,
DomainMuteList,
BlockCard,
MuteCard,
DomainMuteCard,
ProgressButton,
Autosuggest,
Checkbox,
},
computed: {
knownDomains() {
return useInstanceStore().knownDomains
},
user() {
return this.$store.state.users.currentUser
},
},
methods: {
importFollows(file) {
return this.$store.state.api.backendInteractor
.importFollows({ file })
.then((status) => {
if (!status) {
throw new Error('failed')
}
})
},
importBlocks(file) {
return this.$store.state.api.backendInteractor
.importBlocks({ file })
.then((status) => {
if (!status) {
throw new Error('failed')
}
})
},
generateExportableUsersContent(users) {
// Get addresses
return users
.map((user) => {
// check is it's a local user
if (user && user.is_local) {
// append the instance address
return user.screen_name + '@' + location.hostname
}
return user.screen_name
})
.join('\n')
},
activateTab(tabName) {
this.activeTab = tabName
},
filterUnblockedUsers(userIds) {
return reject(userIds, (userId) => {
const relationship = this.$store.getters.relationship(this.userId)
return relationship.blocking || userId === this.user.id
})
},
filterUnMutedUsers(userIds) {
return reject(userIds, (userId) => {
const relationship = this.$store.getters.relationship(this.userId)
return relationship.muting || userId === this.user.id
})
},
queryUserIds(query) {
return this.$store
.dispatch('searchUsers', { query })
.then((users) => map(users, 'id'))
},
blockUsers(ids) {
return this.$store.dispatch('blockUsers', ids)
},
unblockUsers(ids) {
return this.$store.dispatch('unblockUsers', ids)
},
muteUsers(ids) {
return this.$store.dispatch('muteUsers', ids)
},
unmuteUsers(ids) {
return this.$store.dispatch('unmuteUsers', ids)
},
filterUnMutedDomains(urls) {
return urls.filter((url) => !this.user.domainMutes.includes(url))
},
queryKnownDomains(query) {
return new Promise((resolve) => {
resolve(
this.knownDomains.filter((url) => url.toLowerCase().includes(query)),
)
})
},
unmuteDomains(domains) {
return this.$store.dispatch('unmuteDomains', domains)
},
},
}
export default MutesAndBlocks
diff --git a/src/components/side_drawer/side_drawer.js b/src/components/side_drawer/side_drawer.js
index f2b9f32972..840beeb7c9 100644
--- a/src/components/side_drawer/side_drawer.js
+++ b/src/components/side_drawer/side_drawer.js
@@ -1,134 +1,137 @@
import { mapActions, mapState } from 'pinia'
+import { defineAsyncComponent } from 'vue'
import { mapGetters } from 'vuex'
import { USERNAME_ROUTES } from 'src/components/navigation/navigation.js'
+import UserCard from 'src/components/user_card/user_card.vue'
import GestureService from '../../services/gesture_service/gesture_service'
import { unseenNotificationsFromStore } from '../../services/notification_utils/notification_utils'
-import UserCard from '../user_card/user_card.vue'
import { useAnnouncementsStore } from 'src/stores/announcements'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useInterfaceStore } from 'src/stores/interface'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useShoutStore } from 'src/stores/shout'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faBell,
faBullhorn,
faCog,
faComments,
faCompass,
faFilePen,
faHome,
faInfoCircle,
faList,
faSearch,
faSignInAlt,
faSignOutAlt,
faTachometerAlt,
faUserPlus,
} from '@fortawesome/free-solid-svg-icons'
library.add(
faSignInAlt,
faSignOutAlt,
faHome,
faComments,
faBell,
faUserPlus,
faBullhorn,
faSearch,
faTachometerAlt,
faCog,
faInfoCircle,
faCompass,
faList,
faFilePen,
)
const SideDrawer = {
props: ['logout'],
data: () => ({
closed: true,
closeGesture: undefined,
}),
created() {
this.closeGesture = GestureService.swipeGesture(
GestureService.DIRECTION_LEFT,
this.toggleDrawer,
)
if (this.currentUser && this.currentUser.locked) {
this.$store.dispatch('startFetchingFollowRequests')
}
},
- components: { UserCard },
+ components: {
+ UserCard,
+ },
computed: {
currentUser() {
return this.$store.state.users.currentUser
},
shout() {
return useShoutStore().joined
},
unseenNotifications() {
return unseenNotificationsFromStore(
this.$store,
useMergedConfigStore().mergedConfig.notificationVisibility,
useMergedConfigStore().mergedConfig.ignoreInactionableSeen,
)
},
unseenNotificationsCount() {
return this.unseenNotifications.length
},
followRequestCount() {
return this.$store.state.api.followRequests.length
},
timelinesRoute() {
let name
if (useInterfaceStore().lastTimeline) {
name = useInterfaceStore().lastTimeline
}
name = this.currentUser ? 'friends' : 'public-timeline'
if (USERNAME_ROUTES.has(name)) {
return { name, params: { username: this.currentUser.screen_name } }
} else {
return { name }
}
},
...mapState(useAnnouncementsStore, [
'supportsAnnouncements',
'unreadAnnouncementCount',
]),
...mapState(useInstanceCapabilitiesStore, [
'pleromaChatMessagesAvailable',
'suggestionsEnabled',
]),
...mapState(useInstanceStore, ['privateMode', 'federating']),
...mapState(useInstanceStore, {
logo: (store) => store.instanceIdentity.logo,
sitename: (store) => store.instanceIdentity.name,
hideSitename: (store) => store.instanceIdentity.hideSitename,
}),
...mapGetters(['unreadChatCount', 'draftCount']),
},
methods: {
toggleDrawer() {
this.closed = !this.closed
},
doLogout() {
this.logout()
this.toggleDrawer()
},
touchStart(e) {
GestureService.beginSwipe(e, this.closeGesture)
},
touchMove(e) {
GestureService.updateSwipe(e, this.closeGesture)
},
...mapActions(useInterfaceStore, ['openSettingsModal']),
},
}
export default SideDrawer
diff --git a/src/components/staff_panel/staff_panel.js b/src/components/staff_panel/staff_panel.js
index 3f271f4d3f..b736bb9f95 100644
--- a/src/components/staff_panel/staff_panel.js
+++ b/src/components/staff_panel/staff_panel.js
@@ -1,38 +1,37 @@
-import groupBy from 'lodash/groupBy'
-import map from 'lodash/map'
+import { groupBy, map } from 'lodash'
import { mapGetters, mapState } from 'vuex'
-import BasicUserCard from '../basic_user_card/basic_user_card.vue'
+import BasicUserCard from 'src/components/basic_user_card/basic_user_card.vue'
import { useInstanceStore } from 'src/stores/instance.js'
const StaffPanel = {
created() {
const nicknames = useInstanceStore().staffAccounts
nicknames.forEach((nickname) =>
this.$store.dispatch('fetchUserIfMissing', nickname),
)
},
components: {
BasicUserCard,
},
computed: {
groupedStaffAccounts() {
const staffAccounts = map(this.staffAccounts, this.findUserByName).filter(
(_) => _,
)
const groupedStaffAccounts = groupBy(staffAccounts, 'role')
return [
{ role: 'admin', users: groupedStaffAccounts.admin },
{ role: 'moderator', users: groupedStaffAccounts.moderator },
].filter((group) => group.users)
},
...mapGetters(['findUserByName']),
...mapState({
staffAccounts: (state) => useInstanceStore().staffAccounts,
}),
},
}
export default StaffPanel
diff --git a/src/components/status/status.js b/src/components/status/status.js
index 607b7f04e0..0107bde3cf 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -1,667 +1,667 @@
import { unescape as ldUnescape, uniqBy } from 'lodash'
+import { defineAsyncComponent } from 'vue'
+import AvatarList from 'src/components/avatar_list/avatar_list.vue'
+import EmojiReactions from 'src/components/emoji_reactions/emoji_reactions.vue'
import MentionLink from 'src/components/mention_link/mention_link.vue'
import MentionsLine from 'src/components/mentions_line/mentions_line.vue'
-import RichContent from 'src/components/rich_content/rich_content.jsx'
+import PostStatusForm from 'src/components/post_status_form/post_status_form.vue'
import StatusActionButtons from 'src/components/status_action_buttons/status_action_buttons.vue'
+import StatusContent from 'src/components/status_content/status_content.vue'
+import StatusPopover from 'src/components/status_popover/status_popover.vue'
+import Timeago from 'src/components/timeago/timeago.vue'
+import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
+import UserLink from 'src/components/user_link/user_link.vue'
+import UserListPopover from 'src/components/user_list_popover/user_list_popover.vue'
+import UserPopover from 'src/components/user_popover/user_popover.vue'
import { muteFilterHits } from '../../services/status_parser/status_parser.js'
import {
highlightClass,
highlightStyle,
} from '../../services/user_highlighter/user_highlighter.js'
-import AvatarList from '../avatar_list/avatar_list.vue'
-import EmojiReactions from '../emoji_reactions/emoji_reactions.vue'
-import PostStatusForm from '../post_status_form/post_status_form.vue'
-import Quote from '../quote/quote.vue'
-import StatusContent from '../status_content/status_content.vue'
-import StatusPopover from '../status_popover/status_popover.vue'
-import Timeago from '../timeago/timeago.vue'
-import UserAvatar from '../user_avatar/user_avatar.vue'
-import UserLink from '../user_link/user_link.vue'
-import UserListPopover from '../user_list_popover/user_list_popover.vue'
-import UserPopover from '../user_popover/user_popover.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { useUserHighlightStore } from 'src/stores/user_highlight.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faAngleDoubleRight,
faChevronDown,
faChevronUp,
faEllipsisH,
faEnvelope,
faEye,
faEyeSlash,
faGlobe,
faIgloo,
faLock,
faLockOpen,
faPlay,
faPlusSquare,
faReply,
faRetweet,
faSmileBeam,
faStar,
faThumbtack,
faTimes,
} from '@fortawesome/free-solid-svg-icons'
library.add(
faEnvelope,
faGlobe,
faIgloo,
faLock,
faLockOpen,
faTimes,
faRetweet,
faReply,
faPlusSquare,
faStar,
faSmileBeam,
faEllipsisH,
faEyeSlash,
faEye,
faThumbtack,
faChevronUp,
faChevronDown,
faAngleDoubleRight,
faPlay,
)
const camelCase = (name) => name.charAt(0).toUpperCase() + name.slice(1)
const controlledOrUncontrolledGetters = (list) =>
list.reduce((res, name) => {
const camelized = camelCase(name)
const toggle = `controlledToggle${camelized}`
const controlledName = `controlled${camelized}`
const uncontrolledName = `uncontrolled${camelized}`
res[name] = function () {
return (this.$data[toggle] !== undefined ||
this.$props[toggle] !== undefined) &&
this[toggle]
? this[controlledName]
: this[uncontrolledName]
}
return res
}, {})
const controlledOrUncontrolledToggle = (obj, name) => {
const camelized = camelCase(name)
const toggle = `controlledToggle${camelized}`
const uncontrolledName = `uncontrolled${camelized}`
if (obj[toggle]) {
obj[toggle]()
} else {
obj[uncontrolledName] = !obj[uncontrolledName]
}
}
const controlledOrUncontrolledSet = (obj, name, val) => {
const camelized = camelCase(name)
const set = `controlledSet${camelized}`
const uncontrolledName = `uncontrolled${camelized}`
if (obj[set]) {
obj[set](val)
} else {
obj[uncontrolledName] = val
}
}
const Status = {
name: 'Status',
components: {
PostStatusForm,
UserAvatar,
AvatarList,
Timeago,
StatusPopover,
UserListPopover,
EmojiReactions,
StatusContent,
- RichContent,
MentionLink,
MentionsLine,
UserPopover,
UserLink,
- Quote,
+ Quote: defineAsyncComponent(() => import('src/components/quote/quote.vue')),
StatusActionButtons,
},
props: [
'statusoid',
'replies',
'expandable',
'focused',
'highlight',
'compact',
'isPreview',
'noHeading',
'inlineExpanded',
'showPinned',
'inProfile',
'inConversation',
'inQuote',
'profileUserId',
'simpleTree',
'showOtherRepliesAsButton',
'dive',
'ignoreMute',
'controlledThreadDisplayStatus',
'controlledToggleThreadDisplay',
'controlledShowingTall',
'controlledToggleShowingTall',
'controlledExpandingSubject',
'controlledToggleExpandingSubject',
'controlledShowingLongSubject',
'controlledToggleShowingLongSubject',
'controlledReplying',
'controlledToggleReplying',
'controlledMediaPlaying',
'controlledSetMediaPlaying',
],
emits: ['goto', 'toggleExpanded'],
data() {
return {
uncontrolledReplying: false,
unmuted: false,
userExpanded: false,
uncontrolledMediaPlaying: [],
suspendable: true,
error: null,
headTailLinks: null,
}
},
computed: {
...controlledOrUncontrolledGetters(['replying', 'mediaPlaying']),
showReasonMutedThread() {
return (
(this.status.thread_muted ||
(this.status.reblog && this.status.reblog.thread_muted)) &&
!this.inConversation
)
},
allowNonSquareEmoji() {
return this.mergedConfig.nonSquareEmoji
},
repeaterClass() {
const user = this.statusoid.user
return highlightClass(user)
},
userClass() {
const user = this.retweet
? this.statusoid.retweeted_status.user
: this.statusoid.user
return highlightClass(user)
},
deleted() {
return this.statusoid.deleted
},
repeaterStyle() {
const user = this.statusoid.user
return highlightStyle(useUserHighlightStore().get(user.screen_name))
},
userStyle() {
if (this.noHeading) return
const user = this.retweet
? this.statusoid.retweeted_status.user
: this.statusoid.user
return highlightStyle(useUserHighlightStore().get(user.screen_name))
},
userProfileLink() {
return this.generateUserProfileLink(
this.status.user.id,
this.status.user.screen_name,
)
},
replyProfileLink() {
if (this.isReply) {
const user = this.$store.getters.findUser(
this.status.in_reply_to_user_id,
)
// FIXME Why user not found sometimes???
return user ? user.statusnet_profile_url : 'NOT_FOUND'
}
},
retweet() {
return !!this.statusoid.retweeted_status
},
retweeterUser() {
return this.statusoid.user
},
retweeter() {
return this.statusoid.user.name || this.statusoid.user.screen_name_ui
},
retweeterHtml() {
return this.statusoid.user.name
},
retweeterProfileLink() {
return this.generateUserProfileLink(
this.statusoid.user.id,
this.statusoid.user.screen_name,
)
},
status() {
if (this.retweet) {
return this.statusoid.retweeted_status
} else {
return this.statusoid
}
},
statusFromGlobalRepository() {
// NOTE: Consider to replace status with statusFromGlobalRepository
return this.$store.state.statuses.allStatusesObject[this.status.id]
},
loggedIn() {
return !!this.currentUser
},
muteFilterHits() {
return muteFilterHits(
- Object.values(useSyncConfigStore().prefsStorage.simple.muteFilters || {}),
+ Object.values(
+ useSyncConfigStore().prefsStorage.simple.muteFilters || {},
+ ),
this.status,
)
},
botStatus() {
return this.status.user.actor_type === 'Service'
},
showActorTypeIndicator() {
return !this.hideBotIndication
},
sensitiveStatus() {
return this.status.nsfw
},
mentionsLine() {
if (!this.headTailLinks) return []
const writtenSet = new Set(
this.headTailLinks.writtenMentions.map((_) => _.url),
)
return this.status.attentions
.filter((attn) => {
// no reply user
return (
attn.id !== this.status.in_reply_to_user_id &&
// no self-replies
attn.statusnet_profile_url !==
this.status.user.statusnet_profile_url &&
// don't include if mentions is written
!writtenSet.has(attn.statusnet_profile_url)
)
})
.map((attn) => ({
url: attn.statusnet_profile_url,
content: attn.screen_name,
userId: attn.id,
}))
},
hasMentionsLine() {
return this.mentionsLine.length > 0
},
muteReasons() {
return [
this.userIsMuted ? 'user' : null,
this.status.thread_muted ? 'thread' : null,
this.muteFilterHits.length > 0 ? 'filtered' : null,
this.muteBotStatuses && this.botStatus ? 'bot' : null,
this.muteSensitiveStatuses && this.sensitiveStatus ? 'nsfw' : null,
].filter((_) => _)
},
muteLocalized() {
if (this.muteReasons.length === 0) return null
const mainReason = () => {
switch (this.muteReasons[0]) {
case 'user':
return this.$t('status.muted_user')
case 'thread':
return this.$t('status.thread_muted')
case 'filtered':
return this.$t(
'status.muted_filters',
{
name: this.muteFilterHits[0].name,
filterMore: this.muteFilterHits.length - 1,
},
this.muteFilterHits.length,
)
case 'bot':
return this.$t('status.bot_muted')
case 'nsfw':
return this.$t('status.sensitive_muted')
}
}
if (this.muteReasons.length > 1) {
return this.$t(
'status.multi_reason_mute',
{
main: mainReason(),
numReasonsMore: this.muteReasons.length - 1,
},
this.muteReasons.length - 1,
)
} else {
return mainReason()
}
},
muted() {
if (this.ignoreMute) return false
if (this.statusoid.user.id === this.currentUser.id) return false
return !this.unmuted && !this.shouldNotMute && this.muteReasons.length > 0
},
userIsMuted() {
if (this.statusoid.user.id === this.currentUser.id) return false
const { status } = this
const { reblog } = status
const relationship = this.$store.getters.relationship(status.user.id)
const relationshipReblog =
reblog && this.$store.getters.relationship(reblog.user.id)
return (
(status.muted && !status.thread_muted) ||
// Reprööt of a muted post according to BE
(reblog && reblog.muted && !reblog.thread_muted) ||
// Muted user
relationship.muting ||
// Muted user of a reprööt
(relationshipReblog && relationshipReblog.muting)
)
},
shouldNotMute() {
if (this.ignoreMute) return true
if (this.isFocused) return true
const { status } = this
const { reblog } = status
return (
((this.inProfile &&
// Don't mute user's posts on user timeline (except reblogs)
((!reblog && status.user.id === this.profileUserId) ||
// Same as above but also allow self-reblogs
(reblog && reblog.user.id === this.profileUserId))) ||
// Don't mute statuses in muted conversation when said conversation is opened
(this.inConversation && status.thread_muted)) &&
// No excuses if post has muted words
!this.muteFilterHits.length > 0
)
},
hideMutedUsers() {
return this.mergedConfig.hideMutedPosts
},
hideMutedThreads() {
return this.mergedConfig.hideMutedThreads
},
hideFilteredStatuses() {
return this.mergedConfig.hideFilteredStatuses
},
hideWordFilteredPosts() {
return this.mergedConfig.hideWordFilteredPosts
},
hideStatus() {
return (
!this.shouldNotMute &&
((this.muted && this.hideFilteredStatuses) ||
(this.userIsMuted && this.hideMutedUsers) ||
(this.status.thread_muted && this.hideMutedThreads) ||
(this.muteFilterHits.length > 0 && this.hideWordFilteredPosts) ||
this.muteFilterHits.some((x) => x.hide))
)
},
isFocused() {
// retweet or root of an expanded conversation
if (this.focused) {
return true
} else if (!this.inConversation) {
return false
}
// use conversation highlight only when in conversation
return this.status.id === this.highlight
},
isReply() {
return !!(
this.status.in_reply_to_status_id && this.status.in_reply_to_user_id
)
},
replyToName() {
if (this.status.in_reply_to_screen_name) {
return this.status.in_reply_to_screen_name
} else {
const user = this.$store.getters.findUser(
this.status.in_reply_to_user_id,
)
return user && user.screen_name_ui
}
},
replySubject() {
if (!this.status.summary) return ''
const decodedSummary = ldUnescape(this.status.summary)
const behavior = this.mergedConfig.subjectLineBehavior
const startsWithRe = decodedSummary.match(/^re[: ]/i)
if ((behavior !== 'noop' && startsWithRe) || behavior === 'masto') {
return decodedSummary
} else if (behavior === 'email') {
return 're: '.concat(decodedSummary)
} else if (behavior === 'noop') {
return ''
}
},
combinedFavsAndRepeatsUsers() {
// Use the status from the global status repository since favs and repeats are saved in it
const combinedUsers = [].concat(
this.statusFromGlobalRepository.favoritedBy,
this.statusFromGlobalRepository.rebloggedBy,
)
return uniqBy(combinedUsers, 'id')
},
tags() {
return this.status.tags
.filter((tagObj) => Object.hasOwn(tagObj, 'name'))
.map((tagObj) => tagObj.name)
.join(' ')
},
hidePostStats() {
return this.mergedConfig.hidePostStats
},
shouldDisplayFavsAndRepeats() {
return (
!this.hidePostStats &&
this.isFocused &&
(this.combinedFavsAndRepeatsUsers.length > 0 ||
this.statusFromGlobalRepository.quotes_count)
)
},
muteBotStatuses() {
return this.mergedConfig.muteBotStatuses
},
muteSensitiveStatuses() {
return this.mergedConfig.muteSensitiveStatuses
},
hideBotIndication() {
return this.mergedConfig.hideBotIndication
},
currentUser() {
return this.$store.state.users.currentUser
},
mergedConfig() {
return useMergedConfigStore().mergedConfig
},
isSuspendable() {
return !this.replying && this.mediaPlaying.length === 0
},
inThreadForest() {
return !!this.controlledThreadDisplayStatus
},
threadShowing() {
return this.controlledThreadDisplayStatus === 'showing'
},
visibilityLocalized() {
return this.$i18n.t('general.scope_in_timeline.' + this.status.visibility)
},
isEdited() {
return this.status.edited_at !== null
},
editingAvailable() {
return useInstanceCapabilitiesStore().editingAvailable
},
quoteId() {
return this.status.quote_id
},
quoteUrl() {
return this.status.quote_url
},
quoteVisible() {
return this.status.quote_visible
},
quoteExpanded() {
return !this.inQuote
},
scrobblePresent() {
if (this.mergedConfig.hideScrobbles) return false
if (!this.status.user?.latestScrobble) return false
const value = this.mergedConfig.hideScrobblesAfter.match(/\d+/gs)[0]
const unit = this.mergedConfig.hideScrobblesAfter.match(/\D+/gs)[0]
let multiplier = 60 * 1000 // minutes is smallest unit
switch (unit) {
case 'm':
break
case 'h':
multiplier *= 60 // hour
break
case 'd':
multiplier *= 60 // hour
multiplier *= 24 // day
break
}
const maxAge = Number(value) * multiplier
const createdAt = Date.parse(this.status.user.latestScrobble.created_at)
const age = Date.now() - createdAt
if (age > maxAge) return false
return this.status.user.latestScrobble.artist
},
scrobble() {
return this.status.user?.latestScrobble
},
},
methods: {
visibilityIcon(visibility) {
switch (visibility) {
case 'private':
return 'lock'
case 'unlisted':
return 'lock-open'
case 'direct':
return 'envelope'
case 'local':
return 'igloo'
default:
return 'globe'
}
},
showError(error) {
this.error = error
},
clearError() {
this.error = undefined
},
toggleReplying() {
if (this.replying) {
this.$refs.postStatusForm.requestClose()
} else {
this.doToggleReplying()
}
},
doToggleReplying() {
controlledOrUncontrolledToggle(this, 'replying')
},
gotoOriginal(id) {
if (this.inConversation) {
this.$emit('goto', id)
}
},
toggleExpanded() {
this.$emit('toggleExpanded')
},
toggleMute() {
this.unmuted = !this.unmuted
},
toggleUserExpanded() {
this.userExpanded = !this.userExpanded
},
generateUserProfileLink(id, name) {
return generateProfileLink(
id,
name,
useInstanceStore().restrictedNicknames,
)
},
addMediaPlaying(id) {
controlledOrUncontrolledSet(
this,
'mediaPlaying',
this.mediaPlaying.concat(id),
)
},
removeMediaPlaying(id) {
controlledOrUncontrolledSet(
this,
'mediaPlaying',
this.mediaPlaying.filter((mediaId) => mediaId !== id),
)
},
setHeadTailLinks(headTailLinks) {
this.headTailLinks = headTailLinks
},
toggleThreadDisplay() {
this.controlledToggleThreadDisplay()
},
scrollIfHighlighted(highlightId) {
if (this.$el.getBoundingClientRect == null) return
const id = highlightId
if (this.status.id === id) {
const rect = this.$el.getBoundingClientRect()
if (rect.top < 100) {
// Post is above screen, match its top to screen top
window.scrollBy(0, rect.top - 100)
} else if (rect.height >= window.innerHeight - 50) {
// Post we want to see is taller than screen so match its top to screen top
window.scrollBy(0, rect.top - 100)
} else if (rect.bottom > window.innerHeight - 50) {
// Post is below screen, match its bottom to screen bottom
window.scrollBy(0, rect.bottom - window.innerHeight + 50)
}
}
},
},
watch: {
highlight: function (id) {
this.scrollIfHighlighted(id)
},
'status.repeat_num': function (num) {
// refetch repeats when repeat_num is changed in any way
if (
this.isFocused &&
this.statusFromGlobalRepository.rebloggedBy &&
this.statusFromGlobalRepository.rebloggedBy.length !== num
) {
this.$store.dispatch('fetchRepeats', this.status.id)
}
},
'status.fave_num': function (num) {
// refetch favs when fave_num is changed in any way
if (
this.isFocused &&
this.statusFromGlobalRepository.favoritedBy &&
this.statusFromGlobalRepository.favoritedBy.length !== num
) {
this.$store.dispatch('fetchFavs', this.status.id)
}
},
isSuspendable: function (val) {
this.suspendable = val
},
},
}
export default Status
diff --git a/src/components/status_action_buttons/action_button.js b/src/components/status_action_buttons/action_button.js
index 5f79421629..661d1befd8 100644
--- a/src/components/status_action_buttons/action_button.js
+++ b/src/components/status_action_buttons/action_button.js
@@ -1,162 +1,168 @@
-import EmojiPicker from 'src/components/emoji_picker/emoji_picker.vue'
+import { defineAsyncComponent } from 'vue'
+
import Popover from 'src/components/popover/popover.vue'
-import StatusBookmarkFolderMenu from 'src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.vue'
+import EmojiPicker from '../emoji_picker/emoji_picker.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faBookmark as faBookmarkRegular,
+ faFaceSmileBeam,
faStar as faStarRegular,
} from '@fortawesome/free-regular-svg-icons'
import {
faBookmark,
faCheck,
faChevronDown,
faChevronRight,
faExternalLinkAlt,
faEyeSlash,
faHistory,
faMinus,
faPlus,
faReply,
faRetweet,
faShareAlt,
- faSmileBeam,
faStar,
faThumbtack,
faTimes,
faWrench,
} from '@fortawesome/free-solid-svg-icons'
library.add(
faPlus,
faMinus,
faCheck,
faTimes,
faWrench,
faChevronRight,
faChevronDown,
faReply,
faRetweet,
faStar,
faStarRegular,
- faSmileBeam,
+ faFaceSmileBeam,
faBookmark,
faBookmarkRegular,
faEyeSlash,
faThumbtack,
faShareAlt,
faExternalLinkAlt,
faHistory,
)
export default {
props: [
'button',
'status',
'extra',
'status',
'funcArg',
'getClass',
'getComponent',
'doAction',
'outerClose',
],
components: {
- StatusBookmarkFolderMenu,
+ StatusBookmarkFolderMenu: defineAsyncComponent(
+ () =>
+ import(
+ 'src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.vue'
+ ),
+ ),
EmojiPicker,
Popover,
},
data: () => ({
animationState: false,
}),
computed: {
buttonClass() {
return [
this.button.name + '-button',
{
'-with-extra': this.button.name === 'bookmark',
'-extra': this.extra,
'-quick': !this.extra,
},
]
},
userIsMuted() {
return this.$store.getters.relationship(this.status.user.id).muting
},
threadIsMuted() {
return this.status.thread_muted
},
hideCustomEmoji() {
return !useInstanceCapabilitiesStore()
.pleromaCustomEmojiReactionsAvailable
},
hidePostStats() {
return useMergedConfigStore().mergedConfig.hidePostStats
},
buttonInnerClass() {
return [
this.button.name + '-button',
{
'main-button': this.extra,
'button-unstyled': !this.extra,
'-active': this.button.active?.(this.funcArg),
disabled: this.button.interactive
? !this.button.interactive(this.funcArg)
: false,
},
]
},
remoteInteractionLink() {
return useInstanceStore().getRemoteInteractionLink({
statusId: this.status.id,
})
},
},
methods: {
addReaction(event) {
const emoji = event.insertion
const existingReaction = this.status.emoji_reactions.find(
(r) => r.name === emoji,
)
if (existingReaction && existingReaction.me) {
this.$store.dispatch('unreactWithEmoji', { id: this.status.id, emoji })
} else {
this.$store.dispatch('reactWithEmoji', { id: this.status.id, emoji })
}
},
onShowEmojiPicker() {
this.$emit('emojiPickerShown', true)
},
onHideEmojiPicker() {
this.$emit('emojiPickerShown', false)
},
doActionWrap(
button,
close = () => {
/* no-op */
},
) {
if (
this.button.interactive ? !this.button.interactive(this.funcArg) : false
)
return
if (button.name === 'emoji') {
this.$refs.picker.togglePicker()
} else {
this.animationState = true
this.getComponent(button) === 'button' && this.doAction(button)
setTimeout(() => {
this.animationState = false
}, 500)
close()
}
},
},
}
diff --git a/src/components/status_action_buttons/action_button_container.js b/src/components/status_action_buttons/action_button_container.js
index a5a070ddee..012844dc88 100644
--- a/src/components/status_action_buttons/action_button_container.js
+++ b/src/components/status_action_buttons/action_button_container.js
@@ -1,90 +1,97 @@
-import MuteConfirm from 'src/components/confirm_modal/mute_confirm.vue'
+import { defineAsyncComponent } from 'vue'
+
import Popover from 'src/components/popover/popover.vue'
-import UserTimedFilterModal from 'src/components/user_timed_filter_modal/user_timed_filter_modal.vue'
import ActionButton from './action_button.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faFolderTree,
faGlobe,
faUser,
} from '@fortawesome/free-solid-svg-icons'
library.add(faUser, faGlobe, faFolderTree)
export default {
components: {
ActionButton,
Popover,
- MuteConfirm,
- UserTimedFilterModal,
+ MuteConfirm: defineAsyncComponent(
+ () => import('src/components/confirm_modal/mute_confirm.vue'),
+ ),
+ UserTimedFilterModal: defineAsyncComponent(
+ () =>
+ import(
+ 'src/components/user_timed_filter_modal/user_timed_filter_modal.vue'
+ ),
+ ),
},
props: ['button', 'status'],
emits: ['emojiPickerShown'],
mounted() {
if (this.button.name === 'mute') {
this.$store.dispatch('fetchDomainMutes')
}
},
computed: {
buttonClass() {
return [
this.button.name + '-button',
{
'-with-extra': this.button.name === 'bookmark',
'-extra': this.extra,
'-quick': !this.extra,
},
]
},
user() {
return this.status.user
},
userIsMuted() {
return this.$store.getters.relationship(this.user.id).muting
},
conversationIsMuted() {
return this.status.thread_muted
},
domain() {
return this.user.fqn.split('@')[1]
},
domainIsMuted() {
return new Set(this.$store.state.users.currentUser.domainMutes).has(
this.domain,
)
},
},
methods: {
unmuteUser() {
return this.$store.dispatch('unmuteUser', this.user.id)
},
unmuteConversation() {
return this.$store.dispatch('unmuteConversation', { id: this.status.id })
},
unmuteDomain() {
return this.$store.dispatch('unmuteDomain', this.domain)
},
toggleUserMute() {
if (this.userIsMuted) {
this.unmuteUser()
} else {
this.$refs.confirmUser.optionallyPrompt()
}
},
toggleConversationMute() {
if (this.conversationIsMuted) {
this.unmuteConversation()
} else {
this.$refs.confirmConversation.optionallyPrompt()
}
},
toggleDomainMute() {
if (this.domainIsMuted) {
this.unmuteDomain()
} else {
this.$refs.confirmDomain.optionallyPrompt()
}
},
},
}
diff --git a/src/components/status_action_buttons/buttons_definitions.js b/src/components/status_action_buttons/buttons_definitions.js
index 455da54606..9efc77bff1 100644
--- a/src/components/status_action_buttons/buttons_definitions.js
+++ b/src/components/status_action_buttons/buttons_definitions.js
@@ -1,295 +1,295 @@
import { useEditStatusStore } from 'src/stores/editStatus.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useReportsStore } from 'src/stores/reports.js'
import { useStatusHistoryStore } from 'src/stores/statusHistory.js'
const PRIVATE_SCOPES = new Set(['private', 'direct'])
const PUBLIC_SCOPES = new Set(['public', 'unlisted'])
export const BUTTONS = [
{
// =========
// REPLY
// =========
name: 'reply',
label: 'tool_tip.reply',
icon: 'reply',
active: ({ replying }) => replying,
counter: ({ status }) => status.replies_count,
anon: true,
anonLink: true,
toggleable: true,
closeIndicator: 'times',
activeIndicator: null,
action({ emit }) {
emit('toggleReplying')
return Promise.resolve()
},
},
{
// =========
// REPEAT
// =========
name: 'retweet',
label: ({ status }) =>
status.repeated ? 'tool_tip.unrepeat' : 'tool_tip.repeat',
icon({ status, currentUser }) {
if (
currentUser.id !== status.user.id &&
PRIVATE_SCOPES.has(status.visibility)
) {
return 'lock'
}
return 'retweet'
},
animated: true,
active: ({ status }) => status.repeated,
counter: ({ status }) => status.repeat_num,
anonLink: true,
interactive: ({ status, currentUser }) =>
!!currentUser &&
(currentUser.id === status.user.id ||
!PRIVATE_SCOPES.has(status.visibility)),
toggleable: true,
confirm: ({ status, getters }) =>
!status.repeated && useMergedConfigStore().mergedConfig.modalOnRepeat,
confirmStrings: {
title: 'status.repeat_confirm_title',
body: 'status.repeat_confirm',
confirm: 'status.repeat_confirm_accept_button',
cancel: 'status.repeat_confirm_cancel_button',
},
action({ status, dispatch }) {
if (!status.repeated) {
return dispatch('retweet', { id: status.id })
} else {
return dispatch('unretweet', { id: status.id })
}
},
},
{
// =========
// FAVORITE
// =========
name: 'favorite',
label: ({ status }) =>
status.favorited ? 'tool_tip.unfavorite' : 'tool_tip.favorite',
icon: ({ status }) =>
status.favorited ? ['fas', 'star'] : ['far', 'star'],
animated: true,
active: ({ status }) => status.favorited,
counter: ({ status }) => status.fave_num,
anonLink: true,
toggleable: true,
action({ status, dispatch }) {
if (!status.favorited) {
return dispatch('favorite', { id: status.id })
} else {
return dispatch('unfavorite', { id: status.id })
}
},
},
{
// =========
// EMOJI REACTIONS
// =========
name: 'emoji',
label: 'tool_tip.add_reaction',
- icon: ['far', 'smile-beam'],
+ icon: ['far', 'face-smile-beam'],
interactive: () => true,
active: ({ emojiPickerShown }) => emojiPickerShown,
toggleable: true,
anonLink: true,
},
{
// =========
// MUTE
// =========
name: 'mute',
icon: 'eye-slash',
label: 'status.mute_ellipsis',
if: ({ loggedIn }) => loggedIn,
toggleable: false,
dropdown: true,
action({ status, dispatch, emit }) {
/* prevent hiding */
},
},
{
// =========
// PIN STATUS
// =========
name: 'pin',
icon: 'thumbtack',
label: ({ status }) => (status.pinned ? 'status.unpin' : 'status.pin'),
if({ status, loggedIn, currentUser }) {
return (
loggedIn &&
status.user.id === currentUser.id &&
PUBLIC_SCOPES.has(status.visibility)
)
},
action({ status, dispatch }) {
if (status.pinned) {
return dispatch('unpinStatus', status.id)
} else {
return dispatch('pinStatus', status.id)
}
},
},
{
// =========
// BOOKMARK
// =========
name: 'bookmark',
icon: ({ status }) =>
status.bookmarked ? ['fas', 'bookmark'] : ['far', 'bookmark'],
toggleable: true,
active: ({ status }) => status.bookmarked,
label: ({ status }) =>
status.bookmarked ? 'status.unbookmark' : 'status.bookmark',
if: ({ loggedIn }) => loggedIn,
action({ status, dispatch }) {
if (status.bookmarked) {
return dispatch('unbookmark', { id: status.id })
} else {
return dispatch('bookmark', { id: status.id })
}
},
},
{
// =========
// EDIT HISTORY
// =========
name: 'editHistory',
icon: 'history',
label: 'status.status_history',
if({ status, state }) {
return (
useInstanceCapabilitiesStore().editingAvailable &&
status.edited_at !== null
)
},
action({ status }) {
const originalStatus = { ...status }
const stripFieldsList = [
'attachments',
'created_at',
'emojis',
'text',
'raw_html',
'nsfw',
'poll',
'summary',
'summary_raw_html',
]
stripFieldsList.forEach((p) => delete originalStatus[p])
useStatusHistoryStore().openStatusHistoryModal(originalStatus)
return Promise.resolve()
},
},
{
// =========
// EDIT
// =========
name: 'edit',
icon: 'pen',
label: 'status.edit',
if({ status, loggedIn, currentUser, state }) {
return (
loggedIn &&
useInstanceCapabilitiesStore().editingAvailable &&
status.user.id === currentUser.id
)
},
action({ dispatch, status }) {
return dispatch('fetchStatusSource', { id: status.id }).then((data) =>
useEditStatusStore().openEditStatusModal({
statusId: status.id,
subject: data.spoiler_text,
statusText: data.text,
statusIsSensitive: status.nsfw,
statusPoll: status.poll,
statusFiles: [...status.attachments],
visibility: status.visibility,
statusContentType: data.content_type,
}),
)
},
},
{
// =========
// DELETE
// =========
name: 'delete',
icon: 'times',
label: 'status.delete',
if({ status, loggedIn, currentUser }) {
return (
loggedIn &&
(status.user.id === currentUser.id ||
currentUser.privileges.includes('messages_delete'))
)
},
confirm: ({ getters }) => useMergedConfigStore().mergedConfig.modalOnDelete,
confirmStrings: {
title: 'status.delete_confirm_title',
body: 'status.delete_confirm',
confirm: 'status.delete_confirm_accept_button',
cancel: 'status.delete_confirm_cancel_button',
},
action({ dispatch, status }) {
return dispatch('deleteStatus', { id: status.id })
},
},
{
// =========
// SHARE/COPY
// =========
name: 'share',
icon: 'share-alt',
label: 'status.copy_link',
action({ state, status, router }) {
navigator.clipboard.writeText(
[
useInstanceStore().server,
router.resolve({ name: 'conversation', params: { id: status.id } })
.href,
].join(''),
)
return Promise.resolve()
},
},
{
// =========
// EXTERNAL
// =========
name: 'external',
icon: 'external-link-alt',
label: 'status.external_source',
link: ({ status }) => status.external_url,
},
{
// =========
// REPORT
// =========
name: 'report',
icon: 'flag',
label: 'user_card.report',
if: ({ loggedIn }) => loggedIn,
action({ status }) {
return useReportsStore().openUserReportingModal({
userId: status.user.id,
statusIds: [status.id],
})
},
},
].map((button) => {
return Object.fromEntries(
Object.entries(button).map(([k, v]) => [
k,
typeof v === 'function' || k === 'name' ? v : () => v,
]),
)
})
diff --git a/src/components/status_action_buttons/status_action_buttons.js b/src/components/status_action_buttons/status_action_buttons.js
index 05809bbe97..2d0de25ef1 100644
--- a/src/components/status_action_buttons/status_action_buttons.js
+++ b/src/components/status_action_buttons/status_action_buttons.js
@@ -1,155 +1,158 @@
import { mapState } from 'pinia'
+import { defineAsyncComponent } from 'vue'
-import ConfirmModal from 'src/components/confirm_modal/confirm_modal.vue'
import Popover from 'src/components/popover/popover.vue'
import ActionButtonContainer from './action_button_container.vue'
import { BUTTONS } from './buttons_definitions.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
import genRandomSeed from 'src/services/random_seed/random_seed.service.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faEllipsisH } from '@fortawesome/free-solid-svg-icons'
library.add(faEllipsisH)
const StatusActionButtons = {
props: ['status', 'replying'],
emits: ['toggleReplying', 'onSuccess', 'onError'],
data() {
return {
showPin: false,
showingConfirmDialog: false,
currentConfirmTitle: '',
currentConfirmOkText: '',
currentConfirmCancelText: '',
currentConfirmAction: () => {
/* no-op */
},
randomSeed: genRandomSeed(),
emojiPickerShown: false,
}
},
components: {
Popover,
- ConfirmModal,
+ ConfirmModal: defineAsyncComponent(
+ () => import('src/components/confirm_modal/confirm_modal.vue'),
+ ),
+
ActionButtonContainer,
},
computed: {
...mapState(useSyncConfigStore, {
pinnedItems: (store) =>
new Set(store.prefsStorage.collections.pinnedStatusActions),
}),
buttons() {
return BUTTONS.filter((x) => (x.if ? x.if(this.funcArg) : true))
},
quickButtons() {
return this.buttons.filter((x) => this.pinnedItems.has(x.name))
},
extraButtons() {
return this.buttons.filter((x) => !this.pinnedItems.has(x.name))
},
currentUser() {
return this.$store.state.users.currentUser
},
funcArg() {
return {
status: this.status,
replying: this.replying,
emojiPickerShown: this.emojiPickerShown,
emit: this.$emit,
dispatch: this.$store.dispatch,
state: this.$store.state,
getters: this.$store.getters,
router: this.$router,
currentUser: this.currentUser,
loggedIn: !!this.currentUser,
}
},
triggerAttrs() {
return {
title: this.$t('status.more_actions'),
'aria-controls': `popup-menu-${this.randomSeed}`,
'aria-haspopup': 'menu',
}
},
},
methods: {
doAction(button) {
if (button.confirm?.(this.funcArg)) {
// TODO move to action_button
this.currentConfirmTitle = this.$t(
button.confirmStrings(this.funcArg).title,
)
this.currentConfirmOkText = this.$t(
button.confirmStrings(this.funcArg).confirm,
)
this.currentConfirmCancelText = this.$t(
button.confirmStrings(this.funcArg).cancel,
)
this.currentConfirmBody = this.$t(
button.confirmStrings(this.funcArg).body,
)
this.currentConfirmAction = () => {
this.showingConfirmDialog = false
this.doActionReal(button)
}
this.showingConfirmDialog = true
} else {
this.doActionReal(button)
}
},
doActionReal(button) {
button
.action?.(this.funcArg)
.then(() => this.$emit('onSuccess'))
.catch((err) => this.$emit('onError', err.error.error))
},
onExtraClose() {
this.showPin = false
},
onEmojiPickerShown(state) {
this.emojiPickerShown = state
},
isPinned(button) {
return this.pinnedItems.has(button.name)
},
unpin(button) {
useSyncConfigStore().removeCollectionPreference({
path: 'collections.pinnedStatusActions',
value: button.name,
})
useSyncConfigStore().pushSyncConfig()
},
pin(button) {
useSyncConfigStore().addCollectionPreference({
path: 'collections.pinnedStatusActions',
value: button.name,
})
useSyncConfigStore().pushSyncConfig()
},
getComponent(button) {
if (!this.$store.state.users.currentUser && button.anonLink) {
return 'a'
} else if (button.action == null && button.link != null) {
return 'a'
} else {
return 'button'
}
},
getClass(button) {
return {
[button.name + '-button']: true,
disabled: button.interactive
? !button.interactive(this.funcArg)
: false,
'-pin-edit': this.showPin,
'-dropdown': button.dropdown?.(),
'-active': button.active?.(this.funcArg),
}
},
},
}
export default StatusActionButtons
diff --git a/src/components/status_action_buttons/status_action_buttons.vue b/src/components/status_action_buttons/status_action_buttons.vue
index bdb95e83b4..e0432048a9 100644
--- a/src/components/status_action_buttons/status_action_buttons.vue
+++ b/src/components/status_action_buttons/status_action_buttons.vue
@@ -1,135 +1,135 @@
<template>
<div class="StatusActionButtons">
<span
class="quick-action-buttons"
:class="{ '-pin': showPin }"
>
<span
v-for="button in quickButtons"
:key="button.name"
class="quick-action"
:class="{ '-pin': showPin, '-toggle': button.dropdown?.(), '-with-extra': button.name === 'bookmark' }"
>
<ActionButtonContainer
:class="{ '-pin': showPin }"
:button="button"
:status="status"
:extra="false"
:func-arg="funcArg"
:get-class="getClass"
:get-component="getComponent"
:close="() => { /* no-op */ }"
:do-action="doAction"
@emoji-picker-shown="onEmojiPickerShown"
/>
<button
v-if="showPin && currentUser"
type="button"
class="button-unstyled pin-action-button"
:title="$t('general.unpin')"
:aria-pressed="true"
@click.stop.prevent="unpin(button)"
>
<FAIcon
v-if="showPin && currentUser"
fixed-width
icon="thumbtack"
/>
</button>
</span>
<Popover
trigger="click"
:trigger-attrs="triggerAttrs"
class="quick-action"
:tabindex="0"
placement="bottom"
:offset="{ y: 5 }"
remove-padding
@close="onExtraClose"
>
<template #trigger>
<FAIcon
class="action-button-inner"
icon="ellipsis-h"
/>
</template>
<template #content="{close, resize}">
<div
:id="`popup-menu-${randomSeed}`"
class="dropdown-menu extra-action-buttons"
role="menu"
>
<div
v-for="button in extraButtons"
:key="button.name"
class="menu-item dropdown-item extra-action -icon"
:disabled="getClass(button).disabled"
:class="{ disabled: getClass(button).disabled }"
>
<ActionButtonContainer
:button="button"
:status="status"
:extra="true"
:func-arg="funcArg"
:get-class="getClass"
:get-component="getComponent"
:outer-close="close"
:do-action="doAction"
/>
<button
v-if="showPin && currentUser"
type="button"
class="button-unstyled pin-action-button extra-button"
:title="$t('general.pin')"
:aria-pressed="false"
@click.stop.prevent="pin(button)"
>
<FAIcon
v-if="showPin && currentUser"
fixed-width
class="fa-scale-110"
transform="rotate-45"
icon="thumbtack"
/>
</button>
</div>
<div
v-if="currentUser"
class="menu-item dropdown-item extra-action -icon"
>
<button
class="main-button"
role="menuitem"
:tabindex="0"
@click.stop="() => { resize(); showPin = !showPin }"
>
<FAIcon
class="fa-scale-110"
fixed-width
icon="wrench"
/><span>{{ $t('nav.edit_pinned') }}</span>
</button>
</div>
</div>
</template>
</Popover>
</span>
<teleport to="#modal">
- <confirm-modal
+ <ConfirmModal
v-if="showingConfirmDialog"
:title="currentConfirmTitle"
:confirm-text="currentConfirmOkText"
:cancel-text="currentConfirmCancelText"
@accepted="currentConfirmAction"
@cancelled="showingConfirmDialog = false"
>
{{ currentConfirmBody }}
- </confirm-modal>
+ </ConfirmModal>
</teleport>
</div>
</template>
<script src="./status_action_buttons.js"></script>
<style lang="scss" src="./status_action_buttons.scss"></style>
diff --git a/src/components/status_body/status_body.js b/src/components/status_body/status_body.js
index 1b7d264032..cdd43a0246 100644
--- a/src/components/status_body/status_body.js
+++ b/src/components/status_body/status_body.js
@@ -1,165 +1,161 @@
import { mapState } from 'pinia'
-import RichContent from 'src/components/rich_content/rich_content.jsx'
-
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faFile,
faImage,
faLink,
faMusic,
faPollH,
} from '@fortawesome/free-solid-svg-icons'
library.add(faFile, faMusic, faImage, faLink, faPollH)
const StatusBody = {
name: 'StatusBody',
props: [
'compact',
'collapse', // replaces newlines with spaces
'status',
'focused',
'noHeading',
'fullContent',
'singleLine',
'showingTall',
'expandingSubject',
'showingLongSubject',
'toggleShowingTall',
'toggleExpandingSubject',
'toggleShowingLongSubject',
],
data() {
return {
postLength: this.status.text.length,
parseReadyDone: false,
}
},
emits: ['parseReady'],
computed: {
localCollapseSubjectDefault() {
return this.mergedConfig.collapseMessageWithSubject
},
allowNonSquareEmoji() {
return this.mergedConfig.nonSquareEmoji
},
// This is a bit hacky, but we want to approximate post height before rendering
// so we count newlines (masto uses <p> for paragraphs, GS uses <br> between them)
// as well as approximate line count by counting characters and approximating ~80
// per line.
//
// Using max-height + overflow: auto for status components resulted in false positives
// very often with japanese characters, and it was very annoying.
tallStatus() {
if (this.singleLine || this.compact) return false
const lengthScore =
this.status.raw_html.split(/<p|<br/).length + this.postLength / 80
return lengthScore > 20
},
longSubject() {
return this.status.summary.length > 240
},
// When a status has a subject and is also tall, we should only have one show more/less button. If the default is to collapse statuses with subjects, we just treat it like a status with a subject; otherwise, we just treat it like a tall status.
mightHideBecauseSubject() {
return !!this.status.summary && this.localCollapseSubjectDefault
},
mightHideBecauseTall() {
return (
this.tallStatus &&
!(this.status.summary && this.localCollapseSubjectDefault)
)
},
hideSubjectStatus() {
return this.mightHideBecauseSubject && !this.expandingSubject
},
hideTallStatus() {
return this.mightHideBecauseTall && !this.showingTall
},
shouldShowToggle() {
return this.mightHideBecauseSubject || this.mightHideBecauseTall
},
toggleButtonClasses() {
return {
'cw-status-hider': !this.showingMore && this.mightHideBecauseSubject,
'tall-status-hider': !this.showingMore && this.mightHideBecauseTall,
'status-unhider': this.showingMore,
}
},
toggleText() {
if (this.showingMore) {
return this.mightHideBecauseSubject
? this.$t('status.hide_content')
: this.$t('general.show_less')
} else {
return this.mightHideBecauseSubject
? this.$t('status.show_content')
: this.$t('general.show_more')
}
},
showingMore() {
return (
(this.mightHideBecauseTall && this.showingTall) ||
(this.mightHideBecauseSubject && this.expandingSubject)
)
},
attachmentTypes() {
return this.status.attachments.map((file) => file.type)
},
collapsedStatus() {
return this.status.raw_html.replace(/(\n|<br\s?\/?>)/g, ' ')
},
...mapState(useMergedConfigStore, ['mergedConfig']),
},
- components: {
- RichContent,
- },
+ components: {},
mounted() {
this.status.attentions &&
this.status.attentions.forEach((attn) => {
const { id } = attn
this.$store.dispatch('fetchUserIfMissing', id)
})
},
methods: {
onParseReady(event) {
if (this.parseReadyDone) return
this.parseReadyDone = true
this.$emit('parseReady', event)
const { writtenMentions, invisibleMentions } = event
writtenMentions
.filter((mention) => !mention.notifying)
.forEach((mention) => {
const { content, url } = mention
const cleanedString = content.replace(/<[^>]+?>/gi, '') // remove all tags
if (!cleanedString.startsWith('@')) return
const handle = cleanedString.slice(1)
const host = url.replace(/^https?:\/\//, '').replace(/\/.+?$/, '')
this.$store.dispatch('fetchUserIfMissing', `${handle}@${host}`)
})
/* This is a bit of a hack to make current tall status detector work
* with rich mentions. Invisible mentions are detected at RichContent level
* and also we generate plaintext version of mentions by stripping tags
* so here we subtract from post length by each mention that became invisible
* via MentionsLine
*/
this.postLength = invisibleMentions.reduce((acc, mention) => {
return acc - mention.textContent.length - 1
}, this.postLength)
},
toggleShowMore() {
if (this.mightHideBecauseTall) {
this.toggleShowingTall()
} else if (this.mightHideBecauseSubject) {
this.toggleExpandingSubject()
}
},
generateTagLink(tag) {
return `/tag/${tag}`
},
},
}
export default StatusBody
diff --git a/src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.js b/src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.js
index 7e92a02878..c2f070b6d6 100644
--- a/src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.js
+++ b/src/components/status_bookmark_folder_menu/status_bookmark_folder_menu.js
@@ -1,43 +1,41 @@
import { mapState } from 'pinia'
import Popover from 'src/components/popover/popover.vue'
-import StillImage from 'src/components/still-image/still-image.vue'
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faChevronRight, faFolder } from '@fortawesome/free-solid-svg-icons'
library.add(faChevronRight, faFolder)
const StatusBookmarkFolderMenu = {
props: ['status'],
emits: ['success', 'error', 'close'],
data() {
return {}
},
components: {
Popover,
- StillImage,
},
computed: {
...mapState(useBookmarkFoldersStore, {
folders: (store) => store.allFolders,
}),
folderId() {
return this.status.bookmark_folder_id
},
},
methods: {
toggleFolder(id) {
const value = id === this.folderId ? null : id
this.$store
.dispatch('bookmark', { id: this.status.id, bookmark_folder_id: value })
.then(() => this.$emit('success'))
.catch((err) => this.$emit('error', err.error.error))
},
},
}
export default StatusBookmarkFolderMenu
diff --git a/src/components/status_content/status_content.js b/src/components/status_content/status_content.js
index a72db5b96a..0f02bb6fb3 100644
--- a/src/components/status_content/status_content.js
+++ b/src/components/status_content/status_content.js
@@ -1,159 +1,160 @@
import { mapState as mapPiniaState } from 'pinia'
+import { defineAsyncComponent } from 'vue'
import { mapGetters, mapState } from 'vuex'
+import Attachment from 'src/components/attachment/attachment.vue'
+import Gallery from 'src/components/gallery/gallery.vue'
+import LinkPreview from 'src/components/link-preview/link-preview.vue'
+import Poll from 'src/components/poll/poll.vue'
import StatusBody from 'src/components/status_body/status_body.vue'
-import Attachment from '../attachment/attachment.vue'
-import Gallery from '../gallery/gallery.vue'
-import LinkPreview from '../link-preview/link-preview.vue'
-import Poll from '../poll/poll.vue'
import { useMediaViewerStore } from 'src/stores/media_viewer.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faCircleNotch,
faFile,
faImage,
faLink,
faMusic,
faPollH,
} from '@fortawesome/free-solid-svg-icons'
library.add(faCircleNotch, faFile, faMusic, faImage, faLink, faPollH)
const camelCase = (name) => name.charAt(0).toUpperCase() + name.slice(1)
const controlledOrUncontrolledGetters = (list) =>
list.reduce((res, name) => {
const camelized = camelCase(name)
const toggle = `controlledToggle${camelized}`
const controlledName = `controlled${camelized}`
const uncontrolledName = `uncontrolled${camelized}`
res[name] = function () {
return (this.$data[toggle] !== undefined ||
this.$props[toggle] !== undefined) &&
this[toggle]
? this[controlledName]
: this[uncontrolledName]
}
return res
}, {})
const controlledOrUncontrolledToggle = (obj, name) => {
const camelized = camelCase(name)
const toggle = `controlledToggle${camelized}`
const uncontrolledName = `uncontrolled${camelized}`
if (obj[toggle]) {
obj[toggle]()
} else {
obj[uncontrolledName] = !obj[uncontrolledName]
}
}
const StatusContent = {
name: 'StatusContent',
props: [
'status',
'compact',
'collapse',
'focused',
'noHeading',
'fullContent',
'singleLine',
'controlledShowingTall',
'controlledExpandingSubject',
'controlledToggleShowingTall',
'controlledToggleExpandingSubject',
'controlledShowingLongSubject',
'controlledToggleShowingLongSubject',
],
emits: ['parseReady', 'mediaplay', 'mediapause'],
data() {
return {
uncontrolledShowingTall:
this.fullContent || (this.inConversation && this.focused),
uncontrolledShowingLongSubject: false,
// not as computed because it sets the initial state which will be changed later
uncontrolledExpandingSubject:
!useMergedConfigStore().mergedConfig.collapseMessageWithSubject,
}
},
computed: {
...controlledOrUncontrolledGetters([
'showingTall',
'expandingSubject',
'showingLongSubject',
]),
statusCard() {
if (!this.status.card) return null
return this.status.card.url === this.status.quote_url
? null
: this.status.card
},
hideAttachments() {
return (
(this.mergedConfig.hideAttachments && !this.inConversation) ||
(this.mergedConfig.hideAttachmentsInConv && this.inConversation)
)
},
nsfwClickthrough() {
if (!this.status.nsfw) {
return false
}
if (this.status.summary && this.localCollapseSubjectDefault) {
return false
}
return true
},
localCollapseSubjectDefault() {
return this.mergedConfig.collapseMessageWithSubject
},
attachmentSize() {
if (this.compact) {
return 'small'
} else if (
(this.mergedConfig.hideAttachments && !this.inConversation) ||
(this.mergedConfig.hideAttachmentsInConv && this.inConversation) ||
this.status.attachments.length > this.maxThumbnails
) {
return 'hide'
}
return 'normal'
},
maxThumbnails() {
return this.mergedConfig.maxThumbnails
},
...mapPiniaState(useMergedConfigStore, ['mergedConfig']),
...mapState({
currentUser: (state) => state.users.currentUser,
}),
},
components: {
Attachment,
Poll,
Gallery,
LinkPreview,
StatusBody,
},
methods: {
toggleShowingTall() {
controlledOrUncontrolledToggle(this, 'showingTall')
},
toggleExpandingSubject() {
controlledOrUncontrolledToggle(this, 'expandingSubject')
},
toggleShowingLongSubject() {
controlledOrUncontrolledToggle(this, 'showingLongSubject')
},
setMedia() {
const attachments =
this.attachmentSize === 'hide'
? this.status.attachments
: this.galleryAttachments
return () => useMediaViewerStore().setMedia(attachments)
},
},
}
export default StatusContent
diff --git a/src/components/status_content/status_content.vue b/src/components/status_content/status_content.vue
index 460a0714b6..6dc80b8a5f 100644
--- a/src/components/status_content/status_content.vue
+++ b/src/components/status_content/status_content.vue
@@ -1,74 +1,74 @@
<template>
<div
class="StatusContent"
:class="{ '-compact': compact }"
>
<slot name="header" />
<StatusBody
:status="status"
:compact="compact"
:single-line="singleLine"
:showing-tall="showingTall"
:expanding-subject="expandingSubject"
:showing-long-subject="showingLongSubject"
:toggle-showing-tall="toggleShowingTall"
:toggle-expanding-subject="toggleExpandingSubject"
:toggle-showing-long-subject="toggleShowingLongSubject"
:collapse="collapse"
@parse-ready="$emit('parseReady', $event)"
>
<div v-if="status.poll && status.poll.options && !compact">
<Poll
:base-poll="status.poll"
:emoji="status.emojis"
/>
</div>
<div
v-else-if="status.poll && status.poll.options && compact"
class="poll-icon"
>
<FAIcon
icon="poll-h"
size="2x"
/>
</div>
- <gallery
+ <Gallery
v-if="status.attachments.length !== 0"
class="attachments media-body"
:compact="compact"
:nsfw="nsfwClickthrough"
:attachments="status.attachments"
:limit="compact ? 1 : 0"
:size="attachmentSize"
@play="$emit('mediaplay', attachment.id)"
@pause="$emit('mediapause', attachment.id)"
/>
<div
v-if="statusCard && !noHeading && !compact"
class="link-preview media-body"
>
<link-preview
:card="status.card"
:size="attachmentSize"
:nsfw="nsfwClickthrough"
/>
</div>
</StatusBody>
<slot name="footer" />
</div>
</template>
<script src="./status_content.js"></script>
<style lang="scss">
.StatusContent {
flex: 1;
min-width: 0;
.poll-icon {
margin: 0.5em;
}
}
</style>
diff --git a/src/components/status_history_modal/status_history_modal.js b/src/components/status_history_modal/status_history_modal.js
index 2cf97d893a..c165fe411a 100644
--- a/src/components/status_history_modal/status_history_modal.js
+++ b/src/components/status_history_modal/status_history_modal.js
@@ -1,65 +1,63 @@
import { get } from 'lodash'
-import Modal from '../modal/modal.vue'
-import Status from '../status/status.vue'
+import Modal from 'src/components/modal/modal.vue'
import { useStatusHistoryStore } from 'src/stores/statusHistory.js'
const StatusHistoryModal = {
components: {
Modal,
- Status,
},
data() {
return {
statuses: [],
}
},
computed: {
modalActivated() {
return useStatusHistoryStore().modalActivated
},
params() {
return useStatusHistoryStore().params
},
statusId() {
return this.params.id
},
historyCount() {
return this.statuses.length
},
history() {
return this.statuses
},
},
watch: {
params(newVal, oldVal) {
const newStatusId = get(newVal, 'id') !== get(oldVal, 'id')
if (newStatusId) {
this.resetHistory()
}
if (
newStatusId ||
get(newVal, 'edited_at') !== get(oldVal, 'edited_at')
) {
this.fetchStatusHistory()
}
},
},
methods: {
resetHistory() {
this.statuses = []
},
fetchStatusHistory() {
this.$store.dispatch('fetchStatusHistory', this.params).then((data) => {
this.statuses = data
})
},
closeModal() {
useStatusHistoryStore().closeStatusHistoryModal()
},
},
}
export default StatusHistoryModal
diff --git a/src/components/status_popover/status_popover.js b/src/components/status_popover/status_popover.js
index 9ad12356ee..fe00563052 100644
--- a/src/components/status_popover/status_popover.js
+++ b/src/components/status_popover/status_popover.js
@@ -1,49 +1,50 @@
import { find } from 'lodash'
-import { defineAsyncComponent } from 'vue'
+
+import Popover from 'src/components/popover/popover.vue'
+import Status from 'src/components/status/status.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faCircleNotch } from '@fortawesome/free-solid-svg-icons'
library.add(faCircleNotch)
const StatusPopover = {
name: 'StatusPopover',
props: ['statusId'],
data() {
return {
error: false,
}
},
computed: {
status() {
return find(this.$store.state.statuses.allStatuses, { id: this.statusId })
},
},
components: {
- Status: defineAsyncComponent(() => import('../status/status.vue')),
- Popover: defineAsyncComponent(() => import('../popover/popover.vue')),
+ Popover,
},
methods: {
enter() {
if (!this.status) {
if (!this.statusId) {
this.error = true
return
}
this.$store
.dispatch('fetchStatus', this.statusId)
.then(() => (this.error = false))
.catch(() => (this.error = true))
}
},
},
watch: {
status(newStatus, oldStatus) {
if (newStatus !== oldStatus) {
this.$nextTick(() => this.$refs.popover.updateStyles())
}
},
},
}
export default StatusPopover
diff --git a/src/components/still-image/still-image-emoji-popover.js b/src/components/still-image/still-image-emoji-popover.js
index 979a67b1e2..02f036a522 100644
--- a/src/components/still-image/still-image-emoji-popover.js
+++ b/src/components/still-image/still-image-emoji-popover.js
@@ -1,74 +1,72 @@
import Popover from 'components/popover/popover.vue'
import SelectComponent from 'components/select/select.vue'
import { mapState } from 'pinia'
-import StillImage from './still-image.vue'
-
import { useEmojiStore } from 'src/stores/emoji'
import { useInterfaceStore } from 'src/stores/interface'
export default {
- components: { StillImage, Popover, SelectComponent },
+ components: { Popover, SelectComponent },
props: {
shortcode: {
type: String,
required: true,
},
isLocal: {
type: Boolean,
required: true,
},
},
data() {
return {
packName: '',
}
},
computed: {
isUserAdmin() {
return this.$store.state.users.currentUser?.rights.admin
},
...mapState(useEmojiStore, ['adminPacksLocal', 'adminPacksLocalLoading']),
},
methods: {
displayError(msg) {
useInterfaceStore().pushGlobalNotice({
messageKey: 'admin_dash.emoji.error',
messageArgs: [msg],
level: 'error',
})
},
copyToLocalPack() {
this.$store.state.api.backendInteractor
.addNewEmojiFile({
packName: this.packName,
file: this.$attrs.src,
shortcode: this.shortcode,
filename: '',
})
.then((resp) => resp.json())
.then((resp) => {
if (resp.error !== undefined) {
this.displayError(resp.error)
return
}
useInterfaceStore().pushGlobalNotice({
messageKey: 'admin_dash.emoji.copied_successfully',
messageArgs: [this.shortcode, this.packName],
level: 'success',
})
this.$refs.emojiPopover.hidePopover()
this.packName = ''
})
},
fetchEmojiPacksIfAdmin() {
useEmojiStore()
.getAdminPacksLocal()
.then(() => {
this.$refs.emojiPopover.updateStyles()
})
},
},
}
diff --git a/src/components/tag_timeline/tag_timeline.js b/src/components/tag_timeline/tag_timeline.js
index 9784599813..e82e86cfd0 100644
--- a/src/components/tag_timeline/tag_timeline.js
+++ b/src/components/tag_timeline/tag_timeline.js
@@ -1,36 +1,36 @@
-import Timeline from '../timeline/timeline.vue'
+import Timeline from 'src/components/timeline/timeline.vue'
const TagTimeline = {
created() {
this.$store.commit('clearTimeline', { timeline: 'tag' })
this.$store.dispatch('startFetchingTimeline', {
timeline: 'tag',
tag: this.tag,
})
},
components: {
Timeline,
},
computed: {
tag() {
return this.$route.params.tag
},
timeline() {
return this.$store.state.statuses.timelines.tag
},
},
watch: {
tag() {
this.$store.commit('clearTimeline', { timeline: 'tag' })
this.$store.dispatch('startFetchingTimeline', {
timeline: 'tag',
tag: this.tag,
})
},
},
unmounted() {
this.$store.dispatch('stopFetchingTimeline', 'tag')
},
}
export default TagTimeline
diff --git a/src/components/thread_tree/thread_tree.js b/src/components/thread_tree/thread_tree.js
index f5d5d17fe7..ad0c0039ba 100644
--- a/src/components/thread_tree/thread_tree.js
+++ b/src/components/thread_tree/thread_tree.js
@@ -1,102 +1,98 @@
-import Status from '../status/status.vue'
-
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faAngleDoubleDown,
faAngleDoubleRight,
} from '@fortawesome/free-solid-svg-icons'
library.add(faAngleDoubleDown, faAngleDoubleRight)
const ThreadTree = {
- components: {
- Status,
- },
+ components: {},
name: 'ThreadTree',
props: {
depth: Number,
status: Object,
inProfile: Boolean,
conversation: Array,
collapsable: Boolean,
isExpanded: Boolean,
pinnedStatusIdsObject: Object,
profileUserId: String,
isFocusedFunction: Function,
highlight: String,
getReplies: Function,
setHighlight: Function,
toggleExpanded: Function,
simple: Boolean,
// to control display of the whole thread forest
toggleThreadDisplay: Function,
threadDisplayStatus: Object,
showThreadRecursively: Function,
totalReplyCount: Object,
totalReplyDepth: Object,
statusContentProperties: Object,
setStatusContentProperty: Function,
toggleStatusContentProperty: Function,
dive: Function,
},
computed: {
suspendable() {
const selfSuspendable = this.$refs.statusComponent
? this.$refs.statusComponent.suspendable
: true
if (this.$refs.childComponent) {
return (
selfSuspendable &&
this.$refs.childComponent.every((s) => s.suspendable)
)
}
return selfSuspendable
},
reverseLookupTable() {
return this.conversation.reduce(
(table, status, index) => {
table[status.id] = index
return table
},
{
/* no-op */
},
)
},
currentReplies() {
return this.getReplies(this.status.id).map(({ id }) =>
this.statusById(id),
)
},
threadShowing() {
return this.threadDisplayStatus[this.status.id] === 'showing'
},
currentProp() {
return this.statusContentProperties[this.status.id]
},
},
methods: {
statusById(id) {
return this.conversation[this.reverseLookupTable[id]]
},
collapseThread() {
/* no-op */
},
showThread() {
/* no-op */
},
showAllSubthreads() {
/* no-op */
},
toggleCurrentProp(name) {
this.toggleStatusContentProperty(this.status.id, name)
},
setCurrentProp(name) {
this.setStatusContentProperty(this.status.id, name)
},
},
}
export default ThreadTree
diff --git a/src/components/timeline/timeline.js b/src/components/timeline/timeline.js
index e2bcfcf7e5..50b2acd90e 100644
--- a/src/components/timeline/timeline.js
+++ b/src/components/timeline/timeline.js
@@ -1,344 +1,342 @@
import { debounce, keyBy, throttle } from 'lodash'
import { mapState } from 'pinia'
-import Conversation from '../conversation/conversation.vue'
-import QuickFilterSettings from '../quick_filter_settings/quick_filter_settings.vue'
-import QuickViewSettings from '../quick_view_settings/quick_view_settings.vue'
-import ScrollTopButton from '../scroll_top_button/scroll_top_button.vue'
-import Status from '../status/status.vue'
-import TimelineMenu from '../timeline_menu/timeline_menu.vue'
+import Conversation from 'src/components/conversation/conversation.vue'
+import QuickFilterSettings from 'src/components/quick_filter_settings/quick_filter_settings.vue'
+import QuickViewSettings from 'src/components/quick_view_settings/quick_view_settings.vue'
+import ScrollTopButton from 'src/components/scroll_top_button/scroll_top_button.vue'
+import TimelineMenu from 'src/components/timeline_menu/timeline_menu.vue'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import timelineFetcher from 'src/services/timeline_fetcher/timeline_fetcher.service.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faArrowUp,
faCheck,
faCircleNotch,
faCirclePlus,
faCog,
faMinus,
} from '@fortawesome/free-solid-svg-icons'
library.add(faCircleNotch, faCog, faMinus, faArrowUp, faCirclePlus, faCheck)
const Timeline = {
props: [
'timeline',
'timelineName',
'title',
'userId',
'listId',
'statusId',
'bookmarkFolderId',
'tag',
'embedded',
'count',
'pinnedStatusIds',
'inProfile',
'footerSlipgate', // reference to an element where we should put our footer
],
data() {
return {
showScrollTop: false,
paused: false,
unfocused: false,
bottomedOut: false,
virtualScrollIndex: 0,
blockingClicks: false,
}
},
components: {
- Status,
ScrollTopButton,
Conversation,
TimelineMenu,
QuickFilterSettings,
QuickViewSettings,
},
computed: {
filteredVisibleStatuses() {
return this.timeline.visibleStatuses.filter(
(status) =>
this.timelineName !== 'user' ||
(status.id >= this.timeline.minId &&
status.id <= this.timeline.maxId),
)
},
filteredPinnedStatusIds() {
return (this.pinnedStatusIds || []).filter(
(statusId) => this.timeline.statusesObject[statusId],
)
},
newStatusCount() {
return this.timeline.newStatusCount
},
showLoadButton() {
return this.timeline.newStatusCount > 0 || this.timeline.flushMarker !== 0
},
loadButtonString() {
if (this.timeline.flushMarker !== 0) {
return this.$t('timeline.reload')
} else {
return `${this.$t('timeline.show_new')} (${this.newStatusCount})`
}
},
mobileLoadButtonString() {
if (this.timeline.flushMarker !== 0) {
return '+'
} else {
return this.newStatusCount > 99 ? '∞' : this.newStatusCount
}
},
classes() {
let rootClasses = !this.embedded
? ['panel', 'panel-default']
: ['-embedded']
if (this.blockingClicks)
rootClasses = rootClasses.concat(['-blocked', '_misclick-prevention'])
return {
root: rootClasses,
header: ['timeline-heading'].concat(
!this.embedded ? ['panel-heading', '-sticky'] : ['panel-body'],
),
body: ['timeline-body'].concat(
!this.embedded ? ['panel-body'] : ['panel-body'],
),
footer: ['timeline-footer'].concat(
!this.embedded ? ['panel-footer'] : ['panel-body'],
),
}
},
// id map of statuses which need to be hidden in the main list due to pinning logic
pinnedStatusIdsObject() {
return keyBy(this.pinnedStatusIds)
},
statusesToDisplay() {
const amount = this.timeline.visibleStatuses.length
const statusesPerSide = Math.ceil(Math.max(3, window.innerHeight / 80))
const nonPinnedIndex =
this.virtualScrollIndex - this.filteredPinnedStatusIds.length
const min = Math.max(0, nonPinnedIndex - statusesPerSide)
const max = Math.min(amount, nonPinnedIndex + statusesPerSide)
return this.timeline.visibleStatuses.slice(min, max).map((_) => _.id)
},
virtualScrollingEnabled() {
return useMergedConfigStore().mergedConfig.virtualScrolling
},
...mapState(useInterfaceStore, {
mobileLayout: (store) => store.layoutType === 'mobile',
}),
},
created() {
const store = this.$store
const credentials = store.state.users.currentUser.credentials
const showImmediately = this.timeline.visibleStatuses.length === 0
window.addEventListener('scroll', this.handleScroll)
if (store.state.api.fetchers[this.timelineName]) {
return false
}
timelineFetcher.fetchAndUpdate({
store,
credentials,
timeline: this.timelineName,
showImmediately,
userId: this.userId,
listId: this.listId,
statusId: this.statusId,
bookmarkFolderId: this.bookmarkFolderId,
tag: this.tag,
})
},
mounted() {
if (typeof document.hidden !== 'undefined') {
document.addEventListener(
'visibilitychange',
this.handleVisibilityChange,
false,
)
this.unfocused = document.hidden
}
window.addEventListener('keydown', this.handleShortKey)
setTimeout(this.determineVisibleStatuses, 250)
},
unmounted() {
window.removeEventListener('scroll', this.handleScroll)
window.removeEventListener('keydown', this.handleShortKey)
if (typeof document.hidden !== 'undefined')
document.removeEventListener(
'visibilitychange',
this.handleVisibilityChange,
false,
)
this.$store.commit('setLoading', {
timeline: this.timelineName,
value: false,
})
},
methods: {
stopBlockingClicks: debounce(function () {
this.blockingClicks = false
}, 1000),
blockClicksTemporarily() {
if (!this.blockingClicks) {
this.blockingClicks = true
}
this.stopBlockingClicks()
},
handleShortKey(e) {
// Ignore when input fields are focused
if (['textarea', 'input'].includes(e.target.tagName.toLowerCase())) return
if (e.key === '.') this.showNewStatuses()
},
showNewStatuses() {
if (this.timeline.flushMarker !== 0) {
this.$store.commit('clearTimeline', {
timeline: this.timelineName,
excludeUserId: true,
})
this.$store.commit('queueFlush', { timeline: this.timelineName, id: 0 })
if (this.timelineName === 'user') {
this.$store.dispatch('fetchPinnedStatuses', this.userId)
}
this.fetchOlderStatuses()
} else {
this.blockClicksTemporarily()
this.$store.commit('showNewStatuses', { timeline: this.timelineName })
this.paused = false
}
window.scrollTo({ top: 0 })
},
fetchOlderStatuses: throttle(
function () {
const store = this.$store
const credentials = store.state.users.currentUser.credentials
store.commit('setLoading', { timeline: this.timelineName, value: true })
timelineFetcher
.fetchAndUpdate({
store,
credentials,
timeline: this.timelineName,
older: true,
showImmediately: true,
userId: this.userId,
listId: this.listId,
statusId: this.statusId,
bookmarkFolderId: this.bookmarkFolderId,
tag: this.tag,
})
.then(({ statuses }) => {
if (statuses && statuses.length === 0) {
this.bottomedOut = true
}
})
.finally(() =>
store.commit('setLoading', {
timeline: this.timelineName,
value: false,
}),
)
},
1000,
this,
),
determineVisibleStatuses() {
if (!this.$refs.timeline) return
if (!this.virtualScrollingEnabled) return
const statuses = this.$refs.timeline.children
const cappedScrollIndex = Math.max(
0,
Math.min(this.virtualScrollIndex, statuses.length - 1),
)
if (statuses.length === 0) return
const height = Math.max(document.body.offsetHeight, window.pageYOffset)
const centerOfScreen = window.pageYOffset + window.innerHeight * 0.5
// Start from approximating the index of some visible status by using the
// the center of the screen on the timeline.
let approxIndex = Math.floor(statuses.length * (centerOfScreen / height))
let err = statuses[approxIndex].getBoundingClientRect().y
// if we have a previous scroll index that can be used, test if it's
// closer than the previous approximation, use it if so
const virtualScrollIndexY =
statuses[cappedScrollIndex].getBoundingClientRect().y
if (Math.abs(err) > virtualScrollIndexY) {
approxIndex = cappedScrollIndex
err = virtualScrollIndexY
}
// if the status is too far from viewport, check the next/previous ones if
// they happen to be better
while (err < -20 && approxIndex < statuses.length - 1) {
err += statuses[approxIndex].offsetHeight
approxIndex++
}
while (err > window.innerHeight + 100 && approxIndex > 0) {
approxIndex--
err -= statuses[approxIndex].offsetHeight
}
// this status is now the center point for virtual scrolling and visible
// statuses will be nearby statuses before and after it
this.virtualScrollIndex = approxIndex
},
scrollLoad() {
const bodyBRect = document.body.getBoundingClientRect()
const height = Math.max(bodyBRect.height, -bodyBRect.y)
if (
this.timeline.loading === false &&
this.$el.offsetHeight > 0 &&
window.innerHeight + window.pageYOffset >= height - 750
) {
this.fetchOlderStatuses()
}
},
handleScroll: throttle(function (e) {
this.determineVisibleStatuses()
this.scrollLoad(e)
}, 200),
handleVisibilityChange() {
this.unfocused = document.hidden
},
},
watch: {
filteredVisibleStatuses() {
this.determineVisibleStatuses()
},
newStatusCount(count) {
if (!useMergedConfigStore().mergedConfig.streaming) {
return
}
if (count > 0) {
// only 'stream' them when you're scrolled to the top
const doc = document.documentElement
const top = (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0)
if (
top < 15 &&
!this.paused &&
!(
this.unfocused &&
useMergedConfigStore().mergedConfig.pauseOnUnfocused
)
) {
this.showNewStatuses()
} else {
this.paused = true
}
}
},
},
}
export default Timeline
diff --git a/src/components/timeline_menu/timeline_menu.js b/src/components/timeline_menu/timeline_menu.js
index 3db087db60..ee6fa8f205 100644
--- a/src/components/timeline_menu/timeline_menu.js
+++ b/src/components/timeline_menu/timeline_menu.js
@@ -1,127 +1,127 @@
import { mapState as mapPiniaState } from 'pinia'
import { mapState } from 'vuex'
+import BookmarkFoldersMenuContent from 'src/components/bookmark_folders_menu/bookmark_folders_menu_content.vue'
+import ListsMenuContent from 'src/components/lists_menu/lists_menu_content.vue'
import { filterNavigation } from 'src/components/navigation/filter.js'
import { TIMELINES } from 'src/components/navigation/navigation.js'
import NavigationEntry from 'src/components/navigation/navigation_entry.vue'
-import BookmarkFoldersMenuContent from '../bookmark_folders_menu/bookmark_folders_menu_content.vue'
-import ListsMenuContent from '../lists_menu/lists_menu_content.vue'
-import Popover from '../popover/popover.vue'
+import Popover from 'src/components/popover/popover.vue'
import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useInterfaceStore } from 'src/stores/interface'
import { useListsStore } from 'src/stores/lists'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faChevronDown } from '@fortawesome/free-solid-svg-icons'
library.add(faChevronDown)
// Route -> i18n key mapping, exported and not in the computed
// because nav panel benefits from the same information.
export const timelineNames = (supportsBookmarkFolders) => {
return {
friends: 'nav.home_timeline',
bookmarks: supportsBookmarkFolders ? 'nav.all_bookmarks' : 'nav.bookmarks',
dms: 'nav.dms',
'public-timeline': 'nav.public_tl',
'public-external-timeline': 'nav.twkn',
quotes: 'nav.quotes',
bubble: 'nav.bubble',
}
}
const TimelineMenu = {
components: {
Popover,
NavigationEntry,
ListsMenuContent,
BookmarkFoldersMenuContent,
},
data() {
return {
isOpen: false,
}
},
created() {
if (timelineNames(this.bookmarkFolders)[this.$route.name]) {
useInterfaceStore().setLastTimeline(this.$route.name)
}
},
computed: {
useListsMenu() {
const route = this.$route.name
return route === 'lists-timeline'
},
useBookmarkFoldersMenu() {
const route = this.$route.name
return (
this.bookmarkFolders &&
(route === 'bookmark-folder' || route === 'bookmarks')
)
},
...mapPiniaState(useInstanceCapabilitiesStore, [
'pleromaChatMessagesAvailable',
'pleromaBookmarkFoldersAvailable',
'bookmarkFolders',
'localBubble',
]),
...mapPiniaState(useInstanceStore, ['privateMode', 'federating']),
...mapState({
currentUser: (state) => state.users.currentUser,
}),
timelinesList() {
return filterNavigation(
Object.entries(TIMELINES).map(([k, v]) => ({ ...v, name: k })),
{
hasChats: this.pleromaChatMessagesAvailable,
isFederating: this.federating,
isPrivate: this.privateMode,
currentUser: this.currentUser,
supportsBookmarkFolders: this.pleromaBookmarkFoldersAvailable,
supportsBubbleTimeline: this.localBubble,
},
)
},
},
methods: {
openMenu() {
// $nextTick is too fast, animation won't play back but
// instead starts in fully open position. Low values
// like 1-5 work on fast machines but not on mobile, 25
// seems like a good compromise that plays without significant
// added lag.
setTimeout(() => {
this.isOpen = true
}, 25)
},
blockOpen(event) {
// For the blank area inside the button element.
// Just setting @click.stop="" makes unintuitive behavior when
// menu is open and clicking on the blank area doesn't close it.
if (!this.isOpen) {
event.stopPropagation()
}
},
timelineName() {
const route = this.$route.name
if (route === 'tag-timeline') {
return '#' + this.$route.params.tag
}
if (route === 'lists-timeline') {
return useListsStore().findListTitle(this.$route.params.id)
}
if (route === 'bookmark-folder') {
return useBookmarkFoldersStore().findBookmarkFolderName(
this.$route.params.id,
)
}
const i18nkey = timelineNames(this.bookmarkFolders)[this.$route.name]
return i18nkey ? this.$t(i18nkey) : route
},
},
}
export default TimelineMenu
diff --git a/src/components/user_avatar/user_avatar.js b/src/components/user_avatar/user_avatar.js
index d484303c13..3ab0ee9e7b 100644
--- a/src/components/user_avatar/user_avatar.js
+++ b/src/components/user_avatar/user_avatar.js
@@ -1,57 +1,53 @@
-import StillImage from '../still-image/still-image.vue'
-
import { useInstanceStore } from 'src/stores/instance.js'
import { useInterfaceStore } from 'src/stores/interface.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faPeopleGroup, faRobot } from '@fortawesome/free-solid-svg-icons'
library.add(faRobot, faPeopleGroup)
const UserAvatar = {
props: {
// User object to show avatar of
user: {
required: true,
type: Object,
},
// Use less space and use alternative roundness
compact: {
required: false,
type: Boolean,
default: false,
},
// Show small icon indicating if account is a bot or group
showActorTypeIndicator: {
required: false,
type: Boolean,
default: false,
},
// Override avatar image URL, useful for profile editing
url: {
required: false,
type: String,
default: null,
},
},
data() {
return {
showPlaceholder: false,
defaultAvatar: `${useInstanceStore().server + useInstanceStore().instanceIdentity.defaultAvatar}`,
betterShadow: useInterfaceStore().browserSupport.cssFilter,
}
},
- components: {
- StillImage,
- },
+ components: {},
methods: {
imgSrc(src) {
return !src || this.showPlaceholder ? this.defaultAvatar : src
},
imageLoadError() {
this.showPlaceholder = true
},
},
}
export default UserAvatar
diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js
index bcb5f9ddcc..d987695dd9 100644
--- a/src/components/user_card/user_card.js
+++ b/src/components/user_card/user_card.js
@@ -1,603 +1,615 @@
-import ldEscape from 'lodash/escape'
-import isEqual from 'lodash/isEqual'
-import merge from 'lodash/merge'
-import ldUnescape from 'lodash/unescape'
+import {
+ isEqual,
+ escape as ldEscape,
+ unescape as ldUnescape,
+ merge,
+} from 'lodash'
import { mapState } from 'pinia'
+import { defineAsyncComponent } from 'vue'
import Checkbox from 'src/components/checkbox/checkbox.vue'
import ColorInput from 'src/components/color_input/color_input.vue'
-import DialogModal from 'src/components/dialog_modal/dialog_modal.vue'
import EmojiInput from 'src/components/emoji_input/emoji_input.vue'
import suggestor from 'src/components/emoji_input/suggestor.js'
-import ImageCropper from 'src/components/image_cropper/image_cropper.vue'
-import RichContent from 'src/components/rich_content/rich_content.jsx'
-import UserTimedFilterModal from 'src/components/user_timed_filter_modal/user_timed_filter_modal.vue'
-import AccountActions from '../account_actions/account_actions.vue'
-import FollowButton from '../follow_button/follow_button.vue'
-import ModerationTools from '../moderation_tools/moderation_tools.vue'
-import ProgressButton from '../progress_button/progress_button.vue'
-import RemoteFollow from '../remote_follow/remote_follow.vue'
-import Select from '../select/select.vue'
-import UserAvatar from '../user_avatar/user_avatar.vue'
-import UserLink from '../user_link/user_link.vue'
-import UserNote from '../user_note/user_note.vue'
+import ProgressButton from 'src/components/progress_button/progress_button.vue'
+import Select from 'src/components/select/select.vue'
+import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
+import UserLink from 'src/components/user_link/user_link.vue'
import { useEmojiStore } from 'src/stores/emoji.js'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useInterfaceStore } from 'src/stores/interface'
import { useMediaViewerStore } from 'src/stores/media_viewer'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { usePostStatusStore } from 'src/stores/post_status'
import { useUserHighlightStore } from 'src/stores/user_highlight.js'
import { propsToNative } from 'src/services/attributes_helper/attributes_helper.service.js'
import localeService from 'src/services/locale/locale.service.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faBell,
faBirthdayCake,
faClockRotateLeft,
faEdit,
faExpandAlt,
faExternalLinkAlt,
faRss,
faSave,
faSearchPlus,
faTimes,
} from '@fortawesome/free-solid-svg-icons'
library.add(
faSave,
faRss,
faBell,
faSearchPlus,
faExternalLinkAlt,
faEdit,
faTimes,
faExpandAlt,
faBirthdayCake,
faClockRotateLeft,
)
const KNOWN_TAGS = new Set([
'mrf_tag:media-force-nsfw',
'mrf_tag:media-strip',
'mrf_tag:force-unlisted',
'mrf_tag:sandbox',
'mrf_tag:disable-remote-subscription',
'mrf_tag:disable-any-subscription',
])
export default {
props: {
// Enables all the options for profile editing, used in settings -> profile tab
editable: {
required: false,
default: false,
type: Boolean,
},
// ID of user to show data of
userId: {
required: true,
type: String,
},
// Use a compact layout that hides bio, stats etc.
hideBio: {
required: false,
default: false,
type: Boolean,
},
// default - open profile, 'zoom' - zoom, function - call function
avatarAction: {
required: false,
type: String,
default: 'default',
},
// Show note editor if supported
hasNoteEditor: {
required: false,
type: Boolean,
default: false,
},
// Show close icon (for popovers)
showClose: {
required: false,
type: Boolean,
default: false,
},
// Show close icon (for popovers)
showExpand: {
required: false,
type: Boolean,
default: false,
},
// Disable forced 3:1 aspect ratio
compact: {
required: false,
type: Boolean,
default: false,
},
},
components: {
- DialogModal,
+ DialogModal: defineAsyncComponent(
+ () => import('src/components/dialog_modal/dialog_modal.vue'),
+ ),
UserAvatar,
Checkbox,
- RemoteFollow,
- ModerationTools,
- AccountActions,
+ RemoteFollow: defineAsyncComponent(
+ () => import('src/components/remote_follow/remote_follow.vue'),
+ ),
+ ModerationTools: defineAsyncComponent(
+ () => import('src/components/moderation_tools/moderation_tools.vue'),
+ ),
+ AccountActions: defineAsyncComponent(
+ () => import('src/components/account_actions/account_actions.vue'),
+ ),
ProgressButton,
- FollowButton,
+ FollowButton: defineAsyncComponent(
+ () => import('src/components/follow_button/follow_button.vue'),
+ ),
Select,
- RichContent,
UserLink,
- UserNote,
- UserTimedFilterModal,
+ UserNote: defineAsyncComponent(
+ () => import('src/components/user_note/user_note.vue'),
+ ),
+ UserTimedFilterModal: defineAsyncComponent(
+ () =>
+ import(
+ 'src/components/user_timed_filter_modal/user_timed_filter_modal.vue'
+ ),
+ ),
ColorInput,
EmojiInput,
- ImageCropper,
+ ImageCropper: defineAsyncComponent(
+ () => import('src/components/image_cropper/image_cropper.vue'),
+ ),
},
data() {
const user = this.$store.getters.findUser(this.userId)
return {
followRequestInProgress: false,
// Editable stuff
editImage: false,
newName: user.name_unescaped,
editingName: false,
newBio: ldUnescape(user.description),
editingBio: false,
newAvatar: null,
newAvatarFile: null,
newBanner: null,
newBannerFile: null,
newActorType: user.actor_type,
newBirthday: user.birthday,
newShowBirthday: user.show_birthday,
newShowRole: user.show_role,
newFields: user.fields?.map((field) => ({
name: field.name,
value: field.value,
})),
editingFields: false,
}
},
created() {
this.$store.dispatch('fetchUserRelationship', this.user.id)
},
computed: {
escapedNewBio() {
return ldEscape(this.newBio).replace(/\n/g, '<br>')
},
somethingToSave() {
if (this.newName !== this.user.name_unescaped) return true
if (this.newBio !== ldUnescape(this.user.description)) return true
if (this.newAvatar !== null) return true
if (this.newBanner !== null) return true
if (this.newActorType !== this.user.actor_type) return true
if (this.newBirthday !== this.user.birthday) return true
if (this.newShowBirthday !== this.user.show_birthday) return true
if (this.newShowRole !== this.user.show_role) return true
if (
!isEqual(
this.newFields,
this.user.fields?.map((field) => ({
name: field.name,
value: field.value,
})),
)
)
return true
return false
},
groupActorAvailable() {
return useInstanceCapabilitiesStore().groupActorAvailable
},
availableActorTypes() {
return this.groupActorAvailable
? ['Person', 'Service', 'Group']
: ['Person', 'Service']
},
user() {
return this.$store.getters.findUser(this.userId)
},
role() {
return this.user.role
},
relationship() {
return this.$store.getters.relationship(this.userId)
},
isOtherUser() {
return this.user.id !== this.$store.state.users.currentUser.id
},
subscribeUrl() {
const serverUrl = new URL(this.user.statusnet_profile_url)
return `${serverUrl.protocol}//${serverUrl.host}/main/ostatus`
},
loggedIn() {
return this.$store.state.users.currentUser
},
dailyAvg() {
const days = Math.ceil(
(new Date() - new Date(this.user.created_at)) / (60 * 60 * 24 * 1000),
)
return Math.round(this.user.statuses_count / days)
},
emoji() {
return useEmojiStore().customEmoji.map((e) => ({
shortcode: e.displayText,
static_url: e.imageUrl,
url: e.imageUrl,
}))
},
userHighlightType: {
get() {
return useUserHighlightStore().get(this.user.screen_name).type
},
set(type) {
if (type !== 'disabled') {
useUserHighlightStore().setAndSave({
user: this.user.screen_name,
value: { type },
})
} else {
useUserHighlightStore().unsetAndSave({ user: this.user.screen_name })
}
},
},
userHighlightColor: {
get() {
return useUserHighlightStore().get(this.user.screen_name).color
},
set(color) {
useUserHighlightStore().setAndSave({
user: this.user.screen_name,
value: { color },
})
},
},
visibleRole() {
if (!this.newShowRole) {
return
}
const rights = this.user.rights
if (!rights) {
return
}
const validRole = rights.admin || rights.moderator
const roleTitle = rights.admin ? 'admin' : 'moderator'
return validRole && roleTitle
},
hideFollowsCount() {
return this.isOtherUser && this.user.hide_follows_count
},
hideFollowersCount() {
return this.isOtherUser && this.user.hide_followers_count
},
showModerationMenu() {
const privileges = this.loggedIn.privileges
return (
this.loggedIn.role === 'admin' ||
privileges.includes('users_manage_activation_state') ||
privileges.includes('users_delete') ||
privileges.includes('users_manage_tags')
)
},
hasNote() {
return this.relationship.note
},
supportsNote() {
return 'note' in this.relationship
},
muteExpiryAvailable() {
return Object.hasOwn(this.user, 'mute_expires_at')
},
muteExpiry() {
return this.user.mute_expires_at === false
? this.$t('user_card.mute_expires_forever')
: this.$t('user_card.mute_expires_at', [
new Date(this.user.mute_expires_at).toLocaleString(),
])
},
blockExpiryAvailable() {
return Object.hasOwn(this.user, 'block_expires_at')
},
blockExpiry() {
return this.user.block_expires_at == null
? this.$t('user_card.block_expires_forever')
: this.$t('user_card.block_expires_at', [
new Date(this.user.mute_expires_at).toLocaleString(),
])
},
formattedBirthday() {
const browserLocale = localeService.internalToBrowserLocale(
this.$i18n.locale,
)
return (
this.user.birthday &&
new Date(Date.parse(this.user.birthday)).toLocaleDateString(
browserLocale,
{ timeZone: 'UTC', day: 'numeric', month: 'long', year: 'numeric' },
)
)
},
formattedJoinDate() {
const browserLocale = localeService.internalToBrowserLocale(
this.$i18n.locale,
)
return (
this.user.created_at &&
new Date(Date.parse(this.user.created_at)).toLocaleDateString(
browserLocale,
{ timeZone: 'UTC', day: 'numeric', month: 'long', year: 'numeric' },
)
)
},
// Editable stuff
avatarImgSrc() {
const currentUrl =
this.user.profile_image_url_original || this.defaultAvatar
if (!this.editable) return currentUrl
const newUrl =
this.newAvatar === null ? this.defaultAvatar : this.newAvatar
return this.newAvatar === null ? currentUrl : newUrl
},
bannerImgSrc() {
const currentUrl = this.user.cover_photo || this.defaultBanner
if (!this.editable) return currentUrl
const newUrl =
this.newBanner === null ? this.defaultBanner : this.newBanner
return this.newBanner === null ? currentUrl : newUrl
},
defaultAvatar() {
return (
useInstanceStore().server +
useInstanceStore().instanceIdentity.defaultAvatar
)
},
defaultBanner() {
return (
useInstanceStore().server +
useInstanceStore().instanceIdentity.defaultBanner
)
},
isDefaultAvatar() {
const baseAvatar = useInstanceStore().instanceIdenitity.defaultAvatar
return (
!this.$store.state.users.currentUser.profile_image_url ||
this.$store.state.users.currentUser.profile_image_url.includes(
baseAvatar,
)
)
},
isDefaultBanner() {
const baseBanner = useInstanceStore().instanceIdentity.defaultBanner
return (
!this.$store.state.users.currentUser.cover_photo ||
this.$store.state.users.currentUser.cover_photo.includes(baseBanner)
)
},
fieldsLimits() {
return useInstanceStore().limits.fieldsLimits
},
maxFields() {
return this.fieldsLimits ? this.fieldsLimits.maxFields : 0
},
emojiUserSuggestor() {
return suggestor({
emoji: [
...useEmojiStore().standardEmojiList,
...useEmojiStore().customEmoji,
],
store: this.$store,
})
},
emojiSuggestor() {
return suggestor({
emoji: [
...useEmojiStore().standardEmojiList,
...useEmojiStore().customEmoji,
],
})
},
allowNonSquareEmoji() {
return this.mergedConfig.nonSquareEmoji
},
hideUserStats() {
return this.mergedConfig.hideUserStats
},
hideRemarks() {
return this.mergedConfig.userCardHidePersonalMarks
},
...mapState(useMergedConfigStore, ['mergedConfig']),
},
methods: {
isKnownTag(tag) {
return KNOWN_TAGS.has(tag)
},
muteUser() {
this.$refs.timedMuteDialog.optionallyPrompt()
},
unmuteUser() {
this.$store.dispatch('unmuteUser', this.user.id)
},
subscribeUser() {
return this.$store.dispatch('subscribeUser', this.user.id)
},
unsubscribeUser() {
return this.$store.dispatch('unsubscribeUser', this.user.id)
},
linkClicked({ target }) {
if (target.tagName === 'SPAN') {
target = target.parentNode
}
if (target.tagName === 'A') {
window.open(target.href, '_blank')
}
},
userProfileLink(user) {
return generateProfileLink(
user.id,
user.screen_name,
useInstanceStore().restrictedNicknames,
)
},
openProfileTab() {
useInterfaceStore().openSettingsModalTab('profile')
},
zoomAvatar() {
const attachment = {
url: this.user.profile_image_url_original,
type: 'image',
}
useMediaViewerStore().setMedia([attachment])
useMediaViewerStore().setCurrentMedia(attachment)
},
mentionUser() {
usePostStatusStore().openPostStatusModal({
profileMention: true,
repliedUser: this.user,
})
},
onAvatarClickHandler(e) {
if (this.onAvatarClick) {
e.preventDefault()
this.onAvatarClick()
}
},
// Editable stuff
changeAvatar() {
this.editImage = 'avatar'
},
changeBanner() {
this.editImage = 'banner'
},
submitImage({ canvas, file }) {
if (canvas) {
return canvas.toBlob((data) =>
this.submitImage({ canvas: null, file: data }),
)
}
const reader = new window.FileReader()
reader.onload = (e) => {
const dataUrl = e.target.result
if (this.editImage === 'avatar') {
this.newAvatar = dataUrl
this.newAvatarFile = file
} else {
this.newBanner = dataUrl
this.newBannerFile = file
}
this.editImage = false
}
reader.readAsDataURL(file)
},
resetImage() {
if (this.editImage === 'avatar') {
this.newAvatar = null
this.newAvatarFile = null
} else {
this.newBanner = null
this.newBannerFile = null
}
this.editImage = false
},
addField() {
if (this.newFields.length < this.maxFields) {
this.newFields.push({ name: '', value: '' })
}
},
deleteField(index) {
this.newFields.splice(index, 1)
},
propsToNative(props) {
return propsToNative(props)
},
cancelImageText() {
return
},
resetState() {
const user = this.$store.state.users.currentUser
this.newName = user.name_unescaped
this.newBio = ldUnescape(user.description)
this.newAvatar = null
this.newAvatarFile = null
this.newBanner = null
this.newBannerFile = null
this.newActorType = user.actor_type
this.newBirthday = user.birthday
this.newShowBirthday = user.show_birthday
this.newShowRole = user.show_role
this.newFields = user.fields.map((field) => ({
name: field.name,
value: field.value,
}))
},
updateProfile() {
const params = {
note: this.newBio,
// Backend notation.
display_name: this.newName,
fields_attributes: this.newFields.filter((el) => el != null),
show_role: !!this.newShowRole,
birthday: this.newBirthday || '',
show_birthday: !!this.newShowBirthday,
}
if (this.newActorType) {
params.actor_type = this.newActorType
}
if (this.newAvatarFile !== null) {
params.avatar = this.newAvatarFile
}
if (this.newBannerFile !== null) {
params.header = this.newBannerFile
}
this.$store.state.api.backendInteractor
.updateProfile({ params })
.then((user) => {
this.newFields.splice(this.newFields.length)
merge(this.newFields, user.fields)
this.$store.commit('addNewUsers', [user])
this.$store.commit('setCurrentUser', user)
this.resetState()
})
.catch((error) => {
this.displayUploadError(error)
})
},
displayUploadError(error) {
useInterfaceStore().pushGlobalNotice({
messageKey: 'upload.error.message',
messageArgs: [error.message],
level: 'error',
})
},
},
}
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
index 4d77d92d0f..3eb142954a 100644
--- a/src/components/user_card/user_card.vue
+++ b/src/components/user_card/user_card.vue
@@ -1,744 +1,745 @@
<template>
<div class="user-card">
<div class="user-card-inner">
<div class="user-info">
<div
class="user-identity"
:class="{ '-compact': compact }"
>
<div class="header-overlay">
<div class="banner-image">
<img
:src="bannerImgSrc"
:class="{ 'hide-bio': hideBio }"
>
</div>
<div
class="banner-overlay"
:class="{ 'hide-bio': hideBio }"
/>
</div>
<a
v-if="avatarAction === 'zoom'"
class="user-info-avatar -link"
@click="zoomAvatar"
>
<UserAvatar :user="user" />
<div class="user-info-avatar -link -overlay">
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="search-plus"
/>
</div>
</a>
<button
v-else-if="editable"
class="user-info-avatar button-unstyled -link"
:class="{ '-editable': editable }"
@click="changeAvatar"
>
<UserAvatar
:user="user"
:url="avatarImgSrc"
/>
<div class="user-info-avatar -link -overlay">
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="pencil"
/>
</div>
</button>
<UserAvatar
v-else-if="typeof avatarAction === 'function'"
class="user-info-avatar"
:user="user"
@click="avatarAction"
/>
<router-link
v-else
class="user-info-avatar"
:to="userProfileLink(user)"
>
<UserAvatar :user="user" />
</router-link>
<div class="user-summary">
<div class="top-line">
<div
class="other-actions"
>
<button
v-if="editable"
:disabled="newName && newName.length === 0"
class="btn button-unstyled edit-banner-button"
@click="changeBanner"
>
{{ $t('settings.change_banner') }}
<FAIcon
fixed-width
class="icon"
icon="pencil"
:title="$t('settings.change_banner')"
/>
</button>
<button
v-else-if="!editable && !isOtherUser && user.is_local"
class="button-unstyled edit-profile-button"
@click.stop="openProfileTab"
>
<FAIcon
fixed-width
class="icon"
icon="edit"
:title="$t('user_card.edit_profile')"
/>
</button>
<a
v-if="isOtherUser && !user.is_local"
:href="user.statusnet_profile_url"
target="_blank"
class="button-unstyled external-link-button"
>
<FAIcon
class="icon"
icon="external-link-alt"
/>
</a>
<AccountActions
v-if="isOtherUser && loggedIn"
:user="user"
:relationship="relationship"
/>
<router-link
v-if="showExpand"
:to="userProfileLink(user)"
class="button-unstyled external-link-button"
@click="$emit('close')"
>
<FAIcon
class="icon"
icon="expand-alt"
/>
</router-link>
<button
v-if="showClose"
class="button-unstyled external-link-button"
@click="$emit('close')"
>
<FAIcon
class="icon"
icon="times"
/>
</button>
</div>
<div class="name-wrapper">
<router-link
v-if="!editable || !editingName"
:to="userProfileLink(user)"
class="user-name"
>
<RichContent
:title="editable ? newName : user.name_unescaped"
:html="editable ? newName : user.name_unescaped"
:emoji="editable ? emoji : user.emoji"
:allow-non-square-emoji="allowNonSquareEmoji"
/>
</router-link>
<EmojiInput
v-else-if="editingName"
v-model="newName"
enable-emoji-picker
:suggest="emojiSuggestor"
>
<template #default="inputProps">
<input
id="username"
v-model="newName"
class="input name-changer"
v-bind="propsToNative(inputProps)"
>
</template>
</EmojiInput>
<button
v-if="editable"
class="button-unstyled edit-button"
:title="$t('settings.toggle_edit')"
@click="editingName = !editingName"
>
<FAIcon
class="icon"
icon="pencil"
/>
</button>
</div>
</div>
<div class="bottom-line">
<UserLink
class="user-screen-name"
:user="user"
/>
<span
v-if="user.locked"
class="lock-icon"
>
<FAIcon
icon="lock"
size="sm"
/>
</span>
<span
v-if="relationship.followed_by && loggedIn && isOtherUser"
class="alert neutral user-role"
>
{{ $t('user_card.follows_you') }}
</span>
<template v-if="!hideBio">
<span
v-if="user.deactivated"
class="alert neutral user-role"
>
{{ $t('user_card.deactivated') }}
</span>
<span
v-if="!!visibleRole"
class="alert neutral user-role"
>
{{ $t(`general.role.${visibleRole}`) }}
</span>
<span
v-if="user.actor_type === 'Service'"
class="alert neutral user-role"
>
{{ $t('user_card.bot') }}
</span>
<span
v-if="user.actor_type === 'Group'"
class="alert neutral user-role"
>
{{ $t('user_card.group') }}
</span>
<span
v-for="tag in user.tags"
:key="tag"
class="alert warning user-role"
>
{{ isKnownTag ? $t('user_card.tags.' + tag) : tag }}
</span>
</template>
</div>
</div>
</div>
<div
v-if="loggedIn && isOtherUser"
class="user-interactions"
>
<div class="btn-group">
<FollowButton
:relationship="relationship"
:user="user"
/>
<template v-if="relationship.following">
<ProgressButton
v-if="!relationship.notifying"
class="btn button-default"
:click="subscribeUser"
:title="$t('user_card.subscribe')"
>
<FAIcon icon="bell" />
</ProgressButton>
<ProgressButton
v-else
class="btn button-default toggled"
:click="unsubscribeUser"
:title="$t('user_card.unsubscribe')"
>
<FALayers>
<FAIcon
icon="rss"
transform="left-5 shrink-6 up-3 rotate-20"
flip="horizontal"
/>
<FAIcon
icon="rss"
transform="right-5 shrink-6 up-3 rotate-20"
/>
<FAIcon icon="bell" />
</FALayers>
</ProgressButton>
</template>
</div>
<button
v-if="relationship.muting"
class="btn button-default btn-mute toggled"
:disabled="user.deactivated"
@click="unmuteUser"
>
{{ $t('user_card.muted') }}
</button>
<button
v-else
class="btn button-default btn-mute"
:disabled="user.deactivated"
@click="muteUser"
>
{{ $t('user_card.mute') }}
</button>
<button
class="btn button-default btn-mention"
:disabled="user.deactivated"
@click="mentionUser"
>
{{ $t('user_card.mention') }}
</button>
<ModerationTools
v-if="showModerationMenu"
class="moderation-menu"
:user="user"
/>
</div>
<div
v-if="!loggedIn && user.is_local"
class="user-interactions"
>
<RemoteFollow :user="user" />
</div>
</div>
</div>
<div
v-if="!editable && loggedIn && isOtherUser && (hasNote || !hideBio) && !hideRemarks"
class="personal-marks"
>
<UserNote
v-if="hasNote || (hasNoteEditor && supportsNote)"
:user="user"
:relationship="relationship"
:editable="hasNoteEditor"
/>
<div
v-if="!hideBio"
class="highlighter"
>
<h4>{{ $t('user_card.highlight_header') }}</h4>
<Select
:id="'userHighlightSel'+user.id"
v-model="userHighlightType"
class="userHighlightSel unstyled"
:class="{ '-none': userHighlightType === 'disabled' }"
>
<option value="disabled">
{{ $t('user_card.highlight_new.disabled') }}
</option>
<option value="solid">
{{ $t('user_card.highlight_new.solid') }}
</option>
<option value="striped">
{{ $t('user_card.highlight_new.striped') }}
</option>
<option value="side">
{{ $t('user_card.highlight_new.side') }}
</option>
</Select>
<!-- id's need to be unique, otherwise vue confuses which user-card checkbox belongs to -->
<ColorInput
v-if="userHighlightType !== 'disabled'"
v-model="userHighlightColor"
class="highlighter-color"
:show-optional-checkbox="false"
name="'userHighlightColorTx'+user.id"
:unstyled="true"
/>
</div>
</div>
<h3 v-if="editable">
<span>
{{ $t('settings.bio') }}
</span>
{{ ' ' }}
<button
class="button-default"
@click="editingBio = !editingBio"
>
{{ $t('settings.toggle_edit') }}
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="pencil"
/>
</button>
</h3>
<template v-if="!editable || !editingBio">
<RichContent
v-if="!hideBio"
class="user-card-bio"
:class="{ '-justify-left': mergedConfig.userCardLeftJustify }"
:html="editable ? escapedNewBio : user.description_html"
:emoji="editable ? emoji : user.emoji"
:allow-non-square-emoji="allowNonSquareEmoji"
:handle-links="true"
/>
</template>
<template v-else-if="editingBio">
<EmojiInput
v-model="newBio"
enable-emoji-picker
class="user-card-bio"
:class="{ '-justify-left': mergedConfig.userCardLeftJustify }"
:suggest="emojiUserSuggestor"
>
<template #default="inputProps">
<textarea
v-model="newBio"
class="input bio resize-height"
v-bind="propsToNative(inputProps)"
:rows="newBio.split(/\n/g).length"
/>
</template>
</EmojiInput>
</template>
<h3 v-if="editable">
<span>
{{ $t('settings.profile_fields.label') }}
</span>
{{ ' ' }}
<button
class="button-default"
@click="editingFields = !editingFields"
>
{{ $t('settings.toggle_edit') }}
<FAIcon
class="fa-scale-110 fa-old-padding"
icon="pencil"
/>
</button>
</h3>
<template v-if="!editable || !editingFields">
<div
v-if="!hideBio && user.fields_html && user.fields_html.length > 0"
class="user-profile-fields"
>
<dl
v-for="(field, index) in (editable ? newFields : user.fields_html)"
:key="index"
class="user-profile-field"
>
<dt
:title="field.name"
class="user-profile-field-name"
>
<RichContent
:html="field.name"
:emoji="editable ? emoji : user.emoji"
:allow-non-square-emoji="allowNonSquareEmoji"
/>
</dt>
<dd
:title="field.value"
class="user-profile-field-value"
>
<RichContent
:html="field.value"
:emoji="editable ? emoji : user.emoji"
:allow-non-square-emoji="allowNonSquareEmoji"
/>
</dd>
</dl>
</div>
</template>
<template v-else-if="editingFields">
<div
v-if="maxFields > 0"
class="user-profile-fields"
>
<dl
v-for="(_, i) in newFields"
:key="i"
class="user-profile-field"
>
<dt
class="user-profile-field-name -edit"
>
<EmojiInput
v-model="newFields[i].name"
enable-emoji-picker
:suggest="emojiSuggestor"
>
<template #default="inputProps">
<input
v-model="newFields[i].name"
:placeholder="$t('settings.profile_fields.name')"
v-bind="propsToNative(inputProps)"
class="input"
>
</template>
</EmojiInput>
</dt>
<dd
class="user-profile-field-value -edit"
>
<EmojiInput
v-model="newFields[i].value"
enable-emoji-picker
:suggest="emojiSuggestor"
>
<template #default="inputProps">
<input
v-model="newFields[i].value"
:placeholder="$t('settings.profile_fields.value')"
v-bind="propsToNative(inputProps)"
class="input input"
>
</template>
</EmojiInput>
<button
class="delete-field button-default -hover-highlight"
@click="deleteField(i)"
>
<!-- TODO something is wrong with v-show here -->
<FAIcon
v-if="newFields.length > 1"
icon="times"
/>
</button>
</dd>
</dl>
<button
v-if="newFields.length < maxFields"
class="user-profile-field-add add-field button-default -hover-highlight"
@click="addField"
>
<FAIcon
icon="plus"
class="icon"
/>
<span class="label">
{{ $t("settings.profile_fields.add_field") }}
</span>
</button>
</div>
</template>
<div
v-if="!hideBio"
class="user-extras"
>
<span
v-if="!editable && !hideUserStats"
class="user-stats"
>
<dl
v-if="!hideUserStats && !hideBio"
class="user-count"
>
<dd>{{ user.statuses_count }}</dd>
{{ ' ' }}
<dt>{{ $t('user_card.statuses') }}</dt>
</dl>
<dl class="user-count">
<dd>{{ dailyAvg }}</dd>
{{ ' ' }}
<dt>{{ $t('user_card.statuses_per_day') }}</dt>
</dl>
<dl class="user-count">
<dd>{{ hideFollowsCount ? $t('user_card.hidden') : user.friends_count }}</dd>
{{ ' ' }}
<dt>{{ $t('user_card.followees') }}</dt>
</dl>
<dl class="user-count">
<dd>{{ hideFollowersCount ? $t('user_card.hidden') : user.followers_count }}</dd>
{{ ' ' }}
<dt>{{ $t('user_card.followers') }}</dt>
</dl>
</span>
<span
v-if="!hideUserStats"
class="user-stats"
>
<template v-if="!hideBio">
<dl
v-if="user.birthday && !editable"
class="user-count"
>
<dd>
<FAIcon
class="fa-old-padding"
icon="birthday-cake"
/>
</dd>
{{ ' ' }}
<dt>
{{ $t('user_card.birthday', { birthday: formattedBirthday }) }}
</dt>
</dl>
<div
v-else-if="editable"
class="birthday"
>
<div>
<Checkbox v-model="newShowBirthday">
{{ $t('settings.birthday.show_birthday') }}
</Checkbox>
</div>
<FAIcon
class="fa-old-padding"
icon="birthday-cake"
/>
{{ $t('settings.birthday.label') }}
<input
id="birthday"
v-model="newBirthday"
type="date"
class="input birthday-input"
>
</div>
</template>
<dl
v-if="!editable"
class="user-count"
>
<dd>
{{ $t('user_card.joined') }}
</dd>
{{ ' ' }}
<dt>
{{ formattedJoinDate }}
</dt>
</dl>
</span>
</div>
<template v-if="editable">
<h3>{{ $t('settings.profile_other') }}</h3>
<p
v-if="role === 'admin' || role === 'moderator'"
class="user-card-setting"
>
<Checkbox v-model="newShowRole">
<template v-if="role === 'admin'">
{{ $t('settings.show_admin_badge') }}
</template>
<template v-if="role === 'moderator'">
{{ $t('settings.show_moderator_badge') }}
</template>
</Checkbox>
</p>
<p class="user-card-setting">
<label>
{{ $t('settings.actor_type') }}
<Select v-model="newActorType">
<option
v-for="option in availableActorTypes"
:key="option"
:value="option"
>
{{ $t('settings.actor_type_' + (option === 'Person' ? 'person_proper' : option)) }}
</option>
</Select>
<div v-if="groupActorAvailable">
<small>
{{ $t('settings.actor_type_description') }}
</small>
</div>
</label>
</p>
<div class="bottom-buttons">
<button
v-if="editable"
:disabled="!somethingToSave"
class="btn button-default reset-profile-button"
@click="resetState"
>
{{ $t('settings.reset') }}
<FAIcon
fixed-width
class="icon"
icon="clock-rotate-left"
:title="$t('user_card.edit_profile')"
/>
</button>
<button
v-if="editable"
:disabled="!somethingToSave"
class="btn button-default save-profile-button"
@click="updateProfile"
>
{{ $t('settings.save') }}
<FAIcon
fixed-width
class="icon"
icon="save"
:title="$t('user_card.edit_profile')"
/>
</button>
</div>
</template>
<teleport to="#modal">
<UserTimedFilterModal
+ v-if="isOtherUser"
ref="timedMuteDialog"
:user="user"
:is-mute="true"
/>
</teleport>
<teleport to="#modal">
<DialogModal
v-if="editImage"
class="edit-image"
>
<template #header>
{{ editImage === 'avatar' ? $t('settings.change_avatar') : $t('settings.change_banner') }}
</template>
<p>
{{ editImage === 'avatar' ? $t('settings.avatar_size_instruction') : $t('settings.banner_size_instruction' ) }}
</p>
<div
class="image-container"
:class="{ '-banner': editImage === 'banner' }"
>
<image-cropper
ref="cropper"
class="cropper"
:aspect-ratio="editImage === 'avatar' ? 1 : 3"
@submit="submitImage"
/>
</div>
<button
id="pick-image"
class="button-default btn"
type="button"
@click="() => $refs.cropper.pickImage()"
>
{{ $t('settings.select_picture') }}
</button>
<template #footer>
<button
class="button-default btn"
type="button"
@click="editImage = false"
>
{{ $t('image_cropper.cancel') }}
</button>
<button
:title="editImage === 'avatar' ? $t('settings.reset_avatar') : $t('settings.reset_banner')"
class="button-default btn reset-button"
@click="resetImage"
>
{{ editImage === 'avatar' ? $t('settings.reset_avatar') : $t('settings.reset_banner' ) }}
</button>
<button
class="button-default btn"
type="button"
@click="$refs.cropper.submit(false)"
>
{{ $t('image_cropper.save_without_cropping') }}
</button>
<button
class="button-default btn"
type="button"
@click="$refs.cropper.submit(true)"
>
{{ $t('image_cropper.save') }}
</button>
</template>
</DialogModal>
</teleport>
</div>
</template>
<script src="./user_card.js"></script>
<style lang="scss" src="./user_card.scss" />
diff --git a/src/components/user_link/user_link.vue b/src/components/user_link/user_link.vue
index e8a4ac4a77..49544ff2ee 100644
--- a/src/components/user_link/user_link.vue
+++ b/src/components/user_link/user_link.vue
@@ -1,46 +1,46 @@
<template>
<div class="user-profile-link">
<router-link
:title="user.screen_name_ui"
:to="userProfileLink(user)"
>
<slot>
{{ at ? '@' : '' }}{{ user.screen_name_ui }}<UnicodeDomainIndicator
:user="user"
/>
</slot>
</router-link>
</div>
</template>
<script>
-import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue'
+import UnicodeDomainIndicator from 'src/components/unicode_domain_indicator/unicode_domain_indicator.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
const UserLink = {
props: {
user: Object,
at: {
type: Boolean,
default: true,
},
},
components: {
UnicodeDomainIndicator,
},
methods: {
userProfileLink(user) {
return generateProfileLink(
user.id,
user.screen_name,
useInstanceStore().restrictedNicknames,
)
},
},
}
export default UserLink
</script>
diff --git a/src/components/user_list_menu/user_list_menu.js b/src/components/user_list_menu/user_list_menu.js
index 47a84a6bba..b361752768 100644
--- a/src/components/user_list_menu/user_list_menu.js
+++ b/src/components/user_list_menu/user_list_menu.js
@@ -1,124 +1,68 @@
import { mapState } from 'pinia'
-import DialogModal from '../dialog_modal/dialog_modal.vue'
-import Popover from '../popover/popover.vue'
+import Popover from 'src/components/popover/popover.vue'
import { useListsStore } from 'src/stores/lists.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faChevronRight } from '@fortawesome/free-solid-svg-icons'
library.add(faChevronRight)
const UserListMenu = {
props: ['user'],
data() {
return {}
},
components: {
- DialogModal,
Popover,
},
created() {
this.$store.dispatch('fetchUserInLists', this.user.id)
},
computed: {
...mapState(useListsStore, {
allLists: (store) => store.allLists,
}),
inListsSet() {
return new Set(this.user.inLists.map((x) => x.id))
},
lists() {
if (!this.user.inLists) return []
return this.allLists.map((list) => ({
...list,
inList: this.inListsSet.has(list.id),
}))
},
triggerAttrs() {
return {
class: 'menu-item dropdown-item -has-submenu',
}
},
},
methods: {
toggleList(listId) {
if (this.inListsSet.has(listId)) {
useListsStore()
.removeListAccount({ accountId: this.user.id, listId })
.then((response) => {
if (!response.ok) {
return
}
this.$store.dispatch('fetchUserInLists', this.user.id)
})
} else {
useListsStore()
.addListAccount({ accountId: this.user.id, listId })
.then((response) => {
if (!response.ok) {
return
}
this.$store.dispatch('fetchUserInLists', this.user.id)
})
}
},
- toggleRight(right) {
- const store = this.$store
- if (this.user.rights[right]) {
- store.state.api.backendInteractor
- .deleteRight({ user: this.user, right })
- .then((response) => {
- if (!response.ok) {
- return
- }
- store.commit('updateRight', {
- user: this.user,
- right,
- value: false,
- })
- })
- } else {
- store.state.api.backendInteractor
- .addRight({ user: this.user, right })
- .then((response) => {
- if (!response.ok) {
- return
- }
- store.commit('updateRight', { user: this.user, right, value: true })
- })
- }
- },
- toggleActivationStatus() {
- this.$store.dispatch('toggleActivationStatus', { user: this.user })
- },
- deleteUserDialog(show) {
- this.showDeleteUserDialog = show
- },
- deleteUser() {
- const store = this.$store
- const user = this.user
- const { id, name } = user
- store.state.api.backendInteractor.deleteUser({ user }).then(() => {
- this.$store.dispatch(
- 'markStatusesAsDeleted',
- (status) => user.id === status.user.id,
- )
- const isProfile =
- this.$route.name === 'external-user-profile' ||
- this.$route.name === 'user-profile'
- const isTargetUser =
- this.$route.params.name === name || this.$route.params.id === id
- if (isProfile && isTargetUser) {
- window.history.back()
- }
- })
- },
- setToggled(value) {
- this.toggled = value
- },
},
}
export default UserListMenu
diff --git a/src/components/user_list_popover/user_list_popover.js b/src/components/user_list_popover/user_list_popover.js
index 3d15f3ed4e..8a46126906 100644
--- a/src/components/user_list_popover/user_list_popover.js
+++ b/src/components/user_list_popover/user_list_popover.js
@@ -1,46 +1,44 @@
import { defineAsyncComponent } from 'vue'
-import RichContent from 'src/components/rich_content/rich_content.jsx'
-import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue'
+import Popover from 'src/components/popover/popover.vue'
+import UnicodeDomainIndicator from 'src/components/unicode_domain_indicator/unicode_domain_indicator.vue'
+import UserAvatar from 'src/components/user_avatar/user_avatar.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faCircleNotch } from '@fortawesome/free-solid-svg-icons'
library.add(faCircleNotch)
const UserListPopover = {
name: 'UserListPopover',
props: ['users'],
components: {
- RichContent,
UnicodeDomainIndicator,
- Popover: defineAsyncComponent(() => import('../popover/popover.vue')),
- UserAvatar: defineAsyncComponent(
- () => import('../user_avatar/user_avatar.vue'),
- ),
+ Popover,
+ UserAvatar,
},
computed: {
usersCapped() {
return this.users.slice(0, 16)
},
allowNonSquareEmoji() {
return useMergedConfigStore().mergedConfig.nonSquareEmoji
},
},
methods: {
generateProfileLink(user) {
return generateProfileLink(
user.id,
user.screen_name,
useInstanceStore().restrictedNicknames,
)
},
},
}
export default UserListPopover
diff --git a/src/components/user_panel/user_panel.js b/src/components/user_panel/user_panel.js
index d16fca4e46..ac6bc669c6 100644
--- a/src/components/user_panel/user_panel.js
+++ b/src/components/user_panel/user_panel.js
@@ -1,21 +1,23 @@
+import { defineAsyncComponent } from 'vue'
import { mapState } from 'vuex'
-import AuthForm from '../auth_form/auth_form.js'
-import PostStatusForm from '../post_status_form/post_status_form.vue'
-import UserCard from '../user_card/user_card.vue'
+import PostStatusForm from 'src/components/post_status_form/post_status_form.vue'
+import UserCard from 'src/components/user_card/user_card.vue'
const UserPanel = {
computed: {
signedIn() {
return this.user
},
...mapState({ user: (state) => state.users.currentUser }),
},
components: {
- AuthForm,
+ AuthForm: defineAsyncComponent(
+ () => import('src/components/auth_form/auth_form.js'),
+ ),
PostStatusForm,
UserCard,
},
}
export default UserPanel
diff --git a/src/components/user_popover/user_popover.js b/src/components/user_popover/user_popover.js
index 8c5f63f258..de354d676b 100644
--- a/src/components/user_popover/user_popover.js
+++ b/src/components/user_popover/user_popover.js
@@ -1,22 +1,23 @@
import { mapState } from 'pinia'
import { defineAsyncComponent } from 'vue'
-import UserCard from '../user_card/user_card.vue'
+import Popover from 'src/components/popover/popover.vue'
+import UserCard from 'src/components/user_card/user_card.vue'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
const UserPopover = {
name: 'UserPopover',
props: ['userId', 'overlayCenters', 'disabled', 'overlayCentersSelector'],
components: {
UserCard,
- Popover: defineAsyncComponent(() => import('../popover/popover.vue')),
+ Popover,
},
computed: mapState(useMergedConfigStore, {
userPopoverAvatarAction: (state) =>
state.mergedConfig.userPopoverAvatarAction,
userPopoverOverlay: (state) => state.mergedConfig.userPopoverOverlay,
}),
}
export default UserPopover
diff --git a/src/components/user_profile/user_profile.js b/src/components/user_profile/user_profile.js
index bde19637d4..2c38782921 100644
--- a/src/components/user_profile/user_profile.js
+++ b/src/components/user_profile/user_profile.js
@@ -1,216 +1,214 @@
-import get from 'lodash/get'
+import { get } from 'lodash'
import { mapState } from 'pinia'
-import RichContent from 'src/components/rich_content/rich_content.jsx'
+import Conversation from 'src/components/conversation/conversation.vue'
+import FollowCard from 'src/components/follow_card/follow_card.vue'
+import List from 'src/components/list/list.vue'
import TabSwitcher from 'src/components/tab_switcher/tab_switcher.jsx'
+import Timeline from 'src/components/timeline/timeline.vue'
+import UserCard from 'src/components/user_card/user_card.vue'
import withLoadMore from '../../hocs/with_load_more/with_load_more'
-import Conversation from '../conversation/conversation.vue'
-import FollowCard from '../follow_card/follow_card.vue'
-import List from '../list/list.vue'
-import Timeline from '../timeline/timeline.vue'
-import UserCard from '../user_card/user_card.vue'
import { useInstanceStore } from 'src/stores/instance.js'
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
import { useInterfaceStore } from 'src/stores/interface.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faCircleNotch } from '@fortawesome/free-solid-svg-icons'
library.add(faCircleNotch)
const FollowerList = withLoadMore({
fetch: (props, $store) => $store.dispatch('fetchFollowers', props.userId),
select: (props, $store) =>
get($store.getters.findUser(props.userId), 'followerIds', []).map((id) =>
$store.getters.findUser(id),
),
destroy: (props, $store) => $store.dispatch('clearFollowers', props.userId),
childPropName: 'items',
additionalPropNames: ['userId'],
})(List)
const FriendList = withLoadMore({
fetch: (props, $store) => $store.dispatch('fetchFriends', props.userId),
select: (props, $store) =>
get($store.getters.findUser(props.userId), 'friendIds', []).map((id) =>
$store.getters.findUser(id),
),
destroy: (props, $store) => $store.dispatch('clearFriends', props.userId),
childPropName: 'items',
additionalPropNames: ['userId'],
})(List)
const defaultTabKey = 'statuses'
const UserProfile = {
data() {
return {
error: false,
userId: null,
tab: defaultTabKey,
footerRef: null,
}
},
created() {
const routeParams = this.$route.params
this.load({ name: routeParams.name, id: routeParams.id })
this.tab = get(this.$route, 'query.tab', defaultTabKey)
useInterfaceStore().setForeignProfileBackground(this.user?.background_image)
},
updated() {
useInterfaceStore().setForeignProfileBackground(this.user?.background_image)
},
unmounted() {
this.stopFetching()
useInterfaceStore().setForeignProfileBackground(null)
},
computed: {
timeline() {
return this.$store.state.statuses.timelines.user
},
favorites() {
return this.$store.state.statuses.timelines.favorites
},
media() {
return this.$store.state.statuses.timelines.media
},
isUs() {
return (
this.userId &&
this.$store.state.users.currentUser.id &&
this.userId === this.$store.state.users.currentUser.id
)
},
user() {
return this.$store.getters.findUser(this.userId)
},
isExternal() {
return this.$route.name === 'external-user-profile'
},
followsTabVisible() {
return this.isUs || !this.user.hide_follows
},
followersTabVisible() {
return this.isUs || !this.user.hide_followers
},
favoritesTabVisible() {
return (
this.isUs ||
(useInstanceCapabilitiesStore().pleromaPublicFavouritesAvailable &&
!this.user.hide_favorites)
)
},
compactProfiles() {
return useMergedConfigStore().mergedConfig.compactProfiles
},
},
methods: {
setFooterRef(el) {
this.footerRef = el
},
load(userNameOrId) {
const startFetchingTimeline = (timeline, userId) => {
// Clear timeline only if load another user's profile
if (userId !== this.$store.state.statuses.timelines[timeline].userId) {
this.$store.commit('clearTimeline', { timeline })
}
this.$store.dispatch('startFetchingTimeline', { timeline, userId })
}
const loadById = (userId) => {
this.userId = userId
startFetchingTimeline('user', userId)
startFetchingTimeline('media', userId)
if (this.isUs) {
startFetchingTimeline('favorites')
} else if (!this.user.hide_favorites) {
startFetchingTimeline('favorites', userId)
}
// Fetch all pinned statuses immediately
this.$store.dispatch('fetchPinnedStatuses', userId)
}
// Reset view
this.userId = null
this.error = false
const maybeId = userNameOrId.id
const maybeName = userNameOrId.name
// Check if user data is already loaded in store
const user = maybeId
? this.$store.getters.findUser(maybeId)
: this.$store.getters.findUserByName(maybeName)
if (user) {
loadById(user.id)
} else {
;(maybeId
? this.$store.dispatch('fetchUser', maybeId)
: this.$store.dispatch('fetchUserByName', maybeName)
)
.then(({ id }) => loadById(id))
.catch((reason) => {
const errorMessage = get(reason, 'error.error')
if (errorMessage === 'No user with such user_id') {
// Known error
this.error = this.$t('user_profile.profile_does_not_exist')
} else if (errorMessage) {
this.error = errorMessage
} else {
this.error = this.$t('user_profile.profile_loading_error')
}
})
}
},
stopFetching() {
this.$store.dispatch('stopFetchingTimeline', 'user')
this.$store.dispatch('stopFetchingTimeline', 'favorites')
this.$store.dispatch('stopFetchingTimeline', 'media')
},
switchUser(userNameOrId) {
this.stopFetching()
this.load(userNameOrId)
},
onTabSwitch(tab) {
this.tab = tab
this.$router.replace({ query: { tab } })
},
linkClicked({ target }) {
if (target.tagName === 'SPAN') {
target = target.parentNode
}
if (target.tagName === 'A') {
window.open(target.href, '_blank')
}
},
},
watch: {
'$route.params.id': function (newVal) {
if (newVal) {
this.switchUser({ id: newVal })
}
},
'$route.params.name': function (newVal) {
if (newVal) {
this.switchUser({ name: newVal })
}
},
'$route.query': function (newVal) {
this.tab = newVal.tab || defaultTabKey
},
},
components: {
UserCard,
Timeline,
FollowerList,
FriendList,
FollowCard,
TabSwitcher,
Conversation,
- RichContent,
},
}
export default UserProfile
diff --git a/src/components/user_reporting_modal/user_reporting_modal.js b/src/components/user_reporting_modal/user_reporting_modal.js
index 896167df0a..d55b5a9626 100644
--- a/src/components/user_reporting_modal/user_reporting_modal.js
+++ b/src/components/user_reporting_modal/user_reporting_modal.js
@@ -1,129 +1,127 @@
-import Checkbox from '../checkbox/checkbox.vue'
-import List from '../list/list.vue'
-import Modal from '../modal/modal.vue'
-import Status from '../status/status.vue'
-import UserLink from '../user_link/user_link.vue'
+import Checkbox from 'src/components/checkbox/checkbox.vue'
+import List from 'src/components/list/list.vue'
+import Modal from 'src/components/modal/modal.vue'
+import UserLink from 'src/components/user_link/user_link.vue'
import { useReportsStore } from 'src/stores/reports.js'
const UserReportingModal = {
components: {
- Status,
List,
Checkbox,
Modal,
UserLink,
},
data() {
return {
comment: '',
forward: false,
statusIdsToReport: [],
processing: false,
error: false,
}
},
computed: {
reportModal() {
return useReportsStore().reportModal
},
isLoggedIn() {
return !!this.$store.state.users.currentUser
},
isOpen() {
return this.isLoggedIn && this.reportModal.activated
},
userId() {
return this.reportModal.userId
},
user() {
return this.$store.getters.findUser(this.userId)
},
remoteInstance() {
return (
!this.user.is_local &&
this.user.screen_name.substr(this.user.screen_name.indexOf('@') + 1)
)
},
statuses() {
return this.reportModal.statuses
},
preTickedIds() {
return this.reportModal.preTickedIds
},
},
watch: {
userId: 'resetState',
preTickedIds(newValue) {
this.statusIdsToReport = newValue
},
},
methods: {
resetState() {
// Reset state
this.comment = ''
this.forward = false
this.statusIdsToReport = this.preTickedIds
this.processing = false
this.error = false
},
closeModal() {
useReportsStore().closeUserReportingModal()
},
reportUser() {
this.processing = true
this.error = false
const params = {
userId: this.userId,
comment: this.comment,
forward: this.forward,
statusIds: this.statusIdsToReport,
}
this.$store.state.api.backendInteractor
.reportUser({ ...params })
.then(() => {
this.processing = false
this.resetState()
this.closeModal()
})
.catch(() => {
this.processing = false
this.error = true
})
},
clearError() {
this.error = false
},
isChecked(statusId) {
return this.statusIdsToReport.indexOf(statusId) !== -1
},
toggleStatus(checked, statusId) {
if (checked === this.isChecked(statusId)) {
return
}
if (checked) {
this.statusIdsToReport.push(statusId)
} else {
this.statusIdsToReport.splice(
this.statusIdsToReport.indexOf(statusId),
1,
)
}
},
resize(e) {
const target = e.target || e
if (!(target instanceof window.Element)) {
return
}
// Auto is needed to make textbox shrink when removing lines
target.style.height = 'auto'
target.style.height = `${target.scrollHeight}px`
if (target.value === '') {
target.style.height = null
}
},
},
}
export default UserReportingModal
diff --git a/src/components/user_timed_filter_modal/user_timed_filter_modal.js b/src/components/user_timed_filter_modal/user_timed_filter_modal.js
index 528f92ddfe..f0c1509991 100644
--- a/src/components/user_timed_filter_modal/user_timed_filter_modal.js
+++ b/src/components/user_timed_filter_modal/user_timed_filter_modal.js
@@ -1,112 +1,116 @@
+import { defineAsyncComponent } from 'vue'
+
import Checkbox from 'src/components/checkbox/checkbox.vue'
-import ConfirmModal from 'src/components/confirm_modal/confirm_modal.vue'
import Select from 'src/components/select/select.vue'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
import { durationStrToMs } from 'src/services/date_utils/date_utils.js'
const UserTimedFilterModal = {
data() {
const action = this.isMute
? useMergedConfigStore().mergedConfig.onMuteDefaultAction
: useMergedConfigStore().mergedConfig.onBlockDefaultAction
const doAsk = action === 'ask'
const defaultValues = {}
if (doAsk || action === 'forever') {
defaultValues.expiration = 14
defaultValues.expirationUnit = 'd'
if (action === 'forever') {
defaultValues.forever = true
}
} else {
const unit = action.replace(/[0-9,.]+/, '')
const value = action.replace(/[^0-9,.]+/, '')
defaultValues.expiration = value
defaultValues.expirationUnit = unit
}
return {
showing: false,
forever: false,
dontAskAgain: false,
...defaultValues,
}
},
components: {
- ConfirmModal,
+ ConfirmModal: defineAsyncComponent(
+ () => import('src/components/confirm_modal/confirm_modal.vue'),
+ ),
+
Select,
Checkbox,
},
props: {
isMute: Boolean,
user: Object,
},
computed: {
shouldConfirm() {
if (this.isMute) {
return useMergedConfigStore().mergedConfig.onMuteDefaultAction === 'ask'
} else {
return (
useMergedConfigStore().mergedConfig.onBlockDefaultAction === 'ask'
)
}
},
expiryString() {
return this.expiration.toString() + this.expirationUnit
},
expirySeconds() {
return Math.floor(durationStrToMs(this.expiryString) / 1000)
},
requestBody() {
const object = { id: this.user.id }
if (!this.forever) {
object.expiresIn = this.expirySeconds
}
return object
},
},
watch: {
expiration(newVal) {
if (newVal <= 0) {
this.expiration = 1
}
},
},
methods: {
optionallyPrompt() {
if (this.shouldConfirm) {
this.showing = true
} else {
this.accept()
}
},
accept() {
if (this.isMute) {
this.$store.dispatch('muteUser', this.requestBody)
if (this.dontAskAgain) {
useSyncConfigStore().setSimplePrefAndSave({
path: 'onMuteDefaultAction',
value: this.expiryString,
})
}
} else {
this.$store.dispatch('blockUser', this.requestBody)
if (this.dontAskAgain) {
useSyncConfigStore().setSimplePrefAndSave({
path: 'onBlockDefaultAction',
value: this.expiryString,
})
}
}
this.showing = false
},
cancel() {
this.showing = false
},
},
}
export default UserTimedFilterModal
diff --git a/src/components/user_timed_filter_modal/user_timed_filter_modal.vue b/src/components/user_timed_filter_modal/user_timed_filter_modal.vue
index 0ccf2812c7..055c2f7f40 100644
--- a/src/components/user_timed_filter_modal/user_timed_filter_modal.vue
+++ b/src/components/user_timed_filter_modal/user_timed_filter_modal.vue
@@ -1,88 +1,88 @@
<template>
- <confirm-modal
+ <ConfirmModal
v-if="showing"
class="UserTimedFilterModal"
:title="$t(isMute ? $t('user_card.mute') : $t('user_card.block'))"
:confirm-text="$t(isMute ? 'user_card.mute_confirm_accept_button' : 'user_card.block_confirm_accept_button')"
:cancel-text="$t(isMute ? 'user_card.mute_confirm_cancel_button' : 'user_card.block_confirm_cancel_button')"
@accepted="accept"
@cancelled="cancel"
>
<p>
{{ $t(isMute ? 'user_card.expire_mute_message' : 'user_card.expire_block_message', [user.screen_name]) }}
</p>
<div>
{{ $t('user_card.expire_in') }}
<span class="expirationTime">
<input
id="userFilterExpires"
v-model="expiration"
class="input input-expire-in"
:class="{ disabled: forever }"
:disabled="forever"
min="1"
type="number"
>
<Select
id="userFilterExpiresUnit"
v-model="expirationUnit"
class="input unit-input unstyled"
:disabled="forever"
>
<option
key="s"
value="s"
>
{{ $t('time.unit.seconds_suffix') }}
</option>
<option
key="m"
value="m"
>
{{ $t('time.unit.minutes_suffix') }}
</option>
<option
key="h"
value="h"
>
{{ $t('time.unit.hours_suffix') }}
</option>
<option
key="d"
value="d"
>
{{ $t('time.unit.days_suffix') }}
</option>
</Select>
</span>
{{ $t('user_card.mute_or') }}
<Checkbox
id="forever"
v-model="forever"
name="forever"
class="input-forever"
>
{{ $t('user_card.mute_block_never') }}
</Checkbox>
</div>
<template #footerLeft>
<div class="footer-left-checkbox">
<Checkbox
id="dontAskAgain"
v-model="dontAskAgain"
name="dontAskAgain"
class="input-dont-ask-again"
>
{{ $t(isMute ? 'user_card.dont_ask_again_mute' : 'user_card.dont_ask_again_block') }}
</Checkbox>
</div>
</template>
- </confirm-modal>
+ </ConfirmModal>
</template>
<script src="./user_timed_filter_modal.js"></script>
<style lang="scss" src="./user_timed_filter_modal.scss" />
diff --git a/src/components/who_to_follow/who_to_follow.js b/src/components/who_to_follow/who_to_follow.js
index 720b150414..8ca2d8c1ab 100644
--- a/src/components/who_to_follow/who_to_follow.js
+++ b/src/components/who_to_follow/who_to_follow.js
@@ -1,42 +1,42 @@
+import FollowCard from 'src/components/follow_card/follow_card.vue'
import apiService from '../../services/api/api.service.js'
-import FollowCard from '../follow_card/follow_card.vue'
import { useInstanceStore } from 'src/stores/instance.js'
const WhoToFollow = {
components: {
FollowCard,
},
data() {
return {
users: [],
}
},
mounted() {
this.getWhoToFollow()
},
methods: {
showWhoToFollow(reply) {
reply.forEach((i) => {
this.$store.state.api.backendInteractor
.fetchUser({ id: i.acct })
.then((externalUser) => {
if (!externalUser.error) {
this.$store.commit('addNewUsers', [externalUser])
this.users.push(externalUser)
}
})
})
},
getWhoToFollow() {
const credentials = this.$store.state.users.currentUser.credentials
if (credentials) {
apiService.suggestions({ credentials }).then((reply) => {
this.showWhoToFollow(reply)
})
}
},
},
}
export default WhoToFollow
diff --git a/src/hocs/with_load_more/with_load_more.jsx b/src/hocs/with_load_more/with_load_more.jsx
index 9cb9d78c4a..e839f796f8 100644
--- a/src/hocs/with_load_more/with_load_more.jsx
+++ b/src/hocs/with_load_more/with_load_more.jsx
@@ -1,119 +1,119 @@
// eslint-disable-next-line no-unused
-import isEmpty from 'lodash/isEmpty'
+import { isEmpty } from 'lodash'
import { h } from 'vue'
import { getComponentProps } from '../../services/component_utils/component_utils'
import './with_load_more.scss'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faCircleNotch } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome'
library.add(faCircleNotch)
const withLoadMore =
({
fetch, // function to fetch entries and return a promise
select, // function to select data from store
unmounted, // function called at "destroyed" lifecycle
childPropName = 'entries', // name of the prop to be passed into the wrapped component
additionalPropNames = [], // additional prop name list of the wrapper component
}) =>
(WrappedComponent) => {
const originalProps = Object.keys(getComponentProps(WrappedComponent))
const props = originalProps
.filter((v) => v !== childPropName)
.concat(additionalPropNames)
return {
props,
data() {
return {
loading: false,
bottomedOut: false,
error: false,
entries: [],
}
},
created() {
window.addEventListener('scroll', this.scrollLoad)
if (this.entries.length === 0) {
this.fetchEntries()
}
},
unmounted() {
window.removeEventListener('scroll', this.scrollLoad)
unmounted && unmounted(this.$props, this.$store)
},
methods: {
// Entries is not a computed because computed can't track the dynamic
// selector for changes and won't trigger after fetch.
updateEntries() {
this.entries = select(this.$props, this.$store) || []
},
fetchEntries() {
if (!this.loading) {
this.loading = true
this.error = false
fetch(this.$props, this.$store)
.then((newEntries) => {
this.loading = false
this.bottomedOut = isEmpty(newEntries)
})
.catch(() => {
this.loading = false
this.error = true
})
.finally(() => {
this.updateEntries()
})
}
},
scrollLoad(e) {
const bodyBRect = document.body.getBoundingClientRect()
const height = Math.max(bodyBRect.height, -bodyBRect.y)
if (
this.loading === false &&
this.bottomedOut === false &&
this.$el.offsetHeight > 0 &&
window.innerHeight + window.pageYOffset >= height - 750
) {
this.fetchEntries()
}
},
},
render() {
const props = {
...this.$props,
[childPropName]: this.entries,
}
const children = this.$slots
return (
<div class="with-load-more">
<WrappedComponent {...props}>{children}</WrappedComponent>
<div class="with-load-more-footer">
{this.error && (
<button
onClick={this.fetchEntries}
class="button-unstyled -link -fullwidth alert error"
>
{this.$t('general.generic_error')}
</button>
)}
{!this.error && this.loading && (
<FAIcon spin icon="circle-notch" />
)}
{!this.error && !this.loading && !this.bottomedOut && (
<a onClick={this.fetchEntries} role="button" tabindex="0">
{this.$t('general.more')}
</a>
)}
</div>
</div>
)
},
}
}
export default withLoadMore
diff --git a/src/hocs/with_subscription/with_subscription.jsx b/src/hocs/with_subscription/with_subscription.jsx
index 198be68623..7805161c6d 100644
--- a/src/hocs/with_subscription/with_subscription.jsx
+++ b/src/hocs/with_subscription/with_subscription.jsx
@@ -1,94 +1,94 @@
// eslint-disable-next-line no-unused
-import isEmpty from 'lodash/isEmpty'
+import { isEmpty } from 'lodash'
import { h } from 'vue'
import { getComponentProps } from '../../services/component_utils/component_utils'
import './with_subscription.scss'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faCircleNotch } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome'
library.add(faCircleNotch)
const withSubscription =
({
fetch, // function to fetch entries and return a promise
select, // function to select data from store
childPropName = 'content', // name of the prop to be passed into the wrapped component
additionalPropNames = [], // additional prop name list of the wrapper component
}) =>
(WrappedComponent) => {
const originalProps = Object.keys(getComponentProps(WrappedComponent))
const props = originalProps
.filter((v) => v !== childPropName)
.concat(additionalPropNames)
return {
props: [
...props,
'refresh', // boolean saying to force-fetch data whenever created
],
data() {
return {
loading: false,
error: false,
}
},
computed: {
fetchedData() {
return select(this.$props, this.$store)
},
},
created() {
if (this.refresh || isEmpty(this.fetchedData)) {
this.fetchData()
}
},
methods: {
fetchData() {
if (!this.loading) {
this.loading = true
this.error = false
fetch(this.$props, this.$store)
.then(() => {
this.loading = false
})
.catch(() => {
this.error = true
this.loading = false
})
}
},
},
render() {
if (!this.error && !this.loading) {
const props = {
...this.$props,
[childPropName]: this.fetchedData,
}
const children = this.$slots
return (
<div class="with-subscription">
<WrappedComponent {...props}>{children}</WrappedComponent>
</div>
)
} else {
return (
<div class="with-subscription-loading">
{this.error ? (
<a onClick={this.fetchData} class="alert error">
{this.$t('general.generic_error')}
</a>
) : (
<FAIcon spin icon="circle-notch" />
)}
</div>
)
}
},
}
}
export default withSubscription
diff --git a/src/i18n/messages.js b/src/i18n/messages.js
index df851c88fb..76d6b53860 100644
--- a/src/i18n/messages.js
+++ b/src/i18n/messages.js
@@ -1,57 +1,58 @@
// When contributing, please sort JSON before committing so it would be easier to see what's missing and what's being added compared to English and other languages. It's not obligatory, but just an advice.
// To sort json use jq https://stedolan.github.io/jq and invoke it like `jq -S . xx.json > xx.sorted.json`, AFAIK, there's no inplace edit option like in sed
// Also, when adding a new language to "messages" variable, please do it alphabetically by language code so that users can search or check their custom language easily.
// For anyone contributing to old huge messages.js and in need to quickly convert it to JSON
// sed command for converting currently formatted JS to JSON:
// sed -i -e "s/'//gm" -e 's/"/\\"/gm' -re 's/^( +)(.+?): ((.+?))?(,?)(\{?)$/\1"\2": "\4"/gm' -e 's/\"\{\"/{/g' -e 's/,"$/",/g' file.json
// There's only problem that apostrophe character ' gets replaced by \\ so you have to fix it manually, sorry.
import { isEqual } from 'lodash'
import enMessages from './en.json'
import { langCodeToJsonName, languages } from './languages.js'
const ULTIMATE_FALLBACK_LOCALE = 'en'
const hasLanguageFile = (code) => languages.includes(code)
-const languageFileMap = import.meta.glob('./*.json')
+const languageFileMap = import.meta.glob(['./*.json', '!./en.json'])
const loadLanguageFile = (code) => {
const jsonName = langCodeToJsonName(code)
+ if (jsonName === 'en') return Promise.resolve({ default: enMessages })
return languageFileMap[`./${jsonName}.json`]()
}
const messages = {
languages,
default: {
en: enMessages,
},
setLanguage: async (i18n, language) => {
const languages = (Array.isArray(language) ? language : [language]).filter(
(k) => k,
)
if (!languages.includes(ULTIMATE_FALLBACK_LOCALE)) {
languages.push(ULTIMATE_FALLBACK_LOCALE)
}
const [first, ...rest] = languages
if (first === i18n.locale && isEqual(rest, i18n.fallbackLocale)) {
return
}
for (const lang of languages) {
if (hasLanguageFile(lang)) {
const messages = await loadLanguageFile(lang)
i18n.setLocaleMessage(lang, messages.default)
}
}
i18n.fallbackLocale = rest
i18n.locale = first
},
}
export default messages
diff --git a/src/lib/persisted_state.js b/src/lib/persisted_state.js
index f7e2b0b086..f6375dfede 100644
--- a/src/lib/persisted_state.js
+++ b/src/lib/persisted_state.js
@@ -1,265 +1,264 @@
-import { cloneDeep, each, get, set } from 'lodash'
-import merge from 'lodash.merge'
+import { cloneDeep, each, get, merge, set } from 'lodash'
import { storage } from './storage.js'
import { useInterfaceStore } from 'src/stores/interface'
let loaded = false
const defaultReducer = (state, paths) =>
paths.length === 0
? state
: paths.reduce((substate, path) => {
set(substate, path, get(state, path))
return substate
}, {})
const saveImmedeatelyActions = [
'markNotificationsAsSeen',
'clearCurrentUser',
'setCurrentUser',
'setHighlight',
'setOption',
'setClientData',
'setToken',
'clearToken',
]
const defaultStorage = (() => {
return storage
})()
export default function createPersistedState({
key = 'vuex-lz',
paths = [],
getState = (key, storage) => {
const value = storage.getItem(key)
return value
},
setState = (key, state, storage) => {
if (!loaded) {
console.info('waiting for old state to be loaded...')
return Promise.resolve()
} else {
return storage.setItem(key, state)
}
},
reducer = defaultReducer,
storage = defaultStorage,
subscriber = (store) => (handler) => store.subscribe(handler),
} = {}) {
return getState(key, storage).then((savedState) => {
return (store) => {
try {
if (savedState !== null && typeof savedState === 'object') {
// build user cache
const usersState = savedState.users || {}
usersState.usersObject = {}
const users = usersState.users || []
each(users, (user) => {
usersState.usersObject[user.id] = user
})
savedState.users = usersState
store.replaceState(merge({}, store.state, savedState))
}
loaded = true
} catch (e) {
console.error("Couldn't load state")
console.error(e)
loaded = true
}
subscriber(store)((mutation, state) => {
try {
if (saveImmedeatelyActions.includes(mutation.type)) {
setState(key, reducer(cloneDeep(state), paths), storage).then(
(success) => {
if (typeof success !== 'undefined') {
if (
mutation.type === 'setOption' ||
mutation.type === 'setCurrentUser'
) {
useInterfaceStore().settingsSaved({ success })
}
}
},
(error) => {
if (
mutation.type === 'setOption' ||
mutation.type === 'setCurrentUser'
) {
useInterfaceStore().settingsSaved({ error })
}
},
)
}
} catch (e) {
console.error("Couldn't persist state:")
console.error(e)
}
})
}
})
}
/**
* This persists state for pinia, which falls back to read from the vuex state
* if pinia persisted state does not exist.
*
* When you migrate a module from vuex to pinia, you have to keep the original name.
* If the module was called `xxx`, the name of the store has to be `xxx` too.
*
* This adds one property to the store, $persistLoaded, which is a promise
* that resolves when the initial state is loaded. If the plugin is not enabled,
* $persistLoaded is a promise that resolves immediately.
* If we are not able to get the stored state because storage.getItem() throws or
* rejects, $persistLoaded will be a rejected promise with the thrown error.
*
* Call signature:
*
* defineStore(name, {
* ...,
* // setting the `persist` property enables this plugin
* // IMPORTANT: by default it is disabled, you have to set `persist` to at least an empty object
* persist: {
* // set to list of individual paths, or undefined/unset to persist everything
* paths: [],
* // function to call after loading initial state
* // if afterLoad is a function, it must return a state object that will be sent to `store.$patch`, or a promise to the state object
* // by default afterLoad is undefined
* afterLoad: (originalState) => {
* // ...
* return modifiedState
* },
* // if it exists, only persist state after these actions
* // if it doesn't exist or is undefined, persist state after every mutation of the state
* saveImmediatelyActions: [],
* // what to do after successfully saving the state
* onSaveSuccess: () => {},
* // what to do after there is an error saving the state
* onSaveError: () => {}
* }
* })
*
*/
export const piniaPersistPlugin =
({
vuexKey = 'vuex-lz',
keyFunction = (id) => `pinia-local-${id}`,
storage = defaultStorage,
reducer = defaultReducer,
} = {}) =>
({ store, options }) => {
if (!options.persist) {
return {
$persistLoaded: Promise.resolve(),
}
}
let resolveLoaded
let rejectLoaded
const loadedPromise = new Promise((resolve, reject) => {
resolveLoaded = resolve
rejectLoaded = reject
})
const {
afterLoad,
paths = [],
saveImmediatelyActions,
onSaveSuccess = () => {
/* no-op */
},
onSaveError = () => {
/* no-op */
},
} = options.persist || {}
const loadedGuard = { loaded: false }
const key = keyFunction(store.$id)
const getState = async () => {
const id = store.$id
const value = await storage.getItem(key)
if (value) {
return value
}
const fallbackValue = await storage.getItem(vuexKey)
if (fallbackValue && fallbackValue[id]) {
console.info(`Migrating ${id} store data from vuex to pinia`)
const res = fallbackValue[id]
await storage.setItem(key, res)
return res
}
return {}
}
const setState = (state) => {
if (!loadedGuard.loaded) {
console.info('waiting for old state to be loaded...')
return Promise.reject()
} else {
return storage.setItem(key, state)
}
}
const getMaybeAugmentedState = async () => {
const savedRawState = await getState()
if (typeof afterLoad === 'function') {
try {
return await afterLoad(savedRawState)
} catch (e) {
console.error('Error running afterLoad:', e)
return savedRawState
}
} else {
return savedRawState
}
}
const persistCurrentState = async (state) => {
const stateClone = cloneDeep(state)
const stateToPersist = reducer(stateClone, paths)
try {
const res = await setState(stateToPersist)
onSaveSuccess(res)
} catch (e) {
console.error('Cannot persist state:', e)
onSaveError(e)
}
}
getMaybeAugmentedState().then(
(savedState) => {
if (savedState) {
store.$patch(savedState)
}
loadedGuard.loaded = true
resolveLoaded()
// only subscribe after we have done setting the initial state
if (!saveImmediatelyActions) {
store.$subscribe(async (_mutation, state) => {
await persistCurrentState(state)
})
} else {
store.$onAction(({ name, store, after }) => {
if (saveImmediatelyActions.includes(name)) {
after(() => persistCurrentState(store.$state))
}
})
}
},
(error) => {
console.error('Cannot load storage:', error)
rejectLoaded(error)
},
)
return {
$persistLoaded: loadedPromise,
}
}
diff --git a/src/modules/notifications.js b/src/modules/notifications.js
index bf1e4b9c0f..d501b39dbd 100644
--- a/src/modules/notifications.js
+++ b/src/modules/notifications.js
@@ -1,189 +1,191 @@
import apiService from '../services/api/api.service.js'
import {
closeAllDesktopNotifications,
closeDesktopNotification,
} from '../services/desktop_notification_utils/desktop_notification_utils.js'
import {
isStatusNotification,
isValidNotification,
maybeShowNotification,
} from '../services/notification_utils/notification_utils.js'
+import { useI18nStore } from 'src/stores/i18n.js'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
import { useReportsStore } from 'src/stores/reports.js'
import { useSyncConfigStore } from 'src/stores/sync_config.js'
const emptyNotifications = () => ({
desktopNotificationSilence: true,
maxId: 0,
minId: Number.POSITIVE_INFINITY,
data: [],
idStore: {},
loading: false,
})
export const defaultState = () => ({
...emptyNotifications(),
})
export const notifications = {
state: defaultState(),
mutations: {
addNewNotifications(state, { notifications }) {
notifications.forEach((notification) => {
state.data.push(notification)
state.idStore[notification.id] = notification
})
},
clearNotifications(state) {
const blankState = defaultState()
Object.keys(state).forEach((k) => {
state[k] = blankState[k]
})
},
updateNotificationsMinMaxId(state, id) {
state.maxId = id > state.maxId ? id : state.maxId
state.minId = id < state.minId ? id : state.minId
},
setNotificationsLoading(state, { value }) {
state.loading = value
},
setNotificationsSilence(state, { value }) {
state.desktopNotificationSilence = value
},
markNotificationsAsSeen(state) {
state.data.forEach((notification) => {
notification.seen = true
})
},
markSingleNotificationAsSeen(state, { id }) {
const notification = state.idStore[id]
if (notification) notification.seen = true
},
dismissNotification(state, { id }) {
state.data = state.data.filter((n) => n.id !== id)
delete state.idStore[id]
},
updateNotification(state, { id, updater }) {
const notification = state.idStore[id]
notification && updater(notification)
},
},
actions: {
addNewNotifications(store, { notifications }) {
const { commit, dispatch, state, rootState } = store
const validNotifications = notifications.filter((notification) => {
// If invalid notification, update ids but don't add it to store
if (!isValidNotification(notification)) {
console.error('Invalid notification:', notification)
commit('updateNotificationsMinMaxId', notification.id)
return false
}
return true
})
const statusNotifications = validNotifications.filter(
(notification) =>
isStatusNotification(notification.type) && notification.status,
)
// Synchronous commit to add all the statuses
commit('addNewStatuses', {
statuses: statusNotifications.map(
(notification) => notification.status,
),
})
// Update references to statuses in notifications to ones in the store
statusNotifications.forEach((notification) => {
const id = notification.status.id
const referenceStatus = rootState.statuses.allStatusesObject[id]
if (referenceStatus) {
notification.status = referenceStatus
}
})
validNotifications.forEach((notification) => {
if (notification.type === 'pleroma:report') {
useReportsStore().addReport(notification.report)
}
if (notification.type === 'pleroma:emoji_reaction') {
dispatch('fetchEmojiReactionsBy', notification.status.id)
}
// Only add a new notification if we don't have one for the same action
if (!Object.hasOwn(state.idStore, notification.id)) {
commit('updateNotificationsMinMaxId', notification.id)
commit('addNewNotifications', { notifications: [notification] })
maybeShowNotification(
store,
useMergedConfigStore().mergedConfig.notificationVisibility,
Object.values(useSyncConfigStore().prefsStorage.simple.muteFilters),
notification,
+ useI18nStore().i18n,
)
} else if (notification.seen) {
state.idStore[notification.id].seen = true
}
})
},
notificationClicked({ state, dispatch }, { id }) {
const notification = state.idStore[id]
const { type, seen } = notification
if (!seen) {
switch (type) {
case 'mention':
case 'pleroma:report':
case 'follow_request':
break
default:
dispatch('markSingleNotificationAsSeen', { id })
}
}
},
setNotificationsLoading({ commit }, { value }) {
commit('setNotificationsLoading', { value })
},
setNotificationsSilence({ commit }, { value }) {
commit('setNotificationsSilence', { value })
},
markNotificationsAsSeen({ rootState, state, commit }) {
commit('markNotificationsAsSeen')
apiService
.markNotificationsAsSeen({
id: state.maxId,
credentials: rootState.users.currentUser.credentials,
})
.then(() => {
closeAllDesktopNotifications(rootState)
})
},
markSingleNotificationAsSeen({ rootState, commit }, { id }) {
commit('markSingleNotificationAsSeen', { id })
apiService
.markNotificationsAsSeen({
single: true,
id,
credentials: rootState.users.currentUser.credentials,
})
.then(() => {
closeDesktopNotification(rootState, { id })
})
},
dismissNotificationLocal({ commit }, { id }) {
commit('dismissNotification', { id })
},
dismissNotification({ rootState, commit }, { id }) {
commit('dismissNotification', { id })
rootState.api.backendInteractor.dismissNotification({ id })
},
updateNotification({ commit }, { id, updater }) {
commit('updateNotification', { id, updater })
},
},
}
export default notifications
diff --git a/src/services/chat_service/chat_service.js b/src/services/chat_service/chat_service.js
index f6d381d6eb..eec267dde7 100644
--- a/src/services/chat_service/chat_service.js
+++ b/src/services/chat_service/chat_service.js
@@ -1,255 +1,251 @@
-import _ from 'lodash'
+import { maxBy, minBy, orderBy, sortBy, uniqueId } from 'lodash'
const empty = (chatId) => {
return {
idIndex: {},
idempotencyKeyIndex: {},
messages: [],
newMessageCount: 0,
lastSeenMessageId: '0',
chatId,
minId: undefined,
maxId: undefined,
}
}
const clear = (storage) => {
const failedMessageIds = []
for (const message of storage.messages) {
if (message.error) {
failedMessageIds.push(message.id)
} else {
delete storage.idIndex[message.id]
delete storage.idempotencyKeyIndex[message.idempotency_key]
}
}
storage.messages = storage.messages.filter((m) =>
failedMessageIds.includes(m.id),
)
storage.newMessageCount = 0
storage.lastSeenMessageId = '0'
storage.minId = undefined
storage.maxId = undefined
}
const deleteMessage = (storage, messageId) => {
if (!storage) {
return
}
storage.messages = storage.messages.filter((m) => m.id !== messageId)
delete storage.idIndex[messageId]
if (storage.maxId === messageId) {
- const lastMessage = _.maxBy(storage.messages, 'id')
+ const lastMessage = maxBy(storage.messages, 'id')
storage.maxId = lastMessage.id
}
if (storage.minId === messageId) {
- const firstMessage = _.minBy(storage.messages, 'id')
+ const firstMessage = minBy(storage.messages, 'id')
storage.minId = firstMessage.id
}
}
const cullOlderMessages = (storage) => {
const maxIndex = storage.messages.length
const minIndex = maxIndex - 50
if (maxIndex <= 50) return
- storage.messages = _.sortBy(storage.messages, ['id'])
+ storage.messages = sortBy(storage.messages, ['id'])
storage.minId = storage.messages[minIndex].id
for (const message of storage.messages) {
if (message.id < storage.minId) {
delete storage.idIndex[message.id]
delete storage.idempotencyKeyIndex[message.idempotency_key]
}
}
storage.messages = storage.messages.slice(minIndex, maxIndex)
}
const handleMessageError = (storage, fakeId, isRetry) => {
if (!storage) {
return
}
const fakeMessage = storage.idIndex[fakeId]
if (fakeMessage) {
fakeMessage.error = true
fakeMessage.pending = false
if (!isRetry) {
// Ensure the failed message doesn't stay at the bottom of the list.
- const lastPersistedMessage = _.orderBy(
+ const lastPersistedMessage = orderBy(
storage.messages,
['pending', 'id'],
['asc', 'desc'],
)[0]
if (lastPersistedMessage) {
const oldId = fakeMessage.id
fakeMessage.id = `${lastPersistedMessage.id}-${new Date().getTime()}`
storage.idIndex[fakeMessage.id] = fakeMessage
delete storage.idIndex[oldId]
}
}
}
}
const add = (storage, { messages: newMessages, updateMaxId = true }) => {
if (!storage) {
return
}
for (let i = 0; i < newMessages.length; i++) {
const message = newMessages[i]
// sanity check
if (message.chat_id !== storage.chatId) {
return
}
if (message.fakeId) {
const fakeMessage = storage.idIndex[message.fakeId]
if (fakeMessage) {
// In case the same id exists (chat update before POST response)
// make sure to remove the older duplicate message.
if (storage.idIndex[message.id]) {
delete storage.idIndex[message.id]
storage.messages = storage.messages.filter(
(msg) => msg.id !== message.id,
)
}
Object.assign(fakeMessage, message, { error: false })
delete fakeMessage.fakeId
storage.idIndex[fakeMessage.id] = fakeMessage
delete storage.idIndex[message.fakeId]
return
}
}
if (!storage.minId || (!message.pending && message.id < storage.minId)) {
storage.minId = message.id
}
if (!storage.maxId || message.id > storage.maxId) {
if (updateMaxId) {
storage.maxId = message.id
}
}
if (!storage.idIndex[message.id] && !isConfirmation(storage, message)) {
if (storage.lastSeenMessageId < message.id) {
storage.newMessageCount++
}
storage.idIndex[message.id] = message
storage.messages.push(storage.idIndex[message.id])
storage.idempotencyKeyIndex[message.idempotency_key] = true
}
}
}
const isConfirmation = (storage, message) => {
if (!message.idempotency_key) return
return storage.idempotencyKeyIndex[message.idempotency_key]
}
const resetNewMessageCount = (storage) => {
if (!storage) {
return
}
storage.newMessageCount = 0
storage.lastSeenMessageId = storage.maxId
}
// Inserts date separators and marks the head and tail if it's the chain of messages made by the same user
const getView = (storage) => {
if (!storage) {
return []
}
const result = []
- const messages = _.orderBy(
- storage.messages,
- ['pending', 'id'],
- ['asc', 'asc'],
- )
+ const messages = orderBy(storage.messages, ['pending', 'id'], ['asc', 'asc'])
const firstMessage = messages[0]
let previousMessage = messages[messages.length - 1]
let currentMessageChainId
if (firstMessage) {
const date = new Date(firstMessage.created_at)
date.setHours(0, 0, 0, 0)
result.push({
type: 'date',
date,
id: date.getTime().toString(),
})
}
let afterDate = false
for (let i = 0; i < messages.length; i++) {
const message = messages[i]
const nextMessage = messages[i + 1]
const date = new Date(message.created_at)
date.setHours(0, 0, 0, 0)
// insert date separator and start a new message chain
if (previousMessage && previousMessage.date < date) {
result.push({
type: 'date',
date,
id: date.getTime().toString(),
})
previousMessage.isTail = true
currentMessageChainId = undefined
afterDate = true
}
const object = {
type: 'message',
data: message,
date,
id: message.id,
messageChainId: currentMessageChainId,
}
// end a message chian
if ((nextMessage && nextMessage.account_id) !== message.account_id) {
object.isTail = true
currentMessageChainId = undefined
}
// start a new message chain
if (
(previousMessage &&
previousMessage.data &&
previousMessage.data.account_id) !== message.account_id ||
afterDate
) {
- currentMessageChainId = _.uniqueId()
+ currentMessageChainId = uniqueId()
object.isHead = true
object.messageChainId = currentMessageChainId
}
result.push(object)
previousMessage = object
afterDate = false
}
return result
}
const ChatService = {
add,
empty,
getView,
deleteMessage,
cullOlderMessages,
resetNewMessageCount,
clear,
handleMessageError,
}
export default ChatService
diff --git a/src/services/component_utils/component_utils.js b/src/services/component_utils/component_utils.js
index 49a1108606..1973a79239 100644
--- a/src/services/component_utils/component_utils.js
+++ b/src/services/component_utils/component_utils.js
@@ -1,8 +1,8 @@
-import isFunction from 'lodash/isFunction'
+import { isFunction } from 'lodash'
const getComponentOptions = (Component) =>
isFunction(Component) ? Component.options : Component
const getComponentProps = (Component) => getComponentOptions(Component).props
export { getComponentOptions, getComponentProps }
diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js
index d356740c1a..1d90617fc0 100644
--- a/src/services/entity_normalizer/entity_normalizer.service.js
+++ b/src/services/entity_normalizer/entity_normalizer.service.js
@@ -1,580 +1,580 @@
import { parseLinkHeader } from '@web3-storage/parse-link-header'
import escapeHtml from 'escape-html'
import { unescape as lodashUnescape } from 'lodash'
import punycode from 'punycode.js'
-import fileTypeService from '../file_type/file_type.service.js'
+import { fileType } from '../file_type/file_type.service.js'
import { isStatusNotification } from '../notification_utils/notification_utils.js'
/** NOTICE! **
* Do not initialize UI-generated data here.
* It will override existing data.
*
* i.e. user.pinnedStatusIds was set to [] here
* UI code would update it with data but upon next user fetch
* it would be reverted back to []
*/
const qvitterStatusType = (status) => {
if (status.is_post_verb) {
return 'status'
}
if (status.retweeted_status) {
return 'retweet'
}
if (
(typeof status.uri === 'string' &&
status.uri.match(/(fave|objectType=Favourite)/)) ||
(typeof status.text === 'string' && status.text.match(/favorited/))
) {
return 'favorite'
}
if (
status.text.match(/deleted notice {{tag/) ||
status.qvitter_delete_notice
) {
return 'deletion'
}
if (
status.text.match(/started following/) ||
status.activity_type === 'follow'
) {
return 'follow'
}
return 'unknown'
}
export const parseUser = (data) => {
const output = {}
const masto = Object.hasOwn(data, 'acct')
// case for users in "mentions" property for statuses in MastoAPI
const mastoShort = masto && !Object.hasOwn(data, 'avatar')
output.inLists = null
output.id = String(data.id)
output._original = data // used for server-side settings
if (masto) {
output.screen_name = data.acct
output.fqn = data.fqn
output.statusnet_profile_url = data.url
if (Object.hasOwn(data, 'mute_expires_at')) {
output.mute_expires_at =
data.mute_expires_at == null ? false : data.mute_expires_at
}
if (Object.hasOwn(data, 'block_expires_at')) {
output.block_expires_at =
data.block_expires_at == null ? false : data.block_expires_at
}
// There's nothing else to get
if (mastoShort) {
return output
}
output.emoji = data.emojis
output.name = escapeHtml(data.display_name)
output.name_html = output.name
output.name_unescaped = data.display_name
output.description = data.note
// TODO cleanup this shit, output.description is overriden with source data
output.description_html = data.note
output.fields = data.fields
output.fields_html = data.fields.map((field) => {
return {
name: escapeHtml(field.name),
value: field.value,
}
})
output.fields_text = data.fields.map((field) => {
return {
name: unescape(field.name.replace(/<[^>]*>/g, '')),
value: unescape(field.value.replace(/<[^>]*>/g, '')),
}
})
// Utilize avatar_static for gif avatars?
output.profile_image_url = data.avatar
output.profile_image_url_original = data.avatar
// Same, utilize header_static?
output.cover_photo = data.header
output.friends_count = data.following_count
output.bot = data.bot
output.privileges = []
if (data.pleroma) {
if (data.pleroma.settings_store) {
output.storage = data.pleroma.settings_store['pleroma-fe']
output.user_highlight = data.pleroma.settings_store['user_highlight']
}
const relationship = data.pleroma.relationship
output.background_image = data.pleroma.background_image
output.favicon = data.pleroma.favicon
output.token = data.pleroma.chat_token
if (relationship) {
output.relationship = relationship
}
output.allow_following_move = data.pleroma.allow_following_move
output.hide_favorites = data.pleroma.hide_favorites
output.hide_follows = data.pleroma.hide_follows
output.hide_followers = data.pleroma.hide_followers
output.hide_follows_count = data.pleroma.hide_follows_count
output.hide_followers_count = data.pleroma.hide_followers_count
output.rights = {
moderator: data.pleroma.is_moderator,
admin: data.pleroma.is_admin,
}
// TODO: Clean up in UI? This is duplication from what BE does for qvitterapi
if (output.rights.admin) {
output.role = 'admin'
} else if (output.rights.moderator) {
output.role = 'moderator'
} else {
output.role = 'member'
}
output.birthday = data.pleroma.birthday
if (data.pleroma.privileges) {
output.privileges = data.pleroma.privileges
} else if (data.pleroma.is_admin) {
output.privileges = [
'users_read',
'users_manage_invites',
'users_manage_activation_state',
'users_manage_tags',
'users_manage_credentials',
'users_delete',
'messages_read',
'messages_delete',
'instances_delete',
'reports_manage_reports',
'moderation_log_read',
'announcements_manage_announcements',
'emoji_manage_emoji',
'statistics_read',
]
} else if (data.pleroma.is_moderator) {
output.privileges = ['messages_delete', 'reports_manage_reports']
} else {
output.privileges = []
}
}
if (data.source) {
output.description = data.source.note
output.default_scope = data.source.privacy
output.fields = data.source.fields
if (data.source.pleroma) {
output.no_rich_text = data.source.pleroma.no_rich_text
output.show_role = data.source.pleroma.show_role
output.discoverable = data.source.pleroma.discoverable
output.show_birthday = data.pleroma.show_birthday
output.actor_type = data.source.pleroma.actor_type
}
}
// TODO: handle is_local
output.is_local = !output.screen_name.includes('@')
} else {
output.screen_name = data.screen_name
output.name = data.name
output.name_html = data.name_html
output.description = data.description
output.description_html = data.description_html
output.profile_image_url = data.profile_image_url
output.profile_image_url_original = data.profile_image_url_original
output.cover_photo = data.cover_photo
output.friends_count = data.friends_count
// output.bot = ??? missing
output.statusnet_profile_url = data.statusnet_profile_url
output.is_local = data.is_local
output.role = data.role
output.show_role = data.show_role
if (data.rights) {
output.rights = {
moderator: data.rights.delete_others_notice,
admin: data.rights.admin,
}
}
output.no_rich_text = data.no_rich_text
output.default_scope = data.default_scope
output.hide_follows = data.hide_follows
output.hide_followers = data.hide_followers
output.hide_follows_count = data.hide_follows_count
output.hide_followers_count = data.hide_followers_count
output.background_image = data.background_image
// Websocket token
output.token = data.token
// Convert relationsip data to expected format
output.relationship = {
muting: data.muted,
blocking: data.statusnet_blocking,
followed_by: data.follows_you,
following: data.following,
}
}
output.created_at = new Date(data.created_at)
output.locked = data.locked
output.last_status_at = new Date(data.last_status_at)
output.followers_count = data.followers_count
output.statuses_count = data.statuses_count
if (data.pleroma) {
output.follow_request_count = data.pleroma.follow_request_count
output.tags = data.pleroma.tags
// deactivated was changed to is_active in Pleroma 2.3.0
// so check if is_active is present
output.deactivated =
typeof data.pleroma.is_active !== 'undefined'
? !data.pleroma.is_active // new backend
: data.pleroma.deactivated // old backend
output.notification_settings = data.pleroma.notification_settings
output.unread_chat_count = data.pleroma.unread_chat_count
}
output.tags = output.tags || []
output.rights = output.rights || {}
output.notification_settings = output.notification_settings || {}
// Convert punycode to unicode for UI
output.screen_name_ui = output.screen_name
if (output.screen_name && output.screen_name.includes('@')) {
const parts = output.screen_name.split('@')
const unicodeDomain = punycode.toUnicode(parts[1])
if (unicodeDomain !== parts[1]) {
// Add some identifier so users can potentially spot spoofing attempts:
// lain.com and xn--lin-6cd.com would appear identical otherwise.
output.screen_name_ui_contains_non_ascii = true
output.screen_name_ui = [parts[0], unicodeDomain].join('@')
} else {
output.screen_name_ui_contains_non_ascii = false
}
}
return output
}
export const parseAttachment = (data) => {
const output = {}
const masto = !Object.hasOwn(data, 'oembed')
if (masto) {
// Not exactly same...
output.mimetype = data.pleroma ? data.pleroma.mime_type : data.type
output.meta = data.meta // not present in BE yet
output.id = data.id
} else {
output.mimetype = data.mimetype
// output.meta = ??? missing
}
if (data.type !== 'unknown') {
// treat gifv like it is "video"
output.type = data.type === 'gifv' ? 'video' : data.type
} else {
- output.type = fileTypeService.fileType(output.mimetype)
+ output.type = fileType(output.mimetype)
}
output.url = data.url
output.large_thumb_url = data.preview_url
output.description = lodashUnescape(data.description)
return output
}
export const parseSource = (data) => {
const output = {}
output.text = data.text
output.spoiler_text = data.spoiler_text
output.content_type = data.content_type
return output
}
export const parseStatus = (data) => {
const output = {}
const masto = Object.hasOwn(data, 'account')
if (masto) {
output.favorited = data.favourited
output.fave_num = data.favourites_count
output.repeated = data.reblogged
output.repeat_num = data.reblogs_count
output.bookmarked = data.bookmarked
output.type = data.reblog ? 'retweet' : 'status'
output.nsfw = data.sensitive
output.raw_html = data.content
output.emojis = data.emojis
output.tags = data.tags
output.edited_at = data.edited_at
const { pleroma } = data
if (data.pleroma) {
output.text = pleroma.content
? data.pleroma.content['text/plain']
: data.content
output.summary = pleroma.spoiler_text
? data.pleroma.spoiler_text['text/plain']
: data.spoiler_text
output.statusnet_conversation_id = data.pleroma.conversation_id
output.is_local = pleroma.local
output.in_reply_to_screen_name = pleroma.in_reply_to_account_acct
output.thread_muted = pleroma.thread_muted
output.emoji_reactions = pleroma.emoji_reactions
output.parent_visible =
pleroma.parent_visible === undefined ? true : pleroma.parent_visible
output.quote_visible = pleroma.quote_visible || true
output.quotes_count = pleroma.quotes_count
output.bookmark_folder_id = pleroma.bookmark_folder
} else {
output.text = data.content
output.summary = data.spoiler_text
}
const quoteRaw = pleroma?.quote || data.quote
const quoteData = quoteRaw ? parseStatus(quoteRaw) : undefined
output.quote = quoteData
output.quote_id =
data.quote?.id ?? data.quote_id ?? quoteData?.id ?? pleroma?.quote_id
output.quote_url = data.quote?.url ?? quoteData?.url ?? pleroma?.quote_url
output.in_reply_to_status_id = data.in_reply_to_id
output.in_reply_to_user_id = data.in_reply_to_account_id
output.replies_count = data.replies_count
if (output.type === 'retweet') {
output.retweeted_status = parseStatus(data.reblog)
}
output.summary_raw_html = escapeHtml(data.spoiler_text)
output.external_url = data.uri || data.url
output.poll = data.poll
if (output.poll) {
output.poll.options = (output.poll.options || []).map((field) => ({
...field,
title_html: escapeHtml(field.title),
}))
}
output.pinned = data.pinned
output.muted = data.muted
} else {
output.favorited = data.favorited
output.fave_num = data.fave_num
output.repeated = data.repeated
output.repeat_num = data.repeat_num
// catchall, temporary
// Object.assign(output, data)
output.type = qvitterStatusType(data)
if (data.nsfw === undefined) {
output.nsfw = isNsfw(data)
if (data.retweeted_status) {
output.nsfw = data.retweeted_status.nsfw
}
} else {
output.nsfw = data.nsfw
}
output.raw_html = data.statusnet_html
output.text = data.text
output.in_reply_to_status_id = data.in_reply_to_status_id
output.in_reply_to_user_id = data.in_reply_to_user_id
output.in_reply_to_screen_name = data.in_reply_to_screen_name
output.statusnet_conversation_id = data.statusnet_conversation_id
if (output.type === 'retweet') {
output.retweeted_status = parseStatus(data.retweeted_status)
}
output.summary = data.summary
output.summary_html = data.summary_html
output.external_url = data.external_url
output.is_local = data.is_local
}
output.id = String(data.id)
output.visibility = data.visibility
output.card = data.card
output.created_at = new Date(data.created_at)
// Converting to string, the right way.
output.in_reply_to_status_id = output.in_reply_to_status_id
? String(output.in_reply_to_status_id)
: null
output.in_reply_to_user_id = output.in_reply_to_user_id
? String(output.in_reply_to_user_id)
: null
output.user = parseUser(masto ? data.account : data.user)
output.attentions = ((masto ? data.mentions : data.attentions) || []).map(
parseUser,
)
output.attachments = (
(masto ? data.media_attachments : data.attachments) || []
).map(parseAttachment)
const retweetedStatus = masto ? data.reblog : data.retweeted_status
if (retweetedStatus) {
output.retweeted_status = parseStatus(retweetedStatus)
}
output.favoritedBy = []
output.rebloggedBy = []
if (Object.hasOwn(data, 'originalStatus')) {
Object.assign(output, data.originalStatus)
}
return output
}
export const parseNotification = (data) => {
const mastoDict = {
favourite: 'like',
reblog: 'repeat',
}
const masto = !Object.hasOwn(data, 'ntype')
const output = {}
if (masto) {
output.type = mastoDict[data.type] || data.type
output.seen = data.pleroma.is_seen
// TODO: null check should be a temporary fix, I guess.
// Investigate why backend does this.
output.status =
isStatusNotification(output.type) && data.status !== null
? parseStatus(data.status)
: null
output.target = output.type !== 'move' ? null : parseUser(data.target)
output.from_profile = parseUser(data.account)
output.emoji = data.emoji
output.emoji_url = data.emoji_url
if (data.report) {
output.report = data.report
output.report.content = data.report.content
output.report.acct = parseUser(data.report.account)
output.report.actor = parseUser(data.report.actor)
output.report.statuses = data.report.statuses.map(parseStatus)
}
} else {
const parsedNotice = parseStatus(data.notice)
output.type = data.ntype
output.seen = Boolean(data.is_seen)
output.status =
output.type === 'like'
? parseStatus(data.notice.favorited_status)
: parsedNotice
output.action = parsedNotice
output.from_profile =
output.type === 'pleroma:chat_mention'
? parseUser(data.account)
: parseUser(data.from_profile)
}
output.created_at = new Date(data.created_at)
output.id = parseInt(data.id)
return output
}
const isNsfw = (status) => {
const nsfwRegex = /#nsfw/i
return (
(status.tags || []).includes('nsfw') ||
!!(status.text || '').match(nsfwRegex)
)
}
export const parseLinkHeaderPagination = (linkHeader, opts = {}) => {
const flakeId = opts.flakeId
const parsedLinkHeader = parseLinkHeader(linkHeader)
if (!parsedLinkHeader) return
const maxId = parsedLinkHeader.next?.max_id
const minId = parsedLinkHeader.prev?.min_id
return {
maxId: flakeId ? maxId : parseInt(maxId, 10),
minId: flakeId ? minId : parseInt(minId, 10),
}
}
export const parseChat = (chat) => {
const output = {}
output.id = chat.id
output.account = parseUser(chat.account)
output.unread = chat.unread
output.lastMessage = parseChatMessage(chat.last_message)
output.updated_at = new Date(chat.updated_at)
return output
}
export const parseChatMessage = (message) => {
if (!message) {
return
}
if (message.isNormalized) {
return message
}
const output = message
output.id = message.id
output.created_at = new Date(message.created_at)
output.chat_id = message.chat_id
output.emojis = message.emojis
output.content = message.content
if (message.attachment) {
output.attachments = [parseAttachment(message.attachment)]
} else {
output.attachments = []
}
output.pending = !!message.pending
output.error = false
output.idempotency_key = message.idempotency_key
output.isNormalized = true
return output
}
diff --git a/src/services/locale/locale.service.js b/src/services/locale/locale.service.js
index 9fe62318c6..bdc07c1ec0 100644
--- a/src/services/locale/locale.service.js
+++ b/src/services/locale/locale.service.js
@@ -1,51 +1,51 @@
import ISO6391 from 'iso-639-1'
-import _ from 'lodash'
+import { map } from 'lodash'
import languagesObject from '../../i18n/messages'
const specialLanguageCodes = {
pdc: 'en',
ja_easy: 'ja',
zh_Hant: 'zh-HANT',
zh: 'zh-Hans',
}
const internalToBrowserLocale = (code) => specialLanguageCodes[code] || code
const internalToBackendLocale = (code) =>
internalToBrowserLocale(code).replace('_', '-')
const internalToBackendLocaleMulti = (codes) => {
const langs = Array.isArray(codes) ? codes : [codes]
return langs.map(internalToBackendLocale).join(',')
}
const getLanguageName = (code) => {
const specialLanguageNames = {
pdc: 'Pennsilfaanisch-Deitsch',
ja_easy: 'やさしいにほんご',
'nan-TW': '臺語(閩南語)',
zh: '简体中文',
zh_Hant: '繁體中文',
}
const languageName = specialLanguageNames[code] || ISO6391.getNativeName(code)
const browserLocale = internalToBrowserLocale(code)
return (
languageName.charAt(0).toLocaleUpperCase(browserLocale) +
languageName.slice(1)
)
}
-const languages = _.map(languagesObject.languages, (code) => ({
+const languages = map(languagesObject.languages, (code) => ({
code,
name: getLanguageName(code),
})).sort((a, b) => a.name.localeCompare(b.name))
const localeService = {
internalToBrowserLocale,
internalToBackendLocale,
internalToBackendLocaleMulti,
languages,
getLanguageName,
}
export default localeService
diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js
index 9216000943..e7987146a8 100644
--- a/src/services/notification_utils/notification_utils.js
+++ b/src/services/notification_utils/notification_utils.js
@@ -1,214 +1,215 @@
import { showDesktopNotification } from '../desktop_notification_utils/desktop_notification_utils.js'
import { muteFilterHits } from '../status_parser/status_parser.js'
import { useAnnouncementsStore } from 'src/stores/announcements.js'
-import { useI18nStore } from 'src/stores/i18n.js'
import FaviconService from 'src/services/favicon_service/favicon_service.js'
export const ACTIONABLE_NOTIFICATION_TYPES = new Set([
'mention',
'pleroma:report',
'follow_request',
])
let cachedBadgeUrl = null
export const notificationsFromStore = (store) => store.state.notifications.data
const visibleTypes = (notificationVisibility) => {
return [
notificationVisibility.likes && 'like',
notificationVisibility.mentions && 'mention',
notificationVisibility.statuses && 'status',
notificationVisibility.repeats && 'repeat',
notificationVisibility.follows && 'follow',
notificationVisibility.followRequest && 'follow_request',
notificationVisibility.moves && 'move',
notificationVisibility.emojiReactions && 'pleroma:emoji_reaction',
notificationVisibility.reports && 'pleroma:report',
notificationVisibility.polls && 'poll',
].filter((_) => _)
}
const statusNotifications = new Set([
'like',
'mention',
'status',
'repeat',
'pleroma:emoji_reaction',
'poll',
])
export const isStatusNotification = (type) => statusNotifications.has(type)
export const isValidNotification = (notification) => {
if (isStatusNotification(notification.type) && !notification.status) {
return false
}
return true
}
const sortById = (a, b) => {
const seqA = Number(a.id)
const seqB = Number(b.id)
const isSeqA = !Number.isNaN(seqA)
const isSeqB = !Number.isNaN(seqB)
if (isSeqA && isSeqB) {
return seqA > seqB ? -1 : 1
} else if (isSeqA && !isSeqB) {
return 1
} else if (!isSeqA && isSeqB) {
return -1
} else {
return a.id > b.id ? -1 : 1
}
}
const isMutedNotification = (muteFilters, notification) => {
if (!notification.status) return false
if (notification.status.muted) return true
return muteFilterHits(muteFilters, notification.status).length > 0
}
export const maybeShowNotification = (
store,
notificationVisibility,
muteFilters,
notification,
+ i18n,
) => {
const rootState = store.rootState || store.state
if (notification.seen) return
if (!visibleTypes(notificationVisibility).includes(notification.type)) return
if (
notification.type === 'mention' &&
isMutedNotification(muteFilters, notification)
)
return
- const notificationObject = prepareNotificationObject(
- notification,
- useI18nStore().i18n,
- )
+ const notificationObject = prepareNotificationObject(notification, i18n)
showDesktopNotification(rootState, notificationObject)
}
export const filteredNotificationsFromStore = (
store,
notificationVisibility,
types,
) => {
// map is just to clone the array since sort mutates it and it causes some issues
const sortedNotifications = notificationsFromStore(store)
.map((_) => _)
.sort(sortById)
// TODO implement sorting elsewhere and make it optional
return sortedNotifications.filter((notification) =>
(types || visibleTypes(notificationVisibility)).includes(notification.type),
)
}
export const unseenNotificationsFromStore = (
store,
notificationVisibility,
ignoreInactionableSeen,
) => {
return filteredNotificationsFromStore(store, notificationVisibility).filter(
({ seen, type }) => {
if (!ignoreInactionableSeen) return !seen
if (seen) return false
return ACTIONABLE_NOTIFICATION_TYPES.has(type)
},
)
}
export const prepareNotificationObject = (notification, i18n) => {
if (cachedBadgeUrl === null) {
const favicons = FaviconService.getOriginalFavicons()
const favicon = favicons[favicons.length - 1]
if (!favicon) {
cachedBadgeUrl = 'about:blank'
} else {
cachedBadgeUrl = favicon.favimg.src
}
}
const notifObj = {
tag: notification.id,
type: notification.type,
badge: cachedBadgeUrl,
}
const status = notification.status
const title = notification.from_profile.name
notifObj.title = title
notifObj.icon = notification.from_profile.profile_image_url
let i18nString
switch (notification.type) {
case 'like':
i18nString = 'favorited_you'
break
case 'status':
i18nString = 'subscribed_status'
break
case 'repeat':
i18nString = 'repeated_you'
break
case 'follow':
i18nString = 'followed_you'
break
case 'move':
i18nString = 'migrated_to'
break
case 'follow_request':
i18nString = 'follow_request'
break
case 'pleroma:report':
i18nString = 'submitted_report'
break
case 'poll':
i18nString = 'poll_ended'
break
}
if (notification.type === 'pleroma:emoji_reaction') {
notifObj.body = i18n.t('notifications.reacted_with', [notification.emoji])
} else if (i18nString) {
notifObj.body = i18n.t('notifications.' + i18nString)
} else if (isStatusNotification(notification.type)) {
notifObj.body = notification.status.text
}
// Shows first attached non-nsfw image, if any. Should add configuration for this somehow...
if (
status &&
status.attachments &&
status.attachments.length > 0 &&
!status.nsfw &&
status.attachments[0].mimetype.startsWith('image/')
) {
notifObj.image = status.attachments[0].url
}
return notifObj
}
-export const countExtraNotifications = (store, mergedConfig) => {
+export const countExtraNotifications = (
+ store,
+ mergedConfig,
+ unreadAnnouncementCount,
+) => {
const rootGetters = store.rootGetters || store.getters
if (!mergedConfig.showExtraNotifications) {
return 0
}
return [
mergedConfig.showChatsInExtraNotifications
? rootGetters.unreadChatCount
: 0,
mergedConfig.showAnnouncementsInExtraNotifications
- ? useAnnouncementsStore().unreadAnnouncementCount
+ ? unreadAnnouncementCount
: 0,
mergedConfig.showFollowRequestsInExtraNotifications
? rootGetters.followRequestCount
: 0,
].reduce((a, c) => a + c, 0)
}
diff --git a/src/stores/reports.js b/src/stores/reports.js
index d2cd4fd7ce..d3acebcb46 100644
--- a/src/stores/reports.js
+++ b/src/stores/reports.js
@@ -1,58 +1,58 @@
-import filter from 'lodash/filter'
+import { filter } from 'lodash'
import { defineStore } from 'pinia'
import { useInterfaceStore } from 'src/stores/interface.js'
export const useReportsStore = defineStore('reports', {
state: () => ({
reportModal: {
userId: null,
statuses: [],
preTickedIds: [],
activated: false,
},
reports: {},
}),
actions: {
openUserReportingModal({ userId, statusIds = [] }) {
const preTickedStatuses = statusIds.map(
(id) => window.vuex.state.statuses.allStatusesObject[id],
)
const preTickedIds = statusIds
const statuses = preTickedStatuses.concat(
filter(
window.vuex.state.statuses.allStatuses,
(status) =>
status.user.id === userId && !preTickedIds.includes(status.id),
),
)
this.reportModal.userId = userId
this.reportModal.statuses = statuses
this.reportModal.preTickedIds = preTickedIds
this.reportModal.activated = true
},
closeUserReportingModal() {
this.reportModal.activated = false
},
setReportState({ id, state }) {
const oldState = this.reports[id].state
this.reports[id].state = state
window.vuex.state.api.backendInteractor
.setReportState({ id, state })
.catch((e) => {
console.error('Failed to set report state', e)
useInterfaceStore().pushGlobalNotice({
level: 'error',
messageKey: 'general.generic_error_message',
messageArgs: [e.message],
timeout: 5000,
})
this.reports[id].state = oldState
})
},
addReport(report) {
this.reports[report.id] = report
},
},
})
diff --git a/static/empty.css b/static/empty.css
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/test/e2e-playwright/specs/user_smoke.spec.js b/test/e2e-playwright/specs/user_smoke.spec.js
index a71378c066..205cd3e69d 100644
--- a/test/e2e-playwright/specs/user_smoke.spec.js
+++ b/test/e2e-playwright/specs/user_smoke.spec.js
@@ -1,90 +1,85 @@
import { randomUUID } from 'node:crypto'
import { expect, test } from 'playwright/test'
const createTestUser = () => {
const id = randomUUID().slice(0, 8)
return {
username: `e2e_${id}`,
fullname: `E2E ${id}`,
email: `e2e_${id}@example.com`,
password: 'e2e-password',
}
}
const register = async (page, user) => {
await page.goto('/registration')
const registrationForm = page.locator('#main-scroller form.registration-form')
await registrationForm.locator('#sign-up-username').fill(user.username)
await registrationForm.locator('#sign-up-fullname').fill(user.fullname)
await registrationForm.locator('#email').fill(user.email)
await registrationForm.locator('#sign-up-password').fill(user.password)
await registrationForm
.locator('#sign-up-password-confirmation')
.fill(user.password)
await Promise.all([
page.waitForURL(/\/main\/friends/),
registrationForm.getByRole('button', { name: 'Register' }).click(),
])
}
const logout = async (page) => {
await page.getByTitle('Log out').click()
const confirmLogout = page.getByRole('button', {
name: 'Logout',
exact: true,
})
- if (await confirmLogout.isVisible()) {
- await Promise.all([
- page.waitForURL(/\/main\/(public|all)/),
- confirmLogout.click(),
- ])
- } else {
- await page.waitForURL(/\/main\/(public|all)/)
- }
+ await expect(confirmLogout).toBeVisible()
+ await confirmLogout.click()
+ await page.waitForURL(/\/main\/(public|all)/)
await expect(page.locator('#sidebar form.login-form')).toBeVisible()
}
const login = async (page, user) => {
await page.goto('/login')
const loginForm = page.locator('#main-scroller form.login-form')
await loginForm.locator('#username').fill(user.username)
await loginForm.locator('#password').fill(user.password)
await loginForm.getByRole('button', { name: 'Log in' }).click()
await page.waitForURL(/\/main\/friends/)
}
test('user can register, log out, and log back in', async ({ page }) => {
const user = createTestUser()
await register(page, user)
await expect(page.getByTitle('Log out')).toBeVisible()
await logout(page)
await login(page, user)
await expect(page.getByTitle('Log out')).toBeVisible()
})
test('user can post a status', async ({ page }) => {
const user = createTestUser()
await register(page, user)
const statusText = `Hello from ${user.username} (${randomUUID().slice(0, 8)})`
const composer = page.locator('#sidebar .user-panel .post-status-form')
await composer.locator('textarea.form-post-body').fill(statusText)
await Promise.all([
page.waitForResponse(
(resp) =>
resp.request().method() === 'POST' &&
resp.url().includes('/api/v1/statuses') &&
resp.ok(),
),
composer.getByRole('button', { name: 'Post', exact: true }).click(),
])
await page.goto(`/users/${user.username}`)
await expect(page.getByText(statusText)).toBeVisible()
})
diff --git a/test/fixtures/setup_test.js b/test/fixtures/setup_test.js
index 02c49eb604..85a062cc76 100644
--- a/test/fixtures/setup_test.js
+++ b/test/fixtures/setup_test.js
@@ -1,136 +1,145 @@
+import { createTestingPinia } from '@pinia/testing'
import { config } from '@vue/test-utils'
import { createMemoryHistory, createRouter } from 'vue-router'
import VueVirtualScroller from 'vue-virtual-scroller'
+import RichContent from 'src/components/rich_content/rich_content.jsx'
+import Status from 'src/components/status/status.vue'
+import StillImage from 'src/components/still-image/still-image.vue'
import makeMockStore from './mock_store'
import routes from 'src/boot/routes'
export const $t = (msg) => msg
const $i18n = { t: (msg) => msg }
const applyAfterStore = (store, afterStore) => {
afterStore(store)
return store
}
const getDefaultOpts = ({
afterStore = () => {
/* no-op */
},
} = {}) => ({
global: {
plugins: [
applyAfterStore(makeMockStore(), afterStore),
VueVirtualScroller,
createRouter({
history: createMemoryHistory(),
routes: routes({
state: {
users: {
currentUser: {},
},
instance: {},
},
}),
}),
(Vue) => {
Vue.directive('body-scroll-lock', {})
},
+ createTestingPinia(),
],
- components: {},
+ components: {
+ RichContent,
+ Status,
+ StillImage,
+ },
stubs: {
I18nT: true,
teleport: true,
FAIcon: true,
FALayers: true,
},
mocks: {
$t,
$i18n,
},
},
})
// https://github.com/vuejs/vue-test-utils/issues/960
const customBehaviors = () => {
const filterByText = (keyword) => {
const match =
keyword instanceof RegExp
? (target) => target && keyword.test(target)
: (target) => keyword === target
return (wrapper) =>
match(wrapper.text()) ||
match(wrapper.attributes('aria-label')) ||
match(wrapper.attributes('title'))
}
return {
findComponentByText(searchedComponent, text) {
return this.findAllComponents(searchedComponent)
.filter(filterByText(text))
.at(0)
},
findByText(searchedElement, text) {
return this.findAll(searchedElement).filter(filterByText(text)).at(0)
},
}
}
config.plugins.VueWrapper.install(customBehaviors)
export const mountOpts = (allOpts = {}) => {
const { afterStore, ...opts } = allOpts
const defaultOpts = getDefaultOpts({ afterStore })
const mergedOpts = {
...opts,
global: {
...defaultOpts.global,
},
}
if (opts.global) {
mergedOpts.global.plugins = mergedOpts.global.plugins.concat(
opts.global.plugins || [],
)
Object.entries(opts.global).forEach(([k, v]) => {
if (k === 'plugins') {
return
}
if (defaultOpts.global[k]) {
mergedOpts.global[k] = {
...defaultOpts.global[k],
...v,
}
} else {
mergedOpts.global[k] = v
}
})
}
return mergedOpts
}
// https://stackoverflow.com/questions/78033718/how-can-i-wait-for-an-emitted-event-of-a-mounted-component-in-vue-test-utils
export const waitForEvent = (
wrapper,
event,
{ timeout = 1000, timesEmitted = 1 } = {},
) => {
const tick = 10
return vi.waitFor(
() => {
const e = wrapper.emitted(event)
if (e && e.length >= timesEmitted) {
return
}
throw new Error('event is not emitted')
},
{
timeout,
interval: tick,
},
)
}
diff --git a/test/unit/specs/boot/routes.spec.js b/test/unit/specs/boot/routes.spec.js
index f4be28a65d..6df0ab80df 100644
--- a/test/unit/specs/boot/routes.spec.js
+++ b/test/unit/specs/boot/routes.spec.js
@@ -1,99 +1,84 @@
import { createTestingPinia } from '@pinia/testing'
createTestingPinia()
import { createMemoryHistory, createRouter } from 'vue-router'
import { createStore } from 'vuex'
import routes from 'src/boot/routes'
const store = createStore({
state: {
instance: {},
},
})
describe('routes', () => {
const router = createRouter({
history: createMemoryHistory(),
routes: routes(store),
})
it('root path', async () => {
await router.push('/main/all')
const matchedComponents = router.currentRoute.value.matched
expect(
Object.hasOwn(
matchedComponents[0].components.default.components,
'Timeline',
),
).to.eql(true)
})
it("user's profile", async () => {
await router.push('/fake-user-name')
const matchedComponents = router.currentRoute.value.matched
- expect(
- Object.hasOwn(
- matchedComponents[0].components.default.components,
- 'UserCard',
- ),
- ).to.eql(true)
+ expect(matchedComponents[0].components.default.name).to.eql(
+ 'AsyncComponentWrapper',
+ )
})
it("user's profile at /users", async () => {
await router.push('/users/fake-user-name')
const matchedComponents = router.currentRoute.value.matched
- expect(
- Object.hasOwn(
- matchedComponents[0].components.default.components,
- 'UserCard',
- ),
- ).to.eql(true)
+ expect(matchedComponents[0].components.default.name).to.eql(
+ 'AsyncComponentWrapper',
+ )
})
it('list view', async () => {
await router.push('/lists')
const matchedComponents = router.currentRoute.value.matched
- expect(
- Object.hasOwn(
- matchedComponents[0].components.default.components,
- 'ListsCard',
- ),
- ).to.eql(true)
+ expect(matchedComponents[0].components.default.name).to.eql(
+ 'AsyncComponentWrapper',
+ )
})
it('list timeline', async () => {
await router.push('/lists/1')
const matchedComponents = router.currentRoute.value.matched
- expect(
- Object.hasOwn(
- matchedComponents[0].components.default.components,
- 'Timeline',
- ),
- ).to.eql(true)
+ expect(matchedComponents[0].components.default.name).to.eql(
+ 'AsyncComponentWrapper',
+ )
})
it('list edit', async () => {
await router.push('/lists/1/edit')
const matchedComponents = router.currentRoute.value.matched
- expect(
- Object.hasOwn(
- matchedComponents[0].components.default.components,
- 'BasicUserCard',
- ),
- ).to.eql(true)
+ expect(matchedComponents[0].components.default.name).to.eql(
+ 'AsyncComponentWrapper',
+ )
})
})
diff --git a/test/unit/specs/components/draft.spec.js b/test/unit/specs/components/draft.spec.js
index 6abf2d75b4..be2400fc3c 100644
--- a/test/unit/specs/components/draft.spec.js
+++ b/test/unit/specs/components/draft.spec.js
@@ -1,180 +1,185 @@
import { createTestingPinia } from '@pinia/testing'
import { flushPromises, mount } from '@vue/test-utils'
import { setActivePinia } from 'pinia'
import { nextTick } from 'vue'
import PostStatusForm from 'src/components/post_status_form/post_status_form.vue'
import { $t, mountOpts, waitForEvent } from '../../../fixtures/setup_test'
import { useMergedConfigStore } from 'src/stores/merged_config.js'
const autoSaveOrNot = (caseFn, caseTitle, runFn) => {
caseFn(`${caseTitle} with auto-save`, function () {
return runFn.bind(this)(true)
})
caseFn(`${caseTitle} with no auto-save`, function () {
return runFn.bind(this)(false)
})
}
const saveManually = async (wrapper) => {
const morePostActions = wrapper.findByText(
'button',
$t('post_status.more_post_actions'),
)
await morePostActions.trigger('click')
const btn = wrapper.findByText(
'button',
$t('post_status.save_to_drafts_button'),
)
await btn.trigger('click')
}
const waitSaveTime = 4000
afterEach(() => {
vi.useRealTimers()
})
describe('Draft saving', () => {
beforeEach(() => {
setActivePinia(createTestingPinia())
})
autoSaveOrNot(
it,
'should save when the button is clicked',
async (autoSave) => {
const wrapper = mount(PostStatusForm, mountOpts())
const store = useMergedConfigStore()
store.mergedConfig = {
autoSaveDraft: autoSave,
}
expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
const textarea = wrapper.get('textarea')
await textarea.setValue('mew mew')
await saveManually(wrapper)
expect(wrapper.vm.$store.getters.draftCount).to.equal(1)
expect(wrapper.vm.$store.getters.draftsArray[0].status).to.equal(
'mew mew',
)
},
)
it('should auto-save if it is enabled', async function () {
vi.useFakeTimers()
const wrapper = mount(PostStatusForm, mountOpts())
const store = useMergedConfigStore()
store.mergedConfig = {
autoSaveDraft: true,
}
expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
const textarea = wrapper.get('textarea')
await textarea.setValue('mew mew')
expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
await vi.advanceTimersByTimeAsync(waitSaveTime)
expect(wrapper.vm.$store.getters.draftCount).to.equal(1)
expect(wrapper.vm.$store.getters.draftsArray[0].status).to.equal('mew mew')
})
it('should auto-save when close if auto-save is on', async () => {
const wrapper = mount(
PostStatusForm,
mountOpts({
props: {
closeable: true,
},
}),
)
const store = useMergedConfigStore()
store.mergedConfig = {
autoSaveDraft: true,
}
expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
const textarea = wrapper.get('textarea')
await textarea.setValue('mew mew')
wrapper.vm.requestClose()
expect(wrapper.vm.$store.getters.draftCount).to.equal(1)
await waitForEvent(wrapper, 'can-close')
})
it('should save when close if auto-save is off, and unsavedPostAction is save', async () => {
const wrapper = mount(
PostStatusForm,
mountOpts({
props: {
closeable: true,
},
}),
)
const store = useMergedConfigStore()
store.mergedConfig = {
autoSaveDraft: false,
unsavedPostAction: 'save',
}
expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
const textarea = wrapper.get('textarea')
await textarea.setValue('mew mew')
wrapper.vm.requestClose()
expect(wrapper.vm.$store.getters.draftCount).to.equal(1)
await waitForEvent(wrapper, 'can-close')
})
it('should discard when close if auto-save is off, and unsavedPostAction is discard', async () => {
const wrapper = mount(
PostStatusForm,
mountOpts({
props: {
closeable: true,
},
}),
)
const store = useMergedConfigStore()
store.mergedConfig = {
autoSaveDraft: false,
unsavedPostAction: 'discard',
}
expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
const textarea = wrapper.get('textarea')
await textarea.setValue('mew mew')
wrapper.vm.requestClose()
await waitForEvent(wrapper, 'can-close')
expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
})
it('should confirm when close if auto-save is off, and unsavedPostAction is confirm', async () => {
const wrapper = mount(
PostStatusForm,
mountOpts({
props: {
closeable: true,
},
}),
)
const store = useMergedConfigStore(createTestingPinia())
store.mergedConfig = {
autoSaveDraft: false,
unsavedPostAction: 'confirm',
}
expect(wrapper.vm.$store.getters.draftCount).to.equal(0)
const textarea = wrapper.get('textarea')
await textarea.setValue('mew mew')
wrapper.vm.requestClose()
await nextTick()
- const saveButton = wrapper.findByText(
- 'button',
- $t('post_status.close_confirm_save_button'),
- )
+ await flushPromises()
+ const saveButton = await vi.waitFor(() => {
+ const button = wrapper.findByText(
+ 'button',
+ $t('post_status.close_confirm_save_button'),
+ )
+ if (!button) throw new Error('Save button not present')
+ return button
+ })
expect(saveButton).to.be.ok
await saveButton.trigger('click')
console.info('clicked')
expect(wrapper.vm.$store.getters.draftCount).to.equal(1)
await flushPromises()
await waitForEvent(wrapper, 'can-close')
})
})
diff --git a/test/unit/specs/services/theme_data/iss_deserializer.spec.js b/test/unit/specs/services/theme_data/iss_deserializer.spec.js
index 0b93b61490..75cd6efabb 100644
--- a/test/unit/specs/services/theme_data/iss_deserializer.spec.js
+++ b/test/unit/specs/services/theme_data/iss_deserializer.spec.js
@@ -1,49 +1,49 @@
import { deserialize } from 'src/services/theme_data/iss_deserializer.js'
import { serialize } from 'src/services/theme_data/iss_serializer.js'
const componentsContext = import.meta.glob(
['/src/**/*.style.js', '/src/**/*.style.json'],
{ eager: true },
)
describe('ISS (de)serialization', () => {
Object.keys(componentsContext).forEach((key) => {
const component = componentsContext[key].default
it(`(De)serialization of component ${component.name} works`, () => {
const normalized = component.defaultRules.map((x) => ({
component: component.name,
...x,
}))
const serialized = serialize(normalized)
const deserialized = deserialize(serialized)
// for some reason comparing objects directly fails the assert
expect(JSON.stringify(deserialized, null, 2)).to.equal(
JSON.stringify(normalized, null, 2),
)
})
})
/*
// Debug snippet
- const onlyComponent = componentsContext('./components/panel_header.style.js').default
+ const onlyComponent = componentsContext('src/components/panel_header.style.js').default
it.only(`(De)serialization of component ${onlyComponent.name} works`, () => {
const normalized = onlyComponent.defaultRules.map(x => ({ component: onlyComponent.name, ...x }))
console.debug('BEGIN INPUT ================')
console.debug(normalized)
console.debug('END INPUT ==================')
const serialized = serialize(normalized)
console.debug('BEGIN SERIAL ===============')
console.debug(serialized)
console.debug('END SERIAL =================')
const deserialized = deserialize(serialized)
console.debug('BEGIN DESERIALIZED =========')
console.debug(serialized)
console.debug('END DESERIALIZED ===========')
// for some reason comparing objects directly fails the assert
expect(JSON.stringify(deserialized, null, 2)).to.equal(JSON.stringify(normalized, null, 2))
})
/* */
})
diff --git a/vite.config.js b/vite.config.js
index 401cb4b354..5b7c22d57a 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -1,258 +1,241 @@
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'
+import { DevTools } from '@vitejs/devtools'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import { defineConfig } from 'vite'
import eslint from 'vite-plugin-eslint2'
import stylelint from 'vite-plugin-stylelint'
import { configDefaults } from 'vitest/config'
import { getCommitHash } from './build/commit_hash.js'
import copyPlugin from './build/copy_plugin.js'
import emojisPlugin from './build/emojis_plugin.js'
import mswPlugin from './build/msw_plugin.js'
-import {
- buildSwPlugin,
- devSwPlugin,
- swMessagesPlugin,
-} from './build/sw_plugin.js'
+import { buildSwPlugin, swMessagesPlugin } from './build/sw_plugin.js'
const localConfigPath = '<projectRoot>/config/local.json'
const normalizeTarget = (target) => {
if (!target || typeof target !== 'string') return target
return target.endsWith('/') ? target.replace(/\/$/, '') : target
}
const getLocalDevSettings = async () => {
const envTarget = normalizeTarget(process.env.VITE_PROXY_TARGET)
const envOrigin = normalizeTarget(process.env.VITE_PROXY_ORIGIN)
try {
const settings = (await import('./config/local.json')).default
settings.target = normalizeTarget(settings.target)
settings.origin = normalizeTarget(settings.origin)
if (envTarget) settings.target = envTarget
if (envOrigin) settings.origin = envOrigin
console.info(`Using local dev server settings (${localConfigPath}):`)
console.info(JSON.stringify(settings, null, 2))
return settings
} catch (e) {
if (!envTarget && !envOrigin) {
console.info(
`Local dev server settings not found (${localConfigPath}), using default`,
e,
)
return {}
}
const settings = { target: envTarget, origin: envOrigin }
console.info(
'Using dev server settings from VITE_PROXY_TARGET/VITE_PROXY_ORIGIN:',
)
console.info(JSON.stringify(settings, null, 2))
return settings
}
}
const projectRoot = dirname(fileURLToPath(import.meta.url))
const getTransformSWSettings = (settings) => {
if ('transformSW' in settings) {
return settings.transformSW
} else {
console.info(
'`transformSW` is not present in your local settings.\n' +
'This option controls whether the service worker should be bundled and transformed into iife (immediately-invoked function expression) during development.\n' +
'If set to false, the service worker will be served as-is, as an ES Module.\n' +
'Some browsers (e.g. Firefox) does not support ESM service workers.\n' +
'To avoid surprises, it is defaulted to true, but this can be slow.\n' +
'If you are using a browser that supports ESM service workers, you can set this option to false.\n' +
`No matter your choice, you can set the transformSW option in ${localConfigPath} in to disable this message.`,
)
return true
}
}
export default defineConfig(async ({ mode, command }) => {
const settings = await getLocalDevSettings()
const target = settings.target || 'http://localhost:4000/'
const origin = settings.origin || target
const transformSW = getTransformSWSettings(settings)
const proxy = {
'/api': {
target,
changeOrigin: true,
cookieDomainRewrite: 'localhost',
ws: true,
},
'/nodeinfo': {
target,
changeOrigin: true,
cookieDomainRewrite: 'localhost',
},
'/instance': {
target,
changeOrigin: true,
cookieDomainRewrite: 'localhost',
},
'/socket': {
target,
changeOrigin: true,
cookieDomainRewrite: 'localhost',
ws: true,
headers: {
Origin: origin,
},
},
'/oauth': {
target,
changeOrigin: true,
cookieDomainRewrite: 'localhost',
},
}
const swSrc = 'src/sw.js'
const swDest = 'sw-pleroma.js'
const alias = {
src: '/src',
components: '/src/components',
...(mode === 'test' ? { vue: 'vue/dist/vue.esm-bundler.js' } : {}),
}
return {
plugins: [
vue({
template: {
compilerOptions: {
isCustomElement(tag) {
if (tag === 'pinch-zoom') {
return true
}
if (tag.startsWith('cropper-')) {
return true
}
return false
},
},
},
}),
vueJsx(),
- devSwPlugin({ swSrc, swDest, transformSW, alias }),
buildSwPlugin({ swSrc, swDest }),
swMessagesPlugin(),
emojisPlugin(),
copyPlugin({
inUrl: '/static/ruffle',
inFs: resolve(projectRoot, 'node_modules/@ruffle-rs/ruffle'),
}),
eslint({
lintInWorker: true,
lintOnStart: true,
cacheLocation: resolve(projectRoot, 'node_modules/.cache/eslintcache'),
}),
stylelint({
lintInWorker: true,
lintOnStart: true,
cacheLocation: resolve(
projectRoot,
'node_modules/.cache/stylelintcache',
),
}),
...(mode === 'test' ? [mswPlugin()] : []),
],
- optimizeDeps: {
- // For unknown reasons, during vitest, vite will re-optimize the following
- // deps, causing the test to reload, so add them here so that it will not
- // reload during tests
- include: [
- 'custom-event-polyfill',
- 'vue-i18n',
- '@ungap/event-target',
- 'lodash.merge',
- 'body-scroll-lock',
- '@kazvmoe-infra/pinch-zoom-element',
- ],
- },
css: {
devSourcemap: true,
},
resolve: {
alias,
},
define: {
'process.env': JSON.stringify({
NODE_ENV:
mode === 'test'
? 'testing'
: command === 'serve'
? 'development'
: 'production',
HAS_MODULE_SERVICE_WORKER: command === 'serve' && !transformSW,
}),
COMMIT_HASH: JSON.stringify(
command === 'serve' ? 'DEV' : getCommitHash(),
),
DEV_OVERRIDES: JSON.stringify(command === 'serve' ? settings : undefined),
__VUE_OPTIONS_API__: true,
__VUE_PROD_DEVTOOLS__: false,
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false,
},
+ // devtools: { enabled: true },
build: {
sourcemap: true,
- rollupOptions: {
+ rolldownOptions: {
input: {
main: 'index.html',
},
output: {
- inlineDynamicImports: false,
entryFileNames(chunkInfo) {
const id = chunkInfo.facadeModuleId
if (id.endsWith(swSrc)) {
return swDest
} else {
return 'static/js/[name].[hash].js'
}
},
chunkFileNames(chunkInfo) {
if (chunkInfo.facadeModuleId) {
if (
chunkInfo.facadeModuleId.includes(
'node_modules/@kazvmoe-infra/unicode-emoji-json/annotations/',
)
) {
return 'static/js/emoji-annotations/[name].[hash].js'
} else if (chunkInfo.facadeModuleId.includes('src/i18n/')) {
return 'static/js/i18n/[name].[hash].js'
}
}
return 'static/js/[name].[hash].js'
},
assetFileNames(assetInfo) {
const name = assetInfo.names?.[0] || ''
if (/\.(png|jpe?g|gif|svg)(\?.*)?$/.test(name)) {
return 'static/img/[name].[hash][extname]'
} else if (/\.css$/.test(name)) {
return 'static/css/[name].[hash][extname]'
} else {
return 'static/misc/[name].[hash][extname]'
}
},
},
},
},
server: {
...(mode === 'test' ? {} : { proxy }),
port: Number(process.env.PORT) || 8080,
},
preview: {
proxy,
},
test: {
globals: true,
exclude: [...configDefaults.exclude, 'test/e2e-playwright/**'],
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'firefox' }],
},
},
}
})
diff --git a/yarn.lock b/yarn.lock
index 54d81f139b..4f3f125892 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1,8572 +1,9858 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
-"@ampproject/remapping@^2.2.0":
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4"
- integrity sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==
- dependencies:
- "@jridgewell/gen-mapping" "^0.3.5"
- "@jridgewell/trace-mapping" "^0.3.24"
-
"@asamuzakjp/css-color@^3.1.1":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@asamuzakjp/css-color/-/css-color-3.1.1.tgz#41a612834dafd9353b89855b37baa8a03fb67bf2"
integrity sha512-hpRD68SV2OMcZCsrbdkccTw5FXjNDLo5OuqSHyHZfwweGsDWZwDJ2+gONyNAbazZclobMirACLw0lk8WVxIqxA==
dependencies:
"@csstools/css-calc" "^2.1.2"
"@csstools/css-color-parser" "^3.0.8"
"@csstools/css-parser-algorithms" "^3.0.4"
"@csstools/css-tokenizer" "^3.0.3"
lru-cache "^10.4.3"
"@babel/code-frame@7.0.0":
version "7.0.0"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8"
integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==
dependencies:
"@babel/highlight" "^7.0.0"
"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.26.2":
version "7.26.2"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85"
integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==
dependencies:
"@babel/helper-validator-identifier" "^7.25.9"
js-tokens "^4.0.0"
picocolors "^1.0.0"
"@babel/code-frame@^7.10.4", "@babel/code-frame@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be"
integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==
dependencies:
"@babel/helper-validator-identifier" "^7.27.1"
js-tokens "^4.0.0"
picocolors "^1.1.1"
+"@babel/code-frame@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.7.tgz#f2fbbfea87c44a21590ec515b778b2c26d8866e7"
+ integrity sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==
+ dependencies:
+ "@babel/helper-validator-identifier" "^7.29.7"
+ js-tokens "^4.0.0"
+ picocolors "^1.1.1"
+
"@babel/compat-data@^7.27.2", "@babel/compat-data@^7.27.7":
version "7.28.0"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.0.tgz#9fc6fd58c2a6a15243cd13983224968392070790"
integrity sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==
"@babel/compat-data@^7.28.5":
version "7.28.5"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.5.tgz#a8a4962e1567121ac0b3b487f52107443b455c7f"
integrity sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==
+"@babel/compat-data@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.29.7.tgz#6f0237f0f36d2e51c0570a636faed9d2d0efe629"
+ integrity sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==
+
"@babel/core@7.28.5":
version "7.28.5"
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.5.tgz#4c81b35e51e1b734f510c99b07dfbc7bbbb48f7e"
integrity sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==
dependencies:
"@babel/code-frame" "^7.27.1"
"@babel/generator" "^7.28.5"
"@babel/helper-compilation-targets" "^7.27.2"
"@babel/helper-module-transforms" "^7.28.3"
"@babel/helpers" "^7.28.4"
"@babel/parser" "^7.28.5"
"@babel/template" "^7.27.2"
"@babel/traverse" "^7.28.5"
"@babel/types" "^7.28.5"
"@jridgewell/remapping" "^2.3.5"
convert-source-map "^2.0.0"
debug "^4.1.0"
gensync "^1.0.0-beta.2"
json5 "^2.2.3"
semver "^6.3.1"
-"@babel/core@^7.27.1":
- version "7.28.3"
- resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.3.tgz#aceddde69c5d1def69b839d09efa3e3ff59c97cb"
- integrity sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==
- dependencies:
- "@ampproject/remapping" "^2.2.0"
- "@babel/code-frame" "^7.27.1"
- "@babel/generator" "^7.28.3"
- "@babel/helper-compilation-targets" "^7.27.2"
- "@babel/helper-module-transforms" "^7.28.3"
- "@babel/helpers" "^7.28.3"
- "@babel/parser" "^7.28.3"
- "@babel/template" "^7.27.2"
- "@babel/traverse" "^7.28.3"
- "@babel/types" "^7.28.2"
+"@babel/core@^7.29.0":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.29.7.tgz#80c10b17248082968b57a857b91640971f2070f7"
+ integrity sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==
+ dependencies:
+ "@babel/code-frame" "^7.29.7"
+ "@babel/generator" "^7.29.7"
+ "@babel/helper-compilation-targets" "^7.29.7"
+ "@babel/helper-module-transforms" "^7.29.7"
+ "@babel/helpers" "^7.29.7"
+ "@babel/parser" "^7.29.7"
+ "@babel/template" "^7.29.7"
+ "@babel/traverse" "^7.29.7"
+ "@babel/types" "^7.29.7"
+ "@jridgewell/remapping" "^2.3.5"
convert-source-map "^2.0.0"
debug "^4.1.0"
gensync "^1.0.0-beta.2"
json5 "^2.2.3"
semver "^6.3.1"
"@babel/eslint-parser@7.28.5":
version "7.28.5"
resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.28.5.tgz#0b8883a4a1c2cbed7b3cd9d7765d80e8f480b9ae"
integrity sha512-fcdRcWahONYo+JRnJg1/AekOacGvKx12Gu0qXJXFi2WBqQA1i7+O5PaxRB7kxE/Op94dExnCiiar6T09pvdHpA==
dependencies:
"@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1"
eslint-visitor-keys "^2.1.0"
semver "^6.3.1"
"@babel/generator@^7.27.0":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.27.0.tgz#764382b5392e5b9aff93cadb190d0745866cbc2c"
integrity sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==
dependencies:
"@babel/parser" "^7.27.0"
"@babel/types" "^7.27.0"
"@jridgewell/gen-mapping" "^0.3.5"
"@jridgewell/trace-mapping" "^0.3.25"
jsesc "^3.0.2"
"@babel/generator@^7.28.3":
version "7.28.3"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.3.tgz#9626c1741c650cbac39121694a0f2d7451b8ef3e"
integrity sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==
dependencies:
"@babel/parser" "^7.28.3"
"@babel/types" "^7.28.2"
"@jridgewell/gen-mapping" "^0.3.12"
"@jridgewell/trace-mapping" "^0.3.28"
jsesc "^3.0.2"
"@babel/generator@^7.28.5":
version "7.28.5"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.5.tgz#712722d5e50f44d07bc7ac9fe84438742dd61298"
integrity sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==
dependencies:
"@babel/parser" "^7.28.5"
"@babel/types" "^7.28.5"
"@jridgewell/gen-mapping" "^0.3.12"
"@jridgewell/trace-mapping" "^0.3.28"
jsesc "^3.0.2"
+"@babel/generator@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.7.tgz#cca0b8827e6bcf3ba176788e7f3b180ad6db2fa3"
+ integrity sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==
+ dependencies:
+ "@babel/parser" "^7.29.7"
+ "@babel/types" "^7.29.7"
+ "@jridgewell/gen-mapping" "^0.3.12"
+ "@jridgewell/trace-mapping" "^0.3.28"
+ jsesc "^3.0.2"
+
"@babel/helper-annotate-as-pure@^7.25.9":
version "7.25.9"
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz#d8eac4d2dc0d7b6e11fa6e535332e0d3184f06b4"
integrity sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==
dependencies:
"@babel/types" "^7.25.9"
"@babel/helper-annotate-as-pure@^7.27.1", "@babel/helper-annotate-as-pure@^7.27.3":
version "7.27.3"
resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz#f31fd86b915fc4daf1f3ac6976c59be7084ed9c5"
integrity sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==
dependencies:
"@babel/types" "^7.27.3"
+"@babel/helper-annotate-as-pure@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.29.7.tgz#c70fe3c6ecbdc3fd2dd1b0f498428b88b82ce47f"
+ integrity sha512-OoK6239jHPuSQOoS0kfTVKn0b/rVTk0seKq4Gd2UMLtmOVLjDC0ki3e+c90Trqv2gMfvJFqkiljrr568+qddiw==
+ dependencies:
+ "@babel/types" "^7.29.7"
+
"@babel/helper-compilation-targets@^7.27.1", "@babel/helper-compilation-targets@^7.27.2":
version "7.27.2"
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz#46a0f6efab808d51d29ce96858dd10ce8732733d"
integrity sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==
dependencies:
"@babel/compat-data" "^7.27.2"
"@babel/helper-validator-option" "^7.27.1"
browserslist "^4.24.0"
lru-cache "^5.1.1"
semver "^6.3.1"
+"@babel/helper-compilation-targets@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz#7a1def704302401c47f64fa85589e974ae217042"
+ integrity sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==
+ dependencies:
+ "@babel/compat-data" "^7.29.7"
+ "@babel/helper-validator-option" "^7.29.7"
+ browserslist "^4.24.0"
+ lru-cache "^5.1.1"
+ semver "^6.3.1"
+
"@babel/helper-create-class-features-plugin@^7.27.1", "@babel/helper-create-class-features-plugin@^7.28.3":
version "7.28.3"
resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.3.tgz#3e747434ea007910c320c4d39a6b46f20f371d46"
integrity sha512-V9f6ZFIYSLNEbuGA/92uOvYsGCJNsuA8ESZ4ldc09bWk/j8H8TKiPw8Mk1eG6olpnO0ALHJmYfZvF4MEE4gajg==
dependencies:
"@babel/helper-annotate-as-pure" "^7.27.3"
"@babel/helper-member-expression-to-functions" "^7.27.1"
"@babel/helper-optimise-call-expression" "^7.27.1"
"@babel/helper-replace-supers" "^7.27.1"
"@babel/helper-skip-transparent-expression-wrappers" "^7.27.1"
"@babel/traverse" "^7.28.3"
semver "^6.3.1"
+"@babel/helper-create-class-features-plugin@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.29.7.tgz#6eddf286f2ec418f740c91d60a83347c55838ddd"
+ integrity sha512-IY3ZD9Tmooqr3TUhc3DUWxiuo8xx1DWLhd5M7hQ+ZWJamqM2BbalrBJb2MisSLoYorOj75U03qULCxQTY9r3hg==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.29.7"
+ "@babel/helper-member-expression-to-functions" "^7.29.7"
+ "@babel/helper-optimise-call-expression" "^7.29.7"
+ "@babel/helper-replace-supers" "^7.29.7"
+ "@babel/helper-skip-transparent-expression-wrappers" "^7.29.7"
+ "@babel/traverse" "^7.29.7"
+ semver "^6.3.1"
+
"@babel/helper-create-regexp-features-plugin@^7.18.6":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.0.tgz#0e41f7d38c2ebe06ebd9cf0e02fb26019c77cd95"
integrity sha512-fO8l08T76v48BhpNRW/nQ0MxfnSdoSKUJBMjubOAYffsVuGG5qOfMq7N6Es7UJvi7Y8goXXo07EfcHZXDPuELQ==
dependencies:
"@babel/helper-annotate-as-pure" "^7.25.9"
regexpu-core "^6.2.0"
semver "^6.3.1"
"@babel/helper-create-regexp-features-plugin@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz#05b0882d97ba1d4d03519e4bce615d70afa18c53"
integrity sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==
dependencies:
"@babel/helper-annotate-as-pure" "^7.27.1"
regexpu-core "^6.2.0"
semver "^6.3.1"
"@babel/helper-define-polyfill-provider@^0.6.5":
version "0.6.5"
resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz#742ccf1cb003c07b48859fc9fa2c1bbe40e5f753"
integrity sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==
dependencies:
"@babel/helper-compilation-targets" "^7.27.2"
"@babel/helper-plugin-utils" "^7.27.1"
debug "^4.4.1"
lodash.debounce "^4.0.8"
resolve "^1.22.10"
"@babel/helper-globals@^7.28.0":
version "7.28.0"
resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz#b9430df2aa4e17bc28665eadeae8aa1d985e6674"
integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==
+"@babel/helper-globals@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.29.7.tgz#f04a96fbd8473241b1079243f5b3f03a3010ab7b"
+ integrity sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==
+
"@babel/helper-member-expression-to-functions@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz#ea1211276be93e798ce19037da6f06fbb994fa44"
integrity sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==
dependencies:
"@babel/traverse" "^7.27.1"
"@babel/types" "^7.27.1"
+"@babel/helper-member-expression-to-functions@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.29.7.tgz#8dbdb3ce0b5c487e1aec10e13c9a43a500814df8"
+ integrity sha512-j+7JYmk1JYDtACIGj0QJqqWZjoUpMoEikQGADMaHgCMCSDqd2+P32rfcibUNrGOMWrlzK1WJBdxrB3JJQZwWtg==
+ dependencies:
+ "@babel/traverse" "^7.29.7"
+ "@babel/types" "^7.29.7"
+
"@babel/helper-module-imports@^7.0.0-beta.49":
version "7.25.9"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz#e7f8d20602ebdbf9ebbea0a0751fb0f2a4141715"
integrity sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==
dependencies:
"@babel/traverse" "^7.25.9"
"@babel/types" "^7.25.9"
"@babel/helper-module-imports@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz#7ef769a323e2655e126673bb6d2d6913bbead204"
integrity sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==
dependencies:
"@babel/traverse" "^7.27.1"
"@babel/types" "^7.27.1"
+"@babel/helper-module-imports@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.29.7.tgz#ef25048a518e828d7393fac5882ddd73921d7396"
+ integrity sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==
+ dependencies:
+ "@babel/traverse" "^7.29.7"
+ "@babel/types" "^7.29.7"
+
"@babel/helper-module-transforms@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.27.1.tgz#e1663b8b71d2de948da5c4fb2a20ca4f3ec27a6f"
integrity sha512-9yHn519/8KvTU5BjTVEEeIM3w9/2yXNKoD82JifINImhpKkARMJKPP59kLo+BafpdN5zgNeIcS4jsGDmd3l58g==
dependencies:
"@babel/helper-module-imports" "^7.27.1"
"@babel/helper-validator-identifier" "^7.27.1"
"@babel/traverse" "^7.27.1"
"@babel/helper-module-transforms@^7.28.3":
version "7.28.3"
resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz#a2b37d3da3b2344fe085dab234426f2b9a2fa5f6"
integrity sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==
dependencies:
"@babel/helper-module-imports" "^7.27.1"
"@babel/helper-validator-identifier" "^7.27.1"
"@babel/traverse" "^7.28.3"
+"@babel/helper-module-transforms@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz#b062747a5997ba138637201328bbff77960574ae"
+ integrity sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==
+ dependencies:
+ "@babel/helper-module-imports" "^7.29.7"
+ "@babel/helper-validator-identifier" "^7.29.7"
+ "@babel/traverse" "^7.29.7"
+
"@babel/helper-optimise-call-expression@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz#c65221b61a643f3e62705e5dd2b5f115e35f9200"
integrity sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==
dependencies:
"@babel/types" "^7.27.1"
+"@babel/helper-optimise-call-expression@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.29.7.tgz#77b0b5b94f1997fa9d6e3125f445227b1faf9d85"
+ integrity sha512-+kmGVjcT9RGYzoDwdwEqEvGgKe3BYq+O1iGzjFubaNgZHwYHP6lsF2Yghf4kEuv9BV7tYDZ913aBW9am6YKong==
+ dependencies:
+ "@babel/types" "^7.29.7"
+
"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.18.6":
version "7.26.5"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.26.5.tgz#18580d00c9934117ad719392c4f6585c9333cc35"
integrity sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==
"@babel/helper-plugin-utils@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz#ddb2f876534ff8013e6c2b299bf4d39b3c51d44c"
integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==
+"@babel/helper-plugin-utils@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.29.7.tgz#c0a0766f1a13617d8a17407d7ab8f9d486225ea4"
+ integrity sha512-G7sHYigPY17oO5SYWnfD/0MTBwVR781S/JI643e/JhUYgVgWE/61SoW3NH9KWUKyKq5LVh3npif99Wkt6j86Jw==
+
"@babel/helper-remap-async-to-generator@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz#4601d5c7ce2eb2aea58328d43725523fcd362ce6"
integrity sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==
dependencies:
"@babel/helper-annotate-as-pure" "^7.27.1"
"@babel/helper-wrap-function" "^7.27.1"
"@babel/traverse" "^7.27.1"
"@babel/helper-replace-supers@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz#b1ed2d634ce3bdb730e4b52de30f8cccfd692bc0"
integrity sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==
dependencies:
"@babel/helper-member-expression-to-functions" "^7.27.1"
"@babel/helper-optimise-call-expression" "^7.27.1"
"@babel/traverse" "^7.27.1"
+"@babel/helper-replace-supers@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.29.7.tgz#bc3c3964329043c79112e513c1b198f16589ac21"
+ integrity sha512-atfGXWSeCiF4DnKZIfmJfQRkSw9b9gNNXR1kqKjbhG4pGYCOnkp8OcTB8E3NXjBu8NpheSnOeNKz8KT7UNFTmQ==
+ dependencies:
+ "@babel/helper-member-expression-to-functions" "^7.29.7"
+ "@babel/helper-optimise-call-expression" "^7.29.7"
+ "@babel/traverse" "^7.29.7"
+
"@babel/helper-skip-transparent-expression-wrappers@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz#62bb91b3abba8c7f1fec0252d9dbea11b3ee7a56"
integrity sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==
dependencies:
"@babel/traverse" "^7.27.1"
"@babel/types" "^7.27.1"
+"@babel/helper-skip-transparent-expression-wrappers@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.29.7.tgz#50c95c7e4c4f54936cfa0116428edc559862d551"
+ integrity sha512-brcMGQaVzIeUb+6/bs1Av0f8YuNNjKY2JyvfRCsFuFsdKccEQ5Ges2y74D74NZ1Rz8lKJ9ksJkfqwQFJ/iNEyQ==
+ dependencies:
+ "@babel/traverse" "^7.29.7"
+ "@babel/types" "^7.29.7"
+
"@babel/helper-string-parser@^7.25.9":
version "7.25.9"
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c"
integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==
"@babel/helper-string-parser@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687"
integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==
+"@babel/helper-string-parser@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz#7f0871d99824d23137d60f86fcf6130fd5a1b51f"
+ integrity sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==
+
"@babel/helper-validator-identifier@^7.25.9", "@babel/helper-validator-identifier@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8"
integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==
"@babel/helper-validator-identifier@^7.28.5":
version "7.28.5"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4"
integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==
+"@babel/helper-validator-identifier@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz#bd87084ced0c796ec46bda492de6e83d29e89fc2"
+ integrity sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==
+
"@babel/helper-validator-option@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f"
integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==
+"@babel/helper-validator-option@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.29.7.tgz#cf315be940213b354eb4abcc0bd01ebe3f73bc2a"
+ integrity sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==
+
"@babel/helper-wrap-function@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.27.1.tgz#b88285009c31427af318d4fe37651cd62a142409"
integrity sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ==
dependencies:
"@babel/template" "^7.27.1"
"@babel/traverse" "^7.27.1"
"@babel/types" "^7.27.1"
-"@babel/helpers@^7.28.3":
- version "7.28.3"
- resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.3.tgz#b83156c0a2232c133d1b535dd5d3452119c7e441"
- integrity sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==
- dependencies:
- "@babel/template" "^7.27.2"
- "@babel/types" "^7.28.2"
-
"@babel/helpers@^7.28.4":
version "7.28.4"
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.4.tgz#fe07274742e95bdf7cf1443593eeb8926ab63827"
integrity sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==
dependencies:
"@babel/template" "^7.27.2"
"@babel/types" "^7.28.4"
+"@babel/helpers@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.29.7.tgz#45abfde7548997e34376c3e69feb475cffb4a607"
+ integrity sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==
+ dependencies:
+ "@babel/template" "^7.29.7"
+ "@babel/types" "^7.29.7"
+
"@babel/highlight@^7.0.0":
version "7.25.9"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.25.9.tgz#8141ce68fc73757946f983b343f1231f4691acc6"
integrity sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==
dependencies:
"@babel/helper-validator-identifier" "^7.25.9"
chalk "^2.4.2"
js-tokens "^4.0.0"
picocolors "^1.0.0"
"@babel/parser@^7.27.0":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.27.0.tgz#3d7d6ee268e41d2600091cbd4e145ffee85a44ec"
integrity sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==
dependencies:
"@babel/types" "^7.27.0"
"@babel/parser@^7.27.2", "@babel/parser@^7.28.0", "@babel/parser@^7.28.3":
version "7.28.3"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.3.tgz#d2d25b814621bca5fe9d172bc93792547e7a2a71"
integrity sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==
dependencies:
"@babel/types" "^7.28.2"
"@babel/parser@^7.28.4":
version "7.28.4"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.4.tgz#da25d4643532890932cc03f7705fe19637e03fa8"
integrity sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==
dependencies:
"@babel/types" "^7.28.4"
"@babel/parser@^7.28.5":
version "7.28.5"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.5.tgz#0b0225ee90362f030efd644e8034c99468893b08"
integrity sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==
dependencies:
"@babel/types" "^7.28.5"
+"@babel/parser@^7.29.3", "@babel/parser@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.7.tgz#837b87387cbf5ec5530cb634b3c622f68edb9334"
+ integrity sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==
+ dependencies:
+ "@babel/types" "^7.29.7"
+
"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.28.5":
version "7.28.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz#fbde57974707bbfa0376d34d425ff4fa6c732421"
integrity sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/traverse" "^7.28.5"
"@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz#43f70a6d7efd52370eefbdf55ae03d91b293856d"
integrity sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz#beb623bd573b8b6f3047bd04c32506adc3e58a72"
integrity sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz#e134a5479eb2ba9c02714e8c1ebf1ec9076124fd"
integrity sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-skip-transparent-expression-wrappers" "^7.27.1"
"@babel/plugin-transform-optional-chaining" "^7.27.1"
"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.28.3":
version "7.28.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz#373f6e2de0016f73caf8f27004f61d167743742a"
integrity sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/traverse" "^7.28.3"
"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2":
version "7.21.0-placeholder-for-preset-env.2"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703"
integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==
"@babel/plugin-syntax-import-assertions@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz#88894aefd2b03b5ee6ad1562a7c8e1587496aecd"
integrity sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-syntax-import-attributes@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz#34c017d54496f9b11b61474e7ea3dfd5563ffe07"
integrity sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-syntax-jsx@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz#2f9beb5eff30fa507c5532d107daac7b888fa34c"
integrity sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-syntax-typescript@^7.27.1":
- version "7.27.1"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz#5147d29066a793450f220c63fa3a9431b7e6dd18"
- integrity sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==
+"@babel/plugin-syntax-typescript@^7.28.6", "@babel/plugin-syntax-typescript@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz#7c29388932313ed58413a0343048d75d92fb5b24"
+ integrity sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==
dependencies:
- "@babel/helper-plugin-utils" "^7.27.1"
+ "@babel/helper-plugin-utils" "^7.29.7"
"@babel/plugin-syntax-unicode-sets-regex@^7.18.6":
version "7.18.6"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357"
integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==
dependencies:
"@babel/helper-create-regexp-features-plugin" "^7.18.6"
"@babel/helper-plugin-utils" "^7.18.6"
"@babel/plugin-transform-arrow-functions@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz#6e2061067ba3ab0266d834a9f94811196f2aba9a"
integrity sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-async-generator-functions@^7.28.0":
version "7.28.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz#1276e6c7285ab2cd1eccb0bc7356b7a69ff842c2"
integrity sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-remap-async-to-generator" "^7.27.1"
"@babel/traverse" "^7.28.0"
"@babel/plugin-transform-async-to-generator@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz#9a93893b9379b39466c74474f55af03de78c66e7"
integrity sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA==
dependencies:
"@babel/helper-module-imports" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-remap-async-to-generator" "^7.27.1"
"@babel/plugin-transform-block-scoped-functions@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz#558a9d6e24cf72802dd3b62a4b51e0d62c0f57f9"
integrity sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-block-scoping@^7.28.5":
version "7.28.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz#e0d3af63bd8c80de2e567e690a54e84d85eb16f6"
integrity sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-class-properties@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz#dd40a6a370dfd49d32362ae206ddaf2bb082a925"
integrity sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==
dependencies:
"@babel/helper-create-class-features-plugin" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-class-static-block@^7.28.3":
version "7.28.3"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz#d1b8e69b54c9993bc558203e1f49bfc979bfd852"
integrity sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg==
dependencies:
"@babel/helper-create-class-features-plugin" "^7.28.3"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-classes@^7.28.4":
version "7.28.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz#75d66175486788c56728a73424d67cbc7473495c"
integrity sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA==
dependencies:
"@babel/helper-annotate-as-pure" "^7.27.3"
"@babel/helper-compilation-targets" "^7.27.2"
"@babel/helper-globals" "^7.28.0"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-replace-supers" "^7.27.1"
"@babel/traverse" "^7.28.4"
"@babel/plugin-transform-computed-properties@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz#81662e78bf5e734a97982c2b7f0a793288ef3caa"
integrity sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/template" "^7.27.1"
"@babel/plugin-transform-destructuring@^7.28.0":
version "7.28.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.0.tgz#0f156588f69c596089b7d5b06f5af83d9aa7f97a"
integrity sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/traverse" "^7.28.0"
"@babel/plugin-transform-destructuring@^7.28.5":
version "7.28.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz#b8402764df96179a2070bb7b501a1586cf8ad7a7"
integrity sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/traverse" "^7.28.5"
"@babel/plugin-transform-dotall-regex@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz#aa6821de864c528b1fecf286f0a174e38e826f4d"
integrity sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==
dependencies:
"@babel/helper-create-regexp-features-plugin" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-duplicate-keys@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz#f1fbf628ece18e12e7b32b175940e68358f546d1"
integrity sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz#5043854ca620a94149372e69030ff8cb6a9eb0ec"
integrity sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==
dependencies:
"@babel/helper-create-regexp-features-plugin" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-dynamic-import@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz#4c78f35552ac0e06aa1f6e3c573d67695e8af5a4"
integrity sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-explicit-resource-management@^7.28.0":
version "7.28.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz#45be6211b778dbf4b9d54c4e8a2b42fa72e09a1a"
integrity sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-destructuring" "^7.28.0"
"@babel/plugin-transform-exponentiation-operator@^7.28.5":
version "7.28.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz#7cc90a8170e83532676cfa505278e147056e94fe"
integrity sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-export-namespace-from@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz#71ca69d3471edd6daa711cf4dfc3400415df9c23"
integrity sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-for-of@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz#bc24f7080e9ff721b63a70ac7b2564ca15b6c40a"
integrity sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-skip-transparent-expression-wrappers" "^7.27.1"
"@babel/plugin-transform-function-name@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz#4d0bf307720e4dce6d7c30fcb1fd6ca77bdeb3a7"
integrity sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==
dependencies:
"@babel/helper-compilation-targets" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/traverse" "^7.27.1"
"@babel/plugin-transform-json-strings@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz#a2e0ce6ef256376bd527f290da023983527a4f4c"
integrity sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-literals@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz#baaefa4d10a1d4206f9dcdda50d7d5827bb70b24"
integrity sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-logical-assignment-operators@^7.28.5":
version "7.28.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz#d028fd6db8c081dee4abebc812c2325e24a85b0e"
integrity sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-member-expression-literals@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz#37b88ba594d852418e99536f5612f795f23aeaf9"
integrity sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-modules-amd@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz#a4145f9d87c2291fe2d05f994b65dba4e3e7196f"
integrity sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==
dependencies:
"@babel/helper-module-transforms" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-modules-commonjs@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz#8e44ed37c2787ecc23bdc367f49977476614e832"
integrity sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==
dependencies:
"@babel/helper-module-transforms" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-modules-systemjs@^7.28.5":
version "7.28.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz#7439e592a92d7670dfcb95d0cbc04bd3e64801d2"
integrity sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew==
dependencies:
"@babel/helper-module-transforms" "^7.28.3"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-validator-identifier" "^7.28.5"
"@babel/traverse" "^7.28.5"
"@babel/plugin-transform-modules-umd@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz#63f2cf4f6dc15debc12f694e44714863d34cd334"
integrity sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==
dependencies:
"@babel/helper-module-transforms" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-named-capturing-groups-regex@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz#f32b8f7818d8fc0cc46ee20a8ef75f071af976e1"
integrity sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==
dependencies:
"@babel/helper-create-regexp-features-plugin" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-new-target@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz#259c43939728cad1706ac17351b7e6a7bea1abeb"
integrity sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-nullish-coalescing-operator@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz#4f9d3153bf6782d73dd42785a9d22d03197bc91d"
integrity sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-numeric-separator@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz#614e0b15cc800e5997dadd9bd6ea524ed6c819c6"
integrity sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-object-rest-spread@^7.28.4":
version "7.28.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz#9ee1ceca80b3e6c4bac9247b2149e36958f7f98d"
integrity sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew==
dependencies:
"@babel/helper-compilation-targets" "^7.27.2"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-destructuring" "^7.28.0"
"@babel/plugin-transform-parameters" "^7.27.7"
"@babel/traverse" "^7.28.4"
"@babel/plugin-transform-object-super@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz#1c932cd27bf3874c43a5cac4f43ebf970c9871b5"
integrity sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-replace-supers" "^7.27.1"
"@babel/plugin-transform-optional-catch-binding@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz#84c7341ebde35ccd36b137e9e45866825072a30c"
integrity sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-optional-chaining@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz#874ce3c4f06b7780592e946026eb76a32830454f"
integrity sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-skip-transparent-expression-wrappers" "^7.27.1"
"@babel/plugin-transform-optional-chaining@^7.28.5":
version "7.28.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz#8238c785f9d5c1c515a90bf196efb50d075a4b26"
integrity sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-skip-transparent-expression-wrappers" "^7.27.1"
"@babel/plugin-transform-parameters@^7.27.7":
version "7.27.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz#1fd2febb7c74e7d21cf3b05f7aebc907940af53a"
integrity sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-private-methods@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz#fdacbab1c5ed81ec70dfdbb8b213d65da148b6af"
integrity sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==
dependencies:
"@babel/helper-create-class-features-plugin" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-private-property-in-object@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz#4dbbef283b5b2f01a21e81e299f76e35f900fb11"
integrity sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==
dependencies:
"@babel/helper-annotate-as-pure" "^7.27.1"
"@babel/helper-create-class-features-plugin" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-property-literals@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz#07eafd618800591e88073a0af1b940d9a42c6424"
integrity sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-regenerator@^7.28.4":
version "7.28.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz#9d3fa3bebb48ddd0091ce5729139cd99c67cea51"
integrity sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-regexp-modifiers@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz#df9ba5577c974e3f1449888b70b76169998a6d09"
integrity sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==
dependencies:
"@babel/helper-create-regexp-features-plugin" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-reserved-words@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz#40fba4878ccbd1c56605a4479a3a891ac0274bb4"
integrity sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-runtime@7.28.5":
version "7.28.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.28.5.tgz#ae3e21fbefe2831ebac04dfa6b463691696afe17"
integrity sha512-20NUVgOrinudkIBzQ2bNxP08YpKprUkRTiRSd2/Z5GOdPImJGkoN4Z7IQe1T5AdyKI1i5L6RBmluqdSzvaq9/w==
dependencies:
"@babel/helper-module-imports" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
babel-plugin-polyfill-corejs2 "^0.4.14"
babel-plugin-polyfill-corejs3 "^0.13.0"
babel-plugin-polyfill-regenerator "^0.6.5"
semver "^6.3.1"
"@babel/plugin-transform-shorthand-properties@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz#532abdacdec87bfee1e0ef8e2fcdee543fe32b90"
integrity sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-spread@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz#1a264d5fc12750918f50e3fe3e24e437178abb08"
integrity sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-skip-transparent-expression-wrappers" "^7.27.1"
"@babel/plugin-transform-sticky-regex@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz#18984935d9d2296843a491d78a014939f7dcd280"
integrity sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-template-literals@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz#1a0eb35d8bb3e6efc06c9fd40eb0bcef548328b8"
integrity sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-typeof-symbol@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz#70e966bb492e03509cf37eafa6dcc3051f844369"
integrity sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
-"@babel/plugin-transform-typescript@^7.27.1":
- version "7.28.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.0.tgz#796cbd249ab56c18168b49e3e1d341b72af04a6b"
- integrity sha512-4AEiDEBPIZvLQaWlc9liCavE0xRM0dNca41WtBeM3jgFptfUOSG9z0uteLhq6+3rq+WB6jIvUwKDTpXEHPJ2Vg==
+"@babel/plugin-transform-typescript@^7.28.6":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.29.7.tgz#f0449c3df7037bbe232043476851c38f5e4a7615"
+ integrity sha512-jK52h8LaLc7JarhQV2ofeFMts4H7vnOXnqZNA6fYglBTZewRBE51KWt3BUltW1P+KoPsYkHoJeXePuz4zo2LMw==
dependencies:
- "@babel/helper-annotate-as-pure" "^7.27.3"
- "@babel/helper-create-class-features-plugin" "^7.27.1"
- "@babel/helper-plugin-utils" "^7.27.1"
- "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1"
- "@babel/plugin-syntax-typescript" "^7.27.1"
+ "@babel/helper-annotate-as-pure" "^7.29.7"
+ "@babel/helper-create-class-features-plugin" "^7.29.7"
+ "@babel/helper-plugin-utils" "^7.29.7"
+ "@babel/helper-skip-transparent-expression-wrappers" "^7.29.7"
+ "@babel/plugin-syntax-typescript" "^7.29.7"
"@babel/plugin-transform-unicode-escapes@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz#3e3143f8438aef842de28816ece58780190cf806"
integrity sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==
dependencies:
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-unicode-property-regex@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz#bdfe2d3170c78c5691a3c3be934c8c0087525956"
integrity sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==
dependencies:
"@babel/helper-create-regexp-features-plugin" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-unicode-regex@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz#25948f5c395db15f609028e370667ed8bae9af97"
integrity sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==
dependencies:
"@babel/helper-create-regexp-features-plugin" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-transform-unicode-sets-regex@^7.27.1":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz#6ab706d10f801b5c72da8bb2548561fa04193cd1"
integrity sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==
dependencies:
"@babel/helper-create-regexp-features-plugin" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/preset-env@7.28.5":
version "7.28.5"
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.28.5.tgz#82dd159d1563f219a1ce94324b3071eb89e280b0"
integrity sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg==
dependencies:
"@babel/compat-data" "^7.28.5"
"@babel/helper-compilation-targets" "^7.27.2"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/helper-validator-option" "^7.27.1"
"@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.28.5"
"@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.27.1"
"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.27.1"
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.27.1"
"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.28.3"
"@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2"
"@babel/plugin-syntax-import-assertions" "^7.27.1"
"@babel/plugin-syntax-import-attributes" "^7.27.1"
"@babel/plugin-syntax-unicode-sets-regex" "^7.18.6"
"@babel/plugin-transform-arrow-functions" "^7.27.1"
"@babel/plugin-transform-async-generator-functions" "^7.28.0"
"@babel/plugin-transform-async-to-generator" "^7.27.1"
"@babel/plugin-transform-block-scoped-functions" "^7.27.1"
"@babel/plugin-transform-block-scoping" "^7.28.5"
"@babel/plugin-transform-class-properties" "^7.27.1"
"@babel/plugin-transform-class-static-block" "^7.28.3"
"@babel/plugin-transform-classes" "^7.28.4"
"@babel/plugin-transform-computed-properties" "^7.27.1"
"@babel/plugin-transform-destructuring" "^7.28.5"
"@babel/plugin-transform-dotall-regex" "^7.27.1"
"@babel/plugin-transform-duplicate-keys" "^7.27.1"
"@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.27.1"
"@babel/plugin-transform-dynamic-import" "^7.27.1"
"@babel/plugin-transform-explicit-resource-management" "^7.28.0"
"@babel/plugin-transform-exponentiation-operator" "^7.28.5"
"@babel/plugin-transform-export-namespace-from" "^7.27.1"
"@babel/plugin-transform-for-of" "^7.27.1"
"@babel/plugin-transform-function-name" "^7.27.1"
"@babel/plugin-transform-json-strings" "^7.27.1"
"@babel/plugin-transform-literals" "^7.27.1"
"@babel/plugin-transform-logical-assignment-operators" "^7.28.5"
"@babel/plugin-transform-member-expression-literals" "^7.27.1"
"@babel/plugin-transform-modules-amd" "^7.27.1"
"@babel/plugin-transform-modules-commonjs" "^7.27.1"
"@babel/plugin-transform-modules-systemjs" "^7.28.5"
"@babel/plugin-transform-modules-umd" "^7.27.1"
"@babel/plugin-transform-named-capturing-groups-regex" "^7.27.1"
"@babel/plugin-transform-new-target" "^7.27.1"
"@babel/plugin-transform-nullish-coalescing-operator" "^7.27.1"
"@babel/plugin-transform-numeric-separator" "^7.27.1"
"@babel/plugin-transform-object-rest-spread" "^7.28.4"
"@babel/plugin-transform-object-super" "^7.27.1"
"@babel/plugin-transform-optional-catch-binding" "^7.27.1"
"@babel/plugin-transform-optional-chaining" "^7.28.5"
"@babel/plugin-transform-parameters" "^7.27.7"
"@babel/plugin-transform-private-methods" "^7.27.1"
"@babel/plugin-transform-private-property-in-object" "^7.27.1"
"@babel/plugin-transform-property-literals" "^7.27.1"
"@babel/plugin-transform-regenerator" "^7.28.4"
"@babel/plugin-transform-regexp-modifiers" "^7.27.1"
"@babel/plugin-transform-reserved-words" "^7.27.1"
"@babel/plugin-transform-shorthand-properties" "^7.27.1"
"@babel/plugin-transform-spread" "^7.27.1"
"@babel/plugin-transform-sticky-regex" "^7.27.1"
"@babel/plugin-transform-template-literals" "^7.27.1"
"@babel/plugin-transform-typeof-symbol" "^7.27.1"
"@babel/plugin-transform-unicode-escapes" "^7.27.1"
"@babel/plugin-transform-unicode-property-regex" "^7.27.1"
"@babel/plugin-transform-unicode-regex" "^7.27.1"
"@babel/plugin-transform-unicode-sets-regex" "^7.27.1"
"@babel/preset-modules" "0.1.6-no-external-plugins"
babel-plugin-polyfill-corejs2 "^0.4.14"
babel-plugin-polyfill-corejs3 "^0.13.0"
babel-plugin-polyfill-regenerator "^0.6.5"
core-js-compat "^3.43.0"
semver "^6.3.1"
"@babel/preset-modules@0.1.6-no-external-plugins":
version "0.1.6-no-external-plugins"
resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a"
integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==
dependencies:
"@babel/helper-plugin-utils" "^7.0.0"
"@babel/types" "^7.4.4"
esutils "^2.0.2"
"@babel/register@7.28.3":
version "7.28.3"
resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.28.3.tgz#abd8a3753480c799bdaf9c9092d6745d16e052c2"
integrity sha512-CieDOtd8u208eI49bYl4z1J22ySFw87IGwE+IswFEExH7e3rLgKb0WNQeumnacQ1+VoDJLYI5QFA3AJZuyZQfA==
dependencies:
clone-deep "^4.0.1"
find-cache-dir "^2.0.0"
make-dir "^2.1.0"
pirates "^4.0.6"
source-map-support "^0.5.16"
"@babel/runtime@7.28.4":
version "7.28.4"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.4.tgz#a70226016fabe25c5783b2f22d3e1c9bc5ca3326"
integrity sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==
"@babel/runtime@^7.12.5":
version "7.27.1"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.1.tgz#9fce313d12c9a77507f264de74626e87fd0dc541"
integrity sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==
"@babel/template@^7.27.0":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.0.tgz#b253e5406cc1df1c57dcd18f11760c2dbf40c0b4"
integrity sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==
dependencies:
"@babel/code-frame" "^7.26.2"
"@babel/parser" "^7.27.0"
"@babel/types" "^7.27.0"
"@babel/template@^7.27.1", "@babel/template@^7.27.2":
version "7.27.2"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.2.tgz#fa78ceed3c4e7b63ebf6cb39e5852fca45f6809d"
integrity sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==
dependencies:
"@babel/code-frame" "^7.27.1"
"@babel/parser" "^7.27.2"
"@babel/types" "^7.27.1"
+"@babel/template@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.29.7.tgz#4d9d4004f645cdd304de958c725162784ecac700"
+ integrity sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==
+ dependencies:
+ "@babel/code-frame" "^7.29.7"
+ "@babel/parser" "^7.29.7"
+ "@babel/types" "^7.29.7"
+
"@babel/traverse@^7.25.9":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.27.0.tgz#11d7e644779e166c0442f9a07274d02cd91d4a70"
integrity sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==
dependencies:
"@babel/code-frame" "^7.26.2"
"@babel/generator" "^7.27.0"
"@babel/parser" "^7.27.0"
"@babel/template" "^7.27.0"
"@babel/types" "^7.27.0"
debug "^4.3.1"
globals "^11.1.0"
"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.0", "@babel/traverse@^7.28.3":
version "7.28.3"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.3.tgz#6911a10795d2cce43ec6a28cffc440cca2593434"
integrity sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==
dependencies:
"@babel/code-frame" "^7.27.1"
"@babel/generator" "^7.28.3"
"@babel/helper-globals" "^7.28.0"
"@babel/parser" "^7.28.3"
"@babel/template" "^7.27.2"
"@babel/types" "^7.28.2"
debug "^4.3.1"
"@babel/traverse@^7.28.4":
version "7.28.4"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.4.tgz#8d456101b96ab175d487249f60680221692b958b"
integrity sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==
dependencies:
"@babel/code-frame" "^7.27.1"
"@babel/generator" "^7.28.3"
"@babel/helper-globals" "^7.28.0"
"@babel/parser" "^7.28.4"
"@babel/template" "^7.27.2"
"@babel/types" "^7.28.4"
debug "^4.3.1"
"@babel/traverse@^7.28.5":
version "7.28.5"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.5.tgz#450cab9135d21a7a2ca9d2d35aa05c20e68c360b"
integrity sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==
dependencies:
"@babel/code-frame" "^7.27.1"
"@babel/generator" "^7.28.5"
"@babel/helper-globals" "^7.28.0"
"@babel/parser" "^7.28.5"
"@babel/template" "^7.27.2"
"@babel/types" "^7.28.5"
debug "^4.3.1"
+"@babel/traverse@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.7.tgz#c47b07a41b95da0907d026b5dd894d98de7d2f2d"
+ integrity sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==
+ dependencies:
+ "@babel/code-frame" "^7.29.7"
+ "@babel/generator" "^7.29.7"
+ "@babel/helper-globals" "^7.29.7"
+ "@babel/parser" "^7.29.7"
+ "@babel/template" "^7.29.7"
+ "@babel/types" "^7.29.7"
+ debug "^4.3.1"
+
"@babel/types@^7.0.0-beta.49", "@babel/types@^7.25.9", "@babel/types@^7.27.0", "@babel/types@^7.4.4":
version "7.27.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.27.0.tgz#ef9acb6b06c3173f6632d993ecb6d4ae470b4559"
integrity sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==
dependencies:
"@babel/helper-string-parser" "^7.25.9"
"@babel/helper-validator-identifier" "^7.25.9"
"@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2":
version "7.28.2"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.2.tgz#da9db0856a9a88e0a13b019881d7513588cf712b"
integrity sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==
dependencies:
"@babel/helper-string-parser" "^7.27.1"
"@babel/helper-validator-identifier" "^7.27.1"
"@babel/types@^7.28.4":
version "7.28.4"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.4.tgz#0a4e618f4c60a7cd6c11cb2d48060e4dbe38ac3a"
integrity sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==
dependencies:
"@babel/helper-string-parser" "^7.27.1"
"@babel/helper-validator-identifier" "^7.27.1"
"@babel/types@^7.28.5":
version "7.28.5"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.5.tgz#10fc405f60897c35f07e85493c932c7b5ca0592b"
integrity sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==
dependencies:
"@babel/helper-string-parser" "^7.27.1"
"@babel/helper-validator-identifier" "^7.28.5"
+"@babel/types@^7.29.7":
+ version "7.29.7"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.7.tgz#8005e31d82712ee7adaef6e23c63b71a62770a92"
+ integrity sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==
+ dependencies:
+ "@babel/helper-string-parser" "^7.29.7"
+ "@babel/helper-validator-identifier" "^7.29.7"
+
"@bazel/runfiles@^6.3.1":
version "6.3.1"
resolved "https://registry.yarnpkg.com/@bazel/runfiles/-/runfiles-6.3.1.tgz#3f8824b2d82853377799d42354b4df78ab0ace0b"
integrity sha512-1uLNT5NZsUVIGS4syuHwTzZ8HycMPyr6POA3FCE4GbMtc4rhoJk8aZKtNIRthJYfL+iioppi+rTfH3olMPr9nA==
"@biomejs/biome@2.3.11":
version "2.3.11"
resolved "https://registry.yarnpkg.com/@biomejs/biome/-/biome-2.3.11.tgz#a8f3682b3b2c0112e2728f6d51d9c67a6c5521f8"
integrity sha512-/zt+6qazBWguPG6+eWmiELqO+9jRsMZ/DBU3lfuU2ngtIQYzymocHhKiZRyrbra4aCOoyTg/BmY+6WH5mv9xmQ==
optionalDependencies:
"@biomejs/cli-darwin-arm64" "2.3.11"
"@biomejs/cli-darwin-x64" "2.3.11"
"@biomejs/cli-linux-arm64" "2.3.11"
"@biomejs/cli-linux-arm64-musl" "2.3.11"
"@biomejs/cli-linux-x64" "2.3.11"
"@biomejs/cli-linux-x64-musl" "2.3.11"
"@biomejs/cli-win32-arm64" "2.3.11"
"@biomejs/cli-win32-x64" "2.3.11"
"@biomejs/cli-darwin-arm64@2.3.11":
version "2.3.11"
resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.3.11.tgz#3aa71d119e7216d66620282121673b95257fcc35"
integrity sha512-/uXXkBcPKVQY7rc9Ys2CrlirBJYbpESEDme7RKiBD6MmqR2w3j0+ZZXRIL2xiaNPsIMMNhP1YnA+jRRxoOAFrA==
"@biomejs/cli-darwin-x64@2.3.11":
version "2.3.11"
resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.3.11.tgz#3003d7c24e4fbba9693fba98692c6386884fedcf"
integrity sha512-fh7nnvbweDPm2xEmFjfmq7zSUiox88plgdHF9OIW4i99WnXrAC3o2P3ag9judoUMv8FCSUnlwJCM1B64nO5Fbg==
"@biomejs/cli-linux-arm64-musl@2.3.11":
version "2.3.11"
resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.3.11.tgz#a17fb411ba8146ba60f3592857b7c49c8f0fe936"
integrity sha512-XPSQ+XIPZMLaZ6zveQdwNjbX+QdROEd1zPgMwD47zvHV+tCGB88VH+aynyGxAHdzL+Tm/+DtKST5SECs4iwCLg==
"@biomejs/cli-linux-arm64@2.3.11":
version "2.3.11"
resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.3.11.tgz#643830d1e53071d594e16b919e88a46fbc5c0b55"
integrity sha512-l4xkGa9E7Uc0/05qU2lMYfN1H+fzzkHgaJoy98wO+b/7Gl78srbCRRgwYSW+BTLixTBrM6Ede5NSBwt7rd/i6g==
"@biomejs/cli-linux-x64-musl@2.3.11":
version "2.3.11"
resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.3.11.tgz#e9165c6d05f085829ab73a7ea0123a6a9b45dc89"
integrity sha512-vU7a8wLs5C9yJ4CB8a44r12aXYb8yYgBn+WeyzbMjaCMklzCv1oXr8x+VEyWodgJt9bDmhiaW/I0RHbn7rsNmw==
"@biomejs/cli-linux-x64@2.3.11":
version "2.3.11"
resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64/-/cli-linux-x64-2.3.11.tgz#3571049b1310132f1d12d67596ea5f39419836d0"
integrity sha512-/1s9V/H3cSe0r0Mv/Z8JryF5x9ywRxywomqZVLHAoa/uN0eY7F8gEngWKNS5vbbN/BsfpCG5yeBT5ENh50Frxg==
"@biomejs/cli-win32-arm64@2.3.11":
version "2.3.11"
resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.3.11.tgz#6769907655cd06938b00d040c6576c2fdf6c34a2"
integrity sha512-PZQ6ElCOnkYapSsysiTy0+fYX+agXPlWugh6+eQ6uPKI3vKAqNp6TnMhoM3oY2NltSB89hz59o8xIfOdyhi9Iw==
"@biomejs/cli-win32-x64@2.3.11":
version "2.3.11"
resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-x64/-/cli-win32-x64-2.3.11.tgz#71ba2fb5505b3b01dd3cf551ef329e0094636125"
integrity sha512-43VrG813EW+b5+YbDbz31uUsheX+qFKCpXeY9kfdAx+ww3naKxeVkTD9zLIWxUPfJquANMHrmW3wbe/037G0Qg==
+"@bufbuild/protobuf@^2.5.0":
+ version "2.12.0"
+ resolved "https://registry.yarnpkg.com/@bufbuild/protobuf/-/protobuf-2.12.0.tgz#53225636a8fcebb2bd94998ad9d42f99f96add4d"
+ integrity sha512-B/XlCaFIP8LOwzo+bz5uFzATYokcwCKQcghqnlfwSmM5eX/qTkvDBnDPs+gXtX/RyjxJ4DRikECcPJbyALA8FA==
+
"@bundled-es-modules/cookie@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@bundled-es-modules/cookie/-/cookie-2.0.1.tgz#b41376af6a06b3e32a15241d927b840a9b4de507"
integrity sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==
dependencies:
cookie "^0.7.2"
"@bundled-es-modules/statuses@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz#761d10f44e51a94902c4da48675b71a76cc98872"
integrity sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==
dependencies:
statuses "^2.0.1"
"@bundled-es-modules/tough-cookie@^0.1.6":
version "0.1.6"
resolved "https://registry.yarnpkg.com/@bundled-es-modules/tough-cookie/-/tough-cookie-0.1.6.tgz#fa9cd3cedfeecd6783e8b0d378b4a99e52bde5d3"
integrity sha512-dvMHbL464C0zI+Yqxbz6kZ5TOEp7GLW+pry/RWndAR8MJQAXZ2rPmIs8tziTZjeIyhSNZgZbCePtfSbdWqStJw==
dependencies:
"@types/tough-cookie" "^4.0.5"
tough-cookie "^4.1.4"
"@cacheable/memoize@^2.0.3":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@cacheable/memoize/-/memoize-2.0.3.tgz#64b18a6b42f987fe8a9e9e2e4391b14cbf85680f"
integrity sha512-hl9wfQgpiydhQEIv7fkjEzTGE+tcosCXLKFDO707wYJ/78FVOlowb36djex5GdbSyeHnG62pomYLMuV/OT8Pbw==
dependencies:
"@cacheable/utils" "^2.0.3"
"@cacheable/memory@^2.0.3":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@cacheable/memory/-/memory-2.0.3.tgz#8d8fa1644b32b85f27c7e4e16e14f36a8460735c"
integrity sha512-R3UKy/CKOyb1LZG/VRCTMcpiMDyLH7SH3JrraRdK6kf3GweWCOU3sgvE13W3TiDRbxnDKylzKJvhUAvWl9LQOA==
dependencies:
"@cacheable/memoize" "^2.0.3"
"@cacheable/utils" "^2.0.3"
"@keyv/bigmap" "^1.0.2"
hookified "^1.12.1"
keyv "^5.5.3"
"@cacheable/utils@^2.0.3":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@cacheable/utils/-/utils-2.0.3.tgz#45d62f5dd3b481ef62677335bada2cbdb579148b"
integrity sha512-m7Rce68cMHlAUjvWBy9Ru1Nmw5gU0SjGGtQDdhpe6E0xnbcvrIY0Epy//JU1VYYBUTzrG9jvgmTauULGKzOkWA==
"@chenfengyuan/vue-qrcode@2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@chenfengyuan/vue-qrcode/-/vue-qrcode-2.0.0.tgz#8cd01f6fc528d471680ebe812ec47c830aea7e63"
integrity sha512-33Cfr0zjbc3Dd8d5b1IgzXRAgXH0c2Gv19VI4snS25V/x9Z41eg769tC+Us1x+vqgQQhgD5YUjLnkpkrQfeMSw==
"@colors/colors@1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==
"@cropper/element-canvas@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@cropper/element-canvas/-/element-canvas-2.0.1.tgz#564451270a642b1da56ad53b7e495dc1a77b19f3"
integrity sha512-OKxq/O0HL9W2JegOsc2zh1NRpERZcLM5+M8aQ/eXdmMcfi1lzosPftag3Irp6pTsVpwV6B6ypIxKESzJ4ci9Fw==
dependencies:
"@cropper/element" "^2.0.1"
"@cropper/utils" "^2.0.1"
"@cropper/element-crosshair@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@cropper/element-crosshair/-/element-crosshair-2.0.1.tgz#207b9962cd1678d8e60418f54825a76bd2382b74"
integrity sha512-bS5msU9cTU/jf1/kDw+QJmEM9/rw8IgOdpolR85iMVUCR8sRcLa0wgom42MBHcpBYB6hvL5YfiOeXZ7lHIYMpw==
dependencies:
"@cropper/element" "^2.0.1"
"@cropper/utils" "^2.0.1"
"@cropper/element-grid@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@cropper/element-grid/-/element-grid-2.0.1.tgz#4d4ee1b873be6b0dbd07e5b3686da30265aed401"
integrity sha512-ayqCvYQJ+GVT31HhFpttzHabW1T/LsIwLJY5PLTMG0cEZLw/E8ihg8mxctjZbo852D7oEePbz6/2SeuCb1018Q==
dependencies:
"@cropper/element" "^2.0.1"
"@cropper/utils" "^2.0.1"
"@cropper/element-handle@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@cropper/element-handle/-/element-handle-2.0.1.tgz#04032ef162ad2dead2bcfb41ebcaa951e37b111c"
integrity sha512-fdifyyPIaR9S2eQ7qPHuM8fX8uToAfBsi8vQlR9EM+oJkDNil0uO4rWyArLWEtlr0/q7U0OvsufcuJ7ffqfmpg==
dependencies:
"@cropper/element" "^2.0.1"
"@cropper/utils" "^2.0.1"
"@cropper/element-image@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@cropper/element-image/-/element-image-2.0.1.tgz#38fb8470ce286b276d384556efa66eb47190c864"
integrity sha512-gPj5Sl2T8Cno198Cz3F3TDfcYoALW3yJ3fV6PHXmhMnX8sBkL7J441do7Vwkg0mEd2CogCtTLAf+p7ljdV0kgA==
dependencies:
"@cropper/element" "^2.0.1"
"@cropper/element-canvas" "^2.0.1"
"@cropper/utils" "^2.0.1"
"@cropper/element-selection@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@cropper/element-selection/-/element-selection-2.0.1.tgz#965df6f2d6cd986c83efa325766c29700488eba1"
integrity sha512-atv+Aeq2N2eWawelIRPGh1kYFdNrpb0QkUPPheGxz1ImfxpLdcHO9gb9T5noQijizUW2G0pNvts4ZaITQ0I71Q==
dependencies:
"@cropper/element" "^2.0.1"
"@cropper/element-canvas" "^2.0.1"
"@cropper/element-image" "^2.0.1"
"@cropper/utils" "^2.0.1"
"@cropper/element-shade@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@cropper/element-shade/-/element-shade-2.0.1.tgz#5ba42c8066fb6439f5f513a73b93f0c62236acaa"
integrity sha512-YIYgJ690NdFQ6wJLRFh/EySNVxGFKArncQ4FrsJ3yHU+ShgtOKz4FpjFLpqJRJB9swoVbD3WKTimGyzXrwjZrQ==
dependencies:
"@cropper/element" "^2.0.1"
"@cropper/element-canvas" "^2.0.1"
"@cropper/element-selection" "^2.0.1"
"@cropper/utils" "^2.0.1"
"@cropper/element-viewer@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@cropper/element-viewer/-/element-viewer-2.0.1.tgz#3bf79a1f09acae5dc12d6e9c88a4dc7ab7de0b9d"
integrity sha512-HDj25l08pWi/AO6El/OqfQHBpBC4Lh5NEnQN1SOldsmxEwt27Ubv6ndDsF8LkTK7XPwjjZRpyQPyfig4w8L2JQ==
dependencies:
"@cropper/element" "^2.0.1"
"@cropper/element-canvas" "^2.0.1"
"@cropper/element-image" "^2.0.1"
"@cropper/element-selection" "^2.0.1"
"@cropper/utils" "^2.0.1"
"@cropper/element@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@cropper/element/-/element-2.0.1.tgz#d5a486064a3b3ea055a655826041d35097a28526"
integrity sha512-Jn1hR7XWzWQM/QfXRGMGzdkJ2gG/UcLdQPZQ7OKs0JiFfRzKpzu4u/nYrXHeH3MM2iOslLqh2kqYju6mjZLMJQ==
dependencies:
"@cropper/utils" "^2.0.1"
"@cropper/elements@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@cropper/elements/-/elements-2.0.1.tgz#954192d3a90c6bfeca2fcc8f5b1df972de1e7661"
integrity sha512-paFbBLXTKXNngn1yDi2ZIf+FO1pIEQXyBntmqOjuxqtG73KuEKv633wsJPFpj958bgcfSakgBbF80j+3nHbPug==
dependencies:
"@cropper/element" "^2.0.1"
"@cropper/element-canvas" "^2.0.1"
"@cropper/element-crosshair" "^2.0.1"
"@cropper/element-grid" "^2.0.1"
"@cropper/element-handle" "^2.0.1"
"@cropper/element-image" "^2.0.1"
"@cropper/element-selection" "^2.0.1"
"@cropper/element-shade" "^2.0.1"
"@cropper/element-viewer" "^2.0.1"
"@cropper/utils@^2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@cropper/utils/-/utils-2.0.1.tgz#ef24496854be61c677c0e97951813ff9495844d6"
integrity sha512-A9RnAFmgNF5aZk5q2VZnFnHtXWu1kPyEN0LVsX8wJ2LBRu2nyETKwz+ZXVsVWliktToCaYojHKrS+6/HODyEZA==
"@csstools/color-helpers@^5.0.2":
version "5.0.2"
resolved "https://registry.yarnpkg.com/@csstools/color-helpers/-/color-helpers-5.0.2.tgz#82592c9a7c2b83c293d9161894e2a6471feb97b8"
integrity sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==
"@csstools/css-calc@^2.1.2":
version "2.1.2"
resolved "https://registry.yarnpkg.com/@csstools/css-calc/-/css-calc-2.1.2.tgz#bffd55f002dab119b76d4023f95cd943e6c8c11e"
integrity sha512-TklMyb3uBB28b5uQdxjReG4L80NxAqgrECqLZFQbyLekwwlcDDS8r3f07DKqeo8C4926Br0gf/ZDe17Zv4wIuw==
"@csstools/css-color-parser@^3.0.8":
version "3.0.8"
resolved "https://registry.yarnpkg.com/@csstools/css-color-parser/-/css-color-parser-3.0.8.tgz#5fe9322920851450bf5e065c2b0e731b9e165394"
integrity sha512-pdwotQjCCnRPuNi06jFuP68cykU1f3ZWExLe/8MQ1LOs8Xq+fTkYgd+2V8mWUWMrOn9iS2HftPVaMZDaXzGbhQ==
dependencies:
"@csstools/color-helpers" "^5.0.2"
"@csstools/css-calc" "^2.1.2"
"@csstools/css-parser-algorithms@^3.0.4":
version "3.0.4"
resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.4.tgz#74426e93bd1c4dcab3e441f5cc7ba4fb35d94356"
integrity sha512-Up7rBoV77rv29d3uKHUIVubz1BTcgyUK72IvCQAbfbMv584xHcGKCKbWh7i8hPrRJ7qU4Y8IO3IY9m+iTB7P3A==
"@csstools/css-parser-algorithms@^3.0.5":
version "3.0.5"
resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz#5755370a9a29abaec5515b43c8b3f2cf9c2e3076"
integrity sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==
"@csstools/css-tokenizer@^3.0.3":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-3.0.3.tgz#a5502c8539265fecbd873c1e395a890339f119c2"
integrity sha512-UJnjoFsmxfKUdNYdWgOB0mWUypuLvAfQPH1+pyvRJs6euowbFkFC6P13w1l8mJyi3vxYMxc9kld5jZEGRQs6bw==
"@csstools/css-tokenizer@^3.0.4":
version "3.0.4"
resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz#333fedabc3fd1a8e5d0100013731cf19e6a8c5d3"
integrity sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==
"@csstools/media-query-list-parser@^4.0.3":
version "4.0.3"
resolved "https://registry.yarnpkg.com/@csstools/media-query-list-parser/-/media-query-list-parser-4.0.3.tgz#7aec77bcb89c2da80ef207e73f474ef9e1b3cdf1"
integrity sha512-HAYH7d3TLRHDOUQK4mZKf9k9Ph/m8Akstg66ywKR4SFAigjs3yBiUeZtFxywiTm5moZMAp/5W/ZuFnNXXYLuuQ==
"@csstools/selector-specificity@^5.0.0":
version "5.0.0"
resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-5.0.0.tgz#037817b574262134cabd68fc4ec1a454f168407b"
integrity sha512-PCqQV3c4CoVm3kdPhyeZ07VmBRdH2EpMFA/pd9OASpOEC3aXNGoqPDAZ80D0cLpMBxnmk0+yNhGsEx31hq7Gtw==
+"@devframes/hub@^0.5.2":
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/@devframes/hub/-/hub-0.5.2.tgz#ac35e96525def8cf9f713fb305f6b1a8a8338ab2"
+ integrity sha512-qMkBFw1OqhPuNs1tQWkRq0z0Tg49kXNu53bs59tdF4lytKupatWVnL3cpsVPqn+Q5P7A70r99BKTcm+prMtHqw==
+ dependencies:
+ birpc "^4.0.0"
+ nostics "^0.2.0"
+ pathe "^2.0.3"
+ perfect-debounce "^2.1.0"
+ tinyexec "^1.2.2"
+
"@dual-bundle/import-meta-resolve@^4.2.1":
version "4.2.1"
resolved "https://registry.yarnpkg.com/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.2.1.tgz#cd0b25b3808cd9e684cd6cd549bbf8e1dcf05ee7"
integrity sha512-id+7YRUgoUX6CgV0DtuhirQWodeeA7Lf4i2x71JS/vtA5pRb/hIGWlw+G6MeXvsM+MXrz0VAydTGElX1rAfgPg==
+"@emnapi/core@1.10.0":
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.10.0.tgz#380ccc8f2412ea22d1d972df7f8ee23a3b9c7467"
+ integrity sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==
+ dependencies:
+ "@emnapi/wasi-threads" "1.2.1"
+ tslib "^2.4.0"
+
+"@emnapi/runtime@1.10.0":
+ version "1.10.0"
+ resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.10.0.tgz#4b260c0d3534204e98c6110b8db1a987d26ec87c"
+ integrity sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==
+ dependencies:
+ tslib "^2.4.0"
+
+"@emnapi/wasi-threads@1.2.1":
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz#28fed21a1ba1ce797c44a070abc94d42f3ae8548"
+ integrity sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==
+ dependencies:
+ tslib "^2.4.0"
+
"@esbuild/aix-ppc64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz#2ae33300598132cc4cf580dbbb28d30fed3c5c49"
integrity sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==
"@esbuild/android-arm64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.11.tgz#927708b3db5d739d6cb7709136924cc81bec9b03"
integrity sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==
"@esbuild/android-arm@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.11.tgz#571f94e7f4068957ec4c2cfb907deae3d01b55ae"
integrity sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==
"@esbuild/android-x64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.11.tgz#8a3bf5cae6c560c7ececa3150b2bde76e0fb81e6"
integrity sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==
"@esbuild/darwin-arm64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.11.tgz#0a678c4ac4bf8717e67481e1a797e6c152f93c84"
integrity sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==
"@esbuild/darwin-x64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.11.tgz#70f5e925a30c8309f1294d407a5e5e002e0315fe"
integrity sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==
"@esbuild/freebsd-arm64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.11.tgz#4ec1db687c5b2b78b44148025da9632397553e8a"
integrity sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==
"@esbuild/freebsd-x64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.11.tgz#4c81abd1b142f1e9acfef8c5153d438ca53f44bb"
integrity sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==
"@esbuild/linux-arm64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.11.tgz#69517a111acfc2b93aa0fb5eaeb834c0202ccda5"
integrity sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==
"@esbuild/linux-arm@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.11.tgz#58dac26eae2dba0fac5405052b9002dac088d38f"
integrity sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==
"@esbuild/linux-ia32@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.11.tgz#b89d4efe9bdad46ba944f0f3b8ddd40834268c2b"
integrity sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==
"@esbuild/linux-loong64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.11.tgz#11f603cb60ad14392c3f5c94d64b3cc8b630fbeb"
integrity sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==
"@esbuild/linux-mips64el@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.11.tgz#b7d447ff0676b8ab247d69dac40a5cf08e5eeaf5"
integrity sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==
"@esbuild/linux-ppc64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.11.tgz#b3a28ed7cc252a61b07ff7c8fd8a984ffd3a2f74"
integrity sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==
"@esbuild/linux-riscv64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.11.tgz#ce75b08f7d871a75edcf4d2125f50b21dc9dc273"
integrity sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==
"@esbuild/linux-s390x@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.11.tgz#cd08f6c73b6b6ff9ccdaabbd3ff6ad3dca99c263"
integrity sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==
"@esbuild/linux-x64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.11.tgz#3c3718af31a95d8946ebd3c32bb1e699bdf74910"
integrity sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==
"@esbuild/netbsd-arm64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.11.tgz#b4c767082401e3a4e8595fe53c47cd7f097c8077"
integrity sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==
"@esbuild/netbsd-x64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.11.tgz#f2a930458ed2941d1f11ebc34b9c7d61f7a4d034"
integrity sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==
"@esbuild/openbsd-arm64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.11.tgz#b4ae93c75aec48bc1e8a0154957a05f0641f2dad"
integrity sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==
"@esbuild/openbsd-x64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.11.tgz#b42863959c8dcf9b01581522e40012d2c70045e2"
integrity sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==
"@esbuild/openharmony-arm64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.11.tgz#b2e717141c8fdf6bddd4010f0912e6b39e1640f1"
integrity sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==
"@esbuild/sunos-x64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.11.tgz#9fbea1febe8778927804828883ec0f6dd80eb244"
integrity sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==
"@esbuild/win32-arm64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.11.tgz#501539cedb24468336073383989a7323005a8935"
integrity sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==
"@esbuild/win32-ia32@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.11.tgz#8ac7229aa82cef8f16ffb58f1176a973a7a15343"
integrity sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==
"@esbuild/win32-x64@0.25.11":
version "0.25.11"
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.11.tgz#5ecda6f3fe138b7e456f4e429edde33c823f392f"
integrity sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==
"@eslint-community/eslint-utils@^4.1.2", "@eslint-community/eslint-utils@^4.4.0", "@eslint-community/eslint-utils@^4.5.0":
version "4.5.1"
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz#b0fc7e06d0c94f801537fd4237edc2706d3b8e4c"
integrity sha512-soEIOALTfTK6EjmKMMoLugwaP0rzkad90iIWd1hMO9ARkSAyjfMfkRRhLvD5qH7vvM0Cg72pieUfR6yh6XxC4w==
dependencies:
eslint-visitor-keys "^3.4.3"
"@eslint-community/eslint-utils@^4.8.0":
version "4.9.0"
resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz#7308df158e064f0dd8b8fdb58aa14fa2a7f913b3"
integrity sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==
dependencies:
eslint-visitor-keys "^3.4.3"
"@eslint-community/regexpp@^4.11.0", "@eslint-community/regexpp@^4.12.1":
version "4.12.1"
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0"
integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==
"@eslint/config-array@^0.21.1":
version "0.21.1"
resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.21.1.tgz#7d1b0060fea407f8301e932492ba8c18aff29713"
integrity sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==
dependencies:
"@eslint/object-schema" "^2.1.7"
debug "^4.3.1"
minimatch "^3.1.2"
"@eslint/config-helpers@^0.4.2":
version "0.4.2"
resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.4.2.tgz#1bd006ceeb7e2e55b2b773ab318d300e1a66aeda"
integrity sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==
dependencies:
"@eslint/core" "^0.17.0"
"@eslint/core@^0.17.0":
version "0.17.0"
resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.17.0.tgz#77225820413d9617509da9342190a2019e78761c"
integrity sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==
dependencies:
"@types/json-schema" "^7.0.15"
"@eslint/eslintrc@^3.3.1":
version "3.3.1"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.3.1.tgz#e55f7f1dd400600dd066dbba349c4c0bac916964"
integrity sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==
dependencies:
ajv "^6.12.4"
debug "^4.3.2"
espree "^10.0.1"
globals "^14.0.0"
ignore "^5.2.0"
import-fresh "^3.2.1"
js-yaml "^4.1.0"
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
"@eslint/js@9.39.2":
version "9.39.2"
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.39.2.tgz#2d4b8ec4c3ea13c1b3748e0c97ecd766bdd80599"
integrity sha512-q1mjIoW1VX4IvSocvM/vbTiveKC4k9eLrajNEuSsmjymSDEbpGddtpfOoN7YGAqBK3NG+uqo8ia4PDTt8buCYA==
"@eslint/object-schema@^2.1.7":
version "2.1.7"
resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.7.tgz#6e2126a1347e86a4dedf8706ec67ff8e107ebbad"
integrity sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==
"@eslint/plugin-kit@^0.4.1":
version "0.4.1"
resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz#9779e3fd9b7ee33571a57435cf4335a1794a6cb2"
integrity sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==
dependencies:
"@eslint/core" "^0.17.0"
levn "^0.4.1"
+"@floating-ui/core@^1.7.5":
+ version "1.7.5"
+ resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.7.5.tgz#d4af157a03330af5a60e69da7a4692507ada0622"
+ integrity sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==
+ dependencies:
+ "@floating-ui/utils" "^0.2.11"
+
+"@floating-ui/dom@^1.7.6":
+ version "1.7.6"
+ resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.7.6.tgz#f915bba5abbb177e1f227cacee1b4d0634b187bf"
+ integrity sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==
+ dependencies:
+ "@floating-ui/core" "^1.7.5"
+ "@floating-ui/utils" "^0.2.11"
+
+"@floating-ui/utils@^0.2.11":
+ version "0.2.11"
+ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.11.tgz#a269e055e40e2f45873bae9d1a2fdccbd314ea3f"
+ integrity sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==
+
"@fortawesome/fontawesome-common-types@7.1.0":
version "7.1.0"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-7.1.0.tgz#a4e0b7e40073d5fdef41182da1bc216a05875659"
integrity sha512-l/BQM7fYntsCI//du+6sEnHOP6a74UixFyOYUyz2DLMXKx+6DEhfR3F2NYGE45XH1JJuIamacb4IZs9S0ZOWLA==
"@fortawesome/fontawesome-svg-core@7.1.0":
version "7.1.0"
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-7.1.0.tgz#b0a45363a4e95ec985130393c0b1b95717ef0760"
integrity sha512-fNxRUk1KhjSbnbuBxlWSnBLKLBNun52ZBTcs22H/xEEzM6Ap81ZFTQ4bZBxVQGQgVY0xugKGoRcCbaKjLQ3XZA==
dependencies:
"@fortawesome/fontawesome-common-types" "7.1.0"
"@fortawesome/free-regular-svg-icons@7.1.0":
version "7.1.0"
resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-7.1.0.tgz#e57c5eb63e6a30bb4fe2276aba851e3470452680"
integrity sha512-0e2fdEyB4AR+e6kU4yxwA/MonnYcw/CsMEP9lH82ORFi9svA6/RhDyhxIv5mlJaldmaHLLYVTb+3iEr+PDSZuQ==
dependencies:
"@fortawesome/fontawesome-common-types" "7.1.0"
"@fortawesome/free-solid-svg-icons@7.1.0":
version "7.1.0"
resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-7.1.0.tgz#cb9d149cefd3419a7a3fd041106e3a2315463e3e"
integrity sha512-Udu3K7SzAo9N013qt7qmm22/wo2hADdheXtBfxFTecp+ogsc0caQNRKEb7pkvvagUGOpG9wJC1ViH6WXs8oXIA==
dependencies:
"@fortawesome/fontawesome-common-types" "7.1.0"
"@fortawesome/vue-fontawesome@3.1.2":
version "3.1.2"
resolved "https://registry.yarnpkg.com/@fortawesome/vue-fontawesome/-/vue-fontawesome-3.1.2.tgz#a61d44522bc0be3283ccd9811ed5a2de282c168a"
integrity sha512-mhYnBIuuW8OIMHf31kOjaBmyE7BMrwBorhrOHVud6vTTu+7IPQNWB+DWaHoE75v10dRF5s/dFtcrgE7vKSEWwQ==
"@humanfs/core@^0.19.1":
version "0.19.1"
resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.1.tgz#17c55ca7d426733fe3c561906b8173c336b40a77"
integrity sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==
"@humanfs/node@^0.16.6":
version "0.16.6"
resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.6.tgz#ee2a10eaabd1131987bf0488fd9b820174cd765e"
integrity sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==
dependencies:
"@humanfs/core" "^0.19.1"
"@humanwhocodes/retry" "^0.3.0"
"@humanwhocodes/module-importer@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c"
integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==
"@humanwhocodes/retry@^0.3.0":
version "0.3.1"
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a"
integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==
"@humanwhocodes/retry@^0.4.2":
version "0.4.2"
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.2.tgz#1860473de7dfa1546767448f333db80cb0ff2161"
integrity sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==
"@inquirer/confirm@^5.0.0":
version "5.1.8"
resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-5.1.8.tgz#476af2476cd4867905dcabfca8598da4dd65e923"
integrity sha512-dNLWCYZvXDjO3rnQfk2iuJNL4Ivwz/T2+C3+WnNfJKsNGSuOs3wAo2F6e0p946gtSAk31nZMfW+MRmYaplPKsg==
dependencies:
"@inquirer/core" "^10.1.9"
"@inquirer/type" "^3.0.5"
"@inquirer/core@^10.1.9":
version "10.1.9"
resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-10.1.9.tgz#9ab672a2d9ca60c5d45c7fa9b63e4fe9e038a02e"
integrity sha512-sXhVB8n20NYkUBfDYgizGHlpRVaCRjtuzNZA6xpALIUbkgfd2Hjz+DfEN6+h1BRnuxw0/P4jCIMjMsEOAMwAJw==
dependencies:
"@inquirer/figures" "^1.0.11"
"@inquirer/type" "^3.0.5"
ansi-escapes "^4.3.2"
cli-width "^4.1.0"
mute-stream "^2.0.0"
signal-exit "^4.1.0"
wrap-ansi "^6.2.0"
yoctocolors-cjs "^2.1.2"
"@inquirer/figures@^1.0.11":
version "1.0.11"
resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.11.tgz#4744e6db95288fea1dead779554859710a959a21"
integrity sha512-eOg92lvrn/aRUqbxRyvpEWnrvRuTYRifixHkYVpJiygTgVSBIHDqLh0SrMQXkafvULg3ck11V7xvR+zcgvpHFw==
"@inquirer/type@^3.0.5":
version "3.0.5"
resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-3.0.5.tgz#fe00207e57d5f040e5b18e809c8e7abc3a2ade3a"
integrity sha512-ZJpeIYYueOz/i/ONzrfof8g89kNdO2hjGuvULROo3O8rlB2CRtSseE5KeirnyE4t/thAn/EwvS/vuQeJCn+NZg==
"@intlify/core-base@11.1.12":
version "11.1.12"
resolved "https://registry.yarnpkg.com/@intlify/core-base/-/core-base-11.1.12.tgz#e02529021a4e69f8a1adcca5ce61963c71cd72ba"
integrity sha512-whh0trqRsSqVLNEUCwU59pyJZYpU8AmSWl8M3Jz2Mv5ESPP6kFh4juas2NpZ1iCvy7GlNRffUD1xr84gceimjg==
dependencies:
"@intlify/message-compiler" "11.1.12"
"@intlify/shared" "11.1.12"
"@intlify/message-compiler@11.1.12":
version "11.1.12"
resolved "https://registry.yarnpkg.com/@intlify/message-compiler/-/message-compiler-11.1.12.tgz#27e69790b711a92cddb07175187dd09a7b270b55"
integrity sha512-Fv9iQSJoJaXl4ZGkOCN1LDM3trzze0AS2zRz2EHLiwenwL6t0Ki9KySYlyr27yVOj5aVz0e55JePO+kELIvfdQ==
dependencies:
"@intlify/shared" "11.1.12"
source-map-js "^1.0.2"
"@intlify/shared@11.1.12":
version "11.1.12"
resolved "https://registry.yarnpkg.com/@intlify/shared/-/shared-11.1.12.tgz#ab41083e017d622cf63c7dc88a0ee0bc27f4127a"
integrity sha512-Om86EjuQtA69hdNj3GQec9ZC0L0vPSAnXzB3gP/gyJ7+mA7t06d9aOAiqMZ+xEOsumGP4eEBlfl8zF2LOTzf2A==
"@isaacs/cliui@^8.0.2":
version "8.0.2"
resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550"
integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==
dependencies:
string-width "^5.1.2"
string-width-cjs "npm:string-width@^4.2.0"
strip-ansi "^7.0.1"
strip-ansi-cjs "npm:strip-ansi@^6.0.1"
wrap-ansi "^8.1.0"
wrap-ansi-cjs "npm:wrap-ansi@^7.0.0"
"@jridgewell/gen-mapping@^0.3.12", "@jridgewell/gen-mapping@^0.3.5":
version "0.3.13"
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f"
integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==
dependencies:
"@jridgewell/sourcemap-codec" "^1.5.0"
"@jridgewell/trace-mapping" "^0.3.24"
"@jridgewell/remapping@^2.3.5":
version "2.3.5"
resolved "https://registry.yarnpkg.com/@jridgewell/remapping/-/remapping-2.3.5.tgz#375c476d1972947851ba1e15ae8f123047445aa1"
integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==
dependencies:
"@jridgewell/gen-mapping" "^0.3.5"
"@jridgewell/trace-mapping" "^0.3.24"
"@jridgewell/resolve-uri@^3.1.0":
version "3.1.2"
resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6"
integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==
"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0", "@jridgewell/sourcemap-codec@^1.5.5":
version "1.5.5"
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba"
integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==
"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.28":
version "0.3.30"
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz#4a76c4daeee5df09f5d3940e087442fb36ce2b99"
integrity sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==
dependencies:
"@jridgewell/resolve-uri" "^3.1.0"
"@jridgewell/sourcemap-codec" "^1.4.14"
"@kazvmoe-infra/pinch-zoom-element@1.3.0":
version "1.3.0"
resolved "https://registry.yarnpkg.com/@kazvmoe-infra/pinch-zoom-element/-/pinch-zoom-element-1.3.0.tgz#a5e35ab190f93d016b8a83f69004fc69a8e6b774"
integrity sha512-YIx1ZsCLyFB/xhJVMc81yLNJO/ZYveYGws0033ZPPyrFLgLwrQrkx79lC1xBIcWlWnvPioTVdmOpnBeTv/0zNw==
dependencies:
pointer-tracker "^2.0.3"
"@kazvmoe-infra/unicode-emoji-json@0.4.0":
version "0.4.0"
resolved "https://registry.yarnpkg.com/@kazvmoe-infra/unicode-emoji-json/-/unicode-emoji-json-0.4.0.tgz#555bab2f8d11db74820ef0a2fbe2805b17c22587"
integrity sha512-22OffREdHzD0U6A/W4RaFPV8NR73za6euibtAxNxO/fu5A6TwxRO2lAdbDWKJH9COv/vYs8zqfEiSalXH2nXJA==
"@keyv/bigmap@^1.0.2":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@keyv/bigmap/-/bigmap-1.0.2.tgz#9480d168c99a4a6c2fd3b677387cd922aa82a470"
integrity sha512-KR03xkEZlAZNF4IxXgVXb+uNIVNvwdh8UwI0cnc7WI6a+aQcDp8GL80qVfeB4E5NpsKJzou5jU0r6yLSSbMOtA==
dependencies:
hookified "^1.12.1"
"@keyv/serialize@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@keyv/serialize/-/serialize-1.1.1.tgz#0c01dd3a3483882af7cf3878d4e71d505c81fc4a"
integrity sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==
"@mswjs/interceptors@^0.39.1":
version "0.39.2"
resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.39.2.tgz#de9de0ab23f99d387c7904df7219a92157d1d666"
integrity sha512-RuzCup9Ct91Y7V79xwCb146RaBRHZ7NBbrIUySumd1rpKqHL5OonaqrGIbug5hNwP/fRyxFMA6ISgw4FTtYFYg==
dependencies:
"@open-draft/deferred-promise" "^2.2.0"
"@open-draft/logger" "^0.3.0"
"@open-draft/until" "^2.0.0"
is-node-process "^1.2.0"
outvariant "^1.4.3"
strict-event-emitter "^0.5.1"
"@napi-rs/nice-android-arm-eabi@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.0.1.tgz#9a0cba12706ff56500df127d6f4caf28ddb94936"
integrity sha512-5qpvOu5IGwDo7MEKVqqyAxF90I6aLj4n07OzpARdgDRfz8UbBztTByBp0RC59r3J1Ij8uzYi6jI7r5Lws7nn6w==
"@napi-rs/nice-android-arm64@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.0.1.tgz#32fc32e9649bd759d2a39ad745e95766f6759d2f"
integrity sha512-GqvXL0P8fZ+mQqG1g0o4AO9hJjQaeYG84FRfZaYjyJtZZZcMjXW5TwkL8Y8UApheJgyE13TQ4YNUssQaTgTyvA==
"@napi-rs/nice-darwin-arm64@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.0.1.tgz#d3c44c51b94b25a82d45803e2255891e833e787b"
integrity sha512-91k3HEqUl2fsrz/sKkuEkscj6EAj3/eZNCLqzD2AA0TtVbkQi8nqxZCZDMkfklULmxLkMxuUdKe7RvG/T6s2AA==
"@napi-rs/nice-darwin-x64@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.0.1.tgz#f1b1365a8370c6a6957e90085a9b4873d0e6a957"
integrity sha512-jXnMleYSIR/+TAN/p5u+NkCA7yidgswx5ftqzXdD5wgy/hNR92oerTXHc0jrlBisbd7DpzoaGY4cFD7Sm5GlgQ==
"@napi-rs/nice-freebsd-x64@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.0.1.tgz#4280f081efbe0b46c5165fdaea8b286e55a8f89e"
integrity sha512-j+iJ/ezONXRQsVIB/FJfwjeQXX7A2tf3gEXs4WUGFrJjpe/z2KB7sOv6zpkm08PofF36C9S7wTNuzHZ/Iiccfw==
"@napi-rs/nice-linux-arm-gnueabihf@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.0.1.tgz#07aec23a9467ed35eb7602af5e63d42c5d7bd473"
integrity sha512-G8RgJ8FYXYkkSGQwywAUh84m946UTn6l03/vmEXBYNJxQJcD+I3B3k5jmjFG/OPiU8DfvxutOP8bi+F89MCV7Q==
"@napi-rs/nice-linux-arm64-gnu@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.0.1.tgz#038a77134cc6df3c48059d5a5e199d6f50fb9a90"
integrity sha512-IMDak59/W5JSab1oZvmNbrms3mHqcreaCeClUjwlwDr0m3BoR09ZiN8cKFBzuSlXgRdZ4PNqCYNeGQv7YMTjuA==
"@napi-rs/nice-linux-arm64-musl@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.0.1.tgz#715d0906582ba0cff025109f42e5b84ea68c2bcc"
integrity sha512-wG8fa2VKuWM4CfjOjjRX9YLIbysSVV1S3Kgm2Fnc67ap/soHBeYZa6AGMeR5BJAylYRjnoVOzV19Cmkco3QEPw==
"@napi-rs/nice-linux-ppc64-gnu@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.0.1.tgz#ac1c8f781c67b0559fa7a1cd4ae3ca2299dc3d06"
integrity sha512-lxQ9WrBf0IlNTCA9oS2jg/iAjQyTI6JHzABV664LLrLA/SIdD+I1i3Mjf7TsnoUbgopBcCuDztVLfJ0q9ubf6Q==
"@napi-rs/nice-linux-riscv64-gnu@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.0.1.tgz#b0a430549acfd3920ffd28ce544e2fe17833d263"
integrity sha512-3xs69dO8WSWBb13KBVex+yvxmUeEsdWexxibqskzoKaWx9AIqkMbWmE2npkazJoopPKX2ULKd8Fm9veEn0g4Ig==
"@napi-rs/nice-linux-s390x-gnu@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.0.1.tgz#5b95caf411ad72a965885217db378c4d09733e97"
integrity sha512-lMFI3i9rlW7hgToyAzTaEybQYGbQHDrpRkg+1gJWEpH0PLAQoZ8jiY0IzakLfNWnVda1eTYYlxxFYzW8Rqczkg==
"@napi-rs/nice-linux-x64-gnu@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.0.1.tgz#a98cdef517549f8c17a83f0236a69418a90e77b7"
integrity sha512-XQAJs7DRN2GpLN6Fb+ZdGFeYZDdGl2Fn3TmFlqEL5JorgWKrQGRUrpGKbgZ25UeZPILuTKJ+OowG2avN8mThBA==
"@napi-rs/nice-linux-x64-musl@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.0.1.tgz#5e26843eafa940138aed437c870cca751c8a8957"
integrity sha512-/rodHpRSgiI9o1faq9SZOp/o2QkKQg7T+DK0R5AkbnI/YxvAIEHf2cngjYzLMQSQgUhxym+LFr+UGZx4vK4QdQ==
"@napi-rs/nice-win32-arm64-msvc@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.0.1.tgz#bd62617d02f04aa30ab1e9081363856715f84cd8"
integrity sha512-rEcz9vZymaCB3OqEXoHnp9YViLct8ugF+6uO5McifTedjq4QMQs3DHz35xBEGhH3gJWEsXMUbzazkz5KNM5YUg==
"@napi-rs/nice-win32-ia32-msvc@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.0.1.tgz#b8b7aad552a24836027473d9b9f16edaeabecf18"
integrity sha512-t7eBAyPUrWL8su3gDxw9xxxqNwZzAqKo0Szv3IjVQd1GpXXVkb6vBBQUuxfIYaXMzZLwlxRQ7uzM2vdUE9ULGw==
"@napi-rs/nice-win32-x64-msvc@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.0.1.tgz#37d8718b8f722f49067713e9f1e85540c9a3dd09"
integrity sha512-JlF+uDcatt3St2ntBG8H02F1mM45i5SF9W+bIKiReVE6wiy3o16oBP/yxt+RZ+N6LbCImJXJ6bXNO2kn9AXicg==
"@napi-rs/nice@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@napi-rs/nice/-/nice-1.0.1.tgz#483d3ff31e5661829a1efb4825591a135c3bfa7d"
integrity sha512-zM0mVWSXE0a0h9aKACLwKmD6nHcRiKrPpCfvaKqG1CqDEyjEawId0ocXxVzPMCAm6kkWr2P025msfxXEnt8UGQ==
optionalDependencies:
"@napi-rs/nice-android-arm-eabi" "1.0.1"
"@napi-rs/nice-android-arm64" "1.0.1"
"@napi-rs/nice-darwin-arm64" "1.0.1"
"@napi-rs/nice-darwin-x64" "1.0.1"
"@napi-rs/nice-freebsd-x64" "1.0.1"
"@napi-rs/nice-linux-arm-gnueabihf" "1.0.1"
"@napi-rs/nice-linux-arm64-gnu" "1.0.1"
"@napi-rs/nice-linux-arm64-musl" "1.0.1"
"@napi-rs/nice-linux-ppc64-gnu" "1.0.1"
"@napi-rs/nice-linux-riscv64-gnu" "1.0.1"
"@napi-rs/nice-linux-s390x-gnu" "1.0.1"
"@napi-rs/nice-linux-x64-gnu" "1.0.1"
"@napi-rs/nice-linux-x64-musl" "1.0.1"
"@napi-rs/nice-win32-arm64-msvc" "1.0.1"
"@napi-rs/nice-win32-ia32-msvc" "1.0.1"
"@napi-rs/nice-win32-x64-msvc" "1.0.1"
+"@napi-rs/wasm-runtime@^1.1.4":
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz#a46bbfedc29751b7170c5d23bc1d8ee8c7e3c1e1"
+ integrity sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==
+ dependencies:
+ "@tybys/wasm-util" "^0.10.1"
+
"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1":
version "5.1.1-v1"
resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129"
integrity sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==
dependencies:
eslint-scope "5.1.1"
"@nightwatch/chai@5.0.3":
version "5.0.3"
resolved "https://registry.yarnpkg.com/@nightwatch/chai/-/chai-5.0.3.tgz#c92ebe0cd2ee986f7e838cbd86abd8af49861b01"
integrity sha512-1OIkOf/7jswOC3/t+Add/HVQO8ib75kz6BVYSNeWGghTlmHUqYEfNJ6vcACbXrn/4v3+9iRlWixuhFkxXkU/RQ==
dependencies:
assertion-error "1.1.0"
check-error "1.0.2"
deep-eql "4.0.1"
loupe "^2.3.7"
pathval "1.1.1"
type-detect "4.0.8"
"@nightwatch/html-reporter-template@^0.3.0":
version "0.3.0"
resolved "https://registry.yarnpkg.com/@nightwatch/html-reporter-template/-/html-reporter-template-0.3.0.tgz#80ca3ccfe880d1db988eefe0e0e9ea7d161d91f3"
integrity sha512-Mze1z6pmUz2O8N9w1/h3QWz1lzMig45PGyh8PrL9ERs3FxVnIX0RCn37vjZUYiV4wgjZOg41JjdcpriZ3dJxkA==
"@nightwatch/nightwatch-inspector@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@nightwatch/nightwatch-inspector/-/nightwatch-inspector-1.0.1.tgz#bbfbf1d17418abf3c6335232e899040832b60678"
integrity sha512-/ax11EOB4eJXT5VioMztcalbCtsNeuFn6icfT75qPLBmkxLvThePSfyGTys+t9AULUR0ug0wMDMiLV1Oy586Fg==
dependencies:
archiver "^5.3.1"
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
dependencies:
"@nodelib/fs.stat" "2.0.5"
run-parallel "^1.1.9"
"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
version "2.0.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b"
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
"@nodelib/fs.walk@^1.2.3":
version "1.2.8"
resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a"
integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==
dependencies:
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
"@one-ini/wasm@0.1.1":
version "0.1.1"
resolved "https://registry.yarnpkg.com/@one-ini/wasm/-/wasm-0.1.1.tgz#6013659736c9dbfccc96e8a9c2b3de317df39323"
integrity sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==
"@open-draft/deferred-promise@^2.2.0":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz#4a822d10f6f0e316be4d67b4d4f8c9a124b073bd"
integrity sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==
"@open-draft/logger@^0.3.0":
version "0.3.0"
resolved "https://registry.yarnpkg.com/@open-draft/logger/-/logger-0.3.0.tgz#2b3ab1242b360aa0adb28b85f5d7da1c133a0954"
integrity sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==
dependencies:
is-node-process "^1.2.0"
outvariant "^1.4.0"
"@open-draft/until@^2.0.0", "@open-draft/until@^2.1.0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@open-draft/until/-/until-2.1.0.tgz#0acf32f470af2ceaf47f095cdecd40d68666efda"
integrity sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==
-"@parcel/watcher-android-arm64@2.5.1":
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz#507f836d7e2042f798c7d07ad19c3546f9848ac1"
- integrity sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==
-
-"@parcel/watcher-darwin-arm64@2.5.1":
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz#3d26dce38de6590ef79c47ec2c55793c06ad4f67"
- integrity sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==
-
-"@parcel/watcher-darwin-x64@2.5.1":
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz#99f3af3869069ccf774e4ddfccf7e64fd2311ef8"
- integrity sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==
-
-"@parcel/watcher-freebsd-x64@2.5.1":
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz#14d6857741a9f51dfe51d5b08b7c8afdbc73ad9b"
- integrity sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==
-
-"@parcel/watcher-linux-arm-glibc@2.5.1":
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz#43c3246d6892381db473bb4f663229ad20b609a1"
- integrity sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==
-
-"@parcel/watcher-linux-arm-musl@2.5.1":
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz#663750f7090bb6278d2210de643eb8a3f780d08e"
- integrity sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==
-
-"@parcel/watcher-linux-arm64-glibc@2.5.1":
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz#ba60e1f56977f7e47cd7e31ad65d15fdcbd07e30"
- integrity sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==
-
-"@parcel/watcher-linux-arm64-musl@2.5.1":
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz#f7fbcdff2f04c526f96eac01f97419a6a99855d2"
- integrity sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==
-
-"@parcel/watcher-linux-x64-glibc@2.5.1":
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz#4d2ea0f633eb1917d83d483392ce6181b6a92e4e"
- integrity sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==
-
-"@parcel/watcher-linux-x64-musl@2.5.1":
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz#277b346b05db54f55657301dd77bdf99d63606ee"
- integrity sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==
-
-"@parcel/watcher-win32-arm64@2.5.1":
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz#7e9e02a26784d47503de1d10e8eab6cceb524243"
- integrity sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==
-
-"@parcel/watcher-win32-ia32@2.5.1":
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz#2d0f94fa59a873cdc584bf7f6b1dc628ddf976e6"
- integrity sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==
-
-"@parcel/watcher-win32-x64@2.5.1":
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz#ae52693259664ba6f2228fa61d7ee44b64ea0947"
- integrity sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==
+"@oxc-parser/binding-android-arm-eabi@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-android-arm-eabi/-/binding-android-arm-eabi-0.132.0.tgz#f88d600252349b5e380e695cadf889cea896f676"
+ integrity sha512-KrLaPWa5c9Y7LkW+rKkaUE3y7DBDrQtaf7rlsSDfv6KAHUjgzAIRA761Lrrp6//Yd/Rlie/yEOt9YENCoJnOcw==
+
+"@oxc-parser/binding-android-arm64@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-android-arm64/-/binding-android-arm64-0.132.0.tgz#ef91deec0305c54fa6c7b519f82da63d36b49788"
+ integrity sha512-SThDrSeamB/kG2+NxcJ5/wSLcV6dUqDknrPLqFYQ0ST/55mtBP4M7Q/f3QbubH6aAd11wpzZn/nwbVRSdobOpg==
+
+"@oxc-parser/binding-darwin-arm64@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-darwin-arm64/-/binding-darwin-arm64-0.132.0.tgz#033a8f2789c3d09509ddd1a219dcbf2fd516125f"
+ integrity sha512-Lc0f/TYoKBghE5/2Gsv7bLXk+TJZunx2Tf61X8hG4ARXdc8UYI26dCGccFSd1AyFbK3jfaNXtMnupggDbjPXdQ==
+
+"@oxc-parser/binding-darwin-x64@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-darwin-x64/-/binding-darwin-x64-0.132.0.tgz#56601549bad307fcee2b3e0756769e36598841f4"
+ integrity sha512-RG2eJIpf7C21z9HSSXFw1bTArdpKe7Y4fwcJTwRq1yCSe1vSavaN9GA1sm9KqzemTLAGVktQ+7qBTGp0vQeUZg==
+
+"@oxc-parser/binding-freebsd-x64@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-freebsd-x64/-/binding-freebsd-x64-0.132.0.tgz#68140dd5670556fca3aa094f0cb7e706854b5967"
+ integrity sha512-wQIPntPLtJ8NcBpvKPbEv3NqzV6k8eP8tP/jE9Rg8HTg/j7urZGFSsTCPCW5k77Qfw2DM4vRvc9p3I4yq/Shvw==
+
+"@oxc-parser/binding-linux-arm-gnueabihf@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.132.0.tgz#84ef8af25ffb6172b02b1747bbbef668e09235c1"
+ integrity sha512-PixKEpeSe3yxQWqNyOCBALRYc72+Tj7ILDofUl3iXo25cVOzLA6jHUhmOINRtWIPh7dbUie3QNeabwaQpZTw6w==
+
+"@oxc-parser/binding-linux-arm-musleabihf@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.132.0.tgz#ca6a2dffed23143c9bcbefd8250832c71fdfb4d7"
+ integrity sha512-sCR+DzGHlyHKnbA2z9zWjTUhIo8Sy0enJl4RDsBwPmkxYynPatpwOAWe8W5127SlW0boqUWHGtr1NWn5UwIhXQ==
+
+"@oxc-parser/binding-linux-arm64-gnu@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.132.0.tgz#ed1a4718c61d05836015c8eac7395ffe74c3f94a"
+ integrity sha512-sQBix5P2cW+IpzTcCwYxnh9yALrKSIkKJThspBvMGcygSMnbzkSvhN7SfuX1hvBk8y1XEChsdkU3ET0V5DmzUw==
+
+"@oxc-parser/binding-linux-arm64-musl@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.132.0.tgz#ae32a94bb666604728fa48c568ced5bb270d1819"
+ integrity sha512-WozHg3Kc//8Sk756HXXgMbEAvqtG+Lzb9JOojwQzIGDtN78Az2dLttkb71akWYUF/8IgYfDSlfKh4Uot8is5Vw==
+
+"@oxc-parser/binding-linux-ppc64-gnu@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.132.0.tgz#0de7511156b2b5d7d4fc3574ab3badd93a07c1ae"
+ integrity sha512-CmX/ulNBOEwWTyVRmcpYKAcAizW6+OjtLJgo7fXoL9OqQvjF4VER8tPomv44vwzfSCy1BHbsB0ZlZYzYJNj4cA==
+
+"@oxc-parser/binding-linux-riscv64-gnu@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.132.0.tgz#9a4a3b3261b6ada598b65adc4521581c45aa1003"
+ integrity sha512-j9oQS+hM90SdhviNGWbPgT4+Rlq+ac++q/zjgwPD1mVHgxHzATvoRGtDx0sXGmFOQ9J9YkwAhYGb5MAHL6TAsA==
+
+"@oxc-parser/binding-linux-riscv64-musl@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.132.0.tgz#e55c1d671e41617f27535216483ccc01f1ff4a5e"
+ integrity sha512-bLz+Xi+Agnfmd7kWPEsSVwCn2k4EyIalZkNBcQ0OGIv9rqn8VgCPLNd03tM9mKX/5TdlvDXalz0q71BIrOPNqg==
+
+"@oxc-parser/binding-linux-s390x-gnu@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.132.0.tgz#2e4b692103d8ee745990c7ed5fd023387e6c93d9"
+ integrity sha512-U6t2qbJU0ypTfyj9QV3W1Y6mITDTL8ai/OR6NUn85vyHthOvobKWgXzU4tu0EskSzlpuVFz1g0jFGulDIUKHxQ==
+
+"@oxc-parser/binding-linux-x64-gnu@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.132.0.tgz#2ba1d08aeaed17247dac4cb5b9a3bc83b7bd7501"
+ integrity sha512-WcEaSNHFk8yz5YFlQQAlhq6jOFmZBB/RKE7uzhyCIf+pF1Lmv9gUH4221mle2Gd9iHyWT3ySNph8yZgb1xYdWg==
+
+"@oxc-parser/binding-linux-x64-musl@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-linux-x64-musl/-/binding-linux-x64-musl-0.132.0.tgz#677889452adb283e791798faf70af0627bd493ad"
+ integrity sha512-iQrV4iJzQgRwK3BWRmQl1C3C6g3wYpXN2WLdQdyR+efoUnncdShZAVp9OgcojtlD3MDRbuOMGG3SjxF4fL4nlQ==
+
+"@oxc-parser/binding-openharmony-arm64@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-openharmony-arm64/-/binding-openharmony-arm64-0.132.0.tgz#2928bbd0f815a7bf11a86b1bccfb0f352b92a7b3"
+ integrity sha512-FWzmUGrZ6GUby4U7WIwcCtab6tdmlTO3xTRRKyb5kjIJVEiaUAT8animUG/nK8ZCA8gkRkPOTId4rl6uTqUmJQ==
+
+"@oxc-parser/binding-wasm32-wasi@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-wasm32-wasi/-/binding-wasm32-wasi-0.132.0.tgz#37df389cce33c8664763a402853a73559b882ce2"
+ integrity sha512-TlbMppxJI5CjWDes0QaP6G3aneVg1yikBu5QYI+DUShF9WDL66ccgKFNNGmi/Wybtszw6hxwAvv76T4DaPKnHw==
+ dependencies:
+ "@emnapi/core" "1.10.0"
+ "@emnapi/runtime" "1.10.0"
+ "@napi-rs/wasm-runtime" "^1.1.4"
+
+"@oxc-parser/binding-win32-arm64-msvc@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.132.0.tgz#b1a0913ad2545c30f498ba181c05de3898240976"
+ integrity sha512-RH/NbFjGKqdUAUi7Oh3LQPxUk2hsWFEEQ38HSnbRQT8QjBZFKqL1fMbmsB3N4jy/KPh9iX94+9dmkEMBBbambw==
+
+"@oxc-parser/binding-win32-ia32-msvc@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.132.0.tgz#13964f4b59671f7235f4f85866ab3db6e4afd6c5"
+ integrity sha512-JUr4jQY9jxoIB/YTLXr6XofSi5xikj6p5/Ns1h0VOBDT0j1jKU+kMsv2xxv51RwnETcXpA1Yw/9oUAfcqfaqEA==
+
+"@oxc-parser/binding-win32-x64-msvc@0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-parser/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.132.0.tgz#468339fb08809ddb856f3bc51db718790fb51f05"
+ integrity sha512-2dapgHpA5X8DSXF4AU36hJWYf6zP0tKjMXFRAZFBD62pkevW/uhFDXoFH9Y/3Fd2EtDrw5ByNnR1wVE9X9y0SQ==
+
+"@oxc-project/types@=0.133.0":
+ version "0.133.0"
+ resolved "https://registry.yarnpkg.com/@oxc-project/types/-/types-0.133.0.tgz#2e282ef9e1d26e06b68ccd14b73f310a3b2cf7f8"
+ integrity sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==
+
+"@oxc-project/types@^0.132.0":
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/@oxc-project/types/-/types-0.132.0.tgz#d77243df4fe1a0a1e60e12ac6240fa898d2363ff"
+ integrity sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ==
+
+"@parcel/watcher-android-arm64@2.5.6":
+ version "2.5.6"
+ resolved "https://registry.yarnpkg.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz#5f32e0dba356f4ac9a11068d2a5c134ca3ba6564"
+ integrity sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==
+
+"@parcel/watcher-darwin-arm64@2.5.6":
+ version "2.5.6"
+ resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz#88d3e720b59b1eceffce98dac46d7c40e8be5e8e"
+ integrity sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==
+
+"@parcel/watcher-darwin-x64@2.5.6":
+ version "2.5.6"
+ resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz#bf05d76a78bc15974f15ec3671848698b0838063"
+ integrity sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==
+
+"@parcel/watcher-freebsd-x64@2.5.6":
+ version "2.5.6"
+ resolved "https://registry.yarnpkg.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz#8bc26e9848e7303ac82922a5ae1b1ef1bdb48a53"
+ integrity sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==
+
+"@parcel/watcher-linux-arm-glibc@2.5.6":
+ version "2.5.6"
+ resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz#1328fee1deb0c2d7865079ef53a2ba4cc2f8b40a"
+ integrity sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==
+
+"@parcel/watcher-linux-arm-musl@2.5.6":
+ version "2.5.6"
+ resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz#bad0f45cb3e2157746db8b9d22db6a125711f152"
+ integrity sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==
+
+"@parcel/watcher-linux-arm64-glibc@2.5.6":
+ version "2.5.6"
+ resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz#b75913fbd501d9523c5f35d420957bf7d0204809"
+ integrity sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==
+
+"@parcel/watcher-linux-arm64-musl@2.5.6":
+ version "2.5.6"
+ resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz#da5621a6a576070c8c0de60dea8b46dc9c3827d4"
+ integrity sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==
+
+"@parcel/watcher-linux-x64-glibc@2.5.6":
+ version "2.5.6"
+ resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz#ce437accdc4b30f93a090b4a221fd95cd9b89639"
+ integrity sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==
+
+"@parcel/watcher-linux-x64-musl@2.5.6":
+ version "2.5.6"
+ resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz#02400c54b4a67efcc7e2327b249711920ac969e2"
+ integrity sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==
+
+"@parcel/watcher-win32-arm64@2.5.6":
+ version "2.5.6"
+ resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz#caae3d3c7583ca0a7171e6bd142c34d20ea1691e"
+ integrity sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==
+
+"@parcel/watcher-win32-ia32@2.5.6":
+ version "2.5.6"
+ resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz#9ac922550896dfe47bfc5ae3be4f1bcaf8155d6d"
+ integrity sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==
+
+"@parcel/watcher-win32-x64@2.5.6":
+ version "2.5.6"
+ resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz#73fdafba2e21c448f0e456bbe13178d8fe11739d"
+ integrity sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==
"@parcel/watcher@^2.4.1":
- version "2.5.1"
- resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.5.1.tgz#342507a9cfaaf172479a882309def1e991fb1200"
- integrity sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==
+ version "2.5.6"
+ resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.5.6.tgz#3f932828c894f06d0ad9cfefade1756ecc6ef1f1"
+ integrity sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==
dependencies:
- detect-libc "^1.0.3"
+ detect-libc "^2.0.3"
is-glob "^4.0.3"
- micromatch "^4.0.5"
node-addon-api "^7.0.0"
+ picomatch "^4.0.3"
optionalDependencies:
- "@parcel/watcher-android-arm64" "2.5.1"
- "@parcel/watcher-darwin-arm64" "2.5.1"
- "@parcel/watcher-darwin-x64" "2.5.1"
- "@parcel/watcher-freebsd-x64" "2.5.1"
- "@parcel/watcher-linux-arm-glibc" "2.5.1"
- "@parcel/watcher-linux-arm-musl" "2.5.1"
- "@parcel/watcher-linux-arm64-glibc" "2.5.1"
- "@parcel/watcher-linux-arm64-musl" "2.5.1"
- "@parcel/watcher-linux-x64-glibc" "2.5.1"
- "@parcel/watcher-linux-x64-musl" "2.5.1"
- "@parcel/watcher-win32-arm64" "2.5.1"
- "@parcel/watcher-win32-ia32" "2.5.1"
- "@parcel/watcher-win32-x64" "2.5.1"
+ "@parcel/watcher-android-arm64" "2.5.6"
+ "@parcel/watcher-darwin-arm64" "2.5.6"
+ "@parcel/watcher-darwin-x64" "2.5.6"
+ "@parcel/watcher-freebsd-x64" "2.5.6"
+ "@parcel/watcher-linux-arm-glibc" "2.5.6"
+ "@parcel/watcher-linux-arm-musl" "2.5.6"
+ "@parcel/watcher-linux-arm64-glibc" "2.5.6"
+ "@parcel/watcher-linux-arm64-musl" "2.5.6"
+ "@parcel/watcher-linux-x64-glibc" "2.5.6"
+ "@parcel/watcher-linux-x64-musl" "2.5.6"
+ "@parcel/watcher-win32-arm64" "2.5.6"
+ "@parcel/watcher-win32-ia32" "2.5.6"
+ "@parcel/watcher-win32-x64" "2.5.6"
"@pinia/testing@1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@pinia/testing/-/testing-1.0.3.tgz#62e0813a7a8ac735505422bb7a4e38eb86f815dc"
integrity sha512-g+qR49GNdI1Z8rZxKrQC3GN+LfnGTNf5Kk8Nz5Cz6mIGva5WRS+ffPXQfzhA0nu6TveWzPNYTjGl4nJqd3Cu9Q==
"@pkgjs/parseargs@^0.11.0":
version "0.11.0"
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
"@polka/url@^1.0.0-next.24":
version "1.0.0-next.29"
resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.29.tgz#5a40109a1ab5f84d6fd8fc928b19f367cbe7e7b1"
integrity sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==
-"@rolldown/pluginutils@^1.0.0-beta.9":
- version "1.0.0-beta.33"
- resolved "https://registry.yarnpkg.com/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.33.tgz#ca02474d97182d0444dfd079c4e8f2c4125bf599"
- integrity sha512-she25NCG6NoEPC/SEB4pHs5STcnfI4VBFOzjeI63maSPrWME5J2XC8ogrBgp8NaE/xzj28/kbpSaebiMvFRj+w==
+"@publint/pack@^0.1.4":
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/@publint/pack/-/pack-0.1.4.tgz#866a82a1a8ab52329ae08baec6f3969ed99a30bf"
+ integrity sha512-HDVTWq3H0uTXiU0eeSQntcVUTPP3GamzeXI41+x7uU9J65JgWQh3qWZHblR1i0npXfFtF+mxBiU2nJH8znxWnQ==
-"@rollup/pluginutils@^5.2.0":
- version "5.2.0"
- resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.2.0.tgz#eac25ca5b0bdda4ba735ddaca5fbf26bd435f602"
- integrity sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==
+"@quansync/fs@^1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@quansync/fs/-/fs-1.0.0.tgz#17131b1f1c261fcfb63893272c488df89c73f48f"
+ integrity sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==
+ dependencies:
+ quansync "^1.0.0"
+
+"@rolldown/binding-android-arm64@1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.3.tgz#54ce8f8382213f4a314a0c2f7ba83f81ffeae592"
+ integrity sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==
+
+"@rolldown/binding-darwin-arm64@1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.3.tgz#388fca1566c14c00c4b446fc3928630e7f0d95fc"
+ integrity sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==
+
+"@rolldown/binding-darwin-x64@1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.3.tgz#53f57de1f599ecf1db13823cfc88c18fb80954ad"
+ integrity sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==
+
+"@rolldown/binding-freebsd-x64@1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.3.tgz#6f3fdda1b7aeaac9d268a526804b4fb96e4e35f1"
+ integrity sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==
+
+"@rolldown/binding-linux-arm-gnueabihf@1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.3.tgz#d87a454bf585cc9676849377e91d6e375297326f"
+ integrity sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==
+
+"@rolldown/binding-linux-arm64-gnu@1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.3.tgz#419fd6bf612cf348f10528cbcd94ebab9607d8d1"
+ integrity sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==
+
+"@rolldown/binding-linux-arm64-musl@1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.3.tgz#fcc6918696bb76844877e1e4930a18fd0d374069"
+ integrity sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==
+
+"@rolldown/binding-linux-ppc64-gnu@1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.3.tgz#32aecb7c8dae5d4f2a8cde57a058ec86991542f8"
+ integrity sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==
+
+"@rolldown/binding-linux-s390x-gnu@1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.3.tgz#bed9346ea81e6bb8b93cf11f5d88b77db890b763"
+ integrity sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==
+
+"@rolldown/binding-linux-x64-gnu@1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.3.tgz#64c2d26f75dffd9b5a1f97557a00ae77250c8cb7"
+ integrity sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==
+
+"@rolldown/binding-linux-x64-musl@1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.3.tgz#5a45132e8a47659eeaaf3b540c2954a97c860ff3"
+ integrity sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==
+
+"@rolldown/binding-openharmony-arm64@1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.3.tgz#290513068c55e849dc8457a32afee1d7b0acb309"
+ integrity sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==
+
+"@rolldown/binding-wasm32-wasi@1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.3.tgz#3d9972dbf1a953d3c7afaa4a0f20ef2b2e39f31b"
+ integrity sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==
+ dependencies:
+ "@emnapi/core" "1.10.0"
+ "@emnapi/runtime" "1.10.0"
+ "@napi-rs/wasm-runtime" "^1.1.4"
+
+"@rolldown/binding-win32-arm64-msvc@1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.3.tgz#a004ab607a16d6f03bcb555728ff888af75773ad"
+ integrity sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==
+
+"@rolldown/binding-win32-x64-msvc@1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.3.tgz#e2a25b34691a1cc8a1209d7de709063026dd0cdb"
+ integrity sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==
+
+"@rolldown/debug@^1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@rolldown/debug/-/debug-1.0.3.tgz#6e818fc76cf3385068decf18ada5061876658f66"
+ integrity sha512-mQ4V7ODNxW4o09we34Dw9I29ByK/m7yTHT8Nqt+wwWCcxPsiGoixUsFDiruxGQwrjk6XYgwi/Cf0Prg0x5ABsA==
+
+"@rolldown/pluginutils@^1.0.0", "@rolldown/pluginutils@^1.0.0-rc.2", "@rolldown/pluginutils@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz#e3fcee093fbb5ce765e1ad088ff4de2889f6f9be"
+ integrity sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==
+
+"@rollup/pluginutils@^5.3.0":
+ version "5.4.0"
+ resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.4.0.tgz#ac23a29ced0247060a210815fca39c17de4d2f26"
+ integrity sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==
dependencies:
"@types/estree" "^1.0.0"
estree-walker "^2.0.2"
picomatch "^4.0.2"
"@rollup/rollup-android-arm-eabi@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.52.5.tgz#0f44a2f8668ed87b040b6fe659358ac9239da4db"
integrity sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==
"@rollup/rollup-android-arm64@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.52.5.tgz#25b9a01deef6518a948431564c987bcb205274f5"
integrity sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==
"@rollup/rollup-darwin-arm64@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.52.5.tgz#8a102869c88f3780c7d5e6776afd3f19084ecd7f"
integrity sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==
"@rollup/rollup-darwin-x64@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.52.5.tgz#8e526417cd6f54daf1d0c04cf361160216581956"
integrity sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==
"@rollup/rollup-freebsd-arm64@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.52.5.tgz#0e7027054493f3409b1f219a3eac5efd128ef899"
integrity sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==
"@rollup/rollup-freebsd-x64@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.52.5.tgz#72b204a920139e9ec3d331bd9cfd9a0c248ccb10"
integrity sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==
"@rollup/rollup-linux-arm-gnueabihf@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.52.5.tgz#ab1b522ebe5b7e06c99504cc38f6cd8b808ba41c"
integrity sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==
"@rollup/rollup-linux-arm-musleabihf@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.52.5.tgz#f8cc30b638f1ee7e3d18eac24af47ea29d9beb00"
integrity sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==
"@rollup/rollup-linux-arm64-gnu@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.52.5.tgz#7af37a9e85f25db59dc8214172907b7e146c12cc"
integrity sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==
"@rollup/rollup-linux-arm64-musl@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.52.5.tgz#a623eb0d3617c03b7a73716eb85c6e37b776f7e0"
integrity sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==
"@rollup/rollup-linux-loong64-gnu@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.52.5.tgz#76ea038b549c5c6c5f0d062942627c4066642ee2"
integrity sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==
"@rollup/rollup-linux-ppc64-gnu@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.52.5.tgz#d9a4c3f0a3492bc78f6fdfe8131ac61c7359ccd5"
integrity sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==
"@rollup/rollup-linux-riscv64-gnu@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.52.5.tgz#87ab033eebd1a9a1dd7b60509f6333ec1f82d994"
integrity sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==
"@rollup/rollup-linux-riscv64-musl@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.52.5.tgz#bda3eb67e1c993c1ba12bc9c2f694e7703958d9f"
integrity sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==
"@rollup/rollup-linux-s390x-gnu@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.52.5.tgz#f7bc10fbe096ab44694233dc42a2291ed5453d4b"
integrity sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==
"@rollup/rollup-linux-x64-gnu@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.52.5.tgz#a151cb1234cc9b2cf5e8cfc02aa91436b8f9e278"
integrity sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==
"@rollup/rollup-linux-x64-musl@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.52.5.tgz#7859e196501cc3b3062d45d2776cfb4d2f3a9350"
integrity sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==
"@rollup/rollup-openharmony-arm64@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.52.5.tgz#85d0df7233734df31e547c1e647d2a5300b3bf30"
integrity sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==
"@rollup/rollup-win32-arm64-msvc@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.52.5.tgz#e62357d00458db17277b88adbf690bb855cac937"
integrity sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==
"@rollup/rollup-win32-ia32-msvc@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.52.5.tgz#fc7cd40f44834a703c1f1c3fe8bcc27ce476cd50"
integrity sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==
"@rollup/rollup-win32-x64-gnu@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.52.5.tgz#1a22acfc93c64a64a48c42672e857ee51774d0d3"
integrity sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==
"@rollup/rollup-win32-x64-msvc@4.52.5":
version "4.52.5"
resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.52.5.tgz#1657f56326bbe0ac80eedc9f9c18fc1ddd24e107"
integrity sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==
"@rtsao/scc@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8"
integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==
"@ruffle-rs/ruffle@0.1.0-nightly.2025.6.22":
version "0.1.0-nightly.2025.6.22"
resolved "https://registry.yarnpkg.com/@ruffle-rs/ruffle/-/ruffle-0.1.0-nightly.2025.6.22.tgz#3f7a3c8989c1781422e5ec0b5b74d428f62b6854"
integrity sha512-ECd7j0+CFY+BKyHsN049RIzSjHvsPJuwv8EMqpJ+2AKCy9F12852ziWoDlk89oKH3i0Da3sP2w1ij8wFKsAvtQ==
"@sinonjs/commons@^3.0.1":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd"
integrity sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==
dependencies:
type-detect "4.0.8"
"@sinonjs/fake-timers@^13.0.5":
version "13.0.5"
resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz#36b9dbc21ad5546486ea9173d6bea063eb1717d5"
integrity sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==
dependencies:
"@sinonjs/commons" "^3.0.1"
"@sinonjs/samsam@^8.0.1":
version "8.0.2"
resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-8.0.2.tgz#e4386bf668ff36c95949e55a38dc5f5892fc2689"
integrity sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==
dependencies:
"@sinonjs/commons" "^3.0.1"
lodash.get "^4.4.2"
type-detect "^4.1.0"
"@testim/chrome-version@^1.1.4":
version "1.1.4"
resolved "https://registry.yarnpkg.com/@testim/chrome-version/-/chrome-version-1.1.4.tgz#86e04e677cd6c05fa230dd15ac223fa72d1d7090"
integrity sha512-kIhULpw9TrGYnHp/8VfdcneIcxKnLixmADtukQRtJUmsVlMg0niMkwV0xZmi8hqa57xqilIHjWFA0GKvEjVU5g==
"@testing-library/dom@^10.4.0":
version "10.4.0"
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-10.4.0.tgz#82a9d9462f11d240ecadbf406607c6ceeeff43a8"
integrity sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==
dependencies:
"@babel/code-frame" "^7.10.4"
"@babel/runtime" "^7.12.5"
"@types/aria-query" "^5.0.1"
aria-query "5.3.0"
chalk "^4.1.0"
dom-accessibility-api "^0.5.9"
lz-string "^1.5.0"
pretty-format "^27.0.2"
"@testing-library/user-event@^14.6.1":
version "14.6.1"
resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-14.6.1.tgz#13e09a32d7a8b7060fe38304788ebf4197cd2149"
integrity sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==
"@tootallnate/quickjs-emscripten@^0.23.0":
version "0.23.0"
resolved "https://registry.yarnpkg.com/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz#db4ecfd499a9765ab24002c3b696d02e6d32a12c"
integrity sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==
+"@tybys/wasm-util@^0.10.1":
+ version "0.10.2"
+ resolved "https://registry.yarnpkg.com/@tybys/wasm-util/-/wasm-util-0.10.2.tgz#12b3a1b33db1f9cad4ddff1f604ab7dd00bf464e"
+ integrity sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==
+ dependencies:
+ tslib "^2.4.0"
+
"@types/aria-query@^5.0.1":
version "5.0.4"
resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.4.tgz#1a31c3d378850d2778dabb6374d036dcba4ba708"
integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==
"@types/chai@^4.3.5":
version "4.3.20"
resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.20.tgz#cb291577ed342ca92600430841a00329ba05cecc"
integrity sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==
"@types/cookie@^0.6.0":
version "0.6.0"
resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.6.0.tgz#eac397f28bf1d6ae0ae081363eca2f425bedf0d5"
integrity sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==
"@types/estree@1.0.8", "@types/estree@^1.0.0":
version "1.0.8"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e"
integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==
"@types/estree@^1.0.6":
version "1.0.7"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.7.tgz#4158d3105276773d5b7695cd4834b1722e4f37a8"
integrity sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==
"@types/http-proxy@^1.17.15":
version "1.17.16"
resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.16.tgz#dee360707b35b3cc85afcde89ffeebff7d7f9240"
integrity sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==
dependencies:
"@types/node" "*"
"@types/json-schema@^7.0.15":
version "7.0.15"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
"@types/json5@^0.0.29":
version "0.0.29"
resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee"
integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==
"@types/node@*":
version "22.13.17"
resolved "https://registry.yarnpkg.com/@types/node/-/node-22.13.17.tgz#9ca6a81a0180cdcfd3719b9cf6c09186756e1754"
integrity sha512-nAJuQXoyPj04uLgu+obZcSmsfOenUg6DxPKogeUy6yNCFwWaj5sBF8/G/pNo8EtBJjAfSVgfIlugR/BCOleO+g==
dependencies:
undici-types "~6.20.0"
"@types/selenium-webdriver@^4.1.14":
version "4.1.28"
resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-4.1.28.tgz#7b4f3c50a67494f8fd6d396a2eaab7d9df1f9f34"
integrity sha512-Au7CXegiS7oapbB16zxPToY4Cjzi9UQQMf3W2ZZM8PigMLTGR3iUAHjPUTddyE5g1SBjT/qpmvlsAQLBfNAdKg==
dependencies:
"@types/node" "*"
"@types/ws" "*"
"@types/statuses@^2.0.4":
version "2.0.5"
resolved "https://registry.yarnpkg.com/@types/statuses/-/statuses-2.0.5.tgz#f61ab46d5352fd73c863a1ea4e1cef3b0b51ae63"
integrity sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==
"@types/tough-cookie@^4.0.5":
version "4.0.5"
resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304"
integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==
"@types/ws@*":
version "8.18.1"
resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9"
integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==
dependencies:
"@types/node" "*"
"@types/yauzl@^2.9.1":
version "2.10.3"
resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.3.tgz#e9b2808b4f109504a03cda958259876f61017999"
integrity sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==
dependencies:
"@types/node" "*"
"@ungap/event-target@0.2.4":
version "0.2.4"
resolved "https://registry.yarnpkg.com/@ungap/event-target/-/event-target-0.2.4.tgz#8b083a62ee665228bac08013fa516a3488528bb8"
integrity sha512-u9Fd3k2qfMtn+0dxbCn/y0pzQ9Ucw6lWR984CrHcbxc+WzcMkJE4VjWHWSb9At40MjwMyHCkJNXroS55Osshhw==
-"@vitejs/plugin-vue-jsx@^4.1.1":
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-4.2.0.tgz#2738ec05d4705ed553a107342017192e37351640"
- integrity sha512-DSTrmrdLp+0LDNF77fqrKfx7X0ErRbOcUAgJL/HbSesqQwoUvUQ4uYQqaex+rovqgGcoPqVk+AwUh3v9CuiYIw==
+"@valibot/to-json-schema@^1.7.0":
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/@valibot/to-json-schema/-/to-json-schema-1.7.0.tgz#a0519849f78d180939befac82a218745b55a913a"
+ integrity sha512-Y3pPVibbIOHzohrlxSINvO7w/bvXkoYS3BQHoImV9ynE+bXKf171bdMucPurV2zp7gdmt0L1HCcNAsbo7cFRQw==
+
+"@vitejs/devtools-kit@0.3.1":
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/@vitejs/devtools-kit/-/devtools-kit-0.3.1.tgz#03818777913d97d2419990fa2384d2217487870d"
+ integrity sha512-0zwX4IpFMbNWsiDMj/WnRZFdJU+zY8gU/uBf2jr5UktDicmwL+6yVZRF5zgOA6XZ3yj4+TLSdWQfVlaMerBWaw==
+ dependencies:
+ "@devframes/hub" "^0.5.2"
+ birpc "^4.0.0"
+ devframe "^0.5.2"
+ mlly "^1.8.2"
+ nostics "^0.2.0"
+ pathe "^2.0.3"
+ perfect-debounce "^2.1.0"
+ tinyexec "^1.2.2"
+
+"@vitejs/devtools-rolldown@0.3.1":
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/@vitejs/devtools-rolldown/-/devtools-rolldown-0.3.1.tgz#a866090dcaf38c08d071df22ebe0b22aef54ac37"
+ integrity sha512-yrlrezS7xaR/nxRRTqsJevUPeZOWIQKX3wwK38zGsEEEMn8oyls8DBmYVagtXNPqUk9XW9bt5sVIsrR2n2F8+w==
+ dependencies:
+ "@floating-ui/dom" "^1.7.6"
+ "@rolldown/debug" "^1.0.3"
+ "@vitejs/devtools-kit" "0.3.1"
+ birpc "^4.0.0"
+ cac "^7.0.0"
+ d3-shape "^3.2.0"
+ devframe "^0.5.2"
+ diff "^9.0.0"
+ get-port-please "^3.2.0"
+ h3 "2.0.1-rc.22"
+ mlly "^1.8.2"
+ mrmime "^2.0.1"
+ nostics "^0.2.0"
+ p-limit "^7.3.0"
+ pathe "^2.0.3"
+ publint "^0.3.21"
+ tinyglobby "^0.2.16"
+ unconfig "^7.5.0"
+ unstorage "^1.17.5"
+ vue-virtual-scroller "^3.0.4"
+ ws "^8.21.0"
+
+"@vitejs/devtools@^0.3.1":
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/@vitejs/devtools/-/devtools-0.3.1.tgz#58c6d8924038f8385f170a0d049c7871ab8344b0"
+ integrity sha512-uRgicpM7gzCJ4dHzs717uLvzvw2sdnVzxp7bui/cyezWyILjc0DYlPlFEwS2kIFLOnnQNGeryRbs/M96C7Ts8Q==
+ dependencies:
+ "@devframes/hub" "^0.5.2"
+ "@vitejs/devtools-kit" "0.3.1"
+ "@vitejs/devtools-rolldown" "0.3.1"
+ birpc "^4.0.0"
+ cac "^7.0.0"
+ devframe "^0.5.2"
+ h3 "2.0.1-rc.22"
+ mlly "^1.8.2"
+ nostics "^0.2.0"
+ obug "^2.1.1"
+ pathe "^2.0.3"
+ perfect-debounce "^2.1.0"
+ tinyexec "^1.2.2"
+ vue "^3.5.35"
+ ws "^8.21.0"
+
+"@vitejs/plugin-vue-jsx@^5.1.5":
+ version "5.1.5"
+ resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue-jsx/-/plugin-vue-jsx-5.1.5.tgz#23b9aa23e55fc81c40b3dab81728339c1f0d177f"
+ integrity sha512-jIAsvHOEtWpslLOI2MeElGFxH7M8pM83BU/Tor4RLyiwH0FM4nUW3xdvbw20EeU9wc5IspQwMq225K3CMnJEpA==
dependencies:
- "@babel/core" "^7.27.1"
- "@babel/plugin-transform-typescript" "^7.27.1"
- "@rolldown/pluginutils" "^1.0.0-beta.9"
- "@vue/babel-plugin-jsx" "^1.4.0"
+ "@babel/core" "^7.29.0"
+ "@babel/plugin-syntax-typescript" "^7.28.6"
+ "@babel/plugin-transform-typescript" "^7.28.6"
+ "@rolldown/pluginutils" "^1.0.0-rc.2"
+ "@vue/babel-plugin-jsx" "^2.0.1"
-"@vitejs/plugin-vue@^5.2.1":
- version "5.2.4"
- resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz#9e8a512eb174bfc2a333ba959bbf9de428d89ad8"
- integrity sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==
+"@vitejs/plugin-vue@^6.0.7":
+ version "6.0.7"
+ resolved "https://registry.yarnpkg.com/@vitejs/plugin-vue/-/plugin-vue-6.0.7.tgz#194235d364a2c601c521b0410e524e521119059f"
+ integrity sha512-km+p+XdSz9Sxm5rqUbqcSfZYaAniKxWBj1KURl+Jr7UaPvvX7BmaWMdP69I5rrFDeQGyxAG7NXdc57vz+snhWg==
+ dependencies:
+ "@rolldown/pluginutils" "^1.0.1"
"@vitest/browser@^3.0.7":
version "3.1.3"
resolved "https://registry.yarnpkg.com/@vitest/browser/-/browser-3.1.3.tgz#985f12382bc4aeddbffa4209850ab5cbaaa43e60"
integrity sha512-Dgyez9LbHJHl9ObZPo5mu4zohWLo7SMv8zRWclMF+dxhQjmOtEP0raEX13ac5ygcvihNoQPBZXdya5LMSbcCDQ==
dependencies:
"@testing-library/dom" "^10.4.0"
"@testing-library/user-event" "^14.6.1"
"@vitest/mocker" "3.1.3"
"@vitest/utils" "3.1.3"
magic-string "^0.30.17"
sirv "^3.0.1"
tinyrainbow "^2.0.0"
ws "^8.18.1"
"@vitest/expect@3.1.3":
version "3.1.3"
resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-3.1.3.tgz#bbca175cd2f23d7de9448a215baed8f3d7abd7b7"
integrity sha512-7FTQQuuLKmN1Ig/h+h/GO+44Q1IlglPlR2es4ab7Yvfx+Uk5xsv+Ykk+MEt/M2Yn/xGmzaLKxGw2lgy2bwuYqg==
dependencies:
"@vitest/spy" "3.1.3"
"@vitest/utils" "3.1.3"
chai "^5.2.0"
tinyrainbow "^2.0.0"
"@vitest/mocker@3.1.3":
version "3.1.3"
resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-3.1.3.tgz#121d0f2fcca20c9ccada9e2d6e761f7fc687f4ce"
integrity sha512-PJbLjonJK82uCWHjzgBJZuR7zmAOrSvKk1QBxrennDIgtH4uK0TB1PvYmc0XBCigxxtiAVPfWtAdy4lpz8SQGQ==
dependencies:
"@vitest/spy" "3.1.3"
estree-walker "^3.0.3"
magic-string "^0.30.17"
"@vitest/pretty-format@3.1.3", "@vitest/pretty-format@^3.1.3":
version "3.1.3"
resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-3.1.3.tgz#760b9eab5f253d7d2e7dcd28ef34570f584023d4"
integrity sha512-i6FDiBeJUGLDKADw2Gb01UtUNb12yyXAqC/mmRWuYl+m/U9GS7s8us5ONmGkGpUUo7/iAYzI2ePVfOZTYvUifA==
dependencies:
tinyrainbow "^2.0.0"
"@vitest/runner@3.1.3":
version "3.1.3"
resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-3.1.3.tgz#b268fa90fca38fab363f1107f057c0a2a141ee45"
integrity sha512-Tae+ogtlNfFei5DggOsSUvkIaSuVywujMj6HzR97AHK6XK8i3BuVyIifWAm/sE3a15lF5RH9yQIrbXYuo0IFyA==
dependencies:
"@vitest/utils" "3.1.3"
pathe "^2.0.3"
"@vitest/snapshot@3.1.3":
version "3.1.3"
resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-3.1.3.tgz#39a8f9f8c6ba732ffde59adeacf0a549bef11e76"
integrity sha512-XVa5OPNTYUsyqG9skuUkFzAeFnEzDp8hQu7kZ0N25B1+6KjGm4hWLtURyBbsIAOekfWQ7Wuz/N/XXzgYO3deWQ==
dependencies:
"@vitest/pretty-format" "3.1.3"
magic-string "^0.30.17"
pathe "^2.0.3"
"@vitest/spy@3.1.3":
version "3.1.3"
resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-3.1.3.tgz#ca81e2b4f0c3d6c75f35defa77c3336f39c8f605"
integrity sha512-x6w+ctOEmEXdWaa6TO4ilb7l9DxPR5bwEb6hILKuxfU1NqWT2mpJD9NJN7t3OTfxmVlOMrvtoFJGdgyzZ605lQ==
dependencies:
tinyspy "^3.0.2"
"@vitest/ui@^3.0.7":
version "3.1.3"
resolved "https://registry.yarnpkg.com/@vitest/ui/-/ui-3.1.3.tgz#ad3c3160e6c86d79f817e09b1f8f02f0e2799851"
integrity sha512-IipSzX+8DptUdXN/GWq3hq5z18MwnpphYdOMm0WndkRGYELzfq7NDP8dMpZT7JGW1uXFrIGxOW2D0Xi++ulByg==
dependencies:
"@vitest/utils" "3.1.3"
fflate "^0.8.2"
flatted "^3.3.3"
pathe "^2.0.3"
sirv "^3.0.1"
tinyglobby "^0.2.13"
tinyrainbow "^2.0.0"
"@vitest/utils@3.1.3":
version "3.1.3"
resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-3.1.3.tgz#4f31bdfd646cd82d30bfa730d7410cb59d529669"
integrity sha512-2Ltrpht4OmHO9+c/nmHtF09HWiyWdworqnHIwjfvDyWjuwKbdkcS9AnhsDn+8E2RM4x++foD1/tNuLPVvWG1Rg==
dependencies:
"@vitest/pretty-format" "3.1.3"
loupe "^3.1.3"
tinyrainbow "^2.0.0"
"@vue/babel-helper-vue-jsx-merge-props@1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-jsx-merge-props/-/babel-helper-vue-jsx-merge-props-1.4.0.tgz#8d53a1e21347db8edbe54d339902583176de09f2"
integrity sha512-JkqXfCkUDp4PIlFdDQ0TdXoIejMtTHP67/pvxlgeY+u5k3LEdKuWZ3LK6xkxo52uDoABIVyRwqVkfLQJhk7VBA==
"@vue/babel-helper-vue-transform-on@1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.5.0.tgz#b7e99d37eeb144d7b9757d7a1f40cd977fde748a"
integrity sha512-0dAYkerNhhHutHZ34JtTl2czVQHUNWv6xEbkdF5W+Yrv5pCWsqjeORdOgbtW2I9gWlt+wBmVn+ttqN9ZxR5tzA==
-"@vue/babel-plugin-jsx@1.5.0", "@vue/babel-plugin-jsx@^1.4.0":
+"@vue/babel-helper-vue-transform-on@2.0.1":
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-2.0.1.tgz#3cadaa769fda53b61f193ab63668ccc5c7dfe244"
+ integrity sha512-uZ66EaFbnnZSYqYEyplWvn46GhZ1KuYSThdT68p+am7MgBNbQ3hphTL9L+xSIsWkdktwhPYLwPgVWqo96jDdRA==
+
+"@vue/babel-plugin-jsx@1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-1.5.0.tgz#1b988b497cb1f79725da94463e75cebe60b72e70"
integrity sha512-mneBhw1oOqCd2247O0Yw/mRwC9jIGACAJUlawkmMBiNmL4dGA2eMzuNZVNqOUfYTa6vqmND4CtOPzmEEEqLKFw==
dependencies:
"@babel/helper-module-imports" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/plugin-syntax-jsx" "^7.27.1"
"@babel/template" "^7.27.2"
"@babel/traverse" "^7.28.0"
"@babel/types" "^7.28.2"
"@vue/babel-helper-vue-transform-on" "1.5.0"
"@vue/babel-plugin-resolve-type" "1.5.0"
"@vue/shared" "^3.5.18"
+"@vue/babel-plugin-jsx@^2.0.1":
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/@vue/babel-plugin-jsx/-/babel-plugin-jsx-2.0.1.tgz#5ee72f05d89d82dc8030df6d826c1efd54d3604b"
+ integrity sha512-a8CaLQjD/s4PVdhrLD/zT574ZNPnZBOY+IhdtKWRB4HRZ0I2tXBi5ne7d9eCfaYwp5gU5+4KIyFTV1W1YL9xZA==
+ dependencies:
+ "@babel/helper-module-imports" "^7.27.1"
+ "@babel/helper-plugin-utils" "^7.27.1"
+ "@babel/plugin-syntax-jsx" "^7.27.1"
+ "@babel/template" "^7.27.2"
+ "@babel/traverse" "^7.28.4"
+ "@babel/types" "^7.28.4"
+ "@vue/babel-helper-vue-transform-on" "2.0.1"
+ "@vue/babel-plugin-resolve-type" "2.0.1"
+ "@vue/shared" "^3.5.22"
+
"@vue/babel-plugin-resolve-type@1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-1.5.0.tgz#6881d7b1478e9fc0ea4bb08aaad1f4d206655568"
integrity sha512-Wm/60o+53JwJODm4Knz47dxJnLDJ9FnKnGZJbUUf8nQRAtt6P+undLUAVU3Ha33LxOJe6IPoifRQ6F/0RrU31w==
dependencies:
"@babel/code-frame" "^7.27.1"
"@babel/helper-module-imports" "^7.27.1"
"@babel/helper-plugin-utils" "^7.27.1"
"@babel/parser" "^7.28.0"
"@vue/compiler-sfc" "^3.5.18"
+"@vue/babel-plugin-resolve-type@2.0.1":
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/@vue/babel-plugin-resolve-type/-/babel-plugin-resolve-type-2.0.1.tgz#4a191a0139a1bc106dae560abebf342bdeef5639"
+ integrity sha512-ybwgIuRGRRBhOU37GImDoWQoz+TlSqap65qVI6iwg/J7FfLTLmMf97TS7xQH9I7Qtr/gp161kYVdhr1ZMraSYQ==
+ dependencies:
+ "@babel/code-frame" "^7.27.1"
+ "@babel/helper-module-imports" "^7.27.1"
+ "@babel/helper-plugin-utils" "^7.27.1"
+ "@babel/parser" "^7.28.4"
+ "@vue/compiler-sfc" "^3.5.22"
+
"@vue/compiler-core@3.5.19":
version "3.5.19"
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.5.19.tgz#f141d35b61b55ce72c3cbb4dc9eeca3821d451aa"
integrity sha512-/afpyvlkrSNYbPo94Qu8GtIOWS+g5TRdOvs6XZNw6pWQQmj5pBgSZvEPOIZlqWq0YvoUhDDQaQ2TnzuJdOV4hA==
dependencies:
"@babel/parser" "^7.28.3"
"@vue/shared" "3.5.19"
entities "^4.5.0"
estree-walker "^2.0.2"
source-map-js "^1.2.1"
"@vue/compiler-core@3.5.22":
version "3.5.22"
resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.5.22.tgz#bb8294a0dd31df540563cc6ffa0456f1f7687b97"
integrity sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==
dependencies:
"@babel/parser" "^7.28.4"
"@vue/shared" "3.5.22"
entities "^4.5.0"
estree-walker "^2.0.2"
source-map-js "^1.2.1"
+"@vue/compiler-core@3.5.35":
+ version "3.5.35"
+ resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.5.35.tgz#e789c89b0fee47683e5300c715bb9243c07a6bbd"
+ integrity sha512-BUmHaR1J+O+CKZ9uJucdVTEr1LHsdyvv7vG3eNRhK3CczEHeMd/LtsHAuD7PbrxvI2envCY2v7HI1vC1aBRzKw==
+ dependencies:
+ "@babel/parser" "^7.29.3"
+ "@vue/shared" "3.5.35"
+ entities "^7.0.1"
+ estree-walker "^2.0.2"
+ source-map-js "^1.2.1"
+
"@vue/compiler-dom@3.5.19":
version "3.5.19"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.19.tgz#fc57d9dca4987df67d6ce64dbddaac6d73f1a6ef"
integrity sha512-Drs6rPHQZx/pN9S6ml3Z3K/TWCIRPvzG2B/o5kFK9X0MNHt8/E+38tiRfojufrYBfA6FQUFB2qBBRXlcSXWtOA==
dependencies:
"@vue/compiler-core" "3.5.19"
"@vue/shared" "3.5.19"
"@vue/compiler-dom@3.5.22":
version "3.5.22"
resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.22.tgz#6c9c2c9843520f6d3dbc685e5d0e1e12a2c04c56"
integrity sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==
dependencies:
"@vue/compiler-core" "3.5.22"
"@vue/shared" "3.5.22"
+"@vue/compiler-dom@3.5.35":
+ version "3.5.35"
+ resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.5.35.tgz#523a42dcc49af499588c51e3db52e672b9491325"
+ integrity sha512-k+bprkXxuqhVajgTx5mUHuir7TwQzUKOWR40ng1ncAqQRPnrLngGGgqVEEhOnTMlc8btHYVKmrP8s5Qyg0hvYA==
+ dependencies:
+ "@vue/compiler-core" "3.5.35"
+ "@vue/shared" "3.5.35"
+
"@vue/compiler-sfc@3.5.22":
version "3.5.22"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.5.22.tgz#663a8483b1dda8de83b6fa1aab38a52bf73dd965"
integrity sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==
dependencies:
"@babel/parser" "^7.28.4"
"@vue/compiler-core" "3.5.22"
"@vue/compiler-dom" "3.5.22"
"@vue/compiler-ssr" "3.5.22"
"@vue/shared" "3.5.22"
estree-walker "^2.0.2"
magic-string "^0.30.19"
postcss "^8.5.6"
source-map-js "^1.2.1"
+"@vue/compiler-sfc@3.5.35", "@vue/compiler-sfc@^3.5.22":
+ version "3.5.35"
+ resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.5.35.tgz#e0310f48a37cf326b5c926ef0006d75c87e34d33"
+ integrity sha512-G5VPMcXTSywXBgtFOZOnHKBxKSrwXUcvY1iaF5/hRcy7t0J6CH/d8ha9F4nzi00Fax1eLV0QHM7v4mQu68jydw==
+ dependencies:
+ "@babel/parser" "^7.29.3"
+ "@vue/compiler-core" "3.5.35"
+ "@vue/compiler-dom" "3.5.35"
+ "@vue/compiler-ssr" "3.5.35"
+ "@vue/shared" "3.5.35"
+ estree-walker "^2.0.2"
+ magic-string "^0.30.21"
+ postcss "^8.5.15"
+ source-map-js "^1.2.1"
+
"@vue/compiler-sfc@^3.5.18":
version "3.5.19"
resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.5.19.tgz#7f9792ad7de5d4be9b6a32129c75e1f6cd4da015"
integrity sha512-YWCm1CYaJ+2RvNmhCwI7t3I3nU+hOrWGWMsn+Z/kmm1jy5iinnVtlmkiZwbLlbV1SRizX7vHsc0/bG5dj0zRTg==
dependencies:
"@babel/parser" "^7.28.3"
"@vue/compiler-core" "3.5.19"
"@vue/compiler-dom" "3.5.19"
"@vue/compiler-ssr" "3.5.19"
"@vue/shared" "3.5.19"
estree-walker "^2.0.2"
magic-string "^0.30.17"
postcss "^8.5.6"
source-map-js "^1.2.1"
"@vue/compiler-ssr@3.5.19":
version "3.5.19"
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.5.19.tgz#1719e7fda6d54f5696ca63d4d40281668c0e601c"
integrity sha512-/wx0VZtkWOPdiQLWPeQeqpHWR/LuNC7bHfSX7OayBTtUy8wur6vT6EQIX6Et86aED6J+y8tTw43qo2uoqGg5sw==
dependencies:
"@vue/compiler-dom" "3.5.19"
"@vue/shared" "3.5.19"
"@vue/compiler-ssr@3.5.22":
version "3.5.22"
resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.5.22.tgz#a0ef16e364731b25e79a13470569066af101320f"
integrity sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==
dependencies:
"@vue/compiler-dom" "3.5.22"
"@vue/shared" "3.5.22"
+"@vue/compiler-ssr@3.5.35":
+ version "3.5.35"
+ resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.5.35.tgz#206cfc3d741c43d605ef0629509c00166022783b"
+ integrity sha512-rGhAeXgdM7/ffTJGXT69rCCdTmjDewnFuUZfBQQHTdcEBeWdT5HCGY60y2ytLJr9/Dsu7IntUi5z/w0h6Rjnzw==
+ dependencies:
+ "@vue/compiler-dom" "3.5.35"
+ "@vue/shared" "3.5.35"
+
"@vue/devtools-api@^6.0.0-beta.11", "@vue/devtools-api@^6.5.0", "@vue/devtools-api@^6.6.4":
version "6.6.4"
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.6.4.tgz#cbe97fe0162b365edc1dba80e173f90492535343"
integrity sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==
-"@vue/devtools-api@^7.7.2":
- version "7.7.7"
- resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-7.7.7.tgz#5ef5f55f60396220725a273548c0d7ee983d5d34"
- integrity sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==
+"@vue/devtools-api@^7.7.7":
+ version "7.7.9"
+ resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-7.7.9.tgz#999dbea50da6b00cf59a1336f11fdc2b43d9e063"
+ integrity sha512-kIE8wvwlcZ6TJTbNeU2HQNtaxLx3a84aotTITUuL/4bzfPxzajGBOoqjMhwZJ8L9qFYDU/lAYMEEm11dnZOD6g==
dependencies:
- "@vue/devtools-kit" "^7.7.7"
+ "@vue/devtools-kit" "^7.7.9"
-"@vue/devtools-kit@^7.7.7":
- version "7.7.7"
- resolved "https://registry.yarnpkg.com/@vue/devtools-kit/-/devtools-kit-7.7.7.tgz#41a64f9526e9363331c72405544df020ce2e3641"
- integrity sha512-wgoZtxcTta65cnZ1Q6MbAfePVFxfM+gq0saaeytoph7nEa7yMXoi6sCPy4ufO111B9msnw0VOWjPEFCXuAKRHA==
+"@vue/devtools-kit@^7.7.9":
+ version "7.7.9"
+ resolved "https://registry.yarnpkg.com/@vue/devtools-kit/-/devtools-kit-7.7.9.tgz#bc218a815616e8987df7ab3e10fc1fb3b8706c58"
+ integrity sha512-PyQ6odHSgiDVd4hnTP+aDk2X4gl2HmLDfiyEnn3/oV+ckFDuswRs4IbBT7vacMuGdwY/XemxBoh302ctbsptuA==
dependencies:
- "@vue/devtools-shared" "^7.7.7"
+ "@vue/devtools-shared" "^7.7.9"
birpc "^2.3.0"
hookable "^5.5.3"
mitt "^3.0.1"
perfect-debounce "^1.0.0"
speakingurl "^14.0.1"
superjson "^2.2.2"
-"@vue/devtools-shared@^7.7.7":
- version "7.7.7"
- resolved "https://registry.yarnpkg.com/@vue/devtools-shared/-/devtools-shared-7.7.7.tgz#ff14aa8c1262ebac8c0397d3b09f767cd489750c"
- integrity sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==
+"@vue/devtools-shared@^7.7.9":
+ version "7.7.9"
+ resolved "https://registry.yarnpkg.com/@vue/devtools-shared/-/devtools-shared-7.7.9.tgz#fa4c096b744927081a7dda5fcf05f34b1ae6ca14"
+ integrity sha512-iWAb0v2WYf0QWmxCGy0seZNDPdO3Sp5+u78ORnyeonS6MT4PC7VPrryX2BpMJrwlDeaZ6BD4vP4XKjK0SZqaeA==
dependencies:
rfdc "^1.4.1"
"@vue/reactivity@3.5.22":
version "3.5.22"
resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.5.22.tgz#9b26f8557c96df46c9a859914a2229f3ca5b8f4f"
integrity sha512-f2Wux4v/Z2pqc9+4SmgZC1p73Z53fyD90NFWXiX9AKVnVBEvLFOWCEgJD3GdGnlxPZt01PSlfmLqbLYzY/Fw4A==
dependencies:
"@vue/shared" "3.5.22"
+"@vue/reactivity@3.5.35":
+ version "3.5.35"
+ resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.5.35.tgz#45b9794ca77ff5ade2eee74bcdeacbc00ae8e7a2"
+ integrity sha512-tVc+SsHConvh/Lz64qq1pP3rYArBmK42xonovEcxY74SQtvctZodG/zhq54P5dr38cVuw25d27cPNRdlMidpGQ==
+ dependencies:
+ "@vue/shared" "3.5.35"
+
"@vue/runtime-core@3.5.22":
version "3.5.22"
resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.5.22.tgz#e004c1e35f423555a0e4c10646ef3e9d380643d1"
integrity sha512-EHo4W/eiYeAzRTN5PCextDUZ0dMs9I8mQ2Fy+OkzvRPUYQEyK9yAjbasrMCXbLNhF7P0OUyivLjIy0yc6VrLJQ==
dependencies:
"@vue/reactivity" "3.5.22"
"@vue/shared" "3.5.22"
+"@vue/runtime-core@3.5.35":
+ version "3.5.35"
+ resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.5.35.tgz#6f16679bc95ffe38af38c5d0bc1414ed4277458e"
+ integrity sha512-A/xFNX9loIcWDygeQuNCfKuh0CoYBzxhqEMNah5TSFg9Z53DrFYEN2qi5CU9necjM1OWYegYREUTHmXTmhfXtg==
+ dependencies:
+ "@vue/reactivity" "3.5.35"
+ "@vue/shared" "3.5.35"
+
"@vue/runtime-dom@3.5.22":
version "3.5.22"
resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.5.22.tgz#01276cea7cb9ac2b9aba046adfb5903b494e2e7e"
integrity sha512-Av60jsryAkI023PlN7LsqrfPvwfxOd2yAwtReCjeuugTJTkgrksYJJstg1e12qle0NarkfhfFu1ox2D+cQotww==
dependencies:
"@vue/reactivity" "3.5.22"
"@vue/runtime-core" "3.5.22"
"@vue/shared" "3.5.22"
csstype "^3.1.3"
+"@vue/runtime-dom@3.5.35":
+ version "3.5.35"
+ resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.5.35.tgz#473f0fbf97b82652780ac9e6bb5873f7c0dde7e7"
+ integrity sha512-odrJ1C391dbGnyDRh8U+rnP7J2amIEzfmRk5vXy7xi3aZhEXofTvpi0T4HJb6jlNqQZTNPR5MPHSB3RHNkIORA==
+ dependencies:
+ "@vue/reactivity" "3.5.35"
+ "@vue/runtime-core" "3.5.35"
+ "@vue/shared" "3.5.35"
+ csstype "^3.2.3"
+
"@vue/server-renderer@3.5.22":
version "3.5.22"
resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.5.22.tgz#d134e3409094044bd066d9803714677457756157"
integrity sha512-gXjo+ao0oHYTSswF+a3KRHZ1WszxIqO7u6XwNHqcqb9JfyIL/pbWrrh/xLv7jeDqla9u+LK7yfZKHih1e1RKAQ==
dependencies:
"@vue/compiler-ssr" "3.5.22"
"@vue/shared" "3.5.22"
+"@vue/server-renderer@3.5.35":
+ version "3.5.35"
+ resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.5.35.tgz#31c7b473de1000472444a0c0a336d1e799b209c3"
+ integrity sha512-NkebSOYdB97wi8OQcO3HqzZSlymJi/aWsN/7h74OSVhRTm6qGs3Jp3e0rCXynmWwSlKeRrnlIug+ilYoHBmQDA==
+ dependencies:
+ "@vue/compiler-ssr" "3.5.35"
+ "@vue/shared" "3.5.35"
+
"@vue/shared@3.5.19", "@vue/shared@^3.5.18":
version "3.5.19"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.19.tgz#5301967a910cb62145e4f17131f3bee88b463c83"
integrity sha512-IhXCOn08wgKrLQxRFKKlSacWg4Goi1BolrdEeLYn6tgHjJNXVrWJ5nzoxZqNwl5p88aLlQ8LOaoMa3AYvaKJ/Q==
"@vue/shared@3.5.22":
version "3.5.22"
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.22.tgz#9d56a1644a3becb8af1e34655928b0e288d827f8"
integrity sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==
+"@vue/shared@3.5.35", "@vue/shared@^3.5.22":
+ version "3.5.35"
+ resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.5.35.tgz#192eb3d720c40715db79313454c4937432a4e86d"
+ integrity sha512-zSbjL7gRXwks2ZQLRGCajBtBXEOXW9Ddhn/HvSdrGkE2dqGnumzW8XtusRrxrE9LvqtiqDXQ+A60Hp6mvdYxfA==
+
"@vue/test-utils@2.4.6":
version "2.4.6"
resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-2.4.6.tgz#7d534e70c4319d2a587d6a3b45a39e9695ade03c"
integrity sha512-FMxEjOpYNYiFe0GkaHsnJPXFHxQ6m4t8vI/ElPGpMWxZKpmRvQ33OIrvRXemy6yha03RxhOlQuy+gZMC3CQSow==
dependencies:
js-beautify "^1.14.9"
vue-component-type-helpers "^2.0.0"
"@vuelidate/core@2.0.3":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@vuelidate/core/-/core-2.0.3.tgz#40468c5ed15b72bde880a026b0699c2f0f1ecede"
integrity sha512-AN6l7KF7+mEfyWG0doT96z+47ljwPpZfi9/JrNMkOGLFv27XVZvKzRLXlmDPQjPl/wOB1GNnHuc54jlCLRNqGA==
dependencies:
vue-demi "^0.13.11"
"@vuelidate/validators@2.0.4":
version "2.0.4"
resolved "https://registry.yarnpkg.com/@vuelidate/validators/-/validators-2.0.4.tgz#0a88a7b2b18f15fd9c384095593f369a6f7384e9"
integrity sha512-odTxtUZ2JpwwiQ10t0QWYJkkYrfd0SyFYhdHH44QQ1jDatlZgTh/KRzrWVmn/ib9Gq7H4hFD4e8ahoo5YlUlDw==
dependencies:
vue-demi "^0.13.11"
"@web3-storage/parse-link-header@^3.1.0":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@web3-storage/parse-link-header/-/parse-link-header-3.1.0.tgz#4562724987649dd6d3e07c87be1826804d212ef7"
integrity sha512-K1undnK70vLLauqdE8bq/l98isTF2FDhcP0UPpXVSjkSWe3xhAn5eRXk5jfA1E5ycNm84Ws/rQFUD7ue11nciw==
abbrev@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-2.0.0.tgz#cf59829b8b4f03f89dda2771cb7f3653828c89bf"
integrity sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==
accepts@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/accepts/-/accepts-2.0.0.tgz#bbcf4ba5075467f3f2131eab3cffc73c2f5d7895"
integrity sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==
dependencies:
mime-types "^3.0.0"
negotiator "^1.0.0"
acorn-jsx@^5.3.2:
version "5.3.2"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
acorn@^8.14.0:
version "8.14.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb"
integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==
acorn@^8.15.0:
version "8.15.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816"
integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==
+acorn@^8.16.0:
+ version "8.16.0"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.16.0.tgz#4ce79c89be40afe7afe8f3adb902a1f1ce9ac08a"
+ integrity sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==
+
agent-base@^7.1.0, agent-base@^7.1.2:
version "7.1.3"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.3.tgz#29435eb821bc4194633a5b89e5bc4703bafc25a1"
integrity sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==
ajv@^6.12.4:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==
dependencies:
fast-deep-equal "^3.1.1"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
ajv@^8.0.1:
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-align@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59"
integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==
dependencies:
string-width "^4.1.0"
ansi-colors@4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
ansi-escapes@^4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e"
integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==
dependencies:
type-fest "^0.21.3"
ansi-regex@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed"
integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==
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-regex@^6.0.1:
version "6.1.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654"
integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
dependencies:
color-convert "^1.9.0"
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
dependencies:
color-convert "^2.0.1"
ansi-styles@^5.0.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b"
integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
ansi-styles@^6.1.0:
version "6.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
ansi-to-html@0.7.2:
version "0.7.2"
resolved "https://registry.yarnpkg.com/ansi-to-html/-/ansi-to-html-0.7.2.tgz#a92c149e4184b571eb29a0135ca001a8e2d710cb"
integrity sha512-v6MqmEpNlxF+POuyhKkidusCHWWkaLcGRURzivcU3I9tv7k4JVhFcnukrM5Rlk2rUywdZuzYAZ+kbZqWCnfN3g==
dependencies:
entities "^2.2.0"
-anymatch@~3.1.2:
+anymatch@^3.1.3, anymatch@~3.1.2:
version "3.1.3"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
dependencies:
normalize-path "^3.0.0"
picomatch "^2.0.4"
archiver-utils@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-2.1.0.tgz#e8a460e94b693c3e3da182a098ca6285ba9249e2"
integrity sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==
dependencies:
glob "^7.1.4"
graceful-fs "^4.2.0"
lazystream "^1.0.0"
lodash.defaults "^4.2.0"
lodash.difference "^4.5.0"
lodash.flatten "^4.4.0"
lodash.isplainobject "^4.0.6"
lodash.union "^4.6.0"
normalize-path "^3.0.0"
readable-stream "^2.0.0"
archiver-utils@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-3.0.4.tgz#a0d201f1cf8fce7af3b5a05aea0a337329e96ec7"
integrity sha512-KVgf4XQVrTjhyWmx6cte4RxonPLR9onExufI1jhvw/MQ4BB6IsZD5gT8Lq+u/+pRkWna/6JoHpiQioaqFP5Rzw==
dependencies:
glob "^7.2.3"
graceful-fs "^4.2.0"
lazystream "^1.0.0"
lodash.defaults "^4.2.0"
lodash.difference "^4.5.0"
lodash.flatten "^4.4.0"
lodash.isplainobject "^4.0.6"
lodash.union "^4.6.0"
normalize-path "^3.0.0"
readable-stream "^3.6.0"
archiver@^5.3.1:
version "5.3.2"
resolved "https://registry.yarnpkg.com/archiver/-/archiver-5.3.2.tgz#99991d5957e53bd0303a392979276ac4ddccf3b0"
integrity sha512-+25nxyyznAXF7Nef3y0EbBeqmGZgeN/BxHX29Rs39djAfaFalmQ89SE6CWyDCHzGL0yt/ycBtNOmGTW0FyGWNw==
dependencies:
archiver-utils "^2.1.0"
async "^3.2.4"
buffer-crc32 "^0.2.1"
readable-stream "^3.6.0"
readdir-glob "^1.1.2"
tar-stream "^2.2.0"
zip-stream "^4.1.0"
argparse@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
aria-query@5.1.3:
version "5.1.3"
resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.1.3.tgz#19db27cd101152773631396f7a95a3b58c22c35e"
integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==
dependencies:
deep-equal "^2.0.5"
aria-query@5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e"
integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==
dependencies:
dequal "^2.0.3"
array-buffer-byte-length@^1.0.0, array-buffer-byte-length@^1.0.1, array-buffer-byte-length@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz#384d12a37295aec3769ab022ad323a18a51ccf8b"
integrity sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==
dependencies:
call-bound "^1.0.3"
is-array-buffer "^3.0.5"
array-includes@^3.1.9:
version "3.1.9"
resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.9.tgz#1f0ccaa08e90cdbc3eb433210f903ad0f17c3f3a"
integrity sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==
dependencies:
call-bind "^1.0.8"
call-bound "^1.0.4"
define-properties "^1.2.1"
es-abstract "^1.24.0"
es-object-atoms "^1.1.1"
get-intrinsic "^1.3.0"
is-string "^1.1.1"
math-intrinsics "^1.1.0"
array-union@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d"
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
array.prototype.findlastindex@^1.2.6:
version "1.2.6"
resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz#cfa1065c81dcb64e34557c9b81d012f6a421c564"
integrity sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==
dependencies:
call-bind "^1.0.8"
call-bound "^1.0.4"
define-properties "^1.2.1"
es-abstract "^1.23.9"
es-errors "^1.3.0"
es-object-atoms "^1.1.1"
es-shim-unscopables "^1.1.0"
array.prototype.flat@^1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz#534aaf9e6e8dd79fb6b9a9917f839ef1ec63afe5"
integrity sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==
dependencies:
call-bind "^1.0.8"
define-properties "^1.2.1"
es-abstract "^1.23.5"
es-shim-unscopables "^1.0.2"
array.prototype.flatmap@^1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz#712cc792ae70370ae40586264629e33aab5dd38b"
integrity sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==
dependencies:
call-bind "^1.0.8"
define-properties "^1.2.1"
es-abstract "^1.23.5"
es-shim-unscopables "^1.0.2"
arraybuffer.prototype.slice@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz#9d760d84dbdd06d0cbf92c8849615a1a7ab3183c"
integrity sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==
dependencies:
array-buffer-byte-length "^1.0.1"
call-bind "^1.0.8"
define-properties "^1.2.1"
es-abstract "^1.23.5"
es-errors "^1.3.0"
get-intrinsic "^1.2.6"
is-array-buffer "^3.0.4"
assertion-error@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b"
integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==
assertion-error@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-2.0.1.tgz#f641a196b335690b1070bf00b6e7593fec190bf7"
integrity sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==
ast-types@^0.13.4:
version "0.13.4"
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.4.tgz#ee0d77b343263965ecc3fb62da16e7222b2b6782"
integrity sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==
dependencies:
tslib "^2.0.1"
astral-regex@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31"
integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
async-function@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/async-function/-/async-function-1.0.0.tgz#509c9fca60eaf85034c6829838188e4e4c8ffb2b"
integrity sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==
async@^3.2.3, async@^3.2.4:
version "3.2.6"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce"
integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
autoprefixer@10.4.21:
version "10.4.21"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.21.tgz#77189468e7a8ad1d9a37fbc08efc9f480cf0a95d"
integrity sha512-O+A6LWV5LDHSJD3LjHYoNi4VLsj/Whi7k6zG12xTYaU4cQ8oxQGckXNX8cRHK5yOZ/ppVHe0ZBXGzSV9jXdVbQ==
dependencies:
browserslist "^4.24.4"
caniuse-lite "^1.0.30001702"
fraction.js "^4.3.7"
normalize-range "^0.1.2"
picocolors "^1.1.1"
postcss-value-parser "^4.2.0"
available-typed-arrays@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846"
integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==
dependencies:
possible-typed-array-names "^1.0.0"
axe-core@^4.9.1:
version "4.10.3"
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.10.3.tgz#04145965ac7894faddbac30861e5d8f11bfd14fc"
integrity sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==
axios@^1.7.4:
version "1.8.4"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.8.4.tgz#78990bb4bc63d2cae072952d374835950a82f447"
integrity sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==
dependencies:
follow-redirects "^1.15.6"
form-data "^4.0.0"
proxy-from-env "^1.1.0"
babel-plugin-lodash@3.3.4:
version "3.3.4"
resolved "https://registry.yarnpkg.com/babel-plugin-lodash/-/babel-plugin-lodash-3.3.4.tgz#4f6844358a1340baed182adbeffa8df9967bc196"
integrity sha512-yDZLjK7TCkWl1gpBeBGmuaDIFhZKmkoL+Cu2MUUjv5VxUZx/z7tBGBCBcQs5RI1Bkz5LLmNdjx7paOyQtMovyg==
dependencies:
"@babel/helper-module-imports" "^7.0.0-beta.49"
"@babel/types" "^7.0.0-beta.49"
glob "^7.1.1"
lodash "^4.17.10"
require-package-name "^2.0.1"
babel-plugin-polyfill-corejs2@^0.4.14:
version "0.4.14"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz#8101b82b769c568835611542488d463395c2ef8f"
integrity sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==
dependencies:
"@babel/compat-data" "^7.27.7"
"@babel/helper-define-polyfill-provider" "^0.6.5"
semver "^6.3.1"
babel-plugin-polyfill-corejs3@^0.13.0:
version "0.13.0"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz#bb7f6aeef7addff17f7602a08a6d19a128c30164"
integrity sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A==
dependencies:
"@babel/helper-define-polyfill-provider" "^0.6.5"
core-js-compat "^3.43.0"
babel-plugin-polyfill-regenerator@^0.6.5:
version "0.6.5"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz#32752e38ab6f6767b92650347bf26a31b16ae8c5"
integrity sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==
dependencies:
"@babel/helper-define-polyfill-provider" "^0.6.5"
balanced-match@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
balanced-match@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-2.0.0.tgz#dc70f920d78db8b858535795867bf48f820633d9"
integrity sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==
base64-js@^1.3.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
basic-ftp@^5.0.2:
version "5.0.5"
resolved "https://registry.yarnpkg.com/basic-ftp/-/basic-ftp-5.0.5.tgz#14a474f5fffecca1f4f406f1c26b18f800225ac0"
integrity sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==
binary-extensions@^2.0.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
birpc@^2.3.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/birpc/-/birpc-2.4.0.tgz#045368a4a30d659c6c06c9215b11cb384903249c"
integrity sha512-5IdNxTyhXHv2UlgnPHQ0h+5ypVmkrYHzL8QT+DwFZ//2N/oNV8Ch+BCRmTJ3x6/z9Axo/cXYBc9eprsUVK/Jsg==
+birpc@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/birpc/-/birpc-4.0.0.tgz#cceef485926b93496735201896d86c3a182ad30f"
+ integrity sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw==
+
bl@^4.0.3, bl@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==
dependencies:
buffer "^5.5.0"
inherits "^2.0.4"
readable-stream "^3.4.0"
body-parser@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-2.2.0.tgz#f7a9656de305249a715b549b7b8fd1ab9dfddcfa"
integrity sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==
dependencies:
bytes "^3.1.2"
content-type "^1.0.5"
debug "^4.4.0"
http-errors "^2.0.0"
iconv-lite "^0.6.3"
on-finished "^2.4.1"
qs "^6.14.0"
raw-body "^3.0.0"
type-is "^2.0.0"
body-scroll-lock@3.1.5:
version "3.1.5"
resolved "https://registry.yarnpkg.com/body-scroll-lock/-/body-scroll-lock-3.1.5.tgz#c1392d9217ed2c3e237fee1e910f6cdd80b7aaec"
integrity sha512-Yi1Xaml0EvNA0OYWxXiYNqY24AfWkbA6w5vxE7GWxtKfzIbZM+Qw+aSmkgsbWzbHiy/RCSkUZBplVxTA+E4jJg==
boolbase@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==
boxen@5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50"
integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==
dependencies:
ansi-align "^3.0.0"
camelcase "^6.2.0"
chalk "^4.1.0"
cli-boxes "^2.2.1"
string-width "^4.2.2"
type-fest "^0.20.2"
widest-line "^3.1.0"
wrap-ansi "^7.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"
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
brace-expansion@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
dependencies:
balanced-match "^1.0.0"
braces@^3.0.3, braces@~3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
dependencies:
fill-range "^7.1.1"
browser-stdout@1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
browserslist@^4.24.0:
version "4.25.3"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.25.3.tgz#9167c9cbb40473f15f75f85189290678b99b16c5"
integrity sha512-cDGv1kkDI4/0e5yON9yM5G/0A5u8sf5TnmdX5C9qHzI9PPu++sQ9zjm1k9NiOrf3riY4OkK0zSGqfvJyJsgCBQ==
dependencies:
caniuse-lite "^1.0.30001735"
electron-to-chromium "^1.5.204"
node-releases "^2.0.19"
update-browserslist-db "^1.1.3"
browserslist@^4.24.4:
version "4.24.4"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.4.tgz#c6b2865a3f08bcb860a0e827389003b9fe686e4b"
integrity sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==
dependencies:
caniuse-lite "^1.0.30001688"
electron-to-chromium "^1.5.73"
node-releases "^2.0.19"
update-browserslist-db "^1.1.1"
browserslist@^4.25.1:
version "4.25.1"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.25.1.tgz#ba9e8e6f298a1d86f829c9b975e07948967bb111"
integrity sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==
dependencies:
caniuse-lite "^1.0.30001726"
electron-to-chromium "^1.5.173"
node-releases "^2.0.19"
update-browserslist-db "^1.1.3"
buffer-crc32@^0.2.1, buffer-crc32@^0.2.13, buffer-crc32@~0.2.3:
version "0.2.13"
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==
buffer-from@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
buffer@^5.5.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0"
integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==
dependencies:
base64-js "^1.3.1"
ieee754 "^1.1.13"
bytes@3.1.2, bytes@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
cac@^6.7.14:
version "6.7.14"
resolved "https://registry.yarnpkg.com/cac/-/cac-6.7.14.tgz#804e1e6f506ee363cb0e3ccbb09cad5dd9870959"
integrity sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==
+cac@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/cac/-/cac-7.0.0.tgz#7dda83da2268f75f840ab89ac3bcc36c120a78da"
+ integrity sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==
+
cacheable@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/cacheable/-/cacheable-2.0.3.tgz#27d490121907166b152cda2d31fdafd41611365e"
integrity sha512-nZF80J3d8RMrroMSYm1E9pBllVDXWPuECZgEZxH+vusCY4MAXAJVrY0jutcHSgh3xYX3G2EUNnmtWGZVVjWCXw==
dependencies:
"@cacheable/memoize" "^2.0.3"
"@cacheable/memory" "^2.0.3"
"@cacheable/utils" "^2.0.3"
hookified "^1.12.1"
keyv "^5.5.3"
call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6"
integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==
dependencies:
es-errors "^1.3.0"
function-bind "^1.1.2"
call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.7, call-bind@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c"
integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==
dependencies:
call-bind-apply-helpers "^1.0.0"
es-define-property "^1.0.0"
get-intrinsic "^1.2.4"
set-function-length "^1.2.2"
call-bound@^1.0.2, call-bound@^1.0.3, call-bound@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a"
integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==
dependencies:
call-bind-apply-helpers "^1.0.2"
get-intrinsic "^1.3.0"
callsites@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
camelcase@^5.0.0:
version "5.3.1"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
camelcase@^6.0.0, camelcase@^6.2.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
caniuse-lite@^1.0.30001688, caniuse-lite@^1.0.30001735:
version "1.0.30001737"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001737.tgz#8292bb7591932ff09e9a765f12fdf5629a241ccc"
integrity sha512-BiloLiXtQNrY5UyF0+1nSJLXUENuhka2pzy2Fx5pGxqavdrxSCW4U6Pn/PoG3Efspi2frRbHpBV2XsrPE6EDlw==
caniuse-lite@^1.0.30001702:
version "1.0.30001707"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001707.tgz#c5e104d199e6f4355a898fcd995a066c7eb9bf41"
integrity sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==
caniuse-lite@^1.0.30001726:
version "1.0.30001727"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz#22e9706422ad37aa50556af8c10e40e2d93a8b85"
integrity sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==
chai-nightwatch@^0.5.3:
version "0.5.3"
resolved "https://registry.yarnpkg.com/chai-nightwatch/-/chai-nightwatch-0.5.3.tgz#980ecf63dde5a04e7f3524370682c7ff01178ffb"
integrity sha512-38ixH/mqpY6IwnZkz6xPqx8aB5/KVR+j6VPugcir3EGOsphnWXrPH/mUt8Jp+ninL6ghY0AaJDQ10hSfCPGy/g==
dependencies:
assertion-error "1.1.0"
chai@5.3.3:
version "5.3.3"
resolved "https://registry.yarnpkg.com/chai/-/chai-5.3.3.tgz#dd3da955e270916a4bd3f625f4b919996ada7e06"
integrity sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==
dependencies:
assertion-error "^2.0.1"
check-error "^2.1.1"
deep-eql "^5.0.1"
loupe "^3.1.0"
pathval "^2.0.0"
chai@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/chai/-/chai-5.2.0.tgz#1358ee106763624114addf84ab02697e411c9c05"
integrity sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==
dependencies:
assertion-error "^2.0.1"
check-error "^2.1.1"
deep-eql "^5.0.1"
loupe "^3.1.0"
pathval "^2.0.0"
chalk@2.4.2, chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
dependencies:
ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chalk@5.6.2:
version "5.6.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.6.2.tgz#b1238b6e23ea337af71c7f8a295db5af0c158aea"
integrity sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==
chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
check-error@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82"
integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==
check-error@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/check-error/-/check-error-2.1.1.tgz#87eb876ae71ee388fa0471fe423f494be1d96ccc"
integrity sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==
chokidar@3.5.3:
version "3.5.3"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd"
integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==
dependencies:
anymatch "~3.1.2"
braces "~3.0.2"
glob-parent "~5.1.2"
is-binary-path "~2.1.0"
is-glob "~4.0.1"
normalize-path "~3.0.0"
readdirp "~3.6.0"
optionalDependencies:
fsevents "~2.3.2"
-chokidar@^4.0.0:
- version "4.0.3"
- resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30"
- integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==
+chokidar@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-5.0.0.tgz#949c126a9238a80792be9a0265934f098af369a5"
+ integrity sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==
dependencies:
- readdirp "^4.0.1"
+ readdirp "^5.0.0"
chromatism@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/chromatism/-/chromatism-3.0.0.tgz#a7249d353c1e4f3577e444ac41171c4e2e624b12"
integrity sha512-slVGC45odKFB6KzD/hpXP8XgS/Y+x72X1ckAhxU/9YZecCy8VwCJUSZsn0O4gQUwaTogun6IfrSiK3YuQaADFw==
chromedriver@135.0.4:
version "135.0.4"
resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-135.0.4.tgz#d70a0e51863e9b5a140358f811214a79d8b20d5c"
integrity sha512-x0DESUcvCfKydljOCTQUve6f0+78Vq71FHcAMmdzBoWzAnyzB+2Fd2PouGRoJJkqk/vgfNzCiuwFosT0hnIjEg==
dependencies:
"@testim/chrome-version" "^1.1.4"
axios "^1.7.4"
compare-versions "^6.1.0"
extract-zip "^2.0.1"
proxy-agent "^6.4.0"
proxy-from-env "^1.1.0"
tcp-port-used "^1.0.2"
ci-info@3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.0.tgz#b4ed1fb6818dea4803a55c623041f9165d2066b2"
integrity sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==
cli-boxes@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f"
integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==
cli-cursor@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307"
integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==
dependencies:
restore-cursor "^3.1.0"
cli-spinners@^2.5.0:
version "2.9.2"
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41"
integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==
cli-table3@^0.6.3:
version "0.6.5"
resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.5.tgz#013b91351762739c16a9567c21a04632e449bf2f"
integrity sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==
dependencies:
string-width "^4.2.0"
optionalDependencies:
"@colors/colors" "1.5.0"
cli-width@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5"
integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==
click-outside-vue3@4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/click-outside-vue3/-/click-outside-vue3-4.0.1.tgz#81a6ac01696b301764b42db6fdbdf28e7cd8ef95"
integrity sha512-sbplNecrup5oGqA3o4bo8XmvHRT6q9fvw21Z67aDbTqB9M6LF7CuYLTlLvNtOgKU6W3zst5H5zJuEh4auqA34g==
cliui@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1"
integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==
dependencies:
string-width "^4.2.0"
strip-ansi "^6.0.0"
wrap-ansi "^6.2.0"
cliui@^7.0.2:
version "7.0.4"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
dependencies:
string-width "^4.2.0"
strip-ansi "^6.0.0"
wrap-ansi "^7.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"
clone-deep@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387"
integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==
dependencies:
is-plain-object "^2.0.4"
kind-of "^6.0.2"
shallow-clone "^3.0.0"
clone@^1.0.2:
version "1.0.4"
resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e"
integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==
color-convert@^1.9.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
dependencies:
color-name "1.1.3"
color-convert@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
dependencies:
color-name "~1.1.4"
color-name@1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
color-name@~1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
colord@^2.9.3:
version "2.9.3"
resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43"
integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==
+colorjs.io@^0.5.0:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/colorjs.io/-/colorjs.io-0.5.2.tgz#63b20139b007591ebc3359932bef84628eb3fcef"
+ integrity sha512-twmVoizEW7ylZSN32OgKdXRmo1qg+wT5/6C3xu5b9QsWzSFAhHLn2xd8ro0diCsKfCj1RdaTP/nrcW+vAoQPIw==
+
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
delayed-stream "~1.0.0"
commander@^10.0.0:
version "10.0.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06"
integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==
commondir@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==
compare-versions@^6.1.0:
version "6.1.1"
resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-6.1.1.tgz#7af3cc1099ba37d244b3145a9af5201b629148a9"
integrity sha512-4hm4VPpIecmlg59CHXnRDnqGplJFrbLG4aFEl5vl6cK1u76ws3LLvX7ikFnTDl5vo39sjWD6AaDPYodJp/NNHg==
compress-commons@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-4.1.2.tgz#6542e59cb63e1f46a8b21b0e06f9a32e4c8b06df"
integrity sha512-D3uMHtGc/fcO1Gt1/L7i1e33VOvD4A9hfQLP+6ewd+BvG/gQ84Yh4oftEhAdjSMgBgwGL+jsppT7JYNpo6MHHg==
dependencies:
buffer-crc32 "^0.2.13"
crc32-stream "^4.0.2"
normalize-path "^3.0.0"
readable-stream "^3.6.0"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
+confbox@^0.1.8:
+ version "0.1.8"
+ resolved "https://registry.yarnpkg.com/confbox/-/confbox-0.1.8.tgz#820d73d3b3c82d9bd910652c5d4d599ef8ff8b06"
+ integrity sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==
+
config-chain@^1.1.13:
version "1.1.13"
resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4"
integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==
dependencies:
ini "^1.3.4"
proto-list "~1.2.1"
connect-history-api-fallback@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8"
integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==
content-disposition@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-1.0.0.tgz#844426cb398f934caefcbb172200126bc7ceace2"
integrity sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==
dependencies:
safe-buffer "5.2.1"
content-type@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
convert-source-map@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a"
integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==
+cookie-es@^1.2.3:
+ version "1.2.3"
+ resolved "https://registry.yarnpkg.com/cookie-es/-/cookie-es-1.2.3.tgz#06ca3c5f5f3531684a2059666a361173f74a89c8"
+ integrity sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==
+
cookie-signature@^1.2.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.2.2.tgz#57c7fc3cc293acab9fec54d73e15690ebe4a1793"
integrity sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==
cookie@^0.7.1, cookie@^0.7.2:
version "0.7.2"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7"
integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==
copy-anything@^3.0.2:
version "3.0.5"
resolved "https://registry.yarnpkg.com/copy-anything/-/copy-anything-3.0.5.tgz#2d92dce8c498f790fa7ad16b01a1ae5a45b020a0"
integrity sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==
dependencies:
is-what "^4.1.8"
core-js-compat@^3.43.0:
version "3.44.0"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.44.0.tgz#62b9165b97e4cbdb8bca16b14818e67428b4a0f8"
integrity sha512-JepmAj2zfl6ogy34qfWtcE7nHKAJnKsQFRn++scjVS2bZFllwptzw61BZcZFYBPpUznLfAvh0LGhxKppk04ClA==
dependencies:
browserslist "^4.25.1"
core-util-is@~1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
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"
crc-32@^1.2.0:
version "1.2.2"
resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff"
integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==
crc32-stream@^4.0.2:
version "4.0.3"
resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-4.0.3.tgz#85dd677eb78fa7cad1ba17cc506a597d41fc6f33"
integrity sha512-NT7w2JVU7DFroFdYkeq8cywxrgjPHWkdX1wjpRQXPX5Asews3tA+Ght6lddQO5Mkumffp3X7GEqku3epj2toIw==
dependencies:
crc-32 "^1.2.0"
readable-stream "^3.4.0"
cropperjs@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/cropperjs/-/cropperjs-2.0.1.tgz#74492df8cf54563691605d1510679b242c7f6d39"
integrity sha512-hiJwk2SCPZqxMA7aR3byzLpYUqOrQo+ihMk8k/WRm/xe/LX8wNzAIzMwEB/NEGJYA6sbewxW9TUlrRUYi/2Ipg==
dependencies:
"@cropper/elements" "^2.0.1"
"@cropper/utils" "^2.0.1"
cross-spawn@7.0.6, cross-spawn@^7.0.3, cross-spawn@^7.0.6:
version "7.0.6"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
dependencies:
path-key "^3.1.0"
shebang-command "^2.0.0"
which "^2.0.1"
+crossws@^0.3.5:
+ version "0.3.5"
+ resolved "https://registry.yarnpkg.com/crossws/-/crossws-0.3.5.tgz#daad331d44148ea6500098bc858869f3a5ab81a6"
+ integrity sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==
+ dependencies:
+ uncrypto "^0.1.3"
+
css-functions-list@^3.2.3:
version "3.2.3"
resolved "https://registry.yarnpkg.com/css-functions-list/-/css-functions-list-3.2.3.tgz#95652b0c24f0f59b291a9fc386041a19d4f40dbe"
integrity sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA==
css-tree@^3.0.1, css-tree@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-3.1.0.tgz#7aabc035f4e66b5c86f54570d55e05b1346eb0fd"
integrity sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==
dependencies:
mdn-data "2.12.2"
source-map-js "^1.0.1"
cssesc@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
cssstyle@^4.0.1:
version "4.3.0"
resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-4.3.0.tgz#83db22d1aec8eb7e5ecd812b4d14a17fb3dd243d"
integrity sha512-6r0NiY0xizYqfBvWp1G7WXJ06/bZyrk7Dc6PHql82C/pKGUTKu4yAX4Y8JPamb1ob9nBKuxWzCGTRuGwU3yxJQ==
dependencies:
"@asamuzakjp/css-color" "^3.1.1"
rrweb-cssom "^0.8.0"
csstype@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
+csstype@^3.2.3:
+ version "3.2.3"
+ resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.2.3.tgz#ec48c0f3e993e50648c86da559e2610995cf989a"
+ integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==
+
custom-event-polyfill@1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/custom-event-polyfill/-/custom-event-polyfill-1.0.7.tgz#9bc993ddda937c1a30ccd335614c6c58c4f87aee"
integrity sha512-TDDkd5DkaZxZFM8p+1I3yAlvM3rSr1wbrOliG4yJiwinMZN8z/iGL7BTlDkrJcYTmgUSb4ywVCc3ZaUtOtC76w==
+d3-path@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.1.0.tgz#22df939032fb5a71ae8b1800d61ddb7851c42526"
+ integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==
+
+d3-shape@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.2.0.tgz#a1a839cbd9ba45f28674c69d7f855bcf91dfc6a5"
+ integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==
+ dependencies:
+ d3-path "^3.1.0"
+
data-uri-to-buffer@^6.0.2:
version "6.0.2"
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz#8a58bb67384b261a38ef18bea1810cb01badd28b"
integrity sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==
data-urls@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-5.0.0.tgz#2f76906bce1824429ffecb6920f45a0b30f00dde"
integrity sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==
dependencies:
whatwg-mimetype "^4.0.0"
whatwg-url "^14.0.0"
data-view-buffer@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/data-view-buffer/-/data-view-buffer-1.0.2.tgz#211a03ba95ecaf7798a8c7198d79536211f88570"
integrity sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==
dependencies:
call-bound "^1.0.3"
es-errors "^1.3.0"
is-data-view "^1.0.2"
data-view-byte-length@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz#9e80f7ca52453ce3e93d25a35318767ea7704735"
integrity sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==
dependencies:
call-bound "^1.0.3"
es-errors "^1.3.0"
is-data-view "^1.0.2"
data-view-byte-offset@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz#068307f9b71ab76dbbe10291389e020856606191"
integrity sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==
dependencies:
call-bound "^1.0.2"
es-errors "^1.3.0"
is-data-view "^1.0.1"
debug@4, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@^4.3.6, debug@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a"
integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==
dependencies:
ms "^2.1.3"
debug@4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
dependencies:
ms "2.1.2"
debug@4.3.4:
version "4.3.4"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
ms "2.1.2"
debug@^3.2.7:
version "3.2.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
dependencies:
ms "^2.1.1"
debug@^4.1.0, debug@^4.3.1, debug@^4.4.1:
version "4.4.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b"
integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==
dependencies:
ms "^2.1.3"
debug@^4.4.3:
version "4.4.3"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a"
integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==
dependencies:
ms "^2.1.3"
decamelize@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==
decamelize@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837"
integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==
decimal.js@^10.4.3:
version "10.5.0"
resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.5.0.tgz#0f371c7cf6c4898ce0afb09836db73cd82010f22"
integrity sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==
deep-eql@4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.0.1.tgz#2b65bc89491d193780c452edee2144a91bb0a445"
integrity sha512-D/Oxqobjr+kxaHsgiQBZq9b6iAWdEj5W/JdJm8deNduAPc9CwXQ3BJJCuEqlrPXcy45iOMkGPZ0T81Dnz7UDCA==
dependencies:
type-detect "^4.0.0"
deep-eql@^5.0.1:
version "5.0.2"
resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-5.0.2.tgz#4b756d8d770a9257300825d52a2c2cff99c3a341"
integrity sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==
deep-equal@^2.0.5:
version "2.2.3"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.3.tgz#af89dafb23a396c7da3e862abc0be27cf51d56e1"
integrity sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==
dependencies:
array-buffer-byte-length "^1.0.0"
call-bind "^1.0.5"
es-get-iterator "^1.1.3"
get-intrinsic "^1.2.2"
is-arguments "^1.1.1"
is-array-buffer "^3.0.2"
is-date-object "^1.0.5"
is-regex "^1.1.4"
is-shared-array-buffer "^1.0.2"
isarray "^2.0.5"
object-is "^1.1.5"
object-keys "^1.1.1"
object.assign "^4.1.4"
regexp.prototype.flags "^1.5.1"
side-channel "^1.0.4"
which-boxed-primitive "^1.0.2"
which-collection "^1.0.1"
which-typed-array "^1.1.13"
deep-is@^0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
defaults@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a"
integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==
dependencies:
clone "^1.0.2"
define-data-property@^1.0.1, define-data-property@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
dependencies:
es-define-property "^1.0.0"
es-errors "^1.3.0"
gopd "^1.0.1"
define-lazy-prop@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f"
integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==
define-properties@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c"
integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==
dependencies:
define-data-property "^1.0.1"
has-property-descriptors "^1.0.0"
object-keys "^1.1.1"
+defu@^6.1.4, defu@^6.1.6:
+ version "6.1.7"
+ resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.7.tgz#72543567c8e9f97ff13ce402b6dbe09ac5ae4d23"
+ integrity sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==
+
degenerator@^5.0.0:
version "5.0.1"
resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-5.0.1.tgz#9403bf297c6dad9a1ece409b37db27954f91f2f5"
integrity sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==
dependencies:
ast-types "^0.13.4"
escodegen "^2.1.0"
esprima "^4.0.1"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
depd@2.0.0, depd@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
dequal@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be"
integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==
-detect-libc@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
- integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==
+destr@^2.0.5:
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/destr/-/destr-2.0.5.tgz#7d112ff1b925fb8d2079fac5bdb4a90973b51fdb"
+ integrity sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==
+
+detect-libc@^2.0.3:
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.2.tgz#689c5dcdc1900ef5583a4cb9f6d7b473742074ad"
+ integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==
+
+devframe@^0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/devframe/-/devframe-0.5.2.tgz#bc709c0d780f98593081c8053da346f79d700f9a"
+ integrity sha512-8dIdlOmuY+6NcCsaI2qS0uRLTZ3SvpejY8OYVbXvdWSQV7pvjdWaYNZhVfOfCSd/a5dSCgSge4vW4DCyJSf7+g==
+ dependencies:
+ "@valibot/to-json-schema" "^1.7.0"
+ birpc "^4.0.0"
+ cac "^7.0.0"
+ h3 "2.0.1-rc.22"
+ mrmime "^2.0.1"
+ nostics "^0.2.0"
+ pathe "^2.0.3"
+ valibot "^1.4.1"
+ ws "^8.21.0"
devtools-protocol@^0.0.1140464:
version "0.0.1140464"
resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1140464.tgz#ee5bb78646008e0dd97724d7659588c80fdb08b6"
integrity sha512-I1jXnjpQh/6TBFyQ0A9dB2kXXk6DprpPFZoI8pUsxHtlNuOTQEdv9fUqYBsFtf8tOJCbdsZZyQrWeXu6GfK+Bw==
didyoumean@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==
diff@5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b"
integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==
diff@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-7.0.0.tgz#3fb34d387cd76d803f6eebea67b921dab0182a9a"
integrity sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==
+diff@^9.0.0:
+ version "9.0.0"
+ resolved "https://registry.yarnpkg.com/diff/-/diff-9.0.0.tgz#297c31cd7c280f13dfe335791ec2063bd4a73a6f"
+ integrity sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==
+
dijkstrajs@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.3.tgz#4c8dbdea1f0f6478bff94d9c49c784d623e4fc23"
integrity sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==
dir-glob@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f"
integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==
dependencies:
path-type "^4.0.0"
doctrine@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d"
integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==
dependencies:
esutils "^2.0.2"
dom-accessibility-api@^0.5.9:
version "0.5.16"
resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453"
integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==
dom-serializer@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53"
integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==
dependencies:
domelementtype "^2.3.0"
domhandler "^5.0.2"
entities "^4.2.0"
domelementtype@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
domhandler@^5.0.2, domhandler@^5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31"
integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
dependencies:
domelementtype "^2.3.0"
domutils@^3.0.1:
version "3.2.2"
resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.2.2.tgz#edbfe2b668b0c1d97c24baf0f1062b132221bc78"
integrity sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==
dependencies:
dom-serializer "^2.0.0"
domelementtype "^2.3.0"
domhandler "^5.0.3"
dotenv@16.3.1:
version "16.3.1"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e"
integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==
dunder-proto@^1.0.0, dunder-proto@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a"
integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==
dependencies:
call-bind-apply-helpers "^1.0.1"
es-errors "^1.3.0"
gopd "^1.2.0"
eastasianwidth@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
editorconfig@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/editorconfig/-/editorconfig-1.0.4.tgz#040c9a8e9a6c5288388b87c2db07028aa89f53a3"
integrity sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==
dependencies:
"@one-ini/wasm" "0.1.1"
commander "^10.0.0"
minimatch "9.0.1"
semver "^7.5.3"
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
ejs@^3.1.10:
version "3.1.10"
resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b"
integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==
dependencies:
jake "^10.8.5"
electron-to-chromium@^1.5.173:
version "1.5.191"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.191.tgz#8ae49a471447b1ceaf1d4d183a9000082f52363c"
integrity sha512-xcwe9ELcuxYLUFqZZxL19Z6HVKcvNkIwhbHUz7L3us6u12yR+7uY89dSl570f/IqNthx8dAw3tojG7i4Ni4tDA==
electron-to-chromium@^1.5.204, electron-to-chromium@^1.5.73:
version "1.5.208"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.208.tgz#609c29502fd7257b4d721e3446f3ae391a0ca1b3"
integrity sha512-ozZyibehoe7tOhNaf16lKmljVf+3npZcJIEbJRVftVsmAg5TeA1mGS9dVCZzOwr2xT7xK15V0p7+GZqSPgkuPg==
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==
emoji-regex@^9.2.2:
version "9.2.2"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
encodeurl@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58"
integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==
end-of-stream@^1.1.0, end-of-stream@^1.4.1:
version "1.4.4"
resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
dependencies:
once "^1.4.0"
enhanced-resolve@^5.17.1:
version "5.18.1"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz#728ab082f8b7b6836de51f1637aab5d3b9568faf"
integrity sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==
dependencies:
graceful-fs "^4.2.4"
tapable "^2.2.0"
entities@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
entities@^4.2.0, entities@^4.4.0, entities@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48"
integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==
+entities@^7.0.1:
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-7.0.1.tgz#26e8a88889db63417dcb9a1e79a3f1bc92b5976b"
+ integrity sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==
+
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==
envinfo@7.11.0:
version "7.11.0"
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.11.0.tgz#c3793f44284a55ff8c82faf1ffd91bc6478ea01f"
integrity sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg==
error-ex@^1.3.1:
version "1.3.2"
resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
dependencies:
is-arrayish "^0.2.1"
es-abstract@^1.23.2, es-abstract@^1.23.5, es-abstract@^1.23.9:
version "1.23.9"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.9.tgz#5b45994b7de78dada5c1bebf1379646b32b9d606"
integrity sha512-py07lI0wjxAC/DcfK1S6G7iANonniZwTISvdPzk9hzeH0IZIshbuuFxLIU96OyF89Yb9hiqWn8M/bY83KY5vzA==
dependencies:
array-buffer-byte-length "^1.0.2"
arraybuffer.prototype.slice "^1.0.4"
available-typed-arrays "^1.0.7"
call-bind "^1.0.8"
call-bound "^1.0.3"
data-view-buffer "^1.0.2"
data-view-byte-length "^1.0.2"
data-view-byte-offset "^1.0.1"
es-define-property "^1.0.1"
es-errors "^1.3.0"
es-object-atoms "^1.0.0"
es-set-tostringtag "^2.1.0"
es-to-primitive "^1.3.0"
function.prototype.name "^1.1.8"
get-intrinsic "^1.2.7"
get-proto "^1.0.0"
get-symbol-description "^1.1.0"
globalthis "^1.0.4"
gopd "^1.2.0"
has-property-descriptors "^1.0.2"
has-proto "^1.2.0"
has-symbols "^1.1.0"
hasown "^2.0.2"
internal-slot "^1.1.0"
is-array-buffer "^3.0.5"
is-callable "^1.2.7"
is-data-view "^1.0.2"
is-regex "^1.2.1"
is-shared-array-buffer "^1.0.4"
is-string "^1.1.1"
is-typed-array "^1.1.15"
is-weakref "^1.1.0"
math-intrinsics "^1.1.0"
object-inspect "^1.13.3"
object-keys "^1.1.1"
object.assign "^4.1.7"
own-keys "^1.0.1"
regexp.prototype.flags "^1.5.3"
safe-array-concat "^1.1.3"
safe-push-apply "^1.0.0"
safe-regex-test "^1.1.0"
set-proto "^1.0.0"
string.prototype.trim "^1.2.10"
string.prototype.trimend "^1.0.9"
string.prototype.trimstart "^1.0.8"
typed-array-buffer "^1.0.3"
typed-array-byte-length "^1.0.3"
typed-array-byte-offset "^1.0.4"
typed-array-length "^1.0.7"
unbox-primitive "^1.1.0"
which-typed-array "^1.1.18"
es-abstract@^1.24.0:
version "1.24.0"
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.24.0.tgz#c44732d2beb0acc1ed60df840869e3106e7af328"
integrity sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==
dependencies:
array-buffer-byte-length "^1.0.2"
arraybuffer.prototype.slice "^1.0.4"
available-typed-arrays "^1.0.7"
call-bind "^1.0.8"
call-bound "^1.0.4"
data-view-buffer "^1.0.2"
data-view-byte-length "^1.0.2"
data-view-byte-offset "^1.0.1"
es-define-property "^1.0.1"
es-errors "^1.3.0"
es-object-atoms "^1.1.1"
es-set-tostringtag "^2.1.0"
es-to-primitive "^1.3.0"
function.prototype.name "^1.1.8"
get-intrinsic "^1.3.0"
get-proto "^1.0.1"
get-symbol-description "^1.1.0"
globalthis "^1.0.4"
gopd "^1.2.0"
has-property-descriptors "^1.0.2"
has-proto "^1.2.0"
has-symbols "^1.1.0"
hasown "^2.0.2"
internal-slot "^1.1.0"
is-array-buffer "^3.0.5"
is-callable "^1.2.7"
is-data-view "^1.0.2"
is-negative-zero "^2.0.3"
is-regex "^1.2.1"
is-set "^2.0.3"
is-shared-array-buffer "^1.0.4"
is-string "^1.1.1"
is-typed-array "^1.1.15"
is-weakref "^1.1.1"
math-intrinsics "^1.1.0"
object-inspect "^1.13.4"
object-keys "^1.1.1"
object.assign "^4.1.7"
own-keys "^1.0.1"
regexp.prototype.flags "^1.5.4"
safe-array-concat "^1.1.3"
safe-push-apply "^1.0.0"
safe-regex-test "^1.1.0"
set-proto "^1.0.0"
stop-iteration-iterator "^1.1.0"
string.prototype.trim "^1.2.10"
string.prototype.trimend "^1.0.9"
string.prototype.trimstart "^1.0.8"
typed-array-buffer "^1.0.3"
typed-array-byte-length "^1.0.3"
typed-array-byte-offset "^1.0.4"
typed-array-length "^1.0.7"
unbox-primitive "^1.1.0"
which-typed-array "^1.1.19"
es-define-property@^1.0.0, es-define-property@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa"
integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==
es-errors@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
es-get-iterator@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6"
integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==
dependencies:
call-bind "^1.0.2"
get-intrinsic "^1.1.3"
has-symbols "^1.0.3"
is-arguments "^1.1.1"
is-map "^2.0.2"
is-set "^2.0.2"
is-string "^1.0.7"
isarray "^2.0.5"
stop-iteration-iterator "^1.0.0"
es-module-lexer@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz#9159601561880a85f2734560a9099b2c31e5372a"
integrity sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==
es-object-atoms@^1.0.0, es-object-atoms@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1"
integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==
dependencies:
es-errors "^1.3.0"
es-set-tostringtag@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz#f31dbbe0c183b00a6d26eb6325c810c0fd18bd4d"
integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==
dependencies:
es-errors "^1.3.0"
get-intrinsic "^1.2.6"
has-tostringtag "^1.0.2"
hasown "^2.0.2"
es-shim-unscopables@^1.0.2, es-shim-unscopables@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz#438df35520dac5d105f3943d927549ea3b00f4b5"
integrity sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==
dependencies:
hasown "^2.0.2"
es-to-primitive@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.3.0.tgz#96c89c82cc49fd8794a24835ba3e1ff87f214e18"
integrity sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==
dependencies:
is-callable "^1.2.7"
is-date-object "^1.0.5"
is-symbol "^1.0.4"
esbuild@^0.25.0:
version "0.25.11"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.11.tgz#0f31b82f335652580f75ef6897bba81962d9ae3d"
integrity sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==
optionalDependencies:
"@esbuild/aix-ppc64" "0.25.11"
"@esbuild/android-arm" "0.25.11"
"@esbuild/android-arm64" "0.25.11"
"@esbuild/android-x64" "0.25.11"
"@esbuild/darwin-arm64" "0.25.11"
"@esbuild/darwin-x64" "0.25.11"
"@esbuild/freebsd-arm64" "0.25.11"
"@esbuild/freebsd-x64" "0.25.11"
"@esbuild/linux-arm" "0.25.11"
"@esbuild/linux-arm64" "0.25.11"
"@esbuild/linux-ia32" "0.25.11"
"@esbuild/linux-loong64" "0.25.11"
"@esbuild/linux-mips64el" "0.25.11"
"@esbuild/linux-ppc64" "0.25.11"
"@esbuild/linux-riscv64" "0.25.11"
"@esbuild/linux-s390x" "0.25.11"
"@esbuild/linux-x64" "0.25.11"
"@esbuild/netbsd-arm64" "0.25.11"
"@esbuild/netbsd-x64" "0.25.11"
"@esbuild/openbsd-arm64" "0.25.11"
"@esbuild/openbsd-x64" "0.25.11"
"@esbuild/openharmony-arm64" "0.25.11"
"@esbuild/sunos-x64" "0.25.11"
"@esbuild/win32-arm64" "0.25.11"
"@esbuild/win32-ia32" "0.25.11"
"@esbuild/win32-x64" "0.25.11"
escalade@^3.1.1, escalade@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5"
integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==
escape-html@1.0.3, escape-html@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
escape-string-regexp@4.0.0, 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"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
escodegen@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17"
integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==
dependencies:
esprima "^4.0.1"
estraverse "^5.2.0"
esutils "^2.0.2"
optionalDependencies:
source-map "~0.6.1"
eslint-compat-utils@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz#7fc92b776d185a70c4070d03fd26fde3d59652e4"
integrity sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==
dependencies:
semver "^7.5.4"
eslint-config-standard@17.1.0:
version "17.1.0"
resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-17.1.0.tgz#40ffb8595d47a6b242e07cbfd49dc211ed128975"
integrity sha512-IwHwmaBNtDK4zDHQukFDW5u/aTb8+meQWZvNFWkiGmbWjD6bqyuSSBxxXKkCftCUzc1zwCH2m/baCNDLGmuO5Q==
eslint-formatter-friendly@7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/eslint-formatter-friendly/-/eslint-formatter-friendly-7.0.0.tgz#32a4998ababa0a39994aed629b831fda7dabc864"
integrity sha512-WXg2D5kMHcRxIZA3ulxdevi8/BGTXu72pfOO5vXHqcAfClfIWDSlOljROjCSOCcKvilgmHz1jDWbvFCZHjMQ5w==
dependencies:
"@babel/code-frame" "7.0.0"
chalk "2.4.2"
extend "3.0.2"
strip-ansi "5.2.0"
text-table "0.2.0"
eslint-import-resolver-node@^0.3.9:
version "0.3.9"
resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac"
integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==
dependencies:
debug "^3.2.7"
is-core-module "^2.13.0"
resolve "^1.22.4"
eslint-module-utils@^2.12.1:
version "2.12.1"
resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz#f76d3220bfb83c057651359295ab5854eaad75ff"
integrity sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==
dependencies:
debug "^3.2.7"
eslint-plugin-es-x@^7.8.0:
version "7.8.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz#a207aa08da37a7923f2a9599e6d3eb73f3f92b74"
integrity sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==
dependencies:
"@eslint-community/eslint-utils" "^4.1.2"
"@eslint-community/regexpp" "^4.11.0"
eslint-compat-utils "^0.5.1"
eslint-plugin-import@2.32.0:
version "2.32.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz#602b55faa6e4caeaa5e970c198b5c00a37708980"
integrity sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==
dependencies:
"@rtsao/scc" "^1.1.0"
array-includes "^3.1.9"
array.prototype.findlastindex "^1.2.6"
array.prototype.flat "^1.3.3"
array.prototype.flatmap "^1.3.3"
debug "^3.2.7"
doctrine "^2.1.0"
eslint-import-resolver-node "^0.3.9"
eslint-module-utils "^2.12.1"
hasown "^2.0.2"
is-core-module "^2.16.1"
is-glob "^4.0.3"
minimatch "^3.1.2"
object.fromentries "^2.0.8"
object.groupby "^1.0.3"
object.values "^1.2.1"
semver "^6.3.1"
string.prototype.trimend "^1.0.9"
tsconfig-paths "^3.15.0"
eslint-plugin-n@17.23.1:
version "17.23.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-n/-/eslint-plugin-n-17.23.1.tgz#467db2aba0ead574ea6150143d079d544c11cf48"
integrity sha512-68PealUpYoHOBh332JLLD9Sj7OQUDkFpmcfqt8R9sySfFSeuGJjMTJQvCRRB96zO3A/PELRLkPrzsHmzEFQQ5A==
dependencies:
"@eslint-community/eslint-utils" "^4.5.0"
enhanced-resolve "^5.17.1"
eslint-plugin-es-x "^7.8.0"
get-tsconfig "^4.8.1"
globals "^15.11.0"
globrex "^0.1.2"
ignore "^5.3.2"
semver "^7.6.3"
ts-declaration-location "^1.0.6"
eslint-plugin-promise@7.2.1:
version "7.2.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-7.2.1.tgz#a0652195700aea40b926dc3c74b38e373377bfb0"
integrity sha512-SWKjd+EuvWkYaS+uN2csvj0KoP43YTu7+phKQ5v+xw6+A0gutVX2yqCeCkC3uLCJFiPfR2dD8Es5L7yUsmvEaA==
dependencies:
"@eslint-community/eslint-utils" "^4.4.0"
eslint-plugin-vue@10.6.2:
version "10.6.2"
resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-10.6.2.tgz#5d8790fa2e1105cf06259afc14c8a55cb110f346"
integrity sha512-nA5yUs/B1KmKzvC42fyD0+l9Yd+LtEpVhWRbXuDj0e+ZURcTtyRbMDWUeJmTAh2wC6jC83raS63anNM2YT3NPw==
dependencies:
"@eslint-community/eslint-utils" "^4.4.0"
natural-compare "^1.4.0"
nth-check "^2.1.1"
postcss-selector-parser "^7.1.0"
semver "^7.6.3"
xml-name-validator "^4.0.0"
eslint-scope@5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
dependencies:
esrecurse "^4.3.0"
estraverse "^4.1.1"
eslint-scope@^8.2.0:
version "8.3.0"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.3.0.tgz#10cd3a918ffdd722f5f3f7b5b83db9b23c87340d"
integrity sha512-pUNxi75F8MJ/GdeKtVLSbYg4ZI34J6C0C7sbL4YOp2exGwen7ZsuBqKzUhXd0qMQ362yET3z+uPwKeg/0C2XCQ==
dependencies:
esrecurse "^4.3.0"
estraverse "^5.2.0"
eslint-scope@^8.4.0:
version "8.4.0"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.4.0.tgz#88e646a207fad61436ffa39eb505147200655c82"
integrity sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==
dependencies:
esrecurse "^4.3.0"
estraverse "^5.2.0"
eslint-visitor-keys@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303"
integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
eslint-visitor-keys@^3.4.3:
version "3.4.3"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800"
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
eslint-visitor-keys@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45"
integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==
eslint-visitor-keys@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz#4cfea60fe7dd0ad8e816e1ed026c1d5251b512c1"
integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==
eslint@9.39.2:
version "9.39.2"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.39.2.tgz#cb60e6d16ab234c0f8369a3fe7cc87967faf4b6c"
integrity sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==
dependencies:
"@eslint-community/eslint-utils" "^4.8.0"
"@eslint-community/regexpp" "^4.12.1"
"@eslint/config-array" "^0.21.1"
"@eslint/config-helpers" "^0.4.2"
"@eslint/core" "^0.17.0"
"@eslint/eslintrc" "^3.3.1"
"@eslint/js" "9.39.2"
"@eslint/plugin-kit" "^0.4.1"
"@humanfs/node" "^0.16.6"
"@humanwhocodes/module-importer" "^1.0.1"
"@humanwhocodes/retry" "^0.4.2"
"@types/estree" "^1.0.6"
ajv "^6.12.4"
chalk "^4.0.0"
cross-spawn "^7.0.6"
debug "^4.3.2"
escape-string-regexp "^4.0.0"
eslint-scope "^8.4.0"
eslint-visitor-keys "^4.2.1"
espree "^10.4.0"
esquery "^1.5.0"
esutils "^2.0.2"
fast-deep-equal "^3.1.3"
file-entry-cache "^8.0.0"
find-up "^5.0.0"
glob-parent "^6.0.2"
ignore "^5.2.0"
imurmurhash "^0.1.4"
is-glob "^4.0.0"
json-stable-stringify-without-jsonify "^1.0.1"
lodash.merge "^4.6.2"
minimatch "^3.1.2"
natural-compare "^1.4.0"
optionator "^0.9.3"
espree@^10.0.1, espree@^10.3.0:
version "10.3.0"
resolved "https://registry.yarnpkg.com/espree/-/espree-10.3.0.tgz#29267cf5b0cb98735b65e64ba07e0ed49d1eed8a"
integrity sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==
dependencies:
acorn "^8.14.0"
acorn-jsx "^5.3.2"
eslint-visitor-keys "^4.2.0"
espree@^10.4.0:
version "10.4.0"
resolved "https://registry.yarnpkg.com/espree/-/espree-10.4.0.tgz#d54f4949d4629005a1fa168d937c3ff1f7e2a837"
integrity sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==
dependencies:
acorn "^8.15.0"
acorn-jsx "^5.3.2"
eslint-visitor-keys "^4.2.1"
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==
esquery@^1.5.0, esquery@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7"
integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==
dependencies:
estraverse "^5.1.0"
esrecurse@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921"
integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==
dependencies:
estraverse "^5.2.0"
estraverse@^4.1.1:
version "4.3.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d"
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
estraverse@^5.1.0, estraverse@^5.2.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
estree-walker@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
estree-walker@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d"
integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==
dependencies:
"@types/estree" "^1.0.0"
esutils@^2.0.2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
etag@^1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
eventemitter3@^4.0.0:
version "4.0.7"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
eventsource-polyfill@0.9.6:
version "0.9.6"
resolved "https://registry.yarnpkg.com/eventsource-polyfill/-/eventsource-polyfill-0.9.6.tgz#10e0d187f111b167f28fdab918843ce7d818f13c"
integrity sha512-LyMFp2oPDGhum2lMvkjqKZEwWd2/AoXyt8aoyftTBMWwPHNgU+2tdxhTHPluDxoz+z4gNj0uHAPR9nqevATMbg==
execa@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
dependencies:
cross-spawn "^7.0.3"
get-stream "^6.0.0"
human-signals "^2.1.0"
is-stream "^2.0.0"
merge-stream "^2.0.0"
npm-run-path "^4.0.1"
onetime "^5.1.2"
signal-exit "^3.0.3"
strip-final-newline "^2.0.0"
expect-type@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/expect-type/-/expect-type-1.2.1.tgz#af76d8b357cf5fa76c41c09dafb79c549e75f71f"
integrity sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==
express@5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/express/-/express-5.1.0.tgz#d31beaf715a0016f0d53f47d3b4d7acf28c75cc9"
integrity sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==
dependencies:
accepts "^2.0.0"
body-parser "^2.2.0"
content-disposition "^1.0.0"
content-type "^1.0.5"
cookie "^0.7.1"
cookie-signature "^1.2.1"
debug "^4.4.0"
encodeurl "^2.0.0"
escape-html "^1.0.3"
etag "^1.8.1"
finalhandler "^2.1.0"
fresh "^2.0.0"
http-errors "^2.0.0"
merge-descriptors "^2.0.0"
mime-types "^3.0.0"
on-finished "^2.4.1"
once "^1.4.0"
parseurl "^1.3.3"
proxy-addr "^2.0.7"
qs "^6.14.0"
range-parser "^1.2.1"
router "^2.2.0"
send "^1.1.0"
serve-static "^2.2.0"
statuses "^2.0.1"
type-is "^2.0.1"
vary "^1.1.2"
extend@3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==
extract-zip@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-2.0.1.tgz#663dca56fe46df890d5f131ef4a06d22bb8ba13a"
integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==
dependencies:
debug "^4.1.1"
get-stream "^5.1.0"
yauzl "^2.10.0"
optionalDependencies:
"@types/yauzl" "^2.9.1"
fast-deep-equal@^3.1.1, 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"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
fast-glob@^3.2.9, fast-glob@^3.3.2, fast-glob@^3.3.3:
version "3.3.3"
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818"
integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==
dependencies:
"@nodelib/fs.stat" "^2.0.2"
"@nodelib/fs.walk" "^1.2.3"
glob-parent "^5.1.2"
merge2 "^1.3.0"
micromatch "^4.0.8"
fast-json-stable-stringify@^2.0.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-levenshtein@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==
fast-uri@^3.0.1:
version "3.0.6"
resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.6.tgz#88f130b77cfaea2378d56bf970dea21257a68748"
integrity sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==
fastest-levenshtein@^1.0.16:
version "1.0.16"
resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5"
integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==
fastq@^1.6.0:
version "1.19.1"
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.19.1.tgz#d50eaba803c8846a883c16492821ebcd2cda55f5"
integrity sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==
dependencies:
reusify "^1.0.4"
fd-slicer@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==
dependencies:
pend "~1.2.0"
fdir@^6.4.4, fdir@^6.5.0:
version "6.5.0"
resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.5.0.tgz#ed2ab967a331ade62f18d077dae192684d50d350"
integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==
fflate@^0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/fflate/-/fflate-0.8.2.tgz#fc8631f5347812ad6028bbe4a2308b2792aa1dea"
integrity sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==
file-entry-cache@^10.1.4:
version "10.1.4"
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-10.1.4.tgz#1e81441517dc33ba5fe14421d96dc5fe7e37e820"
integrity sha512-5XRUFc0WTtUbjfGzEwXc42tiGxQHBmtbUG1h9L2apu4SulCGN3Hqm//9D6FAolf8MYNL7f/YlJl9vy08pj5JuA==
dependencies:
flat-cache "^6.1.13"
file-entry-cache@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f"
integrity sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==
dependencies:
flat-cache "^4.0.0"
filelist@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5"
integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==
dependencies:
minimatch "^5.0.1"
fill-range@^7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
dependencies:
to-regex-range "^5.0.1"
finalhandler@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-2.1.0.tgz#72306373aa89d05a8242ed569ed86a1bff7c561f"
integrity sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==
dependencies:
debug "^4.4.0"
encodeurl "^2.0.0"
escape-html "^1.0.3"
on-finished "^2.4.1"
parseurl "^1.3.3"
statuses "^2.0.1"
find-cache-dir@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7"
integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==
dependencies:
commondir "^1.0.1"
make-dir "^2.0.0"
pkg-dir "^3.0.0"
find-up@5.0.0, find-up@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
dependencies:
locate-path "^6.0.0"
path-exists "^4.0.0"
find-up@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73"
integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==
dependencies:
locate-path "^3.0.0"
find-up@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
dependencies:
locate-path "^5.0.0"
path-exists "^4.0.0"
flat-cache@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c"
integrity sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==
dependencies:
flatted "^3.2.9"
keyv "^4.5.4"
flat-cache@^6.1.13:
version "6.1.17"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-6.1.17.tgz#31eb0de23c6a301c1420596d0089dd431649006d"
integrity sha512-Jzse4YoiUJBVYTwz5Bwl4h/2VQM7e2KK3MVAMlXzX9uamIHAH/TXUlRKU1AQGQOryQhN0EsmufiiF40G057YXA==
dependencies:
cacheable "^2.0.3"
flatted "^3.3.3"
hookified "^1.12.0"
flat@^5.0.2:
version "5.0.2"
resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241"
integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==
flatted@^3.2.9, flatted@^3.3.3:
version "3.3.3"
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.3.tgz#67c8fad95454a7c7abebf74bb78ee74a44023358"
integrity sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==
follow-redirects@^1.0.0, follow-redirects@^1.15.6:
version "1.15.9"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1"
integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==
for-each@^0.3.3, for-each@^0.3.5:
version "0.3.5"
resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.5.tgz#d650688027826920feeb0af747ee7b9421a41d47"
integrity sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==
dependencies:
is-callable "^1.2.7"
foreground-child@^3.1.0:
version "3.3.1"
resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.1.tgz#32e8e9ed1b68a3497befb9ac2b6adf92a638576f"
integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==
dependencies:
cross-spawn "^7.0.6"
signal-exit "^4.0.1"
form-data@^4.0.0:
version "4.0.2"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.2.tgz#35cabbdd30c3ce73deb2c42d3c8d3ed9ca51794c"
integrity sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
es-set-tostringtag "^2.1.0"
mime-types "^2.1.12"
forwarded@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
fraction.js@^4.3.7:
version "4.3.7"
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.3.7.tgz#06ca0085157e42fda7f9e726e79fefc4068840f7"
integrity sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==
fresh@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-2.0.0.tgz#8dd7df6a1b3a1b3a5cf186c05a5dd267622635a4"
integrity sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==
fs-constants@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
fsevents@2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
fsevents@~2.3.2, fsevents@~2.3.3:
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.2, function-bind@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
function.prototype.name@^1.1.6, function.prototype.name@^1.1.8:
version "1.1.8"
resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.8.tgz#e68e1df7b259a5c949eeef95cdbde53edffabb78"
integrity sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==
dependencies:
call-bind "^1.0.8"
call-bound "^1.0.3"
define-properties "^1.2.1"
functions-have-names "^1.2.3"
hasown "^2.0.2"
is-callable "^1.2.7"
functions-have-names@^1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
gensync@^1.0.0-beta.2:
version "1.0.0-beta.2"
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
get-caller-file@^2.0.1, 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-func-name@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41"
integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==
get-intrinsic@^1.1.3, get-intrinsic@^1.2.2, get-intrinsic@^1.2.4, get-intrinsic@^1.2.5, get-intrinsic@^1.2.6, get-intrinsic@^1.2.7, get-intrinsic@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01"
integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==
dependencies:
call-bind-apply-helpers "^1.0.2"
es-define-property "^1.0.1"
es-errors "^1.3.0"
es-object-atoms "^1.1.1"
function-bind "^1.1.2"
get-proto "^1.0.1"
gopd "^1.2.0"
has-symbols "^1.1.0"
hasown "^2.0.2"
math-intrinsics "^1.1.0"
+get-port-please@^3.2.0:
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/get-port-please/-/get-port-please-3.2.0.tgz#0ce3cee194c448ac640ec39dc357a500f5d7d2bb"
+ integrity sha512-I9QVvBw5U/hw3RmWpYKRumUeaDgxTPd401x364rLmWBJcOQ753eov1eTgzDqRG9bqFIfDc7gfzcQEWrUri3o1A==
+
get-proto@^1.0.0, get-proto@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1"
integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==
dependencies:
dunder-proto "^1.0.1"
es-object-atoms "^1.0.0"
get-stream@^5.1.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3"
integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==
dependencies:
pump "^3.0.0"
get-stream@^6.0.0:
version "6.0.1"
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
get-symbol-description@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.1.0.tgz#7bdd54e0befe8ffc9f3b4e203220d9f1e881b6ee"
integrity sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==
dependencies:
call-bound "^1.0.3"
es-errors "^1.3.0"
get-intrinsic "^1.2.6"
get-tsconfig@^4.8.1:
version "4.10.0"
resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.10.0.tgz#403a682b373a823612475a4c2928c7326fc0f6bb"
integrity sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A==
dependencies:
resolve-pkg-maps "^1.0.0"
get-uri@^6.0.1:
version "6.0.4"
resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-6.0.4.tgz#6daaee9e12f9759e19e55ba313956883ef50e0a7"
integrity sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==
dependencies:
basic-ftp "^5.0.2"
data-uri-to-buffer "^6.0.2"
debug "^4.3.4"
glob-parent@^5.1.2, glob-parent@~5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
dependencies:
is-glob "^4.0.1"
glob-parent@^6.0.2:
version "6.0.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
dependencies:
is-glob "^4.0.3"
glob@7.2.3, glob@^7.1.1, glob@^7.1.4, glob@^7.2.3:
version "7.2.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.1.1"
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e"
integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^5.0.1"
once "^1.3.0"
glob@^10.4.2:
version "10.4.5"
resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956"
integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==
dependencies:
foreground-child "^3.1.0"
jackspeak "^3.1.2"
minimatch "^9.0.4"
minipass "^7.1.2"
package-json-from-dist "^1.0.0"
path-scurry "^1.11.1"
global-modules@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780"
integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==
dependencies:
global-prefix "^3.0.0"
global-prefix@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97"
integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==
dependencies:
ini "^1.3.5"
kind-of "^6.0.2"
which "^1.3.1"
globals@^11.1.0:
version "11.12.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
globals@^14.0.0:
version "14.0.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e"
integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==
globals@^15.11.0:
version "15.15.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-15.15.0.tgz#7c4761299d41c32b075715a4ce1ede7897ff72a8"
integrity sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==
globals@^16.0.0:
version "16.4.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-16.4.0.tgz#574bc7e72993d40cf27cf6c241f324ee77808e51"
integrity sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==
globalthis@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236"
integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==
dependencies:
define-properties "^1.2.1"
gopd "^1.0.1"
globby@^11.1.0:
version "11.1.0"
resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b"
integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==
dependencies:
array-union "^2.1.0"
dir-glob "^3.0.1"
fast-glob "^3.2.9"
ignore "^5.2.0"
merge2 "^1.4.1"
slash "^3.0.0"
globjoin@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/globjoin/-/globjoin-0.1.4.tgz#2f4494ac8919e3767c5cbb691e9f463324285d43"
integrity sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==
globrex@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098"
integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==
gopd@^1.0.1, gopd@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1"
integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==
graceful-fs@^4.2.0, graceful-fs@^4.2.4:
version "4.2.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
graphql@^16.8.1:
version "16.10.0"
resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.10.0.tgz#24c01ae0af6b11ea87bf55694429198aaa8e220c"
integrity sha512-AjqGKbDGUFRKIRCP9tCKiIGHyriz2oHEbPIbEtcSLSs4YjReZOIPQQWek4+6hjw62H9QShXHyaGivGiYVLeYFQ==
+h3@2.0.1-rc.22:
+ version "2.0.1-rc.22"
+ resolved "https://registry.yarnpkg.com/h3/-/h3-2.0.1-rc.22.tgz#12c94d2f99e9afa42b490ebfda6163035e98be2a"
+ integrity sha512-Esv0DMIuPkCTSWCA0vO73vcTqwzH1wjSrAO1TXNu/K3up1sZHa9EKMapbmxCDYBeymC3fVTk4qxp7ogQWQ+KgA==
+ dependencies:
+ rou3 "^0.8.1"
+ srvx "^0.11.15"
+
+h3@^1.15.10:
+ version "1.15.11"
+ resolved "https://registry.yarnpkg.com/h3/-/h3-1.15.11.tgz#831179fc6b4bc06de8ad1077e7a5c7d63b796577"
+ integrity sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==
+ dependencies:
+ cookie-es "^1.2.3"
+ crossws "^0.3.5"
+ defu "^6.1.6"
+ destr "^2.0.5"
+ iron-webcrypto "^1.2.1"
+ node-mock-http "^1.0.4"
+ radix3 "^1.1.2"
+ ufo "^1.6.3"
+ uncrypto "^0.1.3"
+
has-bigints@^1.0.2:
version "1.1.0"
resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.1.0.tgz#28607e965ac967e03cd2a2c70a2636a1edad49fe"
integrity sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
has-flag@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854"
integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==
dependencies:
es-define-property "^1.0.0"
has-proto@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.2.0.tgz#5de5a6eabd95fdffd9818b43055e8065e39fe9d5"
integrity sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==
dependencies:
dunder-proto "^1.0.0"
has-symbols@^1.0.3, has-symbols@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338"
integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==
has-tostringtag@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc"
integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
dependencies:
has-symbols "^1.0.3"
hash-sum@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-2.0.0.tgz#81d01bb5de8ea4a214ad5d6ead1b523460b0b45a"
integrity sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==
hasown@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
dependencies:
function-bind "^1.1.2"
he@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
headers-polyfill@^4.0.2:
version "4.0.3"
resolved "https://registry.yarnpkg.com/headers-polyfill/-/headers-polyfill-4.0.3.tgz#922a0155de30ecc1f785bcf04be77844ca95ad07"
integrity sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==
hookable@^5.5.3:
version "5.5.3"
resolved "https://registry.yarnpkg.com/hookable/-/hookable-5.5.3.tgz#6cfc358984a1ef991e2518cb9ed4a778bbd3215d"
integrity sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==
hookified@^1.12.0, hookified@^1.12.1:
version "1.12.1"
resolved "https://registry.yarnpkg.com/hookified/-/hookified-1.12.1.tgz#b0de0116ca346fd6c4e55db901f52d5cd728ef00"
integrity sha512-xnKGl+iMIlhrZmGHB729MqlmPoWBznctSQTYCpFKqNsCgimJQmithcW0xSQMMFzYnV2iKUh25alswn6epgxS0Q==
html-encoding-sniffer@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz#696df529a7cfd82446369dc5193e590a3735b448"
integrity sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==
dependencies:
whatwg-encoding "^3.1.1"
html-tags@^3.3.1:
version "3.3.1"
resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce"
integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==
htmlparser2@^8.0.0:
version "8.0.2"
resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.2.tgz#f002151705b383e62433b5cf466f5b716edaec21"
integrity sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==
dependencies:
domelementtype "^2.3.0"
domhandler "^5.0.3"
domutils "^3.0.1"
entities "^4.4.0"
http-errors@2.0.0, http-errors@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==
dependencies:
depd "2.0.0"
inherits "2.0.4"
setprototypeof "1.2.0"
statuses "2.0.1"
toidentifier "1.0.1"
http-proxy-agent@^7.0.0, http-proxy-agent@^7.0.1, http-proxy-agent@^7.0.2:
version "7.0.2"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e"
integrity sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==
dependencies:
agent-base "^7.1.0"
debug "^4.3.4"
http-proxy-middleware@3.0.5:
version "3.0.5"
resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-3.0.5.tgz#9dcde663edc44079bc5a9c63e03fe5e5d6037fab"
integrity sha512-GLZZm1X38BPY4lkXA01jhwxvDoOkkXqjgVyUzVxiEK4iuRu03PZoYHhHRwxnfhQMDuaxi3vVri0YgSro/1oWqg==
dependencies:
"@types/http-proxy" "^1.17.15"
debug "^4.3.6"
http-proxy "^1.18.1"
is-glob "^4.0.3"
is-plain-object "^5.0.0"
micromatch "^4.0.8"
http-proxy@^1.18.1:
version "1.18.1"
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549"
integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==
dependencies:
eventemitter3 "^4.0.0"
follow-redirects "^1.0.0"
requires-port "^1.0.0"
https-proxy-agent@^7.0.5, https-proxy-agent@^7.0.6:
version "7.0.6"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz#da8dfeac7da130b05c2ba4b59c9b6cd66611a6b9"
integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==
dependencies:
agent-base "^7.1.2"
debug "4"
human-signals@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
iconv-lite@0.6.3, iconv-lite@^0.6.3:
version "0.6.3"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==
dependencies:
safer-buffer ">= 2.1.2 < 3.0.0"
ieee754@^1.1.13:
version "1.2.1"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
ignore@^5.2.0, ignore@^5.3.2:
version "5.3.2"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5"
integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==
ignore@^7.0.5:
version "7.0.5"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-7.0.5.tgz#4cb5f6cd7d4c7ab0365738c7aea888baa6d7efd9"
integrity sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==
immediate@~3.0.5:
version "3.0.6"
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==
-immutable@^5.0.2:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/immutable/-/immutable-5.1.1.tgz#d4cb552686f34b076b3dcf23c4384c04424d8354"
- integrity sha512-3jatXi9ObIsPGr3N5hGw/vWWcTkq6hUYhpQz4k0wLC+owqWi/LiugIw9x0EdNZ2yGedKN/HzePiBvaJRXa0Ujg==
+immutable@^5.1.5:
+ version "5.1.6"
+ resolved "https://registry.yarnpkg.com/immutable/-/immutable-5.1.6.tgz#21639bc80f9a0713e141a5f5a154ef9fdabf36dd"
+ integrity sha512-q1swsS8K7L8usSHuOqF2TAoCCkonYz0SG38wLAggaa4Wml70zixIvt2ql4coQ2C2B3hTjltJry4r6bULwgAXLQ==
import-fresh@^3.2.1, import-fresh@^3.3.0:
version "3.3.1"
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.1.tgz#9cecb56503c0ada1f2741dbbd6546e4b13b57ccf"
integrity sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==
dependencies:
parent-module "^1.0.0"
resolve-from "^4.0.0"
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==
dependencies:
once "^1.3.0"
wrappy "1"
inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
ini@^1.3.4, ini@^1.3.5:
version "1.3.8"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
internal-slot@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.1.0.tgz#1eac91762947d2f7056bc838d93e13b2e9604961"
integrity sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==
dependencies:
es-errors "^1.3.0"
hasown "^2.0.2"
side-channel "^1.1.0"
ip-address@^9.0.5:
version "9.0.5"
resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-9.0.5.tgz#117a960819b08780c3bd1f14ef3c1cc1d3f3ea5a"
integrity sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==
dependencies:
jsbn "1.1.0"
sprintf-js "^1.1.3"
ip-regex@^4.1.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-4.3.0.tgz#687275ab0f57fa76978ff8f4dddc8a23d5990db5"
integrity sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==
ipaddr.js@1.9.1:
version "1.9.1"
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
+iron-webcrypto@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz#aa60ff2aa10550630f4c0b11fd2442becdb35a6f"
+ integrity sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==
+
is-arguments@^1.1.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.2.0.tgz#ad58c6aecf563b78ef2bf04df540da8f5d7d8e1b"
integrity sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==
dependencies:
call-bound "^1.0.2"
has-tostringtag "^1.0.2"
is-array-buffer@^3.0.2, is-array-buffer@^3.0.4, is-array-buffer@^3.0.5:
version "3.0.5"
resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.5.tgz#65742e1e687bd2cc666253068fd8707fe4d44280"
integrity sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==
dependencies:
call-bind "^1.0.8"
call-bound "^1.0.3"
get-intrinsic "^1.2.6"
is-arrayish@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==
is-async-function@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-async-function/-/is-async-function-2.1.1.tgz#3e69018c8e04e73b738793d020bfe884b9fd3523"
integrity sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==
dependencies:
async-function "^1.0.0"
call-bound "^1.0.3"
get-proto "^1.0.1"
has-tostringtag "^1.0.2"
safe-regex-test "^1.1.0"
is-bigint@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.1.0.tgz#dda7a3445df57a42583db4228682eba7c4170672"
integrity sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==
dependencies:
has-bigints "^1.0.2"
is-binary-path@~2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
dependencies:
binary-extensions "^2.0.0"
is-boolean-object@^1.2.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.2.2.tgz#7067f47709809a393c71ff5bb3e135d8a9215d9e"
integrity sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==
dependencies:
call-bound "^1.0.3"
has-tostringtag "^1.0.2"
is-callable@^1.2.7:
version "1.2.7"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
is-core-module@^2.13.0, is-core-module@^2.16.0, is-core-module@^2.16.1:
version "2.16.1"
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4"
integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==
dependencies:
hasown "^2.0.2"
is-data-view@^1.0.1, is-data-view@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-data-view/-/is-data-view-1.0.2.tgz#bae0a41b9688986c2188dda6657e56b8f9e63b8e"
integrity sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==
dependencies:
call-bound "^1.0.2"
get-intrinsic "^1.2.6"
is-typed-array "^1.1.13"
is-date-object@^1.0.5, is-date-object@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.1.0.tgz#ad85541996fc7aa8b2729701d27b7319f95d82f7"
integrity sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==
dependencies:
call-bound "^1.0.2"
has-tostringtag "^1.0.2"
is-docker@^2.0.0, is-docker@^2.1.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
is-finalizationregistry@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz#eefdcdc6c94ddd0674d9c85887bf93f944a97c90"
integrity sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==
dependencies:
call-bound "^1.0.3"
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-generator-function@^1.0.10:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.1.0.tgz#bf3eeda931201394f57b5dba2800f91a238309ca"
integrity sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==
dependencies:
call-bound "^1.0.3"
get-proto "^1.0.0"
has-tostringtag "^1.0.2"
safe-regex-test "^1.1.0"
is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
version "4.0.3"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
dependencies:
is-extglob "^2.1.1"
is-interactive@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e"
integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==
is-map@^2.0.2, is-map@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.3.tgz#ede96b7fe1e270b3c4465e3a465658764926d62e"
integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==
is-negative-zero@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747"
integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==
is-node-process@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/is-node-process/-/is-node-process-1.2.0.tgz#ea02a1b90ddb3934a19aea414e88edef7e11d134"
integrity sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==
is-number-object@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.1.1.tgz#144b21e95a1bc148205dcc2814a9134ec41b2541"
integrity sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==
dependencies:
call-bound "^1.0.3"
has-tostringtag "^1.0.2"
is-number@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
is-plain-obj@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
is-plain-object@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==
dependencies:
isobject "^3.0.1"
is-plain-object@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344"
integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==
is-potential-custom-element-name@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5"
integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==
is-promise@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-4.0.0.tgz#42ff9f84206c1991d26debf520dd5c01042dd2f3"
integrity sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==
is-regex@^1.1.4, is-regex@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.2.1.tgz#76d70a3ed10ef9be48eb577887d74205bf0cad22"
integrity sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==
dependencies:
call-bound "^1.0.2"
gopd "^1.2.0"
has-tostringtag "^1.0.2"
hasown "^2.0.2"
is-set@^2.0.2, is-set@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.3.tgz#8ab209ea424608141372ded6e0cb200ef1d9d01d"
integrity sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==
is-shared-array-buffer@^1.0.2, is-shared-array-buffer@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz#9b67844bd9b7f246ba0708c3a93e34269c774f6f"
integrity sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==
dependencies:
call-bound "^1.0.3"
is-stream@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==
is-string@^1.0.7, is-string@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.1.1.tgz#92ea3f3d5c5b6e039ca8677e5ac8d07ea773cbb9"
integrity sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==
dependencies:
call-bound "^1.0.3"
has-tostringtag "^1.0.2"
is-symbol@^1.0.4, is-symbol@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.1.1.tgz#f47761279f532e2b05a7024a7506dbbedacd0634"
integrity sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==
dependencies:
call-bound "^1.0.2"
has-symbols "^1.1.0"
safe-regex-test "^1.1.0"
is-typed-array@^1.1.13, is-typed-array@^1.1.14, is-typed-array@^1.1.15:
version "1.1.15"
resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.15.tgz#4bfb4a45b61cee83a5a46fba778e4e8d59c0ce0b"
integrity sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==
dependencies:
which-typed-array "^1.1.16"
is-unicode-supported@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7"
integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==
is-url@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52"
integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==
is-weakmap@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.2.tgz#bf72615d649dfe5f699079c54b83e47d1ae19cfd"
integrity sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==
is-weakref@^1.0.2, is-weakref@^1.1.0, is-weakref@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.1.1.tgz#eea430182be8d64174bd96bffbc46f21bf3f9293"
integrity sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==
dependencies:
call-bound "^1.0.3"
is-weakset@^2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.4.tgz#c9f5deb0bc1906c6d6f1027f284ddf459249daca"
integrity sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==
dependencies:
call-bound "^1.0.3"
get-intrinsic "^1.2.6"
is-what@^4.1.8:
version "4.1.16"
resolved "https://registry.yarnpkg.com/is-what/-/is-what-4.1.16.tgz#1ad860a19da8b4895ad5495da3182ce2acdd7a6f"
integrity sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==
is-wsl@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
dependencies:
is-docker "^2.0.0"
is2@^2.0.6:
version "2.0.9"
resolved "https://registry.yarnpkg.com/is2/-/is2-2.0.9.tgz#ff63b441f90de343fa8fac2125ee170da8e8240d"
integrity sha512-rZkHeBn9Zzq52sd9IUIV3a5mfwBY+o2HePMh0wkGBM4z4qjvy2GwVxQ6nNXSfw6MmVP6gf1QIlWjiOavhM3x5g==
dependencies:
deep-is "^0.1.3"
ip-regex "^4.1.0"
is-url "^1.2.4"
isarray@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723"
integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==
isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
iso-639-1@3.1.5:
version "3.1.5"
resolved "https://registry.yarnpkg.com/iso-639-1/-/iso-639-1-3.1.5.tgz#e8205aceeeea0f64d6b12f5fac6a943b0d5b452c"
integrity sha512-gXkz5+KN7HrG0Q5UGqSMO2qB9AsbEeyLP54kF1YrMsIxmu+g4BdB7rflReZTSTZGpfj8wywu6pfPBCylPIzGQA==
isobject@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==
jackspeak@^3.1.2:
version "3.4.3"
resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a"
integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==
dependencies:
"@isaacs/cliui" "^8.0.2"
optionalDependencies:
"@pkgjs/parseargs" "^0.11.0"
jake@^10.8.5:
version "10.9.2"
resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.2.tgz#6ae487e6a69afec3a5e167628996b59f35ae2b7f"
integrity sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==
dependencies:
async "^3.2.3"
chalk "^4.0.2"
filelist "^1.0.4"
minimatch "^3.1.2"
+jiti@^2.6.1:
+ version "2.7.0"
+ resolved "https://registry.yarnpkg.com/jiti/-/jiti-2.7.0.tgz#974228f2f4ca2bc21885a1797b45fea68e950c64"
+ integrity sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==
+
js-beautify@^1.14.9:
version "1.15.4"
resolved "https://registry.yarnpkg.com/js-beautify/-/js-beautify-1.15.4.tgz#f579f977ed4c930cef73af8f98f3f0a608acd51e"
integrity sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==
dependencies:
config-chain "^1.1.13"
editorconfig "^1.0.4"
glob "^10.4.2"
js-cookie "^3.0.5"
nopt "^7.2.1"
js-cookie@3.0.5, js-cookie@^3.0.5:
version "3.0.5"
resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-3.0.5.tgz#0b7e2fd0c01552c58ba86e0841f94dc2557dcdbc"
integrity sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==
js-tokens@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
js-tokens@^9.0.0:
version "9.0.1"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-9.0.1.tgz#2ec43964658435296f6761b34e10671c2d9527f4"
integrity sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==
js-yaml@4.1.0, 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"
jsbn@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-1.1.0.tgz#b01307cb29b618a1ed26ec79e911f803c4da0040"
integrity sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==
jsdom@^24.1.0:
version "24.1.3"
resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-24.1.3.tgz#88e4a07cb9dd21067514a619e9f17b090a394a9f"
integrity sha512-MyL55p3Ut3cXbeBEG7Hcv0mVM8pp8PBNWxRqchZnSfAiES1v1mRnMeFfaHWIPULpwsYfvO+ZmMZz5tGCnjzDUQ==
dependencies:
cssstyle "^4.0.1"
data-urls "^5.0.0"
decimal.js "^10.4.3"
form-data "^4.0.0"
html-encoding-sniffer "^4.0.0"
http-proxy-agent "^7.0.2"
https-proxy-agent "^7.0.5"
is-potential-custom-element-name "^1.0.1"
nwsapi "^2.2.12"
parse5 "^7.1.2"
rrweb-cssom "^0.7.1"
saxes "^6.0.0"
symbol-tree "^3.2.4"
tough-cookie "^4.1.4"
w3c-xmlserializer "^5.0.0"
webidl-conversions "^7.0.0"
whatwg-encoding "^3.1.1"
whatwg-mimetype "^4.0.0"
whatwg-url "^14.0.0"
ws "^8.18.0"
xml-name-validator "^5.0.0"
jsesc@^3.0.2:
version "3.1.0"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d"
integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==
jsesc@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e"
integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==
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.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
json-schema-traverse@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
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==
json-stable-stringify-without-jsonify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
json5@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593"
integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==
dependencies:
minimist "^1.2.0"
json5@^2.2.3:
version "2.2.3"
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
jszip@^3.10.1:
version "3.10.1"
resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.10.1.tgz#34aee70eb18ea1faec2f589208a157d1feb091c2"
integrity sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==
dependencies:
lie "~3.3.0"
pako "~1.0.2"
readable-stream "~2.3.6"
setimmediate "^1.0.5"
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"
keyv@^5.5.3:
version "5.5.3"
resolved "https://registry.yarnpkg.com/keyv/-/keyv-5.5.3.tgz#db7b7f89b3e13ade5a8d0fe59d765aebb596e84b"
integrity sha512-h0Un1ieD+HUrzBH6dJXhod3ifSghk5Hw/2Y4/KHBziPlZecrFyE9YOTPU6eOs0V9pYl8gOs86fkr/KN8lUX39A==
dependencies:
"@keyv/serialize" "^1.1.1"
kind-of@^6.0.2:
version "6.0.3"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
known-css-properties@^0.35.0:
version "0.35.0"
resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.35.0.tgz#f6f8e40ab4e5700fa32f5b2ef5218a56bc853bd6"
integrity sha512-a/RAk2BfKk+WFGhhOCAYqSiFLc34k8Mt/6NWRI4joER0EYUzXIcFivjjnoD3+XU1DggLn/tZc3DOAgke7l8a4A==
known-css-properties@^0.37.0:
version "0.37.0"
resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.37.0.tgz#10ebe49b9dbb6638860ff8a002fb65a053f4aec5"
integrity sha512-JCDrsP4Z1Sb9JwG0aJ8Eo2r7k4Ou5MwmThS/6lcIe1ICyb7UBJKGRIUUdqc2ASdE/42lgz6zFUnzAIhtXnBVrQ==
lazystream@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.1.tgz#494c831062f1f9408251ec44db1cba29242a2638"
integrity sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==
dependencies:
readable-stream "^2.0.5"
levn@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade"
integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==
dependencies:
prelude-ls "^1.2.1"
type-check "~0.4.0"
lie@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e"
integrity sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==
dependencies:
immediate "~3.0.5"
lie@~3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a"
integrity sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==
dependencies:
immediate "~3.0.5"
+lightningcss-android-arm64@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz#f033885116dfefd9c6f54787523e3514b61e1968"
+ integrity sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==
+
+lightningcss-darwin-arm64@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz#50b71871b01c8199584b649e292547faea7af9b5"
+ integrity sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==
+
+lightningcss-darwin-x64@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz#35f3e97332d130b9ca181e11b568ded6aebc6d5e"
+ integrity sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==
+
+lightningcss-freebsd-x64@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz#9777a76472b64ed6ff94342ad64c7bafd794a575"
+ integrity sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==
+
+lightningcss-linux-arm-gnueabihf@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz#13ae652e1ab73b9135d7b7da172f666c410ad53d"
+ integrity sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==
+
+lightningcss-linux-arm64-gnu@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz#417858795a94592f680123a1b1f9da8a0e1ef335"
+ integrity sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==
+
+lightningcss-linux-arm64-musl@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz#6be36692e810b718040802fd809623cffe732133"
+ integrity sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==
+
+lightningcss-linux-x64-gnu@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz#0b7803af4eb21cfd38dd39fe2abbb53c7dd091f6"
+ integrity sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==
+
+lightningcss-linux-x64-musl@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz#88dc8ba865ddddb1ac5ef04b0f161804418c163b"
+ integrity sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==
+
+lightningcss-win32-arm64-msvc@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz#4f30ba3fa5e925f5b79f945e8cc0d176c3b1ab38"
+ integrity sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==
+
+lightningcss-win32-x64-msvc@1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz#141aa5605645064928902bb4af045fa7d9f4220a"
+ integrity sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==
+
+lightningcss@^1.32.0:
+ version "1.32.0"
+ resolved "https://registry.yarnpkg.com/lightningcss/-/lightningcss-1.32.0.tgz#b85aae96486dcb1bf49a7c8571221273f4f1e4a9"
+ integrity sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==
+ dependencies:
+ detect-libc "^2.0.3"
+ optionalDependencies:
+ lightningcss-android-arm64 "1.32.0"
+ lightningcss-darwin-arm64 "1.32.0"
+ lightningcss-darwin-x64 "1.32.0"
+ lightningcss-freebsd-x64 "1.32.0"
+ lightningcss-linux-arm-gnueabihf "1.32.0"
+ lightningcss-linux-arm64-gnu "1.32.0"
+ lightningcss-linux-arm64-musl "1.32.0"
+ lightningcss-linux-x64-gnu "1.32.0"
+ lightningcss-linux-x64-musl "1.32.0"
+ lightningcss-win32-arm64-msvc "1.32.0"
+ lightningcss-win32-x64-msvc "1.32.0"
+
lines-and-columns@^1.1.6:
version "1.2.4"
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
localforage@1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.10.0.tgz#5c465dc5f62b2807c3a84c0c6a1b1b3212781dd4"
integrity sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==
dependencies:
lie "3.1.1"
locate-path@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e"
integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==
dependencies:
p-locate "^3.0.0"
path-exists "^3.0.0"
locate-path@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
dependencies:
p-locate "^4.1.0"
locate-path@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286"
integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==
dependencies:
p-locate "^5.0.0"
lodash.debounce@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
lodash.defaults@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c"
integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==
lodash.difference@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c"
integrity sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==
lodash.flatten@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
integrity sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==
lodash.get@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==
lodash.isplainobject@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
integrity sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==
lodash.merge@^4.6.2:
version "4.6.2"
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
lodash.truncate@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==
lodash.union@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88"
integrity sha512-c4pB2CdGrGdjMKYLA+XiRDO7Y0PRQbm/Gzg8qMj+QH+pFVAoTp5sBpO0odL3FjoPCGjK96p6qsP+yQoiLoOBcw==
lodash@4.17.21, lodash@^4.17.10, lodash@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
log-symbols@4.1.0, log-symbols@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503"
integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==
dependencies:
chalk "^4.1.0"
is-unicode-supported "^0.1.0"
loupe@^2.3.7:
version "2.3.7"
resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.7.tgz#6e69b7d4db7d3ab436328013d37d1c8c3540c697"
integrity sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==
dependencies:
get-func-name "^2.0.1"
loupe@^3.1.0, loupe@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/loupe/-/loupe-3.1.3.tgz#042a8f7986d77f3d0f98ef7990a2b2fef18b0fd2"
integrity sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==
lru-cache@^10.2.0, lru-cache@^10.4.3:
version "10.4.3"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119"
integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==
+lru-cache@^11.2.7:
+ version "11.5.1"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.5.1.tgz#f3daa3540847b9737ebc02499ddb36765e54db4a"
+ integrity sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==
+
lru-cache@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==
dependencies:
yallist "^3.0.2"
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
dependencies:
yallist "^4.0.0"
lru-cache@^7.14.1:
version "7.18.3"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89"
integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==
lz-string@^1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941"
integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==
magic-string@^0.30.17:
version "0.30.18"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.18.tgz#905bfbbc6aa5692703a93db26a9edcaa0007d2bb"
integrity sha512-yi8swmWbO17qHhwIBNeeZxTceJMeBvWJaId6dyvTSOwTipqeHhMhOrz6513r1sOKnpvQ7zkhlG8tPrpilwTxHQ==
dependencies:
"@jridgewell/sourcemap-codec" "^1.5.5"
magic-string@^0.30.19:
version "0.30.19"
resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.19.tgz#cebe9f104e565602e5d2098c5f2e79a77cc86da9"
integrity sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==
dependencies:
"@jridgewell/sourcemap-codec" "^1.5.5"
+magic-string@^0.30.21:
+ version "0.30.21"
+ resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.21.tgz#56763ec09a0fa8091df27879fd94d19078c00d91"
+ integrity sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==
+ dependencies:
+ "@jridgewell/sourcemap-codec" "^1.5.5"
+
make-dir@^2.0.0, make-dir@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5"
integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==
dependencies:
pify "^4.0.1"
semver "^5.6.0"
math-intrinsics@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9"
integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==
mathml-tag-names@^2.1.3:
version "2.1.3"
resolved "https://registry.yarnpkg.com/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz#4ddadd67308e780cf16a47685878ee27b736a0a3"
integrity sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==
mdn-data@2.12.2:
version "2.12.2"
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.12.2.tgz#9ae6c41a9e65adf61318b32bff7b64fbfb13f8cf"
integrity sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==
mdn-data@^2.15.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.19.0.tgz#e7195c44715be0485e4cb4997082133db8d2fd16"
integrity sha512-vXxcNOxiaUhwoBShl2gd8xOQFeKWLosotfwPeRQsDwtruBSDFAzPPLfg2KMgdK8iz4RUVdswyWMuZwOVojrVZQ==
media-typer@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-1.1.0.tgz#6ab74b8f2d3320f2064b2a87a38e7931ff3a5561"
integrity sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==
meow@^13.2.0:
version "13.2.0"
resolved "https://registry.yarnpkg.com/meow/-/meow-13.2.0.tgz#6b7d63f913f984063b3cc261b6e8800c4cd3474f"
integrity sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==
merge-descriptors@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-2.0.0.tgz#ea922f660635a2249ee565e0449f951e6b603808"
integrity sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==
merge-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
merge2@^1.3.0, merge2@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
-micromatch@^4.0.5, micromatch@^4.0.8:
+micromatch@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
dependencies:
braces "^3.0.3"
picomatch "^2.3.1"
mime-db@1.52.0:
version "1.52.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-db@^1.54.0:
version "1.54.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.54.0.tgz#cddb3ee4f9c64530dff640236661d42cb6a314f5"
integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==
mime-types@^2.1.12:
version "2.1.35"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
mime-db "1.52.0"
mime-types@^3.0.0, mime-types@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-3.0.1.tgz#b1d94d6997a9b32fd69ebaed0db73de8acb519ce"
integrity sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==
dependencies:
mime-db "^1.54.0"
mimic-fn@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
minimatch@3.1.2, minimatch@^3.1.1, minimatch@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
dependencies:
brace-expansion "^1.1.7"
minimatch@5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b"
integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==
dependencies:
brace-expansion "^2.0.1"
minimatch@9.0.1:
version "9.0.1"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.1.tgz#8a555f541cf976c622daf078bb28f29fb927c253"
integrity sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==
dependencies:
brace-expansion "^2.0.1"
minimatch@^5.0.1, minimatch@^5.1.0:
version "5.1.6"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96"
integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
dependencies:
brace-expansion "^2.0.1"
minimatch@^9.0.4:
version "9.0.5"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5"
integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==
dependencies:
brace-expansion "^2.0.1"
minimist@1.2.6:
version "1.2.6"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
minimist@^1.2.0, minimist@^1.2.6:
version "1.2.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2:
version "7.1.2"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707"
integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==
mitt@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/mitt/-/mitt-2.1.0.tgz#f740577c23176c6205b121b2973514eade1b2230"
integrity sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg==
mitt@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.1.tgz#ea36cf0cc30403601ae074c8f77b7092cdab36d1"
integrity sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==
+mlly@^1.7.4, mlly@^1.8.2:
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.8.2.tgz#e7f7919a82d13b174405613117249a3f449d78bb"
+ integrity sha512-d+ObxMQFmbt10sretNDytwt85VrbkhhUA/JBGm1MPaWJ65Cl4wOgLaB1NYvJSZ0Ef03MMEU/0xpPMXUIQ29UfA==
+ dependencies:
+ acorn "^8.16.0"
+ pathe "^2.0.3"
+ pkg-types "^1.3.1"
+ ufo "^1.6.3"
+
mocha@10.3.0:
version "10.3.0"
resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.3.0.tgz#0e185c49e6dccf582035c05fa91084a4ff6e3fe9"
integrity sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==
dependencies:
ansi-colors "4.1.1"
browser-stdout "1.3.1"
chokidar "3.5.3"
debug "4.3.4"
diff "5.0.0"
escape-string-regexp "4.0.0"
find-up "5.0.0"
glob "8.1.0"
he "1.2.0"
js-yaml "4.1.0"
log-symbols "4.1.0"
minimatch "5.0.1"
ms "2.1.3"
serialize-javascript "6.0.0"
strip-json-comments "3.1.1"
supports-color "8.1.1"
workerpool "6.2.1"
yargs "16.2.0"
yargs-parser "20.2.4"
yargs-unparser "2.0.0"
-mrmime@^2.0.0:
+mri@^1.1.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b"
+ integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==
+
+mrmime@^2.0.0, mrmime@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-2.0.1.tgz#bc3e87f7987853a54c9850eeb1f1078cd44adddc"
integrity sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==
ms@2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
ms@2.1.3, ms@^2.1.1, ms@^2.1.3:
version "2.1.3"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
msw@2.10.5:
version "2.10.5"
resolved "https://registry.yarnpkg.com/msw/-/msw-2.10.5.tgz#3e43f12e97581c260bf38d8817732b9fec3bfdb0"
integrity sha512-0EsQCrCI1HbhpBWd89DvmxY6plmvrM96b0sCIztnvcNHQbXn5vqwm1KlXslo6u4wN9LFGLC1WFjjgljcQhe40A==
dependencies:
"@bundled-es-modules/cookie" "^2.0.1"
"@bundled-es-modules/statuses" "^1.0.1"
"@bundled-es-modules/tough-cookie" "^0.1.6"
"@inquirer/confirm" "^5.0.0"
"@mswjs/interceptors" "^0.39.1"
"@open-draft/deferred-promise" "^2.2.0"
"@open-draft/until" "^2.1.0"
"@types/cookie" "^0.6.0"
"@types/statuses" "^2.0.4"
graphql "^16.8.1"
headers-polyfill "^4.0.2"
is-node-process "^1.2.0"
outvariant "^1.4.3"
path-to-regexp "^6.3.0"
picocolors "^1.1.1"
strict-event-emitter "^0.5.1"
type-fest "^4.26.1"
yargs "^17.7.2"
mute-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-2.0.0.tgz#a5446fc0c512b71c83c44d908d5c7b7b4c493b2b"
integrity sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==
nanoid@^3.3.11, nanoid@^3.3.8:
version "3.3.11"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b"
integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==
+nanoid@^3.3.12:
+ version "3.3.12"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.12.tgz#ab3d912e217a6d0a514f00a72a16543a28982c05"
+ integrity sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==
+
natural-compare@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==
negotiator@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.0.0.tgz#b6c91bb47172d69f93cfd7c357bbb529019b5f6a"
integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==
netmask@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/netmask/-/netmask-2.0.2.tgz#8b01a07644065d536383835823bc52004ebac5e7"
integrity sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==
nightwatch-axe-verbose@^2.3.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/nightwatch-axe-verbose/-/nightwatch-axe-verbose-2.3.1.tgz#42cd226989cb5205b699db42d74b1b967587d099"
integrity sha512-C6N95bwPHsRnv04eVIwJ6w5m6X1+Pddvo6nzpzOHQlO0j+pYRVU7zaQmFUJ0L4cqeUxReNEXyTUg/R9WWfHk7w==
dependencies:
axe-core "^4.9.1"
nightwatch@3.12.2:
version "3.12.2"
resolved "https://registry.yarnpkg.com/nightwatch/-/nightwatch-3.12.2.tgz#95ef5322003473b4e1f4cca1e40259b64f9ffe75"
integrity sha512-B4MGUvO+RjX8gYg84oJ3DKdgzfXIFRKbs19nLBlUt+aJlzBdv6VdN00wlOmzCakHXZlU10MGm1KiW0dsTlgFRA==
dependencies:
"@nightwatch/chai" "5.0.3"
"@nightwatch/html-reporter-template" "^0.3.0"
"@nightwatch/nightwatch-inspector" "^1.0.1"
"@types/chai" "^4.3.5"
"@types/selenium-webdriver" "^4.1.14"
ansi-to-html "0.7.2"
aria-query "5.1.3"
assertion-error "1.1.0"
boxen "5.1.2"
chai-nightwatch "^0.5.3"
chalk "^4.1.2"
ci-info "3.3.0"
cli-table3 "^0.6.3"
devtools-protocol "^0.0.1140464"
didyoumean "^1.2.2"
dotenv "16.3.1"
ejs "^3.1.10"
envinfo "7.11.0"
glob "7.2.3"
jsdom "^24.1.0"
lodash "^4.17.21"
minimatch "3.1.2"
minimist "1.2.6"
mocha "10.3.0"
nightwatch-axe-verbose "^2.3.0"
open "8.4.2"
ora "5.4.1"
piscina "^4.3.1"
selenium-webdriver "4.27.0"
semver "7.5.4"
stacktrace-parser "0.1.10"
strip-ansi "6.0.1"
untildify "4.0.0"
uuid "8.3.2"
node-addon-api@^7.0.0:
version "7.1.1"
resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-7.1.1.tgz#1aba6693b0f255258a049d621329329322aad558"
integrity sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==
+node-fetch-native@^1.6.7:
+ version "1.6.7"
+ resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.6.7.tgz#9d09ca63066cc48423211ed4caf5d70075d76a71"
+ integrity sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==
+
+node-mock-http@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/node-mock-http/-/node-mock-http-1.0.4.tgz#21f2ab4ce2fe4fbe8a660d7c5195a1db85e042a4"
+ integrity sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==
+
node-releases@^2.0.19:
version "2.0.19"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.19.tgz#9e445a52950951ec4d177d843af370b411caf314"
integrity sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==
nopt@^7.2.1:
version "7.2.1"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-7.2.1.tgz#1cac0eab9b8e97c9093338446eddd40b2c8ca1e7"
integrity sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==
dependencies:
abbrev "^2.0.0"
normalize-path@^3.0.0, normalize-path@~3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
normalize-range@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942"
integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==
+nostics@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/nostics/-/nostics-0.2.0.tgz#8c9274d7352bf9c6c556d2b63e179431c88a1a6d"
+ integrity sha512-/WQpI46UMbqvy1okYb+V+9wW3J8/m6GJ33wm691n/tyi6YtJiZ6ssJjENAU7y4evfYrrgYN9HllKDzPvffil1w==
+ dependencies:
+ magic-string "^0.30.21"
+ oxc-parser "^0.132.0"
+ unplugin "^3.0.0"
+
npm-run-path@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
dependencies:
path-key "^3.0.0"
nth-check@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d"
integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==
dependencies:
boolbase "^1.0.0"
nwsapi@^2.2.12:
version "2.2.20"
resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.20.tgz#22e53253c61e7b0e7e93cef42c891154bcca11ef"
integrity sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==
object-inspect@^1.13.3, object-inspect@^1.13.4:
version "1.13.4"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213"
integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==
object-is@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.6.tgz#1a6a53aed2dd8f7e6775ff870bea58545956ab07"
integrity sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==
dependencies:
call-bind "^1.0.7"
define-properties "^1.2.1"
object-keys@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==
object.assign@^4.1.4, object.assign@^4.1.7:
version "4.1.7"
resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.7.tgz#8c14ca1a424c6a561b0bb2a22f66f5049a945d3d"
integrity sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==
dependencies:
call-bind "^1.0.8"
call-bound "^1.0.3"
define-properties "^1.2.1"
es-object-atoms "^1.0.0"
has-symbols "^1.1.0"
object-keys "^1.1.1"
object.fromentries@^2.0.8:
version "2.0.8"
resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.8.tgz#f7195d8a9b97bd95cbc1999ea939ecd1a2b00c65"
integrity sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==
dependencies:
call-bind "^1.0.7"
define-properties "^1.2.1"
es-abstract "^1.23.2"
es-object-atoms "^1.0.0"
object.groupby@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.3.tgz#9b125c36238129f6f7b61954a1e7176148d5002e"
integrity sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==
dependencies:
call-bind "^1.0.7"
define-properties "^1.2.1"
es-abstract "^1.23.2"
object.values@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.2.1.tgz#deed520a50809ff7f75a7cfd4bc64c7a038c6216"
integrity sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==
dependencies:
call-bind "^1.0.8"
call-bound "^1.0.3"
define-properties "^1.2.1"
es-object-atoms "^1.0.0"
+obug@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/obug/-/obug-2.1.1.tgz#2cba74ff241beb77d63055ddf4cd1e9f90b538be"
+ integrity sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==
+
+ofetch@^1.5.1:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/ofetch/-/ofetch-1.5.1.tgz#5c43cc56e03398b273014957060344254505c5c7"
+ integrity sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==
+ dependencies:
+ destr "^2.0.5"
+ node-fetch-native "^1.6.7"
+ ufo "^1.6.1"
+
on-finished@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
dependencies:
ee-first "1.1.1"
once@^1.3.0, once@^1.3.1, once@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==
dependencies:
wrappy "1"
onetime@^5.1.0, onetime@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
dependencies:
mimic-fn "^2.1.0"
open@8.4.2:
version "8.4.2"
resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9"
integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==
dependencies:
define-lazy-prop "^2.0.0"
is-docker "^2.1.1"
is-wsl "^2.2.0"
optionator@^0.9.3:
version "0.9.4"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734"
integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==
dependencies:
deep-is "^0.1.3"
fast-levenshtein "^2.0.6"
levn "^0.4.1"
prelude-ls "^1.2.1"
type-check "^0.4.0"
word-wrap "^1.2.5"
ora@5.4.1:
version "5.4.1"
resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18"
integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==
dependencies:
bl "^4.1.0"
chalk "^4.1.0"
cli-cursor "^3.1.0"
cli-spinners "^2.5.0"
is-interactive "^1.0.0"
is-unicode-supported "^0.1.0"
log-symbols "^4.1.0"
strip-ansi "^6.0.0"
wcwidth "^1.0.1"
outvariant@^1.4.0, outvariant@^1.4.3:
version "1.4.3"
resolved "https://registry.yarnpkg.com/outvariant/-/outvariant-1.4.3.tgz#221c1bfc093e8fec7075497e7799fdbf43d14873"
integrity sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==
own-keys@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/own-keys/-/own-keys-1.0.1.tgz#e4006910a2bf913585289676eebd6f390cf51358"
integrity sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==
dependencies:
get-intrinsic "^1.2.6"
object-keys "^1.1.1"
safe-push-apply "^1.0.0"
+oxc-parser@^0.132.0:
+ version "0.132.0"
+ resolved "https://registry.yarnpkg.com/oxc-parser/-/oxc-parser-0.132.0.tgz#4f0ffad5ccfd0235a8ba79f7e6fc988be6f45476"
+ integrity sha512-+0LAPHaqtfQlvWdpaAa09SmOaZZgP8C552xosEkGJ4+ruEwP1Vgx+sqBgcBCNfR6KDCmagGOZTde8wmAvcI/Hg==
+ dependencies:
+ "@oxc-project/types" "^0.132.0"
+ optionalDependencies:
+ "@oxc-parser/binding-android-arm-eabi" "0.132.0"
+ "@oxc-parser/binding-android-arm64" "0.132.0"
+ "@oxc-parser/binding-darwin-arm64" "0.132.0"
+ "@oxc-parser/binding-darwin-x64" "0.132.0"
+ "@oxc-parser/binding-freebsd-x64" "0.132.0"
+ "@oxc-parser/binding-linux-arm-gnueabihf" "0.132.0"
+ "@oxc-parser/binding-linux-arm-musleabihf" "0.132.0"
+ "@oxc-parser/binding-linux-arm64-gnu" "0.132.0"
+ "@oxc-parser/binding-linux-arm64-musl" "0.132.0"
+ "@oxc-parser/binding-linux-ppc64-gnu" "0.132.0"
+ "@oxc-parser/binding-linux-riscv64-gnu" "0.132.0"
+ "@oxc-parser/binding-linux-riscv64-musl" "0.132.0"
+ "@oxc-parser/binding-linux-s390x-gnu" "0.132.0"
+ "@oxc-parser/binding-linux-x64-gnu" "0.132.0"
+ "@oxc-parser/binding-linux-x64-musl" "0.132.0"
+ "@oxc-parser/binding-openharmony-arm64" "0.132.0"
+ "@oxc-parser/binding-wasm32-wasi" "0.132.0"
+ "@oxc-parser/binding-win32-arm64-msvc" "0.132.0"
+ "@oxc-parser/binding-win32-ia32-msvc" "0.132.0"
+ "@oxc-parser/binding-win32-x64-msvc" "0.132.0"
+
+oxc@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/oxc/-/oxc-1.0.1.tgz#27d3abc73ca8cbc7884b86bf5ed0de278634c9af"
+ integrity sha512-MJ18y2Ekl329i3zdZpRVOqFdEUjoRKC1+uy1f4kuRp9ygindCVVUIhhKxwyAhTsWt3jIV8UczKtlTwWWahcaWQ==
+
p-limit@^2.0.0, p-limit@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
dependencies:
p-try "^2.0.0"
p-limit@^3.0.2:
version "3.1.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b"
integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==
dependencies:
yocto-queue "^0.1.0"
+p-limit@^7.3.0:
+ version "7.3.0"
+ resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-7.3.0.tgz#821398d91491c6b6a1340ecd09cdc402a9c8d0ee"
+ integrity sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==
+ dependencies:
+ yocto-queue "^1.2.1"
+
p-locate@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4"
integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==
dependencies:
p-limit "^2.0.0"
p-locate@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
dependencies:
p-limit "^2.2.0"
p-locate@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834"
integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==
dependencies:
p-limit "^3.0.2"
p-try@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
pac-proxy-agent@^7.1.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz#9cfaf33ff25da36f6147a20844230ec92c06e5df"
integrity sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==
dependencies:
"@tootallnate/quickjs-emscripten" "^0.23.0"
agent-base "^7.1.2"
debug "^4.3.4"
get-uri "^6.0.1"
http-proxy-agent "^7.0.0"
https-proxy-agent "^7.0.6"
pac-resolver "^7.0.1"
socks-proxy-agent "^8.0.5"
pac-resolver@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-7.0.1.tgz#54675558ea368b64d210fd9c92a640b5f3b8abb6"
integrity sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==
dependencies:
degenerator "^5.0.0"
netmask "^2.0.2"
package-json-from-dist@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505"
integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==
+package-manager-detector@^1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/package-manager-detector/-/package-manager-detector-1.6.0.tgz#70d0cf0aa02c877eeaf66c4d984ede0be9130734"
+ integrity sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==
+
pako@~1.0.2:
version "1.0.11"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==
parent-module@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
dependencies:
callsites "^3.0.0"
parse-json@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd"
integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==
dependencies:
"@babel/code-frame" "^7.0.0"
error-ex "^1.3.1"
json-parse-even-better-errors "^2.3.0"
lines-and-columns "^1.1.6"
parse-link-header@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/parse-link-header/-/parse-link-header-2.0.0.tgz#949353e284f8aa01f2ac857a98f692b57733f6b7"
integrity sha512-xjU87V0VyHZybn2RrCX5TIFGxTVZE6zqqZWMPlIKiSKuWh/X5WZdt+w1Ki1nXB+8L/KtL+nZ4iq+sfI6MrhhMw==
dependencies:
xtend "~4.0.1"
parse5@^7.1.2:
version "7.2.1"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.2.1.tgz#8928f55915e6125f430cc44309765bf17556a33a"
integrity sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==
dependencies:
entities "^4.5.0"
parseurl@^1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
path-exists@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==
path-exists@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
path-key@^3.0.0, path-key@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
path-parse@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
path-scurry@^1.11.1:
version "1.11.1"
resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2"
integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==
dependencies:
lru-cache "^10.2.0"
minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
path-to-regexp@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.3.0.tgz#2b6a26a337737a8e1416f9272ed0766b1c0389f4"
integrity sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==
path-to-regexp@^8.0.0:
version "8.2.0"
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-8.2.0.tgz#73990cc29e57a3ff2a0d914095156df5db79e8b4"
integrity sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==
path-type@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
-pathe@^2.0.3:
+pathe@^2.0.1, pathe@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/pathe/-/pathe-2.0.3.tgz#3ecbec55421685b70a9da872b2cff3e1cbed1716"
integrity sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==
pathval@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d"
integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==
pathval@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/pathval/-/pathval-2.0.0.tgz#7e2550b422601d4f6b8e26f1301bc8f15a741a25"
integrity sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==
pend@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==
perfect-debounce@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz#9c2e8bc30b169cc984a58b7d5b28049839591d2a"
integrity sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==
+perfect-debounce@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/perfect-debounce/-/perfect-debounce-2.1.0.tgz#e7078e38f231cb191855c3136a4423aef725d261"
+ integrity sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g==
+
phoenix@1.8.1:
version "1.8.1"
resolved "https://registry.yarnpkg.com/phoenix/-/phoenix-1.8.1.tgz#cc247b29f844f22d54291b558689e2381ed8cc43"
integrity sha512-7i2a5f5y0Qhzi2g/+iuaGr4TzRt5ucqI0JeV2Q9K0swqY8L2C7CLR66RcGCpcQKGOY73B5GLKMYEl13o/9l/Cg==
picocolors@^1.0.0, picocolors@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b"
integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
picomatch@^4.0.2, picomatch@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.3.tgz#796c76136d1eead715db1e7bad785dedd695a042"
integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==
+picomatch@^4.0.4:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.4.tgz#fd6f5e00a143086e074dffe4c924b8fb293b0589"
+ integrity sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==
+
pify@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231"
integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==
-pinia@^3.0.0:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/pinia/-/pinia-3.0.3.tgz#f412019bdeb2f45e85927b432803190343e12d89"
- integrity sha512-ttXO/InUULUXkMHpTdp9Fj4hLpD/2AoJdmAbAeW2yu1iy1k+pkFekQXw5VpC0/5p51IOR/jDaDRfRWRnMMsGOA==
+pinia@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/pinia/-/pinia-3.0.4.tgz#75dde12784a61e34c1fa6abcd13c1a1061c360c0"
+ integrity sha512-l7pqLUFTI/+ESXn6k3nu30ZIzW5E2WZF/LaHJEpoq6ElcLD+wduZoB2kBN19du6K/4FDpPMazY2wJr+IndBtQw==
dependencies:
- "@vue/devtools-api" "^7.7.2"
+ "@vue/devtools-api" "^7.7.7"
pirates@^4.0.6:
version "4.0.7"
resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.7.tgz#643b4a18c4257c8a65104b73f3049ce9a0a15e22"
integrity sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==
piscina@^4.3.1:
version "4.9.2"
resolved "https://registry.yarnpkg.com/piscina/-/piscina-4.9.2.tgz#80f2c2375231720337c703e443941adfac8caf75"
integrity sha512-Fq0FERJWFEUpB4eSY59wSNwXD4RYqR+nR/WiEVcZW8IWfVBxJJafcgTEZDQo8k3w0sUarJ8RyVbbUF4GQ2LGbQ==
optionalDependencies:
"@napi-rs/nice" "^1.0.1"
pkg-dir@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3"
integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==
dependencies:
find-up "^3.0.0"
+pkg-types@^1.3.1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.3.1.tgz#bd7cc70881192777eef5326c19deb46e890917df"
+ integrity sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==
+ dependencies:
+ confbox "^0.1.8"
+ mlly "^1.7.4"
+ pathe "^2.0.1"
+
playwright-core@1.57.0:
version "1.57.0"
resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.57.0.tgz#3dcc9a865af256fa9f0af0d67fc8dd54eecaebf5"
integrity sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ==
playwright@1.57.0:
version "1.57.0"
resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.57.0.tgz#74d1dacff5048dc40bf4676940b1901e18ad0f46"
integrity sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw==
dependencies:
playwright-core "1.57.0"
optionalDependencies:
fsevents "2.3.2"
pngjs@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb"
integrity sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==
pointer-tracker@^2.0.3:
version "2.5.3"
resolved "https://registry.yarnpkg.com/pointer-tracker/-/pointer-tracker-2.5.3.tgz#5ed01f5ff023c649b2d7b20b07d68c3ac40642a6"
integrity sha512-LiJUeIbzk4dXq678YeyrZ++mdY17q4n/2sBHfU9wIuvmSzdiPgMvmvWN2g8mY4J7YwYOIrqrZUWP/MfFHVwYtg==
possible-typed-array-names@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz#93e3582bc0e5426586d9d07b79ee40fc841de4ae"
integrity sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==
postcss-html@^1.5.0:
version "1.8.0"
resolved "https://registry.yarnpkg.com/postcss-html/-/postcss-html-1.8.0.tgz#2ea1e9d6c53f04ea994135219d3bd8a9e380e13b"
integrity sha512-5mMeb1TgLWoRKxZ0Xh9RZDfwUUIqRrcxO2uXO+Ezl1N5lqpCiSU5Gk6+1kZediBfBHFtPCdopr2UZ2SgUsKcgQ==
dependencies:
htmlparser2 "^8.0.0"
js-tokens "^9.0.0"
postcss "^8.5.0"
postcss-safe-parser "^6.0.0"
postcss-media-query-parser@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244"
integrity sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==
postcss-resolve-nested-selector@^0.1.6:
version "0.1.6"
resolved "https://registry.yarnpkg.com/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.6.tgz#3d84dec809f34de020372c41b039956966896686"
integrity sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==
postcss-safe-parser@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz#bb4c29894171a94bc5c996b9a30317ef402adaa1"
integrity sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==
postcss-safe-parser@^7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/postcss-safe-parser/-/postcss-safe-parser-7.0.1.tgz#36e4f7e608111a0ca940fd9712ce034718c40ec0"
integrity sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==
postcss-scss@^4.0.6, postcss-scss@^4.0.9:
version "4.0.9"
resolved "https://registry.yarnpkg.com/postcss-scss/-/postcss-scss-4.0.9.tgz#a03c773cd4c9623cb04ce142a52afcec74806685"
integrity sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==
postcss-selector-parser@^7.1.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz#4d6af97eba65d73bc4d84bcb343e865d7dd16262"
integrity sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==
dependencies:
cssesc "^3.0.0"
util-deprecate "^1.0.2"
postcss-value-parser@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
postcss@8.5.6, postcss@^8.5.3, postcss@^8.5.6:
version "8.5.6"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c"
integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==
dependencies:
nanoid "^3.3.11"
picocolors "^1.1.1"
source-map-js "^1.2.1"
postcss@^8.5.0:
version "8.5.3"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.3.tgz#1463b6f1c7fb16fe258736cba29a2de35237eafb"
integrity sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==
dependencies:
nanoid "^3.3.8"
picocolors "^1.1.1"
source-map-js "^1.2.1"
+postcss@^8.5.15:
+ version "8.5.15"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.15.tgz#d1eaf677a324e9ec02196da2d3fecf4a0b9a735c"
+ integrity sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==
+ dependencies:
+ nanoid "^3.3.12"
+ picocolors "^1.1.1"
+ source-map-js "^1.2.1"
+
prelude-ls@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
pretty-format@^27.0.2:
version "27.5.1"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e"
integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==
dependencies:
ansi-regex "^5.0.1"
ansi-styles "^5.0.0"
react-is "^17.0.1"
process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
proto-list@~1.2.1:
version "1.2.4"
resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==
proxy-addr@^2.0.7:
version "2.0.7"
resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==
dependencies:
forwarded "0.2.0"
ipaddr.js "1.9.1"
proxy-agent@^6.4.0:
version "6.5.0"
resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-6.5.0.tgz#9e49acba8e4ee234aacb539f89ed9c23d02f232d"
integrity sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==
dependencies:
agent-base "^7.1.2"
debug "^4.3.4"
http-proxy-agent "^7.0.1"
https-proxy-agent "^7.0.6"
lru-cache "^7.14.1"
pac-proxy-agent "^7.1.0"
proxy-from-env "^1.1.0"
socks-proxy-agent "^8.0.5"
proxy-from-env@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2"
integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==
psl@^1.1.33:
version "1.15.0"
resolved "https://registry.yarnpkg.com/psl/-/psl-1.15.0.tgz#bdace31896f1d97cec6a79e8224898ce93d974c6"
integrity sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==
dependencies:
punycode "^2.3.1"
+publint@^0.3.21:
+ version "0.3.21"
+ resolved "https://registry.yarnpkg.com/publint/-/publint-0.3.21.tgz#91e1425f638e2128343d5543f77551915d57409a"
+ integrity sha512-OqejcnMV6E9zel2oCrUOJEiiFkGiAAni0A6ibfQNh1k9Gu5z4F+Yso8lllam7AzmV6Do0vp7u3UpZNRBwuXaHQ==
+ dependencies:
+ "@publint/pack" "^0.1.4"
+ package-manager-detector "^1.6.0"
+ picocolors "^1.1.1"
+ sade "^1.8.1"
+
pump@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.2.tgz#836f3edd6bc2ee599256c924ffe0d88573ddcbf8"
integrity sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==
dependencies:
end-of-stream "^1.1.0"
once "^1.3.1"
punycode.js@2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/punycode.js/-/punycode.js-2.3.1.tgz#6b53e56ad75588234e79f4affa90972c7dd8cdb7"
integrity sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==
punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==
punycode@^2.1.0, punycode@^2.1.1, punycode@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
qrcode@1.5.4:
version "1.5.4"
resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.5.4.tgz#5cb81d86eb57c675febb08cf007fff963405da88"
integrity sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==
dependencies:
dijkstrajs "^1.0.1"
pngjs "^5.0.0"
yargs "^15.3.1"
qs@^6.12.3, qs@^6.14.0:
version "6.14.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.0.tgz#c63fa40680d2c5c941412a0e899c89af60c0a930"
integrity sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==
dependencies:
side-channel "^1.1.0"
+quansync@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/quansync/-/quansync-1.0.0.tgz#1c29acccd544cd68d97a7350c5099e0a9bc7e5ee"
+ integrity sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==
+
querystring-es3@0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
integrity sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==
querystringify@^2.1.1:
version "2.2.0"
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
+radix3@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/radix3/-/radix3-1.1.2.tgz#fd27d2af3896c6bf4bcdfab6427c69c2afc69ec0"
+ integrity sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==
+
randombytes@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==
dependencies:
safe-buffer "^5.1.0"
range-parser@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
raw-body@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-3.0.0.tgz#25b3476f07a51600619dae3fe82ddc28a36e5e0f"
integrity sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==
dependencies:
bytes "3.1.2"
http-errors "2.0.0"
iconv-lite "0.6.3"
unpipe "1.0.0"
react-is@^17.0.1:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@~2.3.6:
version "2.3.8"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b"
integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.3"
isarray "~1.0.0"
process-nextick-args "~2.0.0"
safe-buffer "~5.1.1"
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0:
version "3.6.2"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"
integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
dependencies:
inherits "^2.0.3"
string_decoder "^1.1.1"
util-deprecate "^1.0.1"
readdir-glob@^1.1.2:
version "1.1.3"
resolved "https://registry.yarnpkg.com/readdir-glob/-/readdir-glob-1.1.3.tgz#c3d831f51f5e7bfa62fa2ffbe4b508c640f09584"
integrity sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==
dependencies:
minimatch "^5.1.0"
-readdirp@^4.0.1:
- version "4.1.2"
- resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.1.2.tgz#eb85801435fbf2a7ee58f19e0921b068fc69948d"
- integrity sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==
+readdirp@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-5.0.0.tgz#fbf1f71a727891d685bb1786f9ba74084f6e2f91"
+ integrity sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==
readdirp@~3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
dependencies:
picomatch "^2.2.1"
reflect.getprototypeof@^1.0.6, reflect.getprototypeof@^1.0.9:
version "1.0.10"
resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz#c629219e78a3316d8b604c765ef68996964e7bf9"
integrity sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==
dependencies:
call-bind "^1.0.8"
define-properties "^1.2.1"
es-abstract "^1.23.9"
es-errors "^1.3.0"
es-object-atoms "^1.0.0"
get-intrinsic "^1.2.7"
get-proto "^1.0.1"
which-builtin-type "^1.2.1"
regenerate-unicode-properties@^10.2.0:
version "10.2.0"
resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz#626e39df8c372338ea9b8028d1f99dc3fd9c3db0"
integrity sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==
dependencies:
regenerate "^1.4.2"
regenerate@^1.4.2:
version "1.4.2"
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a"
integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==
regexp.prototype.flags@^1.5.1, regexp.prototype.flags@^1.5.3, regexp.prototype.flags@^1.5.4:
version "1.5.4"
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz#1ad6c62d44a259007e55b3970e00f746efbcaa19"
integrity sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==
dependencies:
call-bind "^1.0.8"
define-properties "^1.2.1"
es-errors "^1.3.0"
get-proto "^1.0.1"
gopd "^1.2.0"
set-function-name "^2.0.2"
regexpu-core@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-6.2.0.tgz#0e5190d79e542bf294955dccabae04d3c7d53826"
integrity sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==
dependencies:
regenerate "^1.4.2"
regenerate-unicode-properties "^10.2.0"
regjsgen "^0.8.0"
regjsparser "^0.12.0"
unicode-match-property-ecmascript "^2.0.0"
unicode-match-property-value-ecmascript "^2.1.0"
regjsgen@^0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.8.0.tgz#df23ff26e0c5b300a6470cad160a9d090c3a37ab"
integrity sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==
regjsparser@^0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.12.0.tgz#0e846df6c6530586429377de56e0475583b088dc"
integrity sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==
dependencies:
jsesc "~3.0.2"
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==
require-main-filename@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
require-package-name@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/require-package-name/-/require-package-name-2.0.1.tgz#c11e97276b65b8e2923f75dabf5fb2ef0c3841b9"
integrity sha512-uuoJ1hU/k6M0779t3VMVIYpb2VMJk05cehCaABFhXaibcbvfgR8wKiozLjVFSzJPmQMRqIcO0HMyTFqfV09V6Q==
requires-port@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==
resolve-from@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
resolve-from@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69"
integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==
resolve-pkg-maps@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f"
integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==
resolve@^1.22.10, resolve@^1.22.4:
version "1.22.10"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39"
integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==
dependencies:
is-core-module "^2.16.0"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
restore-cursor@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e"
integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==
dependencies:
onetime "^5.1.0"
signal-exit "^3.0.2"
reusify@^1.0.4:
version "1.1.0"
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.1.0.tgz#0fe13b9522e1473f51b558ee796e08f11f9b489f"
integrity sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==
rfdc@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.4.1.tgz#778f76c4fb731d93414e8f925fbecf64cce7f6ca"
integrity sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==
+rolldown@1.0.3:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/rolldown/-/rolldown-1.0.3.tgz#db88a3008fb0e28230a00423727ce75ba32121ac"
+ integrity sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==
+ dependencies:
+ "@oxc-project/types" "=0.133.0"
+ "@rolldown/pluginutils" "^1.0.0"
+ optionalDependencies:
+ "@rolldown/binding-android-arm64" "1.0.3"
+ "@rolldown/binding-darwin-arm64" "1.0.3"
+ "@rolldown/binding-darwin-x64" "1.0.3"
+ "@rolldown/binding-freebsd-x64" "1.0.3"
+ "@rolldown/binding-linux-arm-gnueabihf" "1.0.3"
+ "@rolldown/binding-linux-arm64-gnu" "1.0.3"
+ "@rolldown/binding-linux-arm64-musl" "1.0.3"
+ "@rolldown/binding-linux-ppc64-gnu" "1.0.3"
+ "@rolldown/binding-linux-s390x-gnu" "1.0.3"
+ "@rolldown/binding-linux-x64-gnu" "1.0.3"
+ "@rolldown/binding-linux-x64-musl" "1.0.3"
+ "@rolldown/binding-openharmony-arm64" "1.0.3"
+ "@rolldown/binding-wasm32-wasi" "1.0.3"
+ "@rolldown/binding-win32-arm64-msvc" "1.0.3"
+ "@rolldown/binding-win32-x64-msvc" "1.0.3"
+
rollup@^4.34.9:
version "4.52.5"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.52.5.tgz#96982cdcaedcdd51b12359981f240f94304ec235"
integrity sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==
dependencies:
"@types/estree" "1.0.8"
optionalDependencies:
"@rollup/rollup-android-arm-eabi" "4.52.5"
"@rollup/rollup-android-arm64" "4.52.5"
"@rollup/rollup-darwin-arm64" "4.52.5"
"@rollup/rollup-darwin-x64" "4.52.5"
"@rollup/rollup-freebsd-arm64" "4.52.5"
"@rollup/rollup-freebsd-x64" "4.52.5"
"@rollup/rollup-linux-arm-gnueabihf" "4.52.5"
"@rollup/rollup-linux-arm-musleabihf" "4.52.5"
"@rollup/rollup-linux-arm64-gnu" "4.52.5"
"@rollup/rollup-linux-arm64-musl" "4.52.5"
"@rollup/rollup-linux-loong64-gnu" "4.52.5"
"@rollup/rollup-linux-ppc64-gnu" "4.52.5"
"@rollup/rollup-linux-riscv64-gnu" "4.52.5"
"@rollup/rollup-linux-riscv64-musl" "4.52.5"
"@rollup/rollup-linux-s390x-gnu" "4.52.5"
"@rollup/rollup-linux-x64-gnu" "4.52.5"
"@rollup/rollup-linux-x64-musl" "4.52.5"
"@rollup/rollup-openharmony-arm64" "4.52.5"
"@rollup/rollup-win32-arm64-msvc" "4.52.5"
"@rollup/rollup-win32-ia32-msvc" "4.52.5"
"@rollup/rollup-win32-x64-gnu" "4.52.5"
"@rollup/rollup-win32-x64-msvc" "4.52.5"
fsevents "~2.3.2"
+rou3@^0.8.1:
+ version "0.8.1"
+ resolved "https://registry.yarnpkg.com/rou3/-/rou3-0.8.1.tgz#d18c9dae42bdd9cd4fffa77bc6731d5cfe92129a"
+ integrity sha512-ePa+XGk00/3HuCqrEnK3LxJW7I0SdNg6EFzKUJG73hMAdDcOUC/i/aSz7LSDwLrGr33kal/rqOGydzwl6U7zBA==
+
router@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/router/-/router-2.2.0.tgz#019be620b711c87641167cc79b99090f00b146ef"
integrity sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==
dependencies:
debug "^4.4.0"
depd "^2.0.0"
is-promise "^4.0.0"
parseurl "^1.3.3"
path-to-regexp "^8.0.0"
rrweb-cssom@^0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz#c73451a484b86dd7cfb1e0b2898df4b703183e4b"
integrity sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==
rrweb-cssom@^0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz#3021d1b4352fbf3b614aaeed0bc0d5739abe0bc2"
integrity sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw==
run-parallel@^1.1.9:
version "1.2.0"
resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
dependencies:
queue-microtask "^1.2.2"
+rxjs@^7.4.0:
+ version "7.8.2"
+ resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.2.tgz#955bc473ed8af11a002a2be52071bf475638607b"
+ integrity sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==
+ dependencies:
+ tslib "^2.1.0"
+
+sade@^1.8.1:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701"
+ integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==
+ dependencies:
+ mri "^1.1.0"
+
safe-array-concat@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.3.tgz#c9e54ec4f603b0bbb8e7e5007a5ee7aecd1538c3"
integrity sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==
dependencies:
call-bind "^1.0.8"
call-bound "^1.0.2"
get-intrinsic "^1.2.6"
has-symbols "^1.1.0"
isarray "^2.0.5"
safe-buffer@5.2.1, safe-buffer@^5.1.0, safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
safe-push-apply@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/safe-push-apply/-/safe-push-apply-1.0.0.tgz#01850e981c1602d398c85081f360e4e6d03d27f5"
integrity sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==
dependencies:
es-errors "^1.3.0"
isarray "^2.0.5"
safe-regex-test@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.1.0.tgz#7f87dfb67a3150782eaaf18583ff5d1711ac10c1"
integrity sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==
dependencies:
call-bound "^1.0.2"
es-errors "^1.3.0"
is-regex "^1.2.1"
"safer-buffer@>= 2.1.2 < 3.0.0":
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
-sass@1.93.2:
- version "1.93.2"
- resolved "https://registry.yarnpkg.com/sass/-/sass-1.93.2.tgz#e97d225d60f59a3b3dbb6d2ae3c1b955fd1f2cd1"
- integrity sha512-t+YPtOQHpGW1QWsh1CHQ5cPIr9lbbGZLZnbihP/D/qZj/yuV68m8qarcV17nvkOX81BCrvzAlq2klCQFZghyTg==
- dependencies:
- chokidar "^4.0.0"
- immutable "^5.0.2"
+sass-embedded-all-unknown@1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass-embedded-all-unknown/-/sass-embedded-all-unknown-1.100.0.tgz#efee7111ec5e2d6c34a2f57d090e6416c01890ff"
+ integrity sha512-auFtXY/kwYILmSVjtBDwyj0axcLbYYiffOKWoaXHnI5bsYwiRbBh3EneR1rpbX2ZIZCrwX93i5pxKLTZF/662Q==
+ dependencies:
+ sass "1.100.0"
+
+sass-embedded-android-arm64@1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass-embedded-android-arm64/-/sass-embedded-android-arm64-1.100.0.tgz#0a4456a751f76a378ac9f3516a034f56eca9b171"
+ integrity sha512-W+Ru9JwTnfU0UX3jSZcbqFdtKFMcYdfFwytc57h2DgnqCOIiAqI2E06mABZBZC+r3LwXCBuS5GbXAGeVgvVDkA==
+
+sass-embedded-android-arm@1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass-embedded-android-arm/-/sass-embedded-android-arm-1.100.0.tgz#7de61d65cfa997c58df426a8b20a096a60497313"
+ integrity sha512-70f3HgX2pFNmzpGQ86n5e6QfWn2fP4QUQGfFQK0P1XH73ZLIzLo2YqygrGKGKeeqtc5eU2Wl1/xQzhzuKnO4kw==
+
+sass-embedded-android-riscv64@1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass-embedded-android-riscv64/-/sass-embedded-android-riscv64-1.100.0.tgz#cc6721c1526ef5b10d9da02f1e44e7dbaffc11e0"
+ integrity sha512-icU3o0V/uCSytSpf+tX5Lf51BvyQEbLzDUJfUi9etSauYBGHpPKkdtdZH0si4v98phq11Kl8rSV1SggksxF1Hg==
+
+sass-embedded-android-x64@1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass-embedded-android-x64/-/sass-embedded-android-x64-1.100.0.tgz#dc38f6c633f8bf61b470ac00452ebb50e36f421f"
+ integrity sha512-mevF9VQk6gEYByy8+jusaHGmd7Usb2ytX/DsEOd0JtOGCtcf1kh575xJ6OUBDIcJ15uLnbau/0iy1eP6WVBvWA==
+
+sass-embedded-darwin-arm64@1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass-embedded-darwin-arm64/-/sass-embedded-darwin-arm64-1.100.0.tgz#7773c0586e78caab599d53370626c28ca08110eb"
+ integrity sha512-1PVlYi61POo93IT/FfrG1mc1tAHxeSTyUALF2aOFmXGWjVXr3bQzEQiBGCOvQbj/ix+5hNyXFXcEMEyKvtUJJA==
+
+sass-embedded-darwin-x64@1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass-embedded-darwin-x64/-/sass-embedded-darwin-x64-1.100.0.tgz#91066f64875b87eba0cb699ba8254b4863d33901"
+ integrity sha512-x97o3JnGyImZNCIVs9wQHJUE5QCvmVIKaH1cwrz/5dK7OT1FpeNiW+u9TUomP9hG6Ekjd8EL8NBHpxTfIhdjmg==
+
+sass-embedded-linux-arm64@1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass-embedded-linux-arm64/-/sass-embedded-linux-arm64-1.100.0.tgz#88d2f51a0882f399c327a1d6cd06757d13de4f82"
+ integrity sha512-Dwjmj8Z6VRy7rAi53JAdEwIyUjpfl7PhpSc2/LpQPQx+aO5Dp7Spaipkax0ufJl1SoDUdchCsM4y/88YaluorQ==
+
+sass-embedded-linux-arm@1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass-embedded-linux-arm/-/sass-embedded-linux-arm-1.100.0.tgz#9721dca177348c1448847ceee1d031a692df0771"
+ integrity sha512-9Ul7O1eKrc5YlhwWjkp8tZPSe3UEwSZ1uwUZOQom1HL0pRlBA6F/IlGZYFTLwnHMIP1fc77MMNaBRfc05mKMpw==
+
+sass-embedded-linux-musl-arm64@1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass-embedded-linux-musl-arm64/-/sass-embedded-linux-musl-arm64-1.100.0.tgz#63a1e0618a2a3acf10bab915585c4dc495327581"
+ integrity sha512-XpACJB2KjSLjf2e9uuvGVdOURsoNrFqgRiihhXyUHK9W0t3LIHb7z5MA/7XGPIT9bWSOO2zyw+rH/FHtDV/Yrg==
+
+sass-embedded-linux-musl-arm@1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass-embedded-linux-musl-arm/-/sass-embedded-linux-musl-arm-1.100.0.tgz#44f9472ae663411de82b7792a918e162c7bcbc02"
+ integrity sha512-sl0JgbGloPyJg66XXx5UDSDScZ0oU85DpMQU4JU/sCUCFj1Z8zZ69SJWKTCNE4/jwnce7WI2zPCV5AG+RHOZJw==
+
+sass-embedded-linux-musl-riscv64@1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass-embedded-linux-musl-riscv64/-/sass-embedded-linux-musl-riscv64-1.100.0.tgz#21954e480cfb55d4ba8167626cde1cc8560d7eee"
+ integrity sha512-ShvI0Kx04mwoCARwZ0UjiT97isQvzO80tAt91zmFyHLN9kelc/IrQi940farSm2xQVPCKdeVyeG0ekBsokSpYQ==
+
+sass-embedded-linux-musl-x64@1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass-embedded-linux-musl-x64/-/sass-embedded-linux-musl-x64-1.100.0.tgz#a6c93d51999a8b22795d383b67e61962d32c96cd"
+ integrity sha512-TDBCRWNuS4RDLQXvRc1gjZlWiWTWaWGp0Bwu/IKwJxov81lsvrCs3TihTyNXtW7V5aoN4Ky3r0QOkNb3mwmBnA==
+
+sass-embedded-linux-riscv64@1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass-embedded-linux-riscv64/-/sass-embedded-linux-riscv64-1.100.0.tgz#01f20471a1be16d18e150993e5ac771d618abd34"
+ integrity sha512-j4ENJGOheO+fm3j/yorLxCjBP6/XskrZx7dTLlT+lXYwN/qqCqoA/gsNLI0McS3DFM6GBwPiffzWsdWS8t6sEQ==
+
+sass-embedded-linux-x64@1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass-embedded-linux-x64/-/sass-embedded-linux-x64-1.100.0.tgz#809649a0df17f7afb1dfd02e76dbf0676dd8471e"
+ integrity sha512-0vUSN8j0WGtCJIOPh//EmUvYGHW0QOe5iul8qyhPk50MAcw49MA0r34AhftjDdx94ILPF6vApFs0gwHPQRlpVA==
+
+sass-embedded-unknown-all@1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass-embedded-unknown-all/-/sass-embedded-unknown-all-1.100.0.tgz#fdc210a25a06e9d79655a02c1c77d656fa6f2ca0"
+ integrity sha512-c+naBgWId4MIpToXcI0DgqetjdAkwTTAxFAuOaBz7HUXLdyG1oZRrEvSsbe41nEdQOKH0vgofVFCeSQgoXOG9A==
+ dependencies:
+ sass "1.100.0"
+
+sass-embedded-win32-arm64@1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass-embedded-win32-arm64/-/sass-embedded-win32-arm64-1.100.0.tgz#fd8cec45b41390c3db40d13c4d291be7f35b6b0b"
+ integrity sha512-iE+yxj+hUXwwbqpHkXxgAWTzeRfcWxJ7SSTQEPMk48lwq3oCrWLlz5sQuWHbuTK/i0GKQfROdP+hOmPi89yjUg==
+
+sass-embedded-win32-x64@1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass-embedded-win32-x64/-/sass-embedded-win32-x64-1.100.0.tgz#a758862b1455d6616be301b363e7e1c93e6361b7"
+ integrity sha512-qI4F8MI7/KYoy9NdjJfhSspG42WPkADSNDvwEV7qWvCSFC83koJssRsKO2/PfY+niZz6BG65Ic/D+A11h959hw==
+
+sass-embedded@^1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass-embedded/-/sass-embedded-1.100.0.tgz#fe4742f2f80c21b287e3b90399b9a3f7ca1dcf6f"
+ integrity sha512-Ut8wlQSk19tm7jMK6mz6cF1+e+E7tUnW2tM02zQDPnOTcVbV8qCQG8UWxZkkNlY50+hV3hqP24OOkUlMz8xBpw==
+ dependencies:
+ "@bufbuild/protobuf" "^2.5.0"
+ colorjs.io "^0.5.0"
+ immutable "^5.1.5"
+ rxjs "^7.4.0"
+ supports-color "^8.1.1"
+ sync-child-process "^1.0.2"
+ varint "^6.0.0"
+ optionalDependencies:
+ sass-embedded-all-unknown "1.100.0"
+ sass-embedded-android-arm "1.100.0"
+ sass-embedded-android-arm64 "1.100.0"
+ sass-embedded-android-riscv64 "1.100.0"
+ sass-embedded-android-x64 "1.100.0"
+ sass-embedded-darwin-arm64 "1.100.0"
+ sass-embedded-darwin-x64 "1.100.0"
+ sass-embedded-linux-arm "1.100.0"
+ sass-embedded-linux-arm64 "1.100.0"
+ sass-embedded-linux-musl-arm "1.100.0"
+ sass-embedded-linux-musl-arm64 "1.100.0"
+ sass-embedded-linux-musl-riscv64 "1.100.0"
+ sass-embedded-linux-musl-x64 "1.100.0"
+ sass-embedded-linux-riscv64 "1.100.0"
+ sass-embedded-linux-x64 "1.100.0"
+ sass-embedded-unknown-all "1.100.0"
+ sass-embedded-win32-arm64 "1.100.0"
+ sass-embedded-win32-x64 "1.100.0"
+
+sass@1.100.0:
+ version "1.100.0"
+ resolved "https://registry.yarnpkg.com/sass/-/sass-1.100.0.tgz#b4cab1bed286fe22ac6c879c514f71cd36aa06c8"
+ integrity sha512-B5j0rYMlinhhOo9tjQebMVVn0TfyXAF+wB3b2ggZUuJ/is/Y+7+JGjirAMxHZ9Z3hIP98NPfamlAkBHa1lAaXQ==
+ dependencies:
+ chokidar "^5.0.0"
+ immutable "^5.1.5"
source-map-js ">=0.6.2 <2.0.0"
optionalDependencies:
"@parcel/watcher" "^2.4.1"
saxes@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/saxes/-/saxes-6.0.0.tgz#fe5b4a4768df4f14a201b1ba6a65c1f3d9988cc5"
integrity sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==
dependencies:
xmlchars "^2.2.0"
selenium-server@3.141.59:
version "3.141.59"
resolved "https://registry.yarnpkg.com/selenium-server/-/selenium-server-3.141.59.tgz#cbefdf50aae636ee4c67b819532a8233ce3fd6b0"
integrity sha512-pL7T1YtAqOEXiBbTx0KdZMkE2U7PYucemd7i0nDLcxcR1APXYZlJfNr5hrvL3mZgwXb7AJEZPINzC6mDU3eP5g==
selenium-webdriver@4.27.0:
version "4.27.0"
resolved "https://registry.yarnpkg.com/selenium-webdriver/-/selenium-webdriver-4.27.0.tgz#f0f26ce453805e7dc77151040442c67e441dbe7a"
integrity sha512-LkTJrNz5socxpPnWPODQ2bQ65eYx9JK+DQMYNihpTjMCqHwgWGYQnQTCAAche2W3ZP87alA+1zYPvgS8tHNzMQ==
dependencies:
"@bazel/runfiles" "^6.3.1"
jszip "^3.10.1"
tmp "^0.2.3"
ws "^8.18.0"
semver@7.5.4:
version "7.5.4"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
dependencies:
lru-cache "^6.0.0"
semver@7.7.3:
version "7.7.3"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.3.tgz#4b5f4143d007633a8dc671cd0a6ef9147b8bb946"
integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==
semver@^5.6.0:
version "5.7.2"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8"
integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
semver@^6.3.1:
version "6.3.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
semver@^7.3.5:
version "7.7.2"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58"
integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==
semver@^7.5.3, semver@^7.5.4, semver@^7.6.3:
version "7.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f"
integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==
send@^1.1.0, send@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/send/-/send-1.2.0.tgz#32a7554fb777b831dfa828370f773a3808d37212"
integrity sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==
dependencies:
debug "^4.3.5"
encodeurl "^2.0.0"
escape-html "^1.0.3"
etag "^1.8.1"
fresh "^2.0.0"
http-errors "^2.0.0"
mime-types "^3.0.1"
ms "^2.1.3"
on-finished "^2.4.1"
range-parser "^1.2.1"
statuses "^2.0.1"
serialize-javascript@6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8"
integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==
dependencies:
randombytes "^2.1.0"
serve-static@2.2.0, serve-static@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-2.2.0.tgz#9c02564ee259bdd2251b82d659a2e7e1938d66f9"
integrity sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==
dependencies:
encodeurl "^2.0.0"
escape-html "^1.0.3"
parseurl "^1.3.3"
send "^1.2.0"
set-blocking@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==
set-function-length@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449"
integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==
dependencies:
define-data-property "^1.1.4"
es-errors "^1.3.0"
function-bind "^1.1.2"
get-intrinsic "^1.2.4"
gopd "^1.0.1"
has-property-descriptors "^1.0.2"
set-function-name@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.2.tgz#16a705c5a0dc2f5e638ca96d8a8cd4e1c2b90985"
integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==
dependencies:
define-data-property "^1.1.4"
es-errors "^1.3.0"
functions-have-names "^1.2.3"
has-property-descriptors "^1.0.2"
set-proto@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/set-proto/-/set-proto-1.0.0.tgz#0760dbcff30b2d7e801fd6e19983e56da337565e"
integrity sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==
dependencies:
dunder-proto "^1.0.1"
es-errors "^1.3.0"
es-object-atoms "^1.0.0"
setimmediate@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==
setprototypeof@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
shallow-clone@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3"
integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==
dependencies:
kind-of "^6.0.2"
shebang-command@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
dependencies:
shebang-regex "^3.0.0"
shebang-regex@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
shelljs@0.10.0:
version "0.10.0"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.10.0.tgz#e3bbae99b0f3f0cc5dce05b46a346fae2090e883"
integrity sha512-Jex+xw5Mg2qMZL3qnzXIfaxEtBaC4n7xifqaqtrZDdlheR70OGkydrPJWT0V1cA1k3nanC86x9FwAmQl6w3Klw==
dependencies:
execa "^5.1.1"
fast-glob "^3.3.2"
side-channel-list@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad"
integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==
dependencies:
es-errors "^1.3.0"
object-inspect "^1.13.3"
side-channel-map@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42"
integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==
dependencies:
call-bound "^1.0.2"
es-errors "^1.3.0"
get-intrinsic "^1.2.5"
object-inspect "^1.13.3"
side-channel-weakmap@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea"
integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==
dependencies:
call-bound "^1.0.2"
es-errors "^1.3.0"
get-intrinsic "^1.2.5"
object-inspect "^1.13.3"
side-channel-map "^1.0.1"
side-channel@^1.0.4, side-channel@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9"
integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==
dependencies:
es-errors "^1.3.0"
object-inspect "^1.13.3"
side-channel-list "^1.0.0"
side-channel-map "^1.0.1"
side-channel-weakmap "^1.0.2"
siginfo@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/siginfo/-/siginfo-2.0.0.tgz#32e76c70b79724e3bb567cb9d543eb858ccfaf30"
integrity sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==
signal-exit@^3.0.2, signal-exit@^3.0.3:
version "3.0.7"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
signal-exit@^4.0.1, signal-exit@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04"
integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==
sinon-chai@4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-4.0.1.tgz#f70000fe0e4f4ab7ceeb3703d3053f8886e0386b"
integrity sha512-xMKEEV3cYHC1G+boyr7QEqi80gHznYsxVdC9CdjP5JnCWz/jPGuXQzJz3PtBcb0CcHAxar15Y5sjLBoAs6a0yA==
sinon@20.0.0:
version "20.0.0"
resolved "https://registry.yarnpkg.com/sinon/-/sinon-20.0.0.tgz#4b653468735f7152ba694d05498c2b5d024ab006"
integrity sha512-+FXOAbdnj94AQIxH0w1v8gzNxkawVvNqE3jUzRLptR71Oykeu2RrQXXl/VQjKay+Qnh73fDt/oDfMo6xMeDQbQ==
dependencies:
"@sinonjs/commons" "^3.0.1"
"@sinonjs/fake-timers" "^13.0.5"
"@sinonjs/samsam" "^8.0.1"
diff "^7.0.0"
supports-color "^7.2.0"
sirv@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/sirv/-/sirv-3.0.1.tgz#32a844794655b727f9e2867b777e0060fbe07bf3"
integrity sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==
dependencies:
"@polka/url" "^1.0.0-next.24"
mrmime "^2.0.0"
totalist "^3.0.0"
slash@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634"
integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==
slice-ansi@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b"
integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==
dependencies:
ansi-styles "^4.0.0"
astral-regex "^2.0.0"
is-fullwidth-code-point "^3.0.0"
smart-buffer@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae"
integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==
socks-proxy-agent@^8.0.5:
version "8.0.5"
resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz#b9cdb4e7e998509d7659d689ce7697ac21645bee"
integrity sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==
dependencies:
agent-base "^7.1.2"
debug "^4.3.4"
socks "^2.8.3"
socks@^2.8.3:
version "2.8.4"
resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.4.tgz#07109755cdd4da03269bda4725baa061ab56d5cc"
integrity sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==
dependencies:
ip-address "^9.0.5"
smart-buffer "^4.2.0"
"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2, source-map-js@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
source-map-support@^0.5.16:
version "0.5.21"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
dependencies:
buffer-from "^1.0.0"
source-map "^0.6.0"
source-map@^0.6.0, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
speakingurl@^14.0.1:
version "14.0.1"
resolved "https://registry.yarnpkg.com/speakingurl/-/speakingurl-14.0.1.tgz#f37ec8ddc4ab98e9600c1c9ec324a8c48d772a53"
integrity sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==
sprintf-js@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.3.tgz#4914b903a2f8b685d17fdf78a70e917e872e444a"
integrity sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==
+srvx@^0.11.15:
+ version "0.11.16"
+ resolved "https://registry.yarnpkg.com/srvx/-/srvx-0.11.16.tgz#750c66514e26cfa26507067156cbf1932b21ada0"
+ integrity sha512-bp07zRuycfTY43IjAvvTFnmnJi8ikW0VFiHwOhhYcVW/L4xQ1XY4PAd4Nuum1rsA17C39zL7x+CDhrn5AL32Rw==
+
stackback@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/stackback/-/stackback-0.0.2.tgz#1ac8a0d9483848d1695e418b6d031a3c3ce68e3b"
integrity sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==
stacktrace-parser@0.1.10:
version "0.1.10"
resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a"
integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==
dependencies:
type-fest "^0.7.1"
statuses@2.0.1, statuses@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
std-env@^3.9.0:
version "3.9.0"
resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.9.0.tgz#1a6f7243b339dca4c9fd55e1c7504c77ef23e8f1"
integrity sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==
stop-iteration-iterator@^1.0.0, stop-iteration-iterator@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz#f481ff70a548f6124d0312c3aa14cbfa7aa542ad"
integrity sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==
dependencies:
es-errors "^1.3.0"
internal-slot "^1.1.0"
strict-event-emitter@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz#1602ece81c51574ca39c6815e09f1a3e8550bd93"
integrity sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==
"string-width-cjs@npm:string-width@^4.2.0":
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"
string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, 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"
string-width@^5.0.1, string-width@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==
dependencies:
eastasianwidth "^0.2.0"
emoji-regex "^9.2.2"
strip-ansi "^7.0.1"
string.prototype.trim@^1.2.10:
version "1.2.10"
resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz#40b2dd5ee94c959b4dcfb1d65ce72e90da480c81"
integrity sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==
dependencies:
call-bind "^1.0.8"
call-bound "^1.0.2"
define-data-property "^1.1.4"
define-properties "^1.2.1"
es-abstract "^1.23.5"
es-object-atoms "^1.0.0"
has-property-descriptors "^1.0.2"
string.prototype.trimend@^1.0.9:
version "1.0.9"
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz#62e2731272cd285041b36596054e9f66569b6942"
integrity sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==
dependencies:
call-bind "^1.0.8"
call-bound "^1.0.2"
define-properties "^1.2.1"
es-object-atoms "^1.0.0"
string.prototype.trimstart@^1.0.8:
version "1.0.8"
resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz#7ee834dda8c7c17eff3118472bb35bfedaa34dde"
integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==
dependencies:
call-bind "^1.0.7"
define-properties "^1.2.1"
es-object-atoms "^1.0.0"
string_decoder@^1.1.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
dependencies:
safe-buffer "~5.2.0"
string_decoder@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
dependencies:
safe-buffer "~5.1.0"
"strip-ansi-cjs@npm: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"
strip-ansi@5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
dependencies:
ansi-regex "^4.1.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"
strip-ansi@^7.0.1:
version "7.1.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==
dependencies:
ansi-regex "^6.0.1"
strip-bom@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==
strip-final-newline@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
strip-json-comments@3.1.1, strip-json-comments@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
stylelint-config-html@>=1.0.0, stylelint-config-html@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/stylelint-config-html/-/stylelint-config-html-1.1.0.tgz#999db19aea713b7ff6dde92ada76e4c1bd812b66"
integrity sha512-IZv4IVESjKLumUGi+HWeb7skgO6/g4VMuAYrJdlqQFndgbj6WJAXPhaysvBiXefX79upBdQVumgYcdd17gCpjQ==
stylelint-config-recommended-scss@^14.0.0:
version "14.1.0"
resolved "https://registry.yarnpkg.com/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-14.1.0.tgz#1a5855655cddcb5f77c10f38c76567adf2bb9aa3"
integrity sha512-bhaMhh1u5dQqSsf6ri2GVWWQW5iUjBYgcHkh7SgDDn92ijoItC/cfO/W+fpXshgTQWhwFkP1rVcewcv4jaftRg==
dependencies:
postcss-scss "^4.0.9"
stylelint-config-recommended "^14.0.1"
stylelint-scss "^6.4.0"
stylelint-config-recommended-vue@^1.6.0:
version "1.6.1"
resolved "https://registry.yarnpkg.com/stylelint-config-recommended-vue/-/stylelint-config-recommended-vue-1.6.1.tgz#6a93082ce4a5c1f64793b789175a833c57ce8309"
integrity sha512-lLW7hTIMBiTfjenGuDq2kyHA6fBWd/+Df7MO4/AWOxiFeXP9clbpKgg27kHfwA3H7UNMGC7aeP3mNlZB5LMmEQ==
dependencies:
semver "^7.3.5"
stylelint-config-html ">=1.0.0"
stylelint-config-recommended ">=6.0.0"
stylelint-config-recommended@>=6.0.0, stylelint-config-recommended@^16.0.0:
version "16.0.0"
resolved "https://registry.yarnpkg.com/stylelint-config-recommended/-/stylelint-config-recommended-16.0.0.tgz#0221f19902816fe7d53d9a01eb0be4cc7b4fe80a"
integrity sha512-4RSmPjQegF34wNcK1e1O3Uz91HN8P1aFdFzio90wNK9mjgAI19u5vsU868cVZboKzCaa5XbpvtTzAAGQAxpcXA==
stylelint-config-recommended@^14.0.1:
version "14.0.1"
resolved "https://registry.yarnpkg.com/stylelint-config-recommended/-/stylelint-config-recommended-14.0.1.tgz#d25e86409aaf79ee6c6085c2c14b33c7e23c90c6"
integrity sha512-bLvc1WOz/14aPImu/cufKAZYfXs/A/owZfSMZ4N+16WGXLoX5lOir53M6odBxvhgmgdxCVnNySJmZKx73T93cg==
stylelint-config-standard@38.0.0:
version "38.0.0"
resolved "https://registry.yarnpkg.com/stylelint-config-standard/-/stylelint-config-standard-38.0.0.tgz#9d673ec1f35d7569476ee4b0582e7dd5faebf036"
integrity sha512-uj3JIX+dpFseqd/DJx8Gy3PcRAJhlEZ2IrlFOc4LUxBX/PNMEQ198x7LCOE2Q5oT9Vw8nyc4CIL78xSqPr6iag==
dependencies:
stylelint-config-recommended "^16.0.0"
stylelint-scss@^6.4.0:
version "6.11.1"
resolved "https://registry.yarnpkg.com/stylelint-scss/-/stylelint-scss-6.11.1.tgz#03860aab250112825b2deb77ca7ff1e2ba3a5414"
integrity sha512-e4rYo0UY+BIMtGeGanghrvHTjcryxgZbyFxUedp8dLFqC4P70aawNdYjRrQxbnKhu3BNr4+lt5e/53tcKXiwFA==
dependencies:
css-tree "^3.0.1"
is-plain-object "^5.0.0"
known-css-properties "^0.35.0"
mdn-data "^2.15.0"
postcss-media-query-parser "^0.2.3"
postcss-resolve-nested-selector "^0.1.6"
postcss-selector-parser "^7.1.0"
postcss-value-parser "^4.2.0"
stylelint@16.25.0:
version "16.25.0"
resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-16.25.0.tgz#c3d602974f2a18fa57fadc9f3f40129b098fe4dc"
integrity sha512-Li0avYWV4nfv1zPbdnxLYBGq4z8DVZxbRgx4Kn6V+Uftz1rMoF1qiEI3oL4kgWqyYgCgs7gT5maHNZ82Gk03vQ==
dependencies:
"@csstools/css-parser-algorithms" "^3.0.5"
"@csstools/css-tokenizer" "^3.0.4"
"@csstools/media-query-list-parser" "^4.0.3"
"@csstools/selector-specificity" "^5.0.0"
"@dual-bundle/import-meta-resolve" "^4.2.1"
balanced-match "^2.0.0"
colord "^2.9.3"
cosmiconfig "^9.0.0"
css-functions-list "^3.2.3"
css-tree "^3.1.0"
debug "^4.4.3"
fast-glob "^3.3.3"
fastest-levenshtein "^1.0.16"
file-entry-cache "^10.1.4"
global-modules "^2.0.0"
globby "^11.1.0"
globjoin "^0.1.4"
html-tags "^3.3.1"
ignore "^7.0.5"
imurmurhash "^0.1.4"
is-plain-object "^5.0.0"
known-css-properties "^0.37.0"
mathml-tag-names "^2.1.3"
meow "^13.2.0"
micromatch "^4.0.8"
normalize-path "^3.0.0"
picocolors "^1.1.1"
postcss "^8.5.6"
postcss-resolve-nested-selector "^0.1.6"
postcss-safe-parser "^7.0.1"
postcss-selector-parser "^7.1.0"
postcss-value-parser "^4.2.0"
resolve-from "^5.0.0"
string-width "^4.2.3"
supports-hyperlinks "^3.2.0"
svg-tags "^1.0.0"
table "^6.9.0"
write-file-atomic "^5.0.1"
superjson@^2.2.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/superjson/-/superjson-2.2.2.tgz#9d52bf0bf6b5751a3c3472f1292e714782ba3173"
integrity sha512-5JRxVqC8I8NuOUjzBbvVJAKNM8qoVuH0O77h4WInc/qC2q5IreqKxYwgkga3PfA22OayK2ikceb/B26dztPl+Q==
dependencies:
copy-anything "^3.0.2"
-supports-color@8.1.1:
+supports-color@8.1.1, supports-color@^8.1.1:
version "8.1.1"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
dependencies:
has-flag "^4.0.0"
supports-color@^5.3.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
dependencies:
has-flag "^3.0.0"
supports-color@^7.0.0, supports-color@^7.1.0, supports-color@^7.2.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
dependencies:
has-flag "^4.0.0"
supports-hyperlinks@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz#b8e485b179681dea496a1e7abdf8985bd3145461"
integrity sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==
dependencies:
has-flag "^4.0.0"
supports-color "^7.0.0"
supports-preserve-symlinks-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
svg-tags@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764"
integrity sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==
symbol-tree@^3.2.4:
version "3.2.4"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==
+sync-child-process@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/sync-child-process/-/sync-child-process-1.0.2.tgz#45e7c72e756d1243e80b547ea2e17957ab9e367f"
+ integrity sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA==
+ dependencies:
+ sync-message-port "^1.0.0"
+
+sync-message-port@^1.0.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/sync-message-port/-/sync-message-port-1.2.0.tgz#4b0d622085f21496061037125dec61755d96e330"
+ integrity sha512-gAQ9qrUN/UCypHtGFbbe7Rc/f9bzO88IwrG8TDo/aMKAApKyD6E3W4Cm0EfhfBb6Z6SKt59tTCTfD+n1xmAvMg==
+
table@^6.9.0:
version "6.9.0"
resolved "https://registry.yarnpkg.com/table/-/table-6.9.0.tgz#50040afa6264141c7566b3b81d4d82c47a8668f5"
integrity sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==
dependencies:
ajv "^8.0.1"
lodash.truncate "^4.4.2"
slice-ansi "^4.0.0"
string-width "^4.2.3"
strip-ansi "^6.0.1"
tapable@^2.2.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
tar-stream@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287"
integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==
dependencies:
bl "^4.0.3"
end-of-stream "^1.4.1"
fs-constants "^1.0.0"
inherits "^2.0.3"
readable-stream "^3.1.1"
tcp-port-used@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/tcp-port-used/-/tcp-port-used-1.0.2.tgz#9652b7436eb1f4cfae111c79b558a25769f6faea"
integrity sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==
dependencies:
debug "4.3.1"
is2 "^2.0.6"
text-table@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==
tinybench@^2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/tinybench/-/tinybench-2.9.0.tgz#103c9f8ba6d7237a47ab6dd1dcff77251863426b"
integrity sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==
tinyexec@^0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-0.3.2.tgz#941794e657a85e496577995c6eef66f53f42b3d2"
integrity sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==
+tinyexec@^1.2.2:
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/tinyexec/-/tinyexec-1.2.4.tgz#ae45bb2edebda94c70f4ea897e0f1243e470db71"
+ integrity sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==
+
tinyglobby@^0.2.13:
version "0.2.15"
resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.15.tgz#e228dd1e638cea993d2fdb4fcd2d4602a79951c2"
integrity sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==
dependencies:
fdir "^6.5.0"
picomatch "^4.0.3"
+tinyglobby@^0.2.16, tinyglobby@^0.2.17:
+ version "0.2.17"
+ resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.17.tgz#562a9a6c9eb2b3b123d39719f9af5bb44fcd7631"
+ integrity sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==
+ dependencies:
+ fdir "^6.5.0"
+ picomatch "^4.0.4"
+
tinypool@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/tinypool/-/tinypool-1.0.2.tgz#706193cc532f4c100f66aa00b01c42173d9051b2"
integrity sha512-al6n+QEANGFOMf/dmUMsuS5/r9B06uwlyNjZZql/zv8J7ybHCgoihBNORZCY2mzUuAnomQa2JdhyHKzZxPCrFA==
tinyrainbow@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-2.0.0.tgz#9509b2162436315e80e3eee0fcce4474d2444294"
integrity sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==
tinyspy@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/tinyspy/-/tinyspy-3.0.2.tgz#86dd3cf3d737b15adcf17d7887c84a75201df20a"
integrity sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==
tmp@^0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae"
integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==
to-regex-range@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
dependencies:
is-number "^7.0.0"
toidentifier@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
totalist@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/totalist/-/totalist-3.0.1.tgz#ba3a3d600c915b1a97872348f79c127475f6acf8"
integrity sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==
tough-cookie@^4.1.4:
version "4.1.4"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36"
integrity sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==
dependencies:
psl "^1.1.33"
punycode "^2.1.1"
universalify "^0.2.0"
url-parse "^1.5.3"
tr46@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/tr46/-/tr46-5.1.0.tgz#4a077922360ae807e172075ce5beb79b36e4a101"
integrity sha512-IUWnUK7ADYR5Sl1fZlO1INDUhVhatWl7BtJWsIhwJ0UAK7ilzzIa8uIqOO/aYVWHZPJkKbEL+362wrzoeRF7bw==
dependencies:
punycode "^2.3.1"
ts-declaration-location@^1.0.6:
version "1.0.7"
resolved "https://registry.yarnpkg.com/ts-declaration-location/-/ts-declaration-location-1.0.7.tgz#d4068fe9975828b3b453b3ab112b4711d8267688"
integrity sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA==
dependencies:
picomatch "^4.0.2"
tsconfig-paths@^3.15.0:
version "3.15.0"
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4"
integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==
dependencies:
"@types/json5" "^0.0.29"
json5 "^1.0.2"
minimist "^1.2.6"
strip-bom "^3.0.0"
-tslib@^2.0.1:
+tslib@^2.0.1, tslib@^2.1.0, tslib@^2.4.0:
version "2.8.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f"
integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==
type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==
dependencies:
prelude-ls "^1.2.1"
type-detect@4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==
type-detect@^4.0.0, type-detect@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.1.0.tgz#deb2453e8f08dcae7ae98c626b13dddb0155906c"
integrity sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==
type-fest@^0.20.2:
version "0.20.2"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
type-fest@^0.21.3:
version "0.21.3"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
type-fest@^0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48"
integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==
type-fest@^4.26.1:
version "4.39.0"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.39.0.tgz#c7758be50a83a5b879e7a59ea52421e9816b3928"
integrity sha512-w2IGJU1tIgcrepg9ZJ82d8UmItNQtOFJG0HCUE3SzMokKkTsruVDALl2fAdiEzJlfduoU+VyXJWIIUZ+6jV+nw==
type-is@^2.0.0, type-is@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-2.0.1.tgz#64f6cf03f92fce4015c2b224793f6bdd4b068c97"
integrity sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==
dependencies:
content-type "^1.0.5"
media-typer "^1.1.0"
mime-types "^3.0.0"
typed-array-buffer@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz#a72395450a4869ec033fd549371b47af3a2ee536"
integrity sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==
dependencies:
call-bound "^1.0.3"
es-errors "^1.3.0"
is-typed-array "^1.1.14"
typed-array-byte-length@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz#8407a04f7d78684f3d252aa1a143d2b77b4160ce"
integrity sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==
dependencies:
call-bind "^1.0.8"
for-each "^0.3.3"
gopd "^1.2.0"
has-proto "^1.2.0"
is-typed-array "^1.1.14"
typed-array-byte-offset@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz#ae3698b8ec91a8ab945016108aef00d5bff12355"
integrity sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==
dependencies:
available-typed-arrays "^1.0.7"
call-bind "^1.0.8"
for-each "^0.3.3"
gopd "^1.2.0"
has-proto "^1.2.0"
is-typed-array "^1.1.15"
reflect.getprototypeof "^1.0.9"
typed-array-length@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.7.tgz#ee4deff984b64be1e118b0de8c9c877d5ce73d3d"
integrity sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==
dependencies:
call-bind "^1.0.7"
for-each "^0.3.3"
gopd "^1.0.1"
is-typed-array "^1.1.13"
possible-typed-array-names "^1.0.0"
reflect.getprototypeof "^1.0.6"
+ufo@^1.6.1, ufo@^1.6.3:
+ version "1.6.4"
+ resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.6.4.tgz#7a8fb875fcc6382d2c7d0b3692738b0500a92467"
+ integrity sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==
+
unbox-primitive@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.1.0.tgz#8d9d2c9edeea8460c7f35033a88867944934d1e2"
integrity sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==
dependencies:
call-bound "^1.0.3"
has-bigints "^1.0.2"
has-symbols "^1.1.0"
which-boxed-primitive "^1.1.1"
+unconfig-core@7.5.0:
+ version "7.5.0"
+ resolved "https://registry.yarnpkg.com/unconfig-core/-/unconfig-core-7.5.0.tgz#68f3d000701288418f3d36203d886f38c3986677"
+ integrity sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==
+ dependencies:
+ "@quansync/fs" "^1.0.0"
+ quansync "^1.0.0"
+
+unconfig@^7.5.0:
+ version "7.5.0"
+ resolved "https://registry.yarnpkg.com/unconfig/-/unconfig-7.5.0.tgz#122d8ef27e27aedf5551485069161c0852ab534d"
+ integrity sha512-oi8Qy2JV4D3UQ0PsopR28CzdQ3S/5A1zwsUwp/rosSbfhJ5z7b90bIyTwi/F7hCLD4SGcZVjDzd4XoUQcEanvA==
+ dependencies:
+ "@quansync/fs" "^1.0.0"
+ defu "^6.1.4"
+ jiti "^2.6.1"
+ quansync "^1.0.0"
+ unconfig-core "7.5.0"
+
+uncrypto@^0.1.3:
+ version "0.1.3"
+ resolved "https://registry.yarnpkg.com/uncrypto/-/uncrypto-0.1.3.tgz#e1288d609226f2d02d8d69ee861fa20d8348ef2b"
+ integrity sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==
+
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==
unicode-canonical-property-names-ecmascript@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz#cb3173fe47ca743e228216e4a3ddc4c84d628cc2"
integrity sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==
unicode-match-property-ecmascript@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3"
integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==
dependencies:
unicode-canonical-property-names-ecmascript "^2.0.0"
unicode-property-aliases-ecmascript "^2.0.0"
unicode-match-property-value-ecmascript@^2.1.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz#a0401aee72714598f739b68b104e4fe3a0cb3c71"
integrity sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==
unicode-property-aliases-ecmascript@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd"
integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==
universalify@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0"
integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==
unpipe@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
+unplugin@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/unplugin/-/unplugin-3.0.0.tgz#01e40c474bf74d363744f4cb262569d26dd9bb43"
+ integrity sha512-0Mqk3AT2TZCXWKdcoaufeXNukv2mTrEZExeXlHIOZXdqYoHHr4n51pymnwV8x2BOVxwXbK2HLlI7usrqMpycdg==
+ dependencies:
+ "@jridgewell/remapping" "^2.3.5"
+ picomatch "^4.0.3"
+ webpack-virtual-modules "^0.6.2"
+
+unstorage@^1.17.5:
+ version "1.17.5"
+ resolved "https://registry.yarnpkg.com/unstorage/-/unstorage-1.17.5.tgz#e76c82fdc1d2c04cb0e2c0a1de08aa08b2253f51"
+ integrity sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==
+ dependencies:
+ anymatch "^3.1.3"
+ chokidar "^5.0.0"
+ destr "^2.0.5"
+ h3 "^1.15.10"
+ lru-cache "^11.2.7"
+ node-fetch-native "^1.6.7"
+ ofetch "^1.5.1"
+ ufo "^1.6.3"
+
untildify@4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b"
integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==
update-browserslist-db@^1.1.1, update-browserslist-db@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420"
integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==
dependencies:
escalade "^3.2.0"
picocolors "^1.1.1"
uri-js@^4.2.2:
version "4.4.1"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
dependencies:
punycode "^2.1.0"
url-parse@^1.5.3:
version "1.5.10"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1"
integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==
dependencies:
querystringify "^2.1.1"
requires-port "^1.0.0"
url@0.11.4:
version "0.11.4"
resolved "https://registry.yarnpkg.com/url/-/url-0.11.4.tgz#adca77b3562d56b72746e76b330b7f27b6721f3c"
integrity sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==
dependencies:
punycode "^1.4.1"
qs "^6.12.3"
utf8@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1"
integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==
util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
uuid@11.1.0:
version "11.1.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-11.1.0.tgz#9549028be1753bb934fc96e2bca09bb4105ae912"
integrity sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==
uuid@8.3.2:
version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
+valibot@^1.4.1:
+ version "1.4.1"
+ resolved "https://registry.yarnpkg.com/valibot/-/valibot-1.4.1.tgz#68f812ae16ec9fffc5f203c33f9d117893df8da8"
+ integrity sha512-klCmFTz2jeDluy9RwX+F884TCiogtdBJ/YaxSx1EOBYXa3NXNWj8kR1jjN8rzluwojJVWWaHJ4r1U5LfICnM3g==
+
+varint@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/varint/-/varint-6.0.0.tgz#9881eb0ce8feaea6512439d19ddf84bf551661d0"
+ integrity sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==
+
vary@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
vite-node@3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-3.1.3.tgz#d021ced40b5a057305eaea9ce62c610c33b60a48"
integrity sha512-uHV4plJ2IxCl4u1up1FQRrqclylKAogbtBfOTwcuJ28xFi+89PZ57BRh+naIRvH70HPwxy5QHYzg1OrEaC7AbA==
dependencies:
cac "^6.7.14"
debug "^4.4.0"
es-module-lexer "^1.7.0"
pathe "^2.0.3"
vite "^5.0.0 || ^6.0.0"
-vite-plugin-eslint2@^5.0.3:
- version "5.0.4"
- resolved "https://registry.yarnpkg.com/vite-plugin-eslint2/-/vite-plugin-eslint2-5.0.4.tgz#7276c9179742d3c19faa94f30f9eb5cb7ac04888"
- integrity sha512-3Yc7K2R/RrONB9JtwEh2Y40YP3tQi/3UiNHrwcYDsDBKDKnEu7B8PwmXLm7piDFRbxcnTPvgrV2LZnBpKP8JUw==
+vite-plugin-eslint2@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/vite-plugin-eslint2/-/vite-plugin-eslint2-5.1.0.tgz#c796d4dc852b35f91db508946a4833589adea319"
+ integrity sha512-fNuO/D7b+EZ5ejhuBA80tiaxWztZWDHc+lCZaXMOHgYfqFXq8WKmGwrudS+/jscp0UNAKGB71du+xoP8azSXiw==
dependencies:
- "@rollup/pluginutils" "^5.2.0"
- debug "^4.4.1"
+ "@rollup/pluginutils" "^5.3.0"
+ debug "^4.4.3"
-vite-plugin-stylelint@^6.0.0:
- version "6.0.2"
- resolved "https://registry.yarnpkg.com/vite-plugin-stylelint/-/vite-plugin-stylelint-6.0.2.tgz#8a44345dacb6710877cd841e0467811c6b90253d"
- integrity sha512-whqm2m5rvfd4cYA+cpwZ3BROR/5enRGdRr65hxQNHYn6YFmP8M1xrVKEbLIEBSmmSZ7G7AEZWccS8X+UAksIXA==
+vite-plugin-stylelint@^6.1.0:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/vite-plugin-stylelint/-/vite-plugin-stylelint-6.1.0.tgz#8c039d1d9bc1db1e81e55ddd2dc6bc6bbda95300"
+ integrity sha512-tMw0gum2gRtul0FA4fbYp5qIvympqUf1YJ7owRjzqMCaWZYoUVN4dXFlauo1ll2UE2ujzBFKfW9VFaXdmODVPQ==
dependencies:
- "@rollup/pluginutils" "^5.2.0"
- debug "^4.4.1"
+ "@rollup/pluginutils" "^5.3.0"
+ debug "^4.4.3"
-"vite@^5.0.0 || ^6.0.0", vite@^6.1.0:
+"vite@^5.0.0 || ^6.0.0":
version "6.4.1"
resolved "https://registry.yarnpkg.com/vite/-/vite-6.4.1.tgz#afbe14518cdd6887e240a4b0221ab6d0ce733f96"
integrity sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g==
dependencies:
esbuild "^0.25.0"
fdir "^6.4.4"
picomatch "^4.0.2"
postcss "^8.5.3"
rollup "^4.34.9"
tinyglobby "^0.2.13"
optionalDependencies:
fsevents "~2.3.3"
+vite@^8.0.0:
+ version "8.0.16"
+ resolved "https://registry.yarnpkg.com/vite/-/vite-8.0.16.tgz#ae073866c06563d6634a90169a496e11bd84f1a6"
+ integrity sha512-h9bXPmJichP5fLmVQo3PyaGSDE2n3aPuomeAlVRm0JLmt4rY6zmPKd59HYI4LNW8oTK7tlTsuC7l/m7awx9Jcw==
+ dependencies:
+ lightningcss "^1.32.0"
+ picomatch "^4.0.4"
+ postcss "^8.5.15"
+ rolldown "1.0.3"
+ tinyglobby "^0.2.17"
+ optionalDependencies:
+ fsevents "~2.3.3"
+
vitest@^3.0.7:
version "3.1.3"
resolved "https://registry.yarnpkg.com/vitest/-/vitest-3.1.3.tgz#0b0b01932408cd3af61867f4468d28bd83406ffb"
integrity sha512-188iM4hAHQ0km23TN/adso1q5hhwKqUpv+Sd6p5sOuh6FhQnRNW3IsiIpvxqahtBabsJ2SLZgmGSpcYK4wQYJw==
dependencies:
"@vitest/expect" "3.1.3"
"@vitest/mocker" "3.1.3"
"@vitest/pretty-format" "^3.1.3"
"@vitest/runner" "3.1.3"
"@vitest/snapshot" "3.1.3"
"@vitest/spy" "3.1.3"
"@vitest/utils" "3.1.3"
chai "^5.2.0"
debug "^4.4.0"
expect-type "^1.2.1"
magic-string "^0.30.17"
pathe "^2.0.3"
std-env "^3.9.0"
tinybench "^2.9.0"
tinyexec "^0.3.2"
tinyglobby "^0.2.13"
tinypool "^1.0.2"
tinyrainbow "^2.0.0"
vite "^5.0.0 || ^6.0.0"
vite-node "3.1.3"
why-is-node-running "^2.3.0"
vue-component-type-helpers@^2.0.0:
version "2.2.8"
resolved "https://registry.yarnpkg.com/vue-component-type-helpers/-/vue-component-type-helpers-2.2.8.tgz#66d25e4405a4bcc06a22aa4c01e35141343da580"
integrity sha512-4bjIsC284coDO9om4HPA62M7wfsTvcmZyzdfR0aUlFXqq4tXxM1APyXpNVxPC8QazKw9OhmZNHBVDA6ODaZsrA==
vue-demi@^0.13.11:
version "0.13.11"
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.13.11.tgz#7d90369bdae8974d87b1973564ad390182410d99"
integrity sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==
vue-eslint-parser@10.2.0:
version "10.2.0"
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-10.2.0.tgz#cb53f89b14c7f5bf6a95c9532e3b2961ab619d61"
integrity sha512-CydUvFOQKD928UzZhTp4pr2vWz1L+H99t7Pkln2QSPdvmURT0MoC4wUccfCnuEaihNsu9aYYyk+bep8rlfkUXw==
dependencies:
debug "^4.4.0"
eslint-scope "^8.2.0"
eslint-visitor-keys "^4.2.0"
espree "^10.3.0"
esquery "^1.6.0"
semver "^7.6.3"
vue-i18n@11:
version "11.1.12"
resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-11.1.12.tgz#230b21d65dd89343ebd40d19c9e3cfb13db8c1fd"
integrity sha512-BnstPj3KLHLrsqbVU2UOrPmr0+Mv11bsUZG0PyCOzsawCivk8W00GMXHeVUWIDOgNaScCuZah47CZFE+Wnl8mw==
dependencies:
"@intlify/core-base" "11.1.12"
"@intlify/shared" "11.1.12"
"@vue/devtools-api" "^6.5.0"
vue-observe-visibility@^2.0.0-alpha.1:
version "2.0.0-alpha.1"
resolved "https://registry.yarnpkg.com/vue-observe-visibility/-/vue-observe-visibility-2.0.0-alpha.1.tgz#1e4eda7b12562161d58984b7e0dea676d83bdb13"
integrity sha512-flFbp/gs9pZniXR6fans8smv1kDScJ8RS7rEpMjhVabiKeq7Qz3D9+eGsypncjfIyyU84saU88XZ0zjbD6Gq/g==
vue-resize@^2.0.0-alpha.1:
version "2.0.0-alpha.1"
resolved "https://registry.yarnpkg.com/vue-resize/-/vue-resize-2.0.0-alpha.1.tgz#43eeb79e74febe932b9b20c5c57e0ebc14e2df3a"
integrity sha512-7+iqOueLU7uc9NrMfrzbG8hwMqchfVfSzpVlCMeJQe4pyibqyoifDNbKTZvwxZKDvGkB+PdFeKvnGZMoEb8esg==
vue-router@4.6.4:
version "4.6.4"
resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.6.4.tgz#a0a9cb9ef811a106d249e4bb9313d286718020d8"
integrity sha512-Hz9q5sa33Yhduglwz6g9skT8OBPii+4bFn88w6J+J4MfEo4KRRpmiNG/hHHkdbRFlLBOqxN8y8gf2Fb0MTUgVg==
dependencies:
"@vue/devtools-api" "^6.6.4"
vue-virtual-scroller@^2.0.0-beta.7:
version "2.0.0-beta.8"
resolved "https://registry.yarnpkg.com/vue-virtual-scroller/-/vue-virtual-scroller-2.0.0-beta.8.tgz#eeceda57e4faa5ba1763994c873923e2a956898b"
integrity sha512-b8/f5NQ5nIEBRTNi6GcPItE4s7kxNHw2AIHLtDp+2QvqdTjVN0FgONwX9cr53jWRgnu+HRLPaWDOR2JPI5MTfQ==
dependencies:
mitt "^2.1.0"
vue-observe-visibility "^2.0.0-alpha.1"
vue-resize "^2.0.0-alpha.1"
+vue-virtual-scroller@^3.0.4:
+ version "3.0.4"
+ resolved "https://registry.yarnpkg.com/vue-virtual-scroller/-/vue-virtual-scroller-3.0.4.tgz#b97214b0e8f32e4667921550a461a3ac0741389e"
+ integrity sha512-3qh3c9VUVysuXynaa4fVZ3ncx3VgD7EPRiQcj+jUVZl5u/TTkD3c27XvSEu3JGJfsJt/vVTVziZ3djiiHtW4cQ==
+
vue@3.5.22:
version "3.5.22"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.5.22.tgz#2b8ddb94ee4b640ef12fe7f6efe1cf16f3b582e7"
integrity sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==
dependencies:
"@vue/compiler-dom" "3.5.22"
"@vue/compiler-sfc" "3.5.22"
"@vue/runtime-dom" "3.5.22"
"@vue/server-renderer" "3.5.22"
"@vue/shared" "3.5.22"
+vue@^3.5.35:
+ version "3.5.35"
+ resolved "https://registry.yarnpkg.com/vue/-/vue-3.5.35.tgz#ba502479bd781825514c8af0f40744eeeb6223d6"
+ integrity sha512-cx89fnr+0kVGHiNFG6y6s0bdjypJRFNZn6x3WPstNdQR1bi1mbB7h4v5IBGTsPJU3nK1+0Iqj3Zf+hZWMieR4Q==
+ dependencies:
+ "@vue/compiler-dom" "3.5.35"
+ "@vue/compiler-sfc" "3.5.35"
+ "@vue/runtime-dom" "3.5.35"
+ "@vue/server-renderer" "3.5.35"
+ "@vue/shared" "3.5.35"
+
vuex@4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/vuex/-/vuex-4.1.0.tgz#aa1b3ea5c7385812b074c86faeeec2217872e36c"
integrity sha512-hmV6UerDrPcgbSy9ORAtNXDr9M4wlNP4pEFKye4ujJF8oqgFFuxDCdOLS3eNoRTtq5O3hoBDh9Doj1bQMYHRbQ==
dependencies:
"@vue/devtools-api" "^6.0.0-beta.11"
w3c-xmlserializer@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz#f925ba26855158594d907313cedd1476c5967f6c"
integrity sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==
dependencies:
xml-name-validator "^5.0.0"
wcwidth@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8"
integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==
dependencies:
defaults "^1.0.3"
webidl-conversions@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a"
integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==
+webpack-virtual-modules@^0.6.2:
+ version "0.6.2"
+ resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz#057faa9065c8acf48f24cb57ac0e77739ab9a7e8"
+ integrity sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==
+
whatwg-encoding@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz#d0f4ef769905d426e1688f3e34381a99b60b76e5"
integrity sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==
dependencies:
iconv-lite "0.6.3"
whatwg-mimetype@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz#bc1bf94a985dc50388d54a9258ac405c3ca2fc0a"
integrity sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==
whatwg-url@^14.0.0:
version "14.2.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-14.2.0.tgz#4ee02d5d725155dae004f6ae95c73e7ef5d95663"
integrity sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==
dependencies:
tr46 "^5.1.0"
webidl-conversions "^7.0.0"
which-boxed-primitive@^1.0.2, which-boxed-primitive@^1.1.0, which-boxed-primitive@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz#d76ec27df7fa165f18d5808374a5fe23c29b176e"
integrity sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==
dependencies:
is-bigint "^1.1.0"
is-boolean-object "^1.2.1"
is-number-object "^1.1.1"
is-string "^1.1.1"
is-symbol "^1.1.1"
which-builtin-type@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.2.1.tgz#89183da1b4907ab089a6b02029cc5d8d6574270e"
integrity sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==
dependencies:
call-bound "^1.0.2"
function.prototype.name "^1.1.6"
has-tostringtag "^1.0.2"
is-async-function "^2.0.0"
is-date-object "^1.1.0"
is-finalizationregistry "^1.1.0"
is-generator-function "^1.0.10"
is-regex "^1.2.1"
is-weakref "^1.0.2"
isarray "^2.0.5"
which-boxed-primitive "^1.1.0"
which-collection "^1.0.2"
which-typed-array "^1.1.16"
which-collection@^1.0.1, which-collection@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.2.tgz#627ef76243920a107e7ce8e96191debe4b16c2a0"
integrity sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==
dependencies:
is-map "^2.0.3"
is-set "^2.0.3"
is-weakmap "^2.0.2"
is-weakset "^2.0.3"
which-module@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409"
integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==
which-typed-array@^1.1.13, which-typed-array@^1.1.16, which-typed-array@^1.1.18, which-typed-array@^1.1.19:
version "1.1.19"
resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.19.tgz#df03842e870b6b88e117524a4b364b6fc689f956"
integrity sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==
dependencies:
available-typed-arrays "^1.0.7"
call-bind "^1.0.8"
call-bound "^1.0.4"
for-each "^0.3.5"
get-proto "^1.0.1"
gopd "^1.2.0"
has-tostringtag "^1.0.2"
which@^1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a"
integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
dependencies:
isexe "^2.0.0"
which@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
dependencies:
isexe "^2.0.0"
why-is-node-running@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/why-is-node-running/-/why-is-node-running-2.3.0.tgz#a3f69a97107f494b3cdc3bdddd883a7d65cebf04"
integrity sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==
dependencies:
siginfo "^2.0.0"
stackback "0.0.2"
widest-line@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca"
integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==
dependencies:
string-width "^4.0.0"
word-wrap@^1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34"
integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==
workerpool@6.2.1:
version "6.2.1"
resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343"
integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==
"wrap-ansi-cjs@npm: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"
wrap-ansi@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53"
integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==
dependencies:
ansi-styles "^4.0.0"
string-width "^4.1.0"
strip-ansi "^6.0.0"
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"
wrap-ansi@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==
dependencies:
ansi-styles "^6.1.0"
string-width "^5.0.1"
strip-ansi "^7.0.1"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
write-file-atomic@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.1.tgz#68df4717c55c6fa4281a7860b4c2ba0a6d2b11e7"
integrity sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==
dependencies:
imurmurhash "^0.1.4"
signal-exit "^4.0.1"
ws@^8.18.0:
version "8.18.1"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.1.tgz#ea131d3784e1dfdff91adb0a4a116b127515e3cb"
integrity sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==
ws@^8.18.1:
version "8.18.2"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.2.tgz#42738b2be57ced85f46154320aabb51ab003705a"
integrity sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==
+ws@^8.21.0:
+ version "8.21.0"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-8.21.0.tgz#012e413fc07429945121b0c153158c4343086951"
+ integrity sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==
+
xml-name-validator@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835"
integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==
xml-name-validator@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-5.0.0.tgz#82be9b957f7afdacf961e5980f1bf227c0bf7673"
integrity sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==
xmlchars@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb"
integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==
xtend@~4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
y18n@^4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf"
integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==
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==
yallist@^3.0.2:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yargs-parser@20.2.4:
version "20.2.4"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54"
integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==
yargs-parser@^18.1.2:
version "18.1.3"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"
integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==
dependencies:
camelcase "^5.0.0"
decamelize "^1.2.0"
yargs-parser@^20.2.2:
version "20.2.9"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
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-unparser@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb"
integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==
dependencies:
camelcase "^6.0.0"
decamelize "^4.0.0"
flat "^5.0.2"
is-plain-obj "^2.1.0"
yargs@16.2.0:
version "16.2.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
dependencies:
cliui "^7.0.2"
escalade "^3.1.1"
get-caller-file "^2.0.5"
require-directory "^2.1.1"
string-width "^4.2.0"
y18n "^5.0.5"
yargs-parser "^20.2.2"
yargs@^15.3.1:
version "15.4.1"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8"
integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==
dependencies:
cliui "^6.0.0"
decamelize "^1.2.0"
find-up "^4.1.0"
get-caller-file "^2.0.1"
require-directory "^2.1.1"
require-main-filename "^2.0.0"
set-blocking "^2.0.0"
string-width "^4.2.0"
which-module "^2.0.0"
y18n "^4.0.0"
yargs-parser "^18.1.2"
yargs@^17.7.2:
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"
yauzl@^2.10.0:
version "2.10.0"
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==
dependencies:
buffer-crc32 "~0.2.3"
fd-slicer "~1.1.0"
yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
+yocto-queue@^1.2.1:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.2.2.tgz#3e09c95d3f1aa89a58c114c99223edf639152c00"
+ integrity sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==
+
yoctocolors-cjs@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz#f4b905a840a37506813a7acaa28febe97767a242"
integrity sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==
zip-stream@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-4.1.1.tgz#1337fe974dbaffd2fa9a1ba09662a66932bd7135"
integrity sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==
dependencies:
archiver-utils "^3.0.4"
compress-commons "^4.1.2"
readable-stream "^3.6.0"

File Metadata

Mime Type
text/x-diff
Expires
Sun, Jun 28, 5:43 AM (7 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1630650
Default Alt Text
(1 MB)

Event Timeline