Compare commits

...

7 Commits

Author SHA1 Message Date
orangecoding
ea24eb4374 upgrading dependencies 2025-12-04 09:58:58 +01:00
orangecoding
9f67e30ff4 upgrade version 2025-11-27 16:09:44 +01:00
orangecoding
20d44b60ad upgrading dependencies 2025-11-27 15:54:54 +01:00
orangecoding
22df683969 more efficient bot protection 2025-11-27 10:30:47 +01:00
Robin Fuchs
4aab850b4f feat: updated the UI to enable editing of provider URLs (#234)
* feat: updated the UI to enable editing of provider URLs


---------

Co-authored-by: foxx-tech <robin.foxx.tech@gmail.com>
2025-11-26 17:10:42 +01:00
Efe
3eb3f6ee66 fix: notification adapter modal improvements (#230)
* fix: fix notification modal
2025-11-18 12:24:27 +01:00
Efe
1b2fc79536 feat: add http adapter (#231)
* feat: add http adapter
2025-11-18 12:23:50 +01:00
12 changed files with 886 additions and 355 deletions

View File

@@ -19,4 +19,4 @@ jobs:
cache: 'yarn' cache: 'yarn'
- run: yarn install - run: yarn install
- run: yarn test - run: yarn testGH

View File

@@ -0,0 +1,57 @@
import { markdown2Html } from '../../services/markdown.js';
const mapListing = (listing) => ({
address: listing.address,
description: listing.description,
id: listing.id,
imageUrl: listing.image,
price: listing.price,
size: listing.size,
title: listing.title,
url: listing.link,
});
export const send = ({ serviceName, newListings, notificationConfig, jobKey }) => {
const { authToken, endpointUrl } = notificationConfig.find((a) => a.id === config.id).fields;
const listings = newListings.map(mapListing);
const body = {
jobId: jobKey,
timestamp: new Date().toISOString(),
provider: serviceName,
listings,
};
const headers = {
'Content-Type': 'application/json',
};
if (authToken != null) {
headers['Authorization'] = `Bearer ${authToken}`;
}
return fetch(endpointUrl, {
method: 'POST',
headers: headers,
body: JSON.stringify(body),
});
};
export const config = {
id: 'http',
name: 'HTTP',
readme: markdown2Html('lib/notification/adapter/http.md'),
description: 'Fredy will send a generic HTTP POST request.',
fields: {
endpointUrl: {
description: "Your application's endpoint URL.",
label: 'Endpoint URL',
type: 'text',
},
authToken: {
description: "Your application's auth token, if required by your endpoint.",
label: 'Auth token (optional)',
optional: true,
type: 'text',
},
},
};

View File

@@ -0,0 +1,43 @@
### HTTP Adapter
This is a generic adapter for sending notifications via HTTP requests.
You can leverage this adapter to integrate with various webhooks or APIs that accept HTTP requests. (e.g. Supabase
Functions, a Node.js server, etc.)
HTTP adapter supports a `authToken` field, which can be used to include an authorization token in the request headers.
Your token would be included as a Bearer token in the `Authorization` header, which is a common method for securing API requests.
Request Details:
<details>
Request Method: POST
Headers:
```
Content Type: `application/json`
Authorization: Bearer {your-optional-auth-token}
```
Body:
```json
{
"jobId": "mg1waX4RHmIzL5NDYtYp-",
"provider": "immoscout",
"timestamp": "2024-06-15T12:34:56Z",
"listings": [
{
"address": "Str. 123, Bielefeld, Germany",
"description": "Möbliert: Einziehen & wohlfühlen: Neu möbliert.",
"id": "123456789",
"imageUrl": "https://<target-url>.com/listings/123456789.jpg",
"price": "1.240 €",
"size": "38 m²",
"title": "Schöne 1-Zimmer-Wohnung in Bielefeld",
"url": "https://<target-url>.com/listings/123456789"
}
]
}
```
</details>

View File

@@ -0,0 +1,274 @@
import { DEFAULT_HEADER } from './utils.js';
// Helper to safely coerce numbers
const toInt = (v, d) => {
const n = parseInt(v, 10);
return Number.isFinite(n) ? n : d;
};
/**
* Compute pre-launch configuration and flags for Puppeteer with bot prevention in mind.
* Returns language, user agent, viewport (with optional jitter), and additional launch args.
*
* @param {string} url
* @param {object} [options]
*/
export function getPreLaunchConfig(url, options = {}) {
const { hostname } = new URL(url);
const acceptLanguage = options.acceptLanguage || 'de-DE,de;q=0.9,en-US;q=0.7,en;q=0.5';
const langForFlag = acceptLanguage.split(',')[0];
const baseViewport = { width: 1366, height: 768, deviceScaleFactor: 1 };
const jitter = options.viewportJitter !== false ? Math.floor(Math.random() * 6) : 0; // 0..5 px
const width = toInt(options?.viewport?.width, baseViewport.width) + jitter;
const height = toInt(options?.viewport?.height, baseViewport.height) + jitter;
const deviceScaleFactor = toInt(options?.viewport?.deviceScaleFactor, baseViewport.deviceScaleFactor);
const viewport = { width, height, deviceScaleFactor };
const userAgent =
options.userAgent ||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36';
const windowSizeArg = `--window-size=${viewport.width},${viewport.height}`;
const langArg = `--lang=${langForFlag}`;
const extraArgs = [
'--disable-blink-features=AutomationControlled',
'--force-webrtc-ip-handling-policy=disable_non_proxied_udp',
'--webrtc-ip-handling-policy=default_public_interface_only',
'--proxy-bypass-list=<-loopback>',
];
const headers = {
...DEFAULT_HEADER,
'Accept-Language': acceptLanguage,
'User-Agent': userAgent,
Referer: options?.referer || `https://${hostname}/`,
Connection: 'keep-alive',
DNT: '1',
};
const timezone = options?.timezone || 'Europe/Berlin';
return {
acceptLanguage,
langForFlag,
userAgent,
viewport,
windowSizeArg,
langArg,
extraArgs,
headers,
timezone,
humanDelay: options?.humanDelay !== false,
};
}
/**
* Apply bot-prevention hardening to a Puppeteer page.
* Sets UA, viewport, JS enabled, headers, timezone and injects stealth-like patches.
*
* @param {import('puppeteer').Page} page
* @param {ReturnType<typeof getPreLaunchConfig>} cfg
*/
export async function applyBotPreventionToPage(page, cfg) {
await page.setUserAgent(cfg.userAgent);
await page.setViewport(cfg.viewport);
await page.setJavaScriptEnabled(true);
await page.setExtraHTTPHeaders(cfg.headers);
try {
if (cfg.timezone) await page.emulateTimezone(cfg.timezone);
} catch {
// ignore timezone failures
}
// Inject patches as early as possible
await page.evaluateOnNewDocument(() => {
try {
// webdriver
Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
// chrome runtime
// @ts-ignore
if (!window.chrome) {
// @ts-ignore
window.chrome = { runtime: {} };
}
// languages
// @ts-ignore
Object.defineProperty(navigator, 'languages', {
get: () => (window.localStorage.getItem('__LANGS__') || 'de-DE,de').split(','),
});
// plugins
// @ts-ignore
Object.defineProperty(navigator, 'plugins', {
get: () => [{}, {}, {}],
});
// platform and concurrency hints
// @ts-ignore
Object.defineProperty(navigator, 'platform', { get: () => 'Win32' });
// @ts-ignore
if (typeof navigator.hardwareConcurrency === 'number' && navigator.hardwareConcurrency < 2) {
Object.defineProperty(navigator, 'hardwareConcurrency', { get: () => 4 });
}
// @ts-ignore
if (typeof navigator.deviceMemory === 'number' && navigator.deviceMemory < 2) {
Object.defineProperty(navigator, 'deviceMemory', { get: () => 8 });
}
// userAgentData (Client Hints)
try {
// @ts-ignore
if ('userAgentData' in navigator) {
// @ts-ignore
Object.defineProperty(navigator, 'userAgentData', {
get: () => ({
brands: [
{ brand: 'Chromium', version: '126' },
{ brand: 'Google Chrome', version: '126' },
],
mobile: false,
platform: 'Windows',
getHighEntropyValues: async (hints) => {
const values = {
platform: 'Windows',
platformVersion: '15.0.0',
architecture: 'x86',
model: '',
uaFullVersion: '126.0.0.0',
bitness: '64',
};
const out = {};
for (const k of hints || []) if (k in values) out[k] = values[k];
return out;
},
}),
});
}
} catch {
//noop
}
// Permissions API
const origQuery = navigator.permissions && navigator.permissions.query;
if (origQuery) {
// @ts-ignore
navigator.permissions.query = (parameters) =>
origQuery.call(navigator.permissions, parameters).then((result) => {
if (parameters && parameters.name === 'notifications') {
Object.defineProperty(result, 'state', { get: () => Notification.permission });
}
return result;
});
}
// WebGL vendor/renderer
const patchWebGL = (proto) => {
if (!proto || !proto.getParameter) return;
const getParameter = proto.getParameter;
// @ts-ignore
proto.getParameter = function (param) {
const UNMASKED_VENDOR_WEBGL = 0x9245;
const UNMASKED_RENDERER_WEBGL = 0x9246;
if (param === UNMASKED_VENDOR_WEBGL) return 'Google Inc.';
if (param === UNMASKED_RENDERER_WEBGL)
return 'ANGLE (NVIDIA, NVIDIA GeForce GTX 1660 Ti Direct3D11 vs_5_0 ps_5_0)';
return getParameter.call(this, param);
};
};
// @ts-ignore
patchWebGL(WebGLRenderingContext?.prototype);
// @ts-ignore
patchWebGL(WebGL2RenderingContext?.prototype);
// AudioContext timestamp rounding consistency
const patchAudio = (Ctx) => {
try {
if (!Ctx) return;
const proto = Ctx.prototype;
const createOsc = proto.createOscillator;
proto.createOscillator = function () {
const osc = createOsc.call(this);
const start = osc.start;
osc.start = function (when) {
return start.call(this, when || 0);
};
return osc;
};
} catch {
//noop
}
};
// @ts-ignore
patchAudio(window.AudioContext);
// @ts-ignore
patchAudio(window.OfflineAudioContext);
// Navigator.connection
try {
// @ts-ignore
Object.defineProperty(navigator, 'connection', { get: () => undefined });
} catch {
//noop
}
// Consistent outer sizes
try {
const calcOuter = () => {
const w = window.innerWidth + 16;
const h = window.innerHeight + 88;
return { w, h };
};
const { w: outerW, h: outerH } = calcOuter();
// @ts-ignore
Object.defineProperty(window, 'outerWidth', { get: () => outerW });
// @ts-ignore
Object.defineProperty(window, 'outerHeight', { get: () => outerH });
} catch {
//noop
}
} catch {
//noop
}
});
}
/**
* Persist languages value before navigation via localStorage.
* @param {import('puppeteer').Page} page
* @param {ReturnType<typeof getPreLaunchConfig>} cfg
*/
export async function applyLanguagePersistence(page, cfg) {
await page.evaluateOnNewDocument((langs) => {
try {
window.localStorage.setItem('__LANGS__', langs);
} catch {
// noop
}
}, cfg.acceptLanguage.split(';')[0]);
}
/**
* Perform subtle human-like interactions post navigation.
* @param {import('puppeteer').Page} page
* @param {ReturnType<typeof getPreLaunchConfig>} cfg
*/
export async function applyPostNavigationHumanSignals(page, cfg) {
if (!cfg.humanDelay) return;
const delay = 200 + Math.floor(Math.random() * 400);
await new Promise((res) => setTimeout(res, delay));
try {
const vw = cfg.viewport.width;
const vh = cfg.viewport.height;
const mx = Math.floor(vw * (0.3 + Math.random() * 0.4));
const my = Math.floor(vh * (0.3 + Math.random() * 0.4));
await page.mouse.move(mx, my, { steps: 10 + Math.floor(Math.random() * 10) });
await page.mouse.wheel({ deltaY: 100 + Math.floor(Math.random() * 200) });
} catch {
// ignore if mouse is unavailable
}
}

View File

@@ -1,11 +1,16 @@
import puppeteer from 'puppeteer-extra'; import puppeteer from 'puppeteer-extra';
import StealthPlugin from 'puppeteer-extra-plugin-stealth'; import StealthPlugin from 'puppeteer-extra-plugin-stealth';
import { debug, DEFAULT_HEADER, botDetected } from './utils.js'; import { debug, botDetected } from './utils.js';
import {
getPreLaunchConfig,
applyBotPreventionToPage,
applyLanguagePersistence,
applyPostNavigationHumanSignals,
} from './botPrevention.js';
import logger from '../logger.js'; import logger from '../logger.js';
import fs from 'fs'; import fs from 'fs';
import os from 'os'; import os from 'os';
import path from 'path'; import path from 'path';
import { URL } from 'url';
puppeteer.use(StealthPlugin()); puppeteer.use(StealthPlugin());
@@ -40,6 +45,11 @@ export default async function execute(url, waitForSelector, options) {
if (options?.proxyUrl) { if (options?.proxyUrl) {
launchArgs.push(`--proxy-server=${options.proxyUrl}`); launchArgs.push(`--proxy-server=${options.proxyUrl}`);
} }
// Prepare bot prevention pre-launch config
const preCfg = getPreLaunchConfig(url, options || {});
launchArgs.push(preCfg.langArg);
launchArgs.push(preCfg.windowSizeArg);
launchArgs.push(...preCfg.extraArgs);
browser = await puppeteer.launch({ browser = await puppeteer.launch({
headless: options?.puppeteerHeadless ?? true, headless: options?.puppeteerHeadless ?? true,
@@ -50,58 +60,9 @@ export default async function execute(url, waitForSelector, options) {
}); });
page = await browser.newPage(); page = await browser.newPage();
await applyBotPreventionToPage(page, preCfg);
// Derive domain-specific defaults
const { hostname } = new URL(url);
// Set a realistic modern user agent unless provided
const userAgent =
options?.userAgent ||
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36';
await page.setUserAgent(userAgent);
// Viewport and device scale for typical desktop
await page.setViewport({ width: 1366, height: 768, deviceScaleFactor: 1 });
// Extra HTTP headers with localized Accept-Language
const acceptLanguage = options?.acceptLanguage || 'de-DE,de;q=0.9,en-US;q=0.7,en;q=0.5';
const headers = {
...DEFAULT_HEADER,
'Accept-Language': acceptLanguage,
'User-Agent': userAgent,
Referer: options?.referer || `https://${hostname}/`,
Connection: 'keep-alive',
DNT: '1',
};
await page.setExtraHTTPHeaders(headers);
// Timezone and locale tweaks to look German when needed
try {
const tz = options?.timezone || 'Europe/Berlin';
if (tz) await page.emulateTimezone(tz);
} catch {
//noop
}
// Harden navigator properties (stealth already covers many, but we ensure critical ones)
await page.evaluateOnNewDocument(() => {
Object.defineProperty(navigator, 'webdriver', { get: () => undefined });
// Plugins and mimeTypes
// @ts-ignore
Object.defineProperty(navigator, 'plugins', { get: () => [1, 2, 3] });
// @ts-ignore
Object.defineProperty(navigator, 'languages', {
get: () => (window.localStorage.getItem('__LANGS__') || 'de-DE,de').split(','),
});
});
// Provide languages value before navigation // Provide languages value before navigation
await page.evaluateOnNewDocument((langs) => { await applyLanguagePersistence(page, preCfg);
try {
window.localStorage.setItem('__LANGS__', langs);
} catch {
//noop
}
}, acceptLanguage.split(';')[0]);
// Optional cookies // Optional cookies
if (Array.isArray(options?.cookies) && options.cookies.length > 0) { if (Array.isArray(options?.cookies) && options.cookies.length > 0) {
@@ -113,11 +74,8 @@ export default async function execute(url, waitForSelector, options) {
waitUntil: options?.waitUntil || 'domcontentloaded', waitUntil: options?.waitUntil || 'domcontentloaded',
}); });
// Optionally wait a random small delay to mimic human rendering time // Optionally wait and add subtle human-like interactions
if (options?.humanDelay !== false) { await applyPostNavigationHumanSignals(page, preCfg);
const delay = 200 + Math.floor(Math.random() * 400);
await new Promise((res) => setTimeout(res, delay));
}
let pageSource; let pageSource;
// if we're extracting data from a SPA, we must wait for the selector // if we're extracting data from a SPA, we must wait for the selector

View File

@@ -1,6 +1,6 @@
{ {
"name": "fredy", "name": "fredy",
"version": "14.3.4", "version": "14.3.7",
"description": "[F]ind [R]eal [E]states [d]amn eas[y].", "description": "[F]ind [R]eal [E]states [d]amn eas[y].",
"scripts": { "scripts": {
"prepare": "husky", "prepare": "husky",
@@ -12,6 +12,7 @@
"format": "prettier --write \"**/*.js\"", "format": "prettier --write \"**/*.js\"",
"format:check": "prettier --check \"**/*.js\"", "format:check": "prettier --check \"**/*.js\"",
"test": "node --import ./test/esmock-loader.mjs ./node_modules/mocha/bin/mocha.js --timeout 60000 test/**/*.test.js", "test": "node --import ./test/esmock-loader.mjs ./node_modules/mocha/bin/mocha.js --timeout 60000 test/**/*.test.js",
"testGH": "node --import ./test/esmock-loader.mjs ./node_modules/mocha/bin/mocha.js --timeout 60000 --exclude test/provider/immonet.test.js --exclude test/provider/immowelt.test.js test/**/*.test.js",
"lint": "eslint .", "lint": "eslint .",
"lint:fix": "yarn lint --fix", "lint:fix": "yarn lint --fix",
"migratedb": "node lib/services/storage/migrations/migrate.js", "migratedb": "node lib/services/storage/migrations/migrate.js",
@@ -56,15 +57,15 @@
"Firefox ESR" "Firefox ESR"
], ],
"dependencies": { "dependencies": {
"@douyinfe/semi-icons": "^2.88.0", "@douyinfe/semi-icons": "^2.88.3",
"@douyinfe/semi-ui": "2.88.0", "@douyinfe/semi-ui": "2.88.3",
"@sendgrid/mail": "8.1.6", "@sendgrid/mail": "8.1.6",
"@visactor/react-vchart": "^2.0.8", "@visactor/react-vchart": "^2.0.10",
"@visactor/vchart": "^2.0.8", "@visactor/vchart": "^2.0.10",
"@visactor/vchart-semi-theme": "^1.12.2", "@visactor/vchart-semi-theme": "^1.12.2",
"@vitejs/plugin-react": "5.1.1", "@vitejs/plugin-react": "5.1.1",
"better-sqlite3": "^12.4.1", "better-sqlite3": "^12.5.0",
"body-parser": "2.2.0", "body-parser": "2.2.1",
"cheerio": "^1.1.2", "cheerio": "^1.1.2",
"cookie-session": "2.1.1", "cookie-session": "2.1.1",
"handlebars": "4.7.8", "handlebars": "4.7.8",
@@ -75,21 +76,21 @@
"node-mailjet": "6.0.11", "node-mailjet": "6.0.11",
"p-throttle": "^8.1.0", "p-throttle": "^8.1.0",
"package-up": "^5.0.0", "package-up": "^5.0.0",
"puppeteer": "^24.30.0", "puppeteer": "^24.32.0",
"puppeteer-extra": "^3.3.6", "puppeteer-extra": "^3.3.6",
"puppeteer-extra-plugin-stealth": "^2.11.2", "puppeteer-extra-plugin-stealth": "^2.11.2",
"query-string": "9.3.1", "query-string": "9.3.1",
"react": "18.3.1", "react": "18.3.1",
"react-dom": "18.3.1", "react-dom": "18.3.1",
"react-router": "7.9.6", "react-router": "7.10.0",
"react-router-dom": "7.9.6", "react-router-dom": "7.10.0",
"restana": "5.1.0", "restana": "5.1.0",
"semver": "^7.7.3", "semver": "^7.7.3",
"serve-static": "2.2.0", "serve-static": "2.2.0",
"slack": "11.0.2", "slack": "11.0.2",
"vite": "7.2.2", "vite": "7.2.6",
"x-var": "^3.0.1", "x-var": "^3.0.1",
"zustand": "^5.0.8" "zustand": "^5.0.9"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "7.28.5", "@babel/core": "7.28.5",
@@ -104,9 +105,9 @@
"history": "5.3.0", "history": "5.3.0",
"husky": "9.1.7", "husky": "9.1.7",
"less": "4.4.2", "less": "4.4.2",
"lint-staged": "16.2.6", "lint-staged": "16.2.7",
"mocha": "11.7.5", "mocha": "11.7.5",
"nodemon": "^3.1.11", "nodemon": "^3.1.11",
"prettier": "3.6.2" "prettier": "3.7.4"
} }
} }

View File

@@ -0,0 +1,99 @@
import { describe, it } from 'mocha';
import { expect } from 'chai';
import {
getPreLaunchConfig,
applyBotPreventionToPage,
applyLanguagePersistence,
applyPostNavigationHumanSignals,
} from '../../../lib/services/extractor/botPrevention.js';
describe('botPrevention helper', () => {
it('getPreLaunchConfig builds deterministic values when jitter disabled', () => {
const url = 'https://example.com/some/path';
const options = {
acceptLanguage: 'de-DE,de;q=0.9',
userAgent: 'TestAgent/1.0',
viewport: { width: 1200, height: 700, deviceScaleFactor: 2 },
viewportJitter: false,
referer: 'https://example.com/ref',
timezone: 'Europe/Berlin',
};
const cfg = getPreLaunchConfig(url, options);
expect(cfg.acceptLanguage).to.equal('de-DE,de;q=0.9');
expect(cfg.langArg).to.equal('--lang=de-DE');
expect(cfg.windowSizeArg).to.equal('--window-size=1200,700');
expect(cfg.viewport).to.deep.equal({ width: 1200, height: 700, deviceScaleFactor: 2 });
expect(cfg.userAgent).to.equal('TestAgent/1.0');
expect(cfg.headers['Accept-Language']).to.equal('de-DE,de;q=0.9');
expect(cfg.headers['User-Agent']).to.equal('TestAgent/1.0');
expect(cfg.headers.Referer).to.equal('https://example.com/ref');
expect(cfg.extraArgs).to.include('--disable-blink-features=AutomationControlled');
expect(cfg.extraArgs).to.include('--proxy-bypass-list=<-loopback>');
});
it('applyBotPreventionToPage sets UA, viewport, headers and injects patches', async () => {
const calls = [];
const page = {
setUserAgent: async (ua) => calls.push(['setUserAgent', ua]),
setViewport: async (vp) => calls.push(['setViewport', vp]),
setJavaScriptEnabled: async (on) => calls.push(['setJavaScriptEnabled', on]),
setExtraHTTPHeaders: async (h) => calls.push(['setExtraHTTPHeaders', h]),
emulateTimezone: async (tz) => calls.push(['emulateTimezone', tz]),
evaluateOnNewDocument: async (fn) => calls.push(['evaluateOnNewDocument', typeof fn]),
};
const cfg = getPreLaunchConfig('https://example.org/', {
userAgent: 'Foo/Bar',
acceptLanguage: 'en-US,en',
viewport: { width: 1000, height: 600, deviceScaleFactor: 1 },
viewportJitter: false,
timezone: 'UTC',
});
await applyBotPreventionToPage(page, cfg);
expect(calls[0]).to.deep.equal(['setUserAgent', 'Foo/Bar']);
expect(calls.some((c) => c[0] === 'setViewport' && c[1].width === 1000 && c[1].height === 600)).to.equal(true);
expect(calls.some((c) => c[0] === 'setJavaScriptEnabled' && c[1] === true)).to.equal(true);
const headerCall = calls.find((c) => c[0] === 'setExtraHTTPHeaders');
expect(headerCall).to.exist;
expect(headerCall[1]['Accept-Language']).to.equal('en-US,en');
expect(headerCall[1]['User-Agent']).to.equal('Foo/Bar');
expect(calls.some((c) => c[0] === 'emulateTimezone' && c[1] === 'UTC')).to.equal(true);
expect(calls.some((c) => c[0] === 'evaluateOnNewDocument' && c[1] === 'function')).to.equal(true);
});
it('applyLanguagePersistence stores languages early', async () => {
const calls = [];
const page = {
evaluateOnNewDocument: async (fn, arg) => calls.push(['evaluateOnNewDocument', typeof fn, arg]),
};
const cfg = getPreLaunchConfig('https://example.org/', {
acceptLanguage: 'de-DE,de;q=0.9',
viewportJitter: false,
});
await applyLanguagePersistence(page, cfg);
const call = calls[0];
expect(call[0]).to.equal('evaluateOnNewDocument');
expect(call[1]).to.equal('function');
expect(call[2]).to.equal('de-DE,de');
});
it('applyPostNavigationHumanSignals moves mouse and scrolls when enabled', async () => {
const mouseCalls = [];
const page = {
mouse: {
move: async (x, y, opts) => mouseCalls.push(['move', x, y, opts && typeof opts.steps === 'number']),
wheel: async (opts) => mouseCalls.push(['wheel', typeof opts.deltaY === 'number']),
},
};
const cfg = {
humanDelay: true,
viewport: { width: 1200, height: 800 },
};
await applyPostNavigationHumanSignals(page, cfg);
expect(mouseCalls.some((c) => c[0] === 'move')).to.equal(true);
expect(mouseCalls.some((c) => c[0] === 'wheel')).to.equal(true);
});
});

View File

@@ -1,9 +1,9 @@
import React from 'react'; import React from 'react';
import { Empty, Table, Button } from '@douyinfe/semi-ui'; import { Empty, Table, Button } from '@douyinfe/semi-ui';
import { IconDelete } from '@douyinfe/semi-icons'; import { IconDelete, IconEdit } from '@douyinfe/semi-icons';
export default function ProviderTable({ providerData = [], onRemove } = {}) { export default function ProviderTable({ providerData = [], onRemove, onEdit } = {}) {
return ( return (
<Table <Table
pagination={false} pagination={false}
@@ -30,6 +30,8 @@ export default function ProviderTable({ providerData = [], onRemove } = {}) {
render: (_, record) => { render: (_, record) => {
return ( return (
<div style={{ float: 'right' }}> <div style={{ float: 'right' }}>
<Button type="secondary" icon={<IconEdit />} onClick={() => onEdit(record)} />
<div style={{ display: 'inline-block', width: '16px' }} />
<Button type="danger" icon={<IconDelete />} onClick={() => onRemove(record.url)} /> <Button type="danger" icon={<IconDelete />} onClick={() => onRemove(record.url)} />
</div> </div>
); );

View File

@@ -11,7 +11,15 @@ import { useNavigate, useParams } from 'react-router-dom';
import { Divider, Input, Switch, Button, TagInput, Toast, Select } from '@douyinfe/semi-ui'; import { Divider, Input, Switch, Button, TagInput, Toast, Select } from '@douyinfe/semi-ui';
import './JobMutation.less'; import './JobMutation.less';
import { SegmentPart } from '../../../components/segment/SegmentPart'; import { SegmentPart } from '../../../components/segment/SegmentPart';
import { IconBell, IconBriefcase, IconPaperclip, IconPlayCircle, IconPlusCircle, IconUser } from '@douyinfe/semi-icons'; import {
IconBell,
IconBriefcase,
IconPaperclip,
IconPlayCircle,
IconPlusCircle,
IconUser,
IconClear,
} from '@douyinfe/semi-icons';
export default function JobMutator() { export default function JobMutator() {
const jobs = useSelector((state) => state.jobs.jobs); const jobs = useSelector((state) => state.jobs.jobs);
@@ -26,6 +34,7 @@ export default function JobMutator() {
const defaultNotificationAdapter = jobToBeEdit?.notificationAdapter || []; const defaultNotificationAdapter = jobToBeEdit?.notificationAdapter || [];
const defaultEnabled = jobToBeEdit?.enabled ?? true; const defaultEnabled = jobToBeEdit?.enabled ?? true;
const [providerToEdit, setProviderToEdit] = useState(null);
const [providerCreationVisible, setProviderCreationVisibility] = useState(false); const [providerCreationVisible, setProviderCreationVisibility] = useState(false);
const [notificationCreationVisible, setNotificationCreationVisibility] = useState(false); const [notificationCreationVisible, setNotificationCreationVisibility] = useState(false);
const [editNotificationAdapter, setEditNotificationAdapter] = useState(null); const [editNotificationAdapter, setEditNotificationAdapter] = useState(null);
@@ -42,6 +51,12 @@ export default function JobMutator() {
return Boolean(notificationAdapterData.length && providerData.length && name); return Boolean(notificationAdapterData.length && providerData.length && name);
}; };
const handleProviderEdit = (data) => {
setProviderData(
providerData.map((provider) => (provider.url === data.oldProviderToEdit.url ? data.newData : provider)),
);
};
const mutateJob = async () => { const mutateJob = async () => {
try { try {
await xhrPost('/api/jobs', { await xhrPost('/api/jobs', {
@@ -70,6 +85,8 @@ export default function JobMutator() {
onData={(data) => { onData={(data) => {
setProviderData([...providerData, data]); setProviderData([...providerData, data]);
}} }}
onEditData={handleProviderEdit}
providerToEdit={providerToEdit}
/> />
{notificationCreationVisible && ( {notificationCreationVisible && (
@@ -119,7 +136,10 @@ export default function JobMutator() {
type="primary" type="primary"
icon={<IconPlusCircle />} icon={<IconPlusCircle />}
className="jobMutation__newButton" className="jobMutation__newButton"
onClick={() => setProviderCreationVisibility(true)} onClick={() => {
setProviderToEdit(null);
setProviderCreationVisibility(true);
}}
> >
Add new Provider Add new Provider
</Button> </Button>
@@ -129,6 +149,10 @@ export default function JobMutator() {
onRemove={(providerUrl) => { onRemove={(providerUrl) => {
setProviderData(providerData.filter((provider) => provider.url !== providerUrl)); setProviderData(providerData.filter((provider) => provider.url !== providerUrl));
}} }}
onEdit={(provider) => {
setProviderCreationVisibility(true);
setProviderToEdit(provider);
}}
/> />
</SegmentPart> </SegmentPart>
<Divider margin="1rem" /> <Divider margin="1rem" />
@@ -160,7 +184,7 @@ export default function JobMutator() {
</SegmentPart> </SegmentPart>
<Divider margin="1rem" /> <Divider margin="1rem" />
<SegmentPart <SegmentPart
Icon={IconBell} Icon={IconClear}
name="Blacklist" name="Blacklist"
helpText="If a listing contains one of these words, it will be filtered out. Type in a word, then hit enter." helpText="If a listing contains one of these words, it will be filtered out. Type in a word, then hit enter."
> >

View File

@@ -7,6 +7,7 @@ import { useSelector } from '../../../../../services/state/store';
import { Banner, Button, Form, Modal, Select, Switch } from '@douyinfe/semi-ui'; import { Banner, Button, Form, Modal, Select, Switch } from '@douyinfe/semi-ui';
import './NotificationAdapterMutator.less'; import './NotificationAdapterMutator.less';
import { useScreenWidth } from '../../../../../hooks/screenWidth.js';
const sortAdapter = (a, b) => { const sortAdapter = (a, b) => {
if (a.name < b.name) { if (a.name < b.name) {
@@ -70,6 +71,9 @@ export default function NotificationAdapterMutator({
const [validationMessage, setValidationMessage] = useState(null); const [validationMessage, setValidationMessage] = useState(null);
const [successMessage, setSuccessMessage] = useState(null); const [successMessage, setSuccessMessage] = useState(null);
const width = useScreenWidth();
const isMobile = width <= 850;
const onSubmit = (doStore) => { const onSubmit = (doStore) => {
if (doStore) { if (doStore) {
const validationResults = validate(selectedAdapter); const validationResults = validate(selectedAdapter);
@@ -170,18 +174,19 @@ export default function NotificationAdapterMutator({
<Modal <Modal
title="Adding a new Notification Adapter" title="Adding a new Notification Adapter"
visible={visible} visible={visible}
style={{ width: '95%' }} style={{ width: isMobile ? '95%' : '50rem' }}
onCancel={() => onSubmit(false)}
footer={ footer={
<div> <div>
<Button type="secondary" disabled={selectedAdapter == null} style={{ float: 'left' }} onClick={() => onTry()}> <Button type="secondary" disabled={selectedAdapter == null} style={{ float: 'left' }} onClick={onTry}>
Try Try
</Button> </Button>
<Button type="danger" onClick={() => onSubmit(true)}> <Button theme="light" type="tertiary" onClick={() => onSubmit(false)}>
Save
</Button>
<Button type="primary" onClick={() => onSubmit(false)}>
Cancel Cancel
</Button> </Button>
<Button theme="solid" type="primary" onClick={() => onSubmit(true)}>
Save
</Button>
</div> </div>
} }
> >
@@ -207,9 +212,9 @@ export default function NotificationAdapterMutator({
)} )}
<p> <p>
When Fredy found new listings, we like to report them to you. To do so, notification adapter can be configured.{' '} When Fredy finds new listings, we like to report them to you. To do so, the notification adapter can be
<br /> configured. <br />
There are multiple ways how Fredy can send new listings to you. Chose your weapon... There are multiple ways Fredy can send new listings to you. Choose your weapon...
</p> </p>
<Select <Select

View File

@@ -1,10 +1,11 @@
import React, { useState } from 'react'; import React, { useState, useEffect } from 'react';
import { Banner, Modal, Select, Input } from '@douyinfe/semi-ui'; import { Banner, Modal, Select, Input } from '@douyinfe/semi-ui';
import { transform } from '../../../../../services/transformer/providerTransformer'; import { transform } from '../../../../../services/transformer/providerTransformer';
import { useSelector } from '../../../../../services/state/store'; import { useSelector } from '../../../../../services/state/store';
import { IconLikeHeart } from '@douyinfe/semi-icons'; import { IconLikeHeart } from '@douyinfe/semi-icons';
import './ProviderMutator.less'; import './ProviderMutator.less';
import { useScreenWidth } from '../../../../../hooks/screenWidth.js';
const sortProvider = (a, b) => { const sortProvider = (a, b) => {
if (a.key < b.key) { if (a.key < b.key) {
@@ -16,11 +17,35 @@ const sortProvider = (a, b) => {
return 0; return 0;
}; };
export default function ProviderMutator({ onVisibilityChanged, visible = false, onData } = {}) { const returnOriginalSelectedProvider = (providerToEdit, provider) => {
return provider.find((pro) => pro.id === providerToEdit.id);
};
export default function ProviderMutator({
onVisibilityChanged,
visible = false,
onData,
onEditData,
providerToEdit,
} = {}) {
const provider = useSelector((state) => state.provider); const provider = useSelector((state) => state.provider);
const [selectedProvider, setSelectedProvider] = useState(null); const [selectedProvider, setSelectedProvider] = useState(null);
const [providerUrl, setProviderUrl] = useState(null); const [providerUrl, setProviderUrl] = useState(null);
const [validationMessage, setValidationMessage] = useState(null); const [validationMessage, setValidationMessage] = useState(null);
useEffect(() => {
if (providerToEdit) {
setSelectedProvider(returnOriginalSelectedProvider(providerToEdit, provider));
setProviderUrl(providerToEdit.url);
} else {
setSelectedProvider(null);
setProviderUrl(null);
}
}, [providerToEdit, visible]);
const width = useScreenWidth();
const isMobile = width <= 850;
const validate = () => { const validate = () => {
if (selectedProvider == null || selectedProvider.length === 0 || providerUrl == null || providerUrl.length === 0) { if (selectedProvider == null || selectedProvider.length === 0 || providerUrl == null || providerUrl.length === 0) {
return 'Please select a provider and copy the browser url into the textfield after configuring your search parameter.'; return 'Please select a provider and copy the browser url into the textfield after configuring your search parameter.';
@@ -41,13 +66,24 @@ export default function ProviderMutator({ onVisibilityChanged, visible = false,
if (doStore) { if (doStore) {
const validationResult = validate(); const validationResult = validate();
if (validationResult == null) { if (validationResult == null) {
onData( if (providerToEdit != null) {
transform({ onEditData({
url: providerUrl, newData: transform({
id: selectedProvider.id, url: providerUrl,
name: selectedProvider.name, id: selectedProvider.id,
}), name: selectedProvider.name,
); }),
oldProviderToEdit: providerToEdit,
});
} else {
onData(
transform({
url: providerUrl,
id: selectedProvider.id,
name: selectedProvider.name,
}),
);
}
setProviderUrl(null); setProviderUrl(null);
setSelectedProvider(null); setSelectedProvider(null);
onVisibilityChanged(false); onVisibilityChanged(false);
@@ -63,11 +99,11 @@ export default function ProviderMutator({ onVisibilityChanged, visible = false,
return ( return (
<Modal <Modal
title="Adding a new Provider" title={providerToEdit ? 'Editing an existing Provider' : 'Adding a new Provider'}
visible={visible} visible={visible}
onOk={() => onSubmit(true)} onOk={() => onSubmit(true)}
onCancel={() => onSubmit(false)} onCancel={() => onSubmit(false)}
style={{ width: '50rem' }} style={{ width: isMobile ? '95%' : '50rem' }}
okText="Save" okText="Save"
> >
{validationMessage != null && ( {validationMessage != null && (
@@ -80,19 +116,26 @@ export default function ProviderMutator({ onVisibilityChanged, visible = false,
description={validationMessage} description={validationMessage}
/> />
)} )}
{providerToEdit != null ? (
<p> <p>
Provider are the <IconLikeHeart style={{ color: '#ff0000' }} /> of Fredy. We're supporting multiple Provider You can now edit the <strong>{providerToEdit.name}</strong> provider's URL in the input field below.
such as Immowelt, Kalaydo etc. Select a provider from the list below. </p>
<br /> ) : (
Fredy will then open the provider's url in a new tab. <>
</p> <p>
<p> Provider are the <IconLikeHeart style={{ color: '#ff0000' }} /> of Fredy. We're supporting multiple Provider
You will need to configure your search parameter like you would do when you do a regular search on the such as Immowelt, Kalaydo etc. Select a provider from the list below.
provider's website. <br />
<br /> Fredy will then open the provider's url in a new tab.
When the search results are shown on the website, copy the url and paste it into the textfield below. </p>
</p> <p>
You will need to configure your search parameter like you would do when you do a regular search on the
provider's website.
<br />
When the search results are shown on the website, copy the url and paste it into the textfield below.
</p>
</>
)}
<Banner <Banner
fullMode={false} fullMode={false}
type="warning" type="warning"
@@ -112,6 +155,7 @@ export default function ProviderMutator({ onVisibilityChanged, visible = false,
filter filter
placeholder="Select a provider" placeholder="Select a provider"
className="providerMutator__fields" className="providerMutator__fields"
disabled={providerToEdit != null}
optionList={provider optionList={provider
.map((pro) => { .map((pro) => {
return { return {
@@ -126,7 +170,6 @@ export default function ProviderMutator({ onVisibilityChanged, visible = false,
onChange={(value) => { onChange={(value) => {
const selectedProvider = provider.find((pro) => pro.id === value); const selectedProvider = provider.find((pro) => pro.id === value);
setSelectedProvider(selectedProvider); setSelectedProvider(selectedProvider);
window.open(selectedProvider.baseUrl); window.open(selectedProvider.baseUrl);
}} }}
/> />
@@ -137,7 +180,8 @@ export default function ProviderMutator({ onVisibilityChanged, visible = false,
placeholder="Provider Url" placeholder="Provider Url"
width={10} width={10}
className="providerMutator__fields" className="providerMutator__fields"
onBlur={(e) => { value={providerUrl}
onInput={(e) => {
setProviderUrl(e.target.value); setProviderUrl(e.target.value);
}} }}
/> />

508
yarn.lock
View File

@@ -997,34 +997,34 @@
dependencies: dependencies:
tslib "^2.0.0" tslib "^2.0.0"
"@douyinfe/semi-animation-react@2.88.0": "@douyinfe/semi-animation-react@2.88.3":
version "2.88.0" version "2.88.3"
resolved "https://registry.yarnpkg.com/@douyinfe/semi-animation-react/-/semi-animation-react-2.88.0.tgz#34d951e46a263b14db563b4044b3144f787e44e5" resolved "https://registry.yarnpkg.com/@douyinfe/semi-animation-react/-/semi-animation-react-2.88.3.tgz#8e3b7e11e90baa3d6b7e5a692c4e3b4b72d33958"
integrity sha512-K6WzTDnLn75I+XOB/9C/hA2Mwjqd+TQpYiEjxSC+l3Ep6MiLS/5VbkGOSt4jiRJJQs584xfw59ReUJ5LGuPQLQ== integrity sha512-Jhk/QXZ1Wz++D7PZpdRSc3Pj9sDHIDeOXal/zfzUVpEjuQWlD/ebup0MM50ChBkMPI9HkOQLCbZ2Z5qV7bX5SQ==
dependencies: dependencies:
"@douyinfe/semi-animation" "2.88.0" "@douyinfe/semi-animation" "2.88.3"
"@douyinfe/semi-animation-styled" "2.88.0" "@douyinfe/semi-animation-styled" "2.88.3"
classnames "^2.2.6" classnames "^2.2.6"
"@douyinfe/semi-animation-styled@2.88.0": "@douyinfe/semi-animation-styled@2.88.3":
version "2.88.0" version "2.88.3"
resolved "https://registry.yarnpkg.com/@douyinfe/semi-animation-styled/-/semi-animation-styled-2.88.0.tgz#abc29d577fc910ee3707af0f581548608c388d27" resolved "https://registry.yarnpkg.com/@douyinfe/semi-animation-styled/-/semi-animation-styled-2.88.3.tgz#e284da909af68e2f7d96a0bf1847ceea69c455e5"
integrity sha512-iHqrD2HoWL9Vd40DAsSjZHONHU91ayelMlziFoBjvvmaiuvcQms2ead7hLFkDtvkDswT0Mfd8BqkVDJSxTwxnw== integrity sha512-VNuMBD4mffSB4yCzhxHf7/AIRddIxUzz6U+jHQbd0ZAt75CXmj6h/YNyURpaYspHKr3bMqgRW98956CTa8qbjQ==
"@douyinfe/semi-animation@2.88.0": "@douyinfe/semi-animation@2.88.3":
version "2.88.0" version "2.88.3"
resolved "https://registry.yarnpkg.com/@douyinfe/semi-animation/-/semi-animation-2.88.0.tgz#2c069476b24a55041837e976b0d045c2c0da0049" resolved "https://registry.yarnpkg.com/@douyinfe/semi-animation/-/semi-animation-2.88.3.tgz#b7ee6f792844c1c8abb087b30e709cd9b4600b83"
integrity sha512-J7fjwnVJEYvS2ZbKvWTjRRXTWQPlmYwkeXasICom+KFuE2vrkCzeqTXXIJ25MuaWlM/OWBPqrkAZBIfmNNQXWg== integrity sha512-x7Ef2IJjW8M0cgg41P7hgePlxz3XvWRVcov4fvzAE3LYBPgYRz9FL+k/gQ/OhT8PpnlHh5XpPUL3N2ATBLeiEQ==
dependencies: dependencies:
bezier-easing "^2.1.0" bezier-easing "^2.1.0"
"@douyinfe/semi-foundation@2.88.0": "@douyinfe/semi-foundation@2.88.3":
version "2.88.0" version "2.88.3"
resolved "https://registry.yarnpkg.com/@douyinfe/semi-foundation/-/semi-foundation-2.88.0.tgz#8fa4d5373acb5bb9f1e9fe1ca97c553c0ae76bfc" resolved "https://registry.yarnpkg.com/@douyinfe/semi-foundation/-/semi-foundation-2.88.3.tgz#761203e8d71359ec61084007a18d7779e627fe5a"
integrity sha512-WYT1blbg2873xAU9iCasMRnTUsE/9WP/9gE1Zd87vsnZYWwl3WP9imH0iSqeSXkFdJllNo/KBImBY7clOoVIYA== integrity sha512-/jlSfki5Bg4lAqbl0oAUtHqzWqFijvqcHvH/dmU1wgLw/kZYj/bQkA3G9/VrTyWggfXmq2JC6bx9EoQAvXEsSQ==
dependencies: dependencies:
"@douyinfe/semi-animation" "2.88.0" "@douyinfe/semi-animation" "2.88.3"
"@douyinfe/semi-json-viewer-core" "2.88.0" "@douyinfe/semi-json-viewer-core" "2.88.3"
"@mdx-js/mdx" "^3.0.1" "@mdx-js/mdx" "^3.0.1"
async-validator "^3.5.0" async-validator "^3.5.0"
classnames "^2.2.6" classnames "^2.2.6"
@@ -1038,53 +1038,53 @@
remark-gfm "^4.0.0" remark-gfm "^4.0.0"
scroll-into-view-if-needed "^2.2.24" scroll-into-view-if-needed "^2.2.24"
"@douyinfe/semi-icons@2.88.0", "@douyinfe/semi-icons@^2.88.0": "@douyinfe/semi-icons@2.88.3", "@douyinfe/semi-icons@^2.88.3":
version "2.88.0" version "2.88.3"
resolved "https://registry.yarnpkg.com/@douyinfe/semi-icons/-/semi-icons-2.88.0.tgz#8bc28881aba3fa5a190599e1ddf4c6fb1840dbaa" resolved "https://registry.yarnpkg.com/@douyinfe/semi-icons/-/semi-icons-2.88.3.tgz#9aaa2e580147affa8587a495679b8d860a8af194"
integrity sha512-kZSni5KZFL6fxs+c2nF4e3biPNcnAxV9U27577kOlaqP7l2FqP9U+d4x2YQisgsoT+Z3brqfWEayastQk5fzig== integrity sha512-g3YFaM8Jr0GRY9rV5OuxvmZiqZUN9grj+TdRC930StxBjxdp901WGhuaPGpkaVahO0mkX3hSAJVlQYPEF/MOzQ==
dependencies: dependencies:
classnames "^2.2.6" classnames "^2.2.6"
"@douyinfe/semi-illustrations@2.88.0": "@douyinfe/semi-illustrations@2.88.3":
version "2.88.0" version "2.88.3"
resolved "https://registry.yarnpkg.com/@douyinfe/semi-illustrations/-/semi-illustrations-2.88.0.tgz#7ba4dad1fe98c813386c3baf7fd9720974cab1b3" resolved "https://registry.yarnpkg.com/@douyinfe/semi-illustrations/-/semi-illustrations-2.88.3.tgz#72101f0eec8d3bb7d10f8108af6cc91c8de3300f"
integrity sha512-fQ+Q9g9KjE9a2nH59uNHEzUdSt40GDloPCB4n7J3Q9EUeOiWpOsXbC/3NCDZc2ElZVryMChT3g6vjvIzHAl9Hw== integrity sha512-L8nqLz7YaRTDM+ZSXmWLrt+zjaGl7SFOBT4QQG7O6q1gmaK2XOiHWLiiQYztp863cMr11LSBIckMy56M9ScCbQ==
"@douyinfe/semi-json-viewer-core@2.88.0": "@douyinfe/semi-json-viewer-core@2.88.3":
version "2.88.0" version "2.88.3"
resolved "https://registry.yarnpkg.com/@douyinfe/semi-json-viewer-core/-/semi-json-viewer-core-2.88.0.tgz#53cd6e6aa2a7f4b517c4cd532b08e65af4d60da7" resolved "https://registry.yarnpkg.com/@douyinfe/semi-json-viewer-core/-/semi-json-viewer-core-2.88.3.tgz#f2451d0423f028758e44ea7035a2f668651959a3"
integrity sha512-LLdLZ477eJBQKlCPIqPhpIcXL1GOy9mvjpwryqiAj/h6BXmwcvp1zJwJQP9Rq9inePawdYMSZozaB2X1FPjKOg== integrity sha512-2tqTXbUrDYxZVu/Stl14Rv/WeiqbYlfyKmra9AIG81ZaqG1fP28g/dkiBlHVzUZbYCMM9s3EGAuZugn1jWkWKQ==
dependencies: dependencies:
jsonc-parser "^3.3.1" jsonc-parser "^3.3.1"
"@douyinfe/semi-theme-default@2.88.0": "@douyinfe/semi-theme-default@2.88.3":
version "2.88.0" version "2.88.3"
resolved "https://registry.yarnpkg.com/@douyinfe/semi-theme-default/-/semi-theme-default-2.88.0.tgz#caa8c24c3afd3c24689a74efacdd6e11199cc22c" resolved "https://registry.yarnpkg.com/@douyinfe/semi-theme-default/-/semi-theme-default-2.88.3.tgz#513506c6eaa9d23510054ae852cb63f4147f37c3"
integrity sha512-Cykl39Tkw9cJYTBpDToyj0uyXBGS15QDZGR2zCskdG52+eaCyZAoCds4W3HOxlToUmuw0JgVES5VSalIy3M07A== integrity sha512-mCuxedgCT1bJChMEQ+AAJ8g0oJQZaXsL+vVKxjqISjFUutbUvs++K+A2pWobgZafOXu1JS+cpppPsEcR4G4JvQ==
"@douyinfe/semi-ui@2.88.0": "@douyinfe/semi-ui@2.88.3":
version "2.88.0" version "2.88.3"
resolved "https://registry.yarnpkg.com/@douyinfe/semi-ui/-/semi-ui-2.88.0.tgz#a220fcfcad593f9669acb44b74c3c1e10efcb262" resolved "https://registry.yarnpkg.com/@douyinfe/semi-ui/-/semi-ui-2.88.3.tgz#d2b1b4fe9147d18371ddc45d91601378eb885d45"
integrity sha512-MlfLjUpTqnfk3Sg6pQOA2JETvZaWFEQwLvEcbfwA5LijX/hu7hG1Zhj1AVnpXTXrOUiU+ENTOiLu4GggoW2EaA== integrity sha512-lVW4euk+j+ev2c4c2LNwx1gwnEU6pGguaB5Z9E11DoyrvMtIg5irow5o1M4pG1r3xbU+4+oQqkRLPXAx01WPzg==
dependencies: dependencies:
"@dnd-kit/core" "^6.0.8" "@dnd-kit/core" "^6.0.8"
"@dnd-kit/sortable" "^7.0.2" "@dnd-kit/sortable" "^7.0.2"
"@dnd-kit/utilities" "^3.2.1" "@dnd-kit/utilities" "^3.2.1"
"@douyinfe/semi-animation" "2.88.0" "@douyinfe/semi-animation" "2.88.3"
"@douyinfe/semi-animation-react" "2.88.0" "@douyinfe/semi-animation-react" "2.88.3"
"@douyinfe/semi-foundation" "2.88.0" "@douyinfe/semi-foundation" "2.88.3"
"@douyinfe/semi-icons" "2.88.0" "@douyinfe/semi-icons" "2.88.3"
"@douyinfe/semi-illustrations" "2.88.0" "@douyinfe/semi-illustrations" "2.88.3"
"@douyinfe/semi-theme-default" "2.88.0" "@douyinfe/semi-theme-default" "2.88.3"
"@tiptap/core" "^3.1.0" "@tiptap/core" "^3.10.7"
"@tiptap/extension-document" "^3.3.0" "@tiptap/extension-document" "^3.10.7"
"@tiptap/extension-hard-break" "^3.3.0" "@tiptap/extension-hard-break" "^3.10.7"
"@tiptap/extension-mention" "^3.1.0" "@tiptap/extension-mention" "^3.10.7"
"@tiptap/extension-paragraph" "^3.3.0" "@tiptap/extension-paragraph" "^3.10.7"
"@tiptap/extension-text" "^3.3.0" "@tiptap/extension-text" "^3.10.7"
"@tiptap/extensions" "^3.1.0" "@tiptap/extensions" "^3.10.7"
"@tiptap/pm" "^3.1.0" "@tiptap/pm" "^3.10.7"
"@tiptap/react" "^3.1.0" "@tiptap/react" "^3.10.7"
async-validator "^3.5.0" async-validator "^3.5.0"
classnames "^2.2.6" classnames "^2.2.6"
copy-text-to-clipboard "^2.1.1" copy-text-to-clipboard "^2.1.1"
@@ -1434,10 +1434,10 @@
resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
"@puppeteer/browsers@2.10.13": "@puppeteer/browsers@2.11.0":
version "2.10.13" version "2.11.0"
resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-2.10.13.tgz#42c8b7df14e992f311ca9dca5fed3f0c2182fd17" resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-2.11.0.tgz#b2dcd7cb02dd2de5909531d00e717a04bd61de73"
integrity sha512-a9Ruw3j3qlnB5a/zHRTkruppynxqaeE4H9WNj5eYGRWqw0ZauZ23f4W2ARf3hghF5doozyD+CRtt7XSYuYRI/Q== integrity sha512-n6oQX6mYkG8TRPuPXmbPidkUbsSRalhmaaVAQxvH1IkQy63cwsH+kOjB3e4cpCDHg0aSvsiX9bQ4s2VB6mGWUQ==
dependencies: dependencies:
debug "^4.4.3" debug "^4.4.3"
extract-zip "^2.0.1" extract-zip "^2.0.1"
@@ -1658,57 +1658,57 @@
"@sendgrid/client" "^8.1.5" "@sendgrid/client" "^8.1.5"
"@sendgrid/helpers" "^8.0.0" "@sendgrid/helpers" "^8.0.0"
"@tiptap/core@^3.1.0": "@tiptap/core@^3.10.7":
version "3.10.7" version "3.11.0"
resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-3.10.7.tgz#3e56d68d2a8f7e686b31261c720052a580d1d5c0" resolved "https://registry.yarnpkg.com/@tiptap/core/-/core-3.11.0.tgz#122a1db7852c9cea48221290210e713bb4efd66e"
integrity sha512-4rD3oHkXNOS6Fxm0mr+ECyq35iMFnnAXheIO+UsQbOexwTxn2yZ5Q1rQiFKcCf+p+rrg1yt8TtxQPM8VLWS+1g== integrity sha512-kmS7ZVpHm1EMnW1Wmft9H5ZLM7E0G0NGBx+aGEHGDcNxZBXD2ZUa76CuWjIhOGpwsPbELp684ZdpF2JWoNi4Dg==
"@tiptap/extension-bubble-menu@^3.10.7": "@tiptap/extension-bubble-menu@^3.11.0":
version "3.10.7" version "3.11.0"
resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.10.7.tgz#0393b889a6ad29ab1b6ac08542d47cd8b05da626" resolved "https://registry.yarnpkg.com/@tiptap/extension-bubble-menu/-/extension-bubble-menu-3.11.0.tgz#2ce7820c9aecd0f4ce36c2668353aa8194ea55a5"
integrity sha512-ezsNpClKQ4Bq6R+Y/jGcmxhSBuYYOCGXV72yy3SlX1w6seA/I8h27ktWy9zAD2RPX560NzpZEyBjaASL3961sQ== integrity sha512-P3j9lQ+EZ5Zg/isJzLpCPX7bp7WUBmz8GPs/HPlyMyN2su8LqXntITBZr8IP1JNBlB/wR83k/W0XqdC57mG7cA==
dependencies: dependencies:
"@floating-ui/dom" "^1.0.0" "@floating-ui/dom" "^1.0.0"
"@tiptap/extension-document@^3.3.0": "@tiptap/extension-document@^3.10.7":
version "3.10.7" version "3.11.0"
resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-3.10.7.tgz#c2e179785dafc778af5842740a2c04153a352912" resolved "https://registry.yarnpkg.com/@tiptap/extension-document/-/extension-document-3.11.0.tgz#fa4ed625730dcfbb5ea35a630f9163d6843adfed"
integrity sha512-RlezqyAf0voUblrMLArh+AZJ9t+rE6buFa+U1V37Ey+I1z+Y8pPqlhtYJoTUz0GtSZWMReirSvoQpQJHM9x3Yw== integrity sha512-N2G3cwL2Dtur/CgD/byJmFx9T5no6fTO/U462VP3rthQYrRA1AB3TCYqtlwJkmyoxRTNd4qIg4imaPl8ej6Heg==
"@tiptap/extension-floating-menu@^3.10.7": "@tiptap/extension-floating-menu@^3.11.0":
version "3.10.7" version "3.11.0"
resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-3.10.7.tgz#d147fcde8961453c0b3d50693a7f1cc98345dccd" resolved "https://registry.yarnpkg.com/@tiptap/extension-floating-menu/-/extension-floating-menu-3.11.0.tgz#521109d9c0d5f6dc5fb6f2fd8181367af8a91be2"
integrity sha512-yuTIGDbx0Q2IWOUrkhVQ/i1fU0Qi+8fCS8jkGB34/+3nbhtqXNYfFajpeaU9rkcCJqXH4aiFJdSGy44kCnYP2g== integrity sha512-nEHdWZHEJYX1II1oJQ4aeZ8O/Kss4BRbYFXQFGIvPelCfCYEATpUJh3aq3767ARSq40bOWyu+Dcd4SCW0We6Sw==
"@tiptap/extension-hard-break@^3.3.0": "@tiptap/extension-hard-break@^3.10.7":
version "3.10.7" version "3.11.0"
resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-3.10.7.tgz#34e7c432058ba66a3432232f76d6a3f08015ae1d" resolved "https://registry.yarnpkg.com/@tiptap/extension-hard-break/-/extension-hard-break-3.11.0.tgz#a0d7c5564c4fed1c4446c53f924ff2e468e157cb"
integrity sha512-EIdTsD2pV4FSef/6nrKlXV8H5861PElnIjuoHkwk1alowAVL/HSvJqPxZwH6k2qLcsabkr0cSdaDixw9gJGAdg== integrity sha512-NJEHTj++kFOayQXKSQSi9j9eAG33eSiJqai2pf4U+snW94fmb8cYLUurDmfYRe20O6EzBSX0X3GjVlkOz+5b7A==
"@tiptap/extension-mention@^3.1.0": "@tiptap/extension-mention@^3.10.7":
version "3.10.7" version "3.11.0"
resolved "https://registry.yarnpkg.com/@tiptap/extension-mention/-/extension-mention-3.10.7.tgz#06fd050c8424239b54e34a5c4ef89ee56fd77f0f" resolved "https://registry.yarnpkg.com/@tiptap/extension-mention/-/extension-mention-3.11.0.tgz#0edf8171587fba2658cf8ee379e7687018c0063b"
integrity sha512-XzHJ7Pgj8uC9QO1PO2Q+yoczupJhaoiXqtVegCaiTJHwzOmdEg20WK5/fYrNNI/3NdS9cEBka1dccdvkT3+a2A== integrity sha512-4y789hKNEvZoNals7PNSGAKThQ+b5nuP/KIEe4wPIfzknjwxzGi0f2YY3L/f+gIhueoZymYpkmhtiRND+wvAWA==
"@tiptap/extension-paragraph@^3.3.0": "@tiptap/extension-paragraph@^3.10.7":
version "3.10.7" version "3.11.0"
resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-3.10.7.tgz#f751b4c8c7991747a3f5899fa39a7c197fbd92bc" resolved "https://registry.yarnpkg.com/@tiptap/extension-paragraph/-/extension-paragraph-3.11.0.tgz#60ecdcb24330b39f72b58760bcaf299b20de43da"
integrity sha512-53+nCxNaKcmeqQ+aWrSauEWywuWPp8qkUTOO2rHlpmM+rk/1bv3IZePKQ2JtHZzYCeRd3xOC33kl60HE7EwakQ== integrity sha512-hxgjZOXOqstRTWv+QjWJjK23rD5qzIV9ePlhX3imLeq/MgX0aU9VBDaG5SGKbSjaBNQnpLw6+sABJi3CDP6Z5A==
"@tiptap/extension-text@^3.3.0": "@tiptap/extension-text@^3.10.7":
version "3.10.7" version "3.11.0"
resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-3.10.7.tgz#3a9f4f104362012e84da4f2751f52c02ec385106" resolved "https://registry.yarnpkg.com/@tiptap/extension-text/-/extension-text-3.11.0.tgz#cf55c8c0fa3a18fbc93ec53be7c31fe60ed4e9bd"
integrity sha512-b7Rjil/uqiabWnRHyd1P84rWD2XRyZZSrmIAO9mDMD/jB2bE+f7rDJcHG76GF03UicDhEEEf2/8mz0dMLa6mUA== integrity sha512-ELAYm2BuChzZOqDG9B0k3W6zqM4pwNvXkam28KgHGiT2y7Ni68Rb+NXp16uVR+5zR6hkqnQ/BmJSKzAW59MXpA==
"@tiptap/extensions@^3.1.0": "@tiptap/extensions@^3.10.7":
version "3.10.7" version "3.11.0"
resolved "https://registry.yarnpkg.com/@tiptap/extensions/-/extensions-3.10.7.tgz#56f2b2ae58d216bcfcc6c3554c52c454ae3ebe5c" resolved "https://registry.yarnpkg.com/@tiptap/extensions/-/extensions-3.11.0.tgz#d6f6020312cda743738bbc1e918cd10a7f7d84fc"
integrity sha512-jYYR7NA7t2hdyJmSLYVAJ3usyIOZ2mfFqPCCHbSn/k3jqmGaPFZuxJSwmYjfmTxisZ9rGn+49/YJF2y/Yej/0Q== integrity sha512-g43beA73ZMLezez1st9LEwYrRHZ0FLzlsSlOZKk7sdmtHLmuqWHf4oyb0XAHol1HZIdGv104rYaGNgmQXr1ecQ==
"@tiptap/pm@^3.1.0": "@tiptap/pm@^3.10.7":
version "3.10.7" version "3.11.0"
resolved "https://registry.yarnpkg.com/@tiptap/pm/-/pm-3.10.7.tgz#d7028d96824e555f78e1b4490107e9db72eb53b4" resolved "https://registry.yarnpkg.com/@tiptap/pm/-/pm-3.11.0.tgz#c9d2bef0db08a5a5b2c6cce035fe893a475ee638"
integrity sha512-/iiurioqSukJk6CrEtfRpdOEafDybyVPToAllgn7i2XcusXSxJSX+K0GUndMUwVR+UqVOCyMYBTRTnE0hdQqgA== integrity sha512-plCQDLCZIOc92cizB8NNhBRN0szvYR3cx9i5IXo6v9Xsgcun8KHNcJkesc2AyeqdIs0BtOJZaqQ9adHThz8UDw==
dependencies: dependencies:
prosemirror-changeset "^2.3.0" prosemirror-changeset "^2.3.0"
prosemirror-collab "^1.3.1" prosemirror-collab "^1.3.1"
@@ -1729,17 +1729,17 @@
prosemirror-transform "^1.10.2" prosemirror-transform "^1.10.2"
prosemirror-view "^1.38.1" prosemirror-view "^1.38.1"
"@tiptap/react@^3.1.0": "@tiptap/react@^3.10.7":
version "3.10.7" version "3.11.0"
resolved "https://registry.yarnpkg.com/@tiptap/react/-/react-3.10.7.tgz#cfd2ade1c6db316136bac46457c394a1e09a80c7" resolved "https://registry.yarnpkg.com/@tiptap/react/-/react-3.11.0.tgz#b9dd344101cd64df45cb7a5785f98c7d3a689f72"
integrity sha512-hhKj62zvs/mSu5HlcmZDRFHVHCjJ6v6/7vB45MTAziP+cZ0+CEbEh2rnGNRNwooumWwm5pWdkVqI1efp7GtnUA== integrity sha512-SDGei/2DjwmhzsxIQNr6dkB6NxLgXZjQ6hF36NfDm4937r5NLrWrNk5tCsoDQiKZ0DHEzuJ6yZM5C7I7LZLB6w==
dependencies: dependencies:
"@types/use-sync-external-store" "^0.0.6" "@types/use-sync-external-store" "^0.0.6"
fast-deep-equal "^3.1.3" fast-deep-equal "^3.1.3"
use-sync-external-store "^1.4.0" use-sync-external-store "^1.4.0"
optionalDependencies: optionalDependencies:
"@tiptap/extension-bubble-menu" "^3.10.7" "@tiptap/extension-bubble-menu" "^3.11.0"
"@tiptap/extension-floating-menu" "^3.10.7" "@tiptap/extension-floating-menu" "^3.11.0"
"@tootallnate/quickjs-emscripten@^0.23.0": "@tootallnate/quickjs-emscripten@^0.23.0":
version "0.23.0" version "0.23.0"
@@ -1937,30 +1937,30 @@
resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8" resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8"
integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==
"@visactor/react-vchart@^2.0.8": "@visactor/react-vchart@^2.0.10":
version "2.0.8" version "2.0.10"
resolved "https://registry.yarnpkg.com/@visactor/react-vchart/-/react-vchart-2.0.8.tgz#4afdc9e41e13a5544edd1bdc58a961f53f9f4314" resolved "https://registry.yarnpkg.com/@visactor/react-vchart/-/react-vchart-2.0.10.tgz#103e8f555a56a6f134bd2f5136480b3912153617"
integrity sha512-/O7dqHp/5CL7Q58eFrnyKfxnBvE/RTGKEoEJXSqyJNNB1JDiPplz10TvlDoz+cmsUCsfoC/Apaj4QIxewXOKqQ== integrity sha512-OGpSBT7kutZZKSw3HlxivsmeqRZ6GEOXAxt20+hcZyeH34yqRHklksJYS6ET9E9uivbfrGzIAPniC4iizR8lhQ==
dependencies: dependencies:
"@visactor/vchart" "2.0.8" "@visactor/vchart" "2.0.10"
"@visactor/vchart-extension" "2.0.8" "@visactor/vchart-extension" "2.0.10"
"@visactor/vrender-core" "~1.0.24" "@visactor/vrender-core" "~1.0.30"
"@visactor/vrender-kits" "~1.0.24" "@visactor/vrender-kits" "~1.0.30"
"@visactor/vutils" "~1.0.12" "@visactor/vutils" "~1.0.12"
react-is "^18.2.0" react-is "^18.2.0"
"@visactor/vchart-extension@2.0.8": "@visactor/vchart-extension@2.0.10":
version "2.0.8" version "2.0.10"
resolved "https://registry.yarnpkg.com/@visactor/vchart-extension/-/vchart-extension-2.0.8.tgz#8fffc4a42920cf2ec31714a262b88dc376474ee5" resolved "https://registry.yarnpkg.com/@visactor/vchart-extension/-/vchart-extension-2.0.10.tgz#1fab69e983ba4a743f2b1a7a53ef5cd3f820cfb4"
integrity sha512-zq6Wc7d9LIhdGRdmhK9I9k+6uNsB7AMwgMUWQID3/rU9y5rgwmqRGOwQWV7h9UFFmI5iUXxVFdSTbHSdVRQ84A== integrity sha512-D/WDodDPtDFtMRXYEm9GNC/Qthu4WkMXMR4hS43dmqA2GYOcAB5/O3CfUFwm+efwBh2EEh46O3STEam20444og==
dependencies: dependencies:
"@visactor/vchart" "2.0.8" "@visactor/vchart" "2.0.10"
"@visactor/vdataset" "~1.0.12" "@visactor/vdataset" "~1.0.12"
"@visactor/vlayouts" "~1.0.12" "@visactor/vlayouts" "~1.0.12"
"@visactor/vrender-animate" "~1.0.24" "@visactor/vrender-animate" "~1.0.30"
"@visactor/vrender-components" "~1.0.24" "@visactor/vrender-components" "~1.0.30"
"@visactor/vrender-core" "~1.0.24" "@visactor/vrender-core" "~1.0.30"
"@visactor/vrender-kits" "~1.0.24" "@visactor/vrender-kits" "~1.0.30"
"@visactor/vutils" "~1.0.12" "@visactor/vutils" "~1.0.12"
"@visactor/vchart-semi-theme@^1.12.2": "@visactor/vchart-semi-theme@^1.12.2":
@@ -1975,20 +1975,20 @@
resolved "https://registry.yarnpkg.com/@visactor/vchart-theme-utils/-/vchart-theme-utils-1.12.2.tgz#bad0035e79dabbe80890bbd6196668551a12c874" resolved "https://registry.yarnpkg.com/@visactor/vchart-theme-utils/-/vchart-theme-utils-1.12.2.tgz#bad0035e79dabbe80890bbd6196668551a12c874"
integrity sha512-PkgSAivtUZukCWVUGCXxKcbTzI/oMj1Ky22VYcVs/KM4VFmmCywU2xjBBe1du0LUey6CAKB7bMlj5bL2jctG0A== integrity sha512-PkgSAivtUZukCWVUGCXxKcbTzI/oMj1Ky22VYcVs/KM4VFmmCywU2xjBBe1du0LUey6CAKB7bMlj5bL2jctG0A==
"@visactor/vchart@2.0.8", "@visactor/vchart@^2.0.8": "@visactor/vchart@2.0.10", "@visactor/vchart@^2.0.10":
version "2.0.8" version "2.0.10"
resolved "https://registry.yarnpkg.com/@visactor/vchart/-/vchart-2.0.8.tgz#10d78f5571781b7bda7294504e028fb2223947e3" resolved "https://registry.yarnpkg.com/@visactor/vchart/-/vchart-2.0.10.tgz#a357cfe8ab33c59d743c902920e9e7489268dd89"
integrity sha512-OyP5LBBTrXOjiauoWdUXW4W5iKLencsASvKqBw3BE6qwHbRrBgo6k5OgyUv3Gt+4jlEZ+PeD+gqnFiWUb4xtJw== integrity sha512-YKOdrU08CVB7851UaxPWRC2+9B0zydzwps2Kdpm4fa8t/KCAn/tfL1/jLdhoTu5brk5UI68w414MX8OsjVosSQ==
dependencies: dependencies:
"@visactor/vdataset" "~1.0.12" "@visactor/vdataset" "~1.0.12"
"@visactor/vlayouts" "~1.0.12" "@visactor/vlayouts" "~1.0.12"
"@visactor/vrender-animate" "~1.0.24" "@visactor/vrender-animate" "~1.0.30"
"@visactor/vrender-components" "~1.0.24" "@visactor/vrender-components" "~1.0.30"
"@visactor/vrender-core" "~1.0.24" "@visactor/vrender-core" "~1.0.30"
"@visactor/vrender-kits" "~1.0.24" "@visactor/vrender-kits" "~1.0.30"
"@visactor/vscale" "~1.0.12" "@visactor/vscale" "~1.0.12"
"@visactor/vutils" "~1.0.12" "@visactor/vutils" "~1.0.12"
"@visactor/vutils-extension" "2.0.8" "@visactor/vutils-extension" "2.0.10"
"@visactor/vdataset@~1.0.12": "@visactor/vdataset@~1.0.12":
version "1.0.16" version "1.0.16"
@@ -2024,44 +2024,44 @@
"@visactor/vutils" "1.0.16" "@visactor/vutils" "1.0.16"
eventemitter3 "^4.0.7" eventemitter3 "^4.0.7"
"@visactor/vrender-animate@1.0.24", "@visactor/vrender-animate@~1.0.24": "@visactor/vrender-animate@1.0.31", "@visactor/vrender-animate@~1.0.30":
version "1.0.24" version "1.0.31"
resolved "https://registry.yarnpkg.com/@visactor/vrender-animate/-/vrender-animate-1.0.24.tgz#928b8d0272b4b43bcd9588417d6e4f62eafc1f52" resolved "https://registry.yarnpkg.com/@visactor/vrender-animate/-/vrender-animate-1.0.31.tgz#4f25203a2073eecbb05dc20af4718b45107bdd12"
integrity sha512-XGTzM0r9bObs6MQ9u0IJ29Oxr1h9eKW6QzSppMnhXtQhiPGFzppp6SiRosI+Gjq0FAR/vmHTeu2C6tWZPDwrcg== integrity sha512-9xA9B8JihlsEfBziFUHdUGUizh6xRk07lejUk4f0+qGmGwMPvz32btszs2gw1eF9J6FVmBhxJdZILzcXz4ha0Q==
dependencies: dependencies:
"@visactor/vrender-core" "1.0.24" "@visactor/vrender-core" "1.0.31"
"@visactor/vutils" "~1.0.12" "@visactor/vutils" "~1.0.12"
"@visactor/vrender-components@~1.0.24": "@visactor/vrender-components@~1.0.30":
version "1.0.24" version "1.0.31"
resolved "https://registry.yarnpkg.com/@visactor/vrender-components/-/vrender-components-1.0.24.tgz#6bfb93fa9f6b8d6f0947a15cd8b286cc475d6202" resolved "https://registry.yarnpkg.com/@visactor/vrender-components/-/vrender-components-1.0.31.tgz#76445c52150e6e4c6f2e23a0afc19afdfe4cc0af"
integrity sha512-GwtRWUuaVw7HJM/GTA3XY/6kjyHzCi10yE4tUSuvrytF2yLdOO+yG920B1nV+rBZGpKgyTpdJmszngQ1RZN4BQ== integrity sha512-kB+ZdqCnfcmoLHleGPml/NmqgXViC0Vqk/64XzQzXd5fvFqCrgS1G6mpq+VrZjZhJx3gxCTQoct6q2qXN1aYIw==
dependencies: dependencies:
"@visactor/vrender-animate" "1.0.24" "@visactor/vrender-animate" "1.0.31"
"@visactor/vrender-core" "1.0.24" "@visactor/vrender-core" "1.0.31"
"@visactor/vrender-kits" "1.0.24" "@visactor/vrender-kits" "1.0.31"
"@visactor/vscale" "~1.0.12" "@visactor/vscale" "~1.0.12"
"@visactor/vutils" "~1.0.12" "@visactor/vutils" "~1.0.12"
"@visactor/vrender-core@1.0.24", "@visactor/vrender-core@~1.0.24": "@visactor/vrender-core@1.0.31", "@visactor/vrender-core@~1.0.30":
version "1.0.24" version "1.0.31"
resolved "https://registry.yarnpkg.com/@visactor/vrender-core/-/vrender-core-1.0.24.tgz#0efd7717796cb1dc91898b90246101fbd15d8f2a" resolved "https://registry.yarnpkg.com/@visactor/vrender-core/-/vrender-core-1.0.31.tgz#995551e4d519dfd0d71dbd27aa1112ff4e1125c3"
integrity sha512-npcXOil6cyP2pLXk1L9XwVyHDGw7eNnjUEtpwUBn34pyI+d1IWJ8hi19IaBSsl3uzc/qfu9MPXiiHGGoTLzH0A== integrity sha512-4tzN2M5GfI7612IHRiDqUetAjd3J3Ns5gHQxQvmMxismdw7UTrlB8PgnWx9djTYwoxZnhNX0MpPGz9CKgbb7RA==
dependencies: dependencies:
"@visactor/vutils" "~1.0.12" "@visactor/vutils" "~1.0.12"
color-convert "2.0.1" color-convert "2.0.1"
"@visactor/vrender-kits@1.0.24", "@visactor/vrender-kits@~1.0.24": "@visactor/vrender-kits@1.0.31", "@visactor/vrender-kits@~1.0.30":
version "1.0.24" version "1.0.31"
resolved "https://registry.yarnpkg.com/@visactor/vrender-kits/-/vrender-kits-1.0.24.tgz#61f9535340fbbf88cdc2e617f6c8210f54528613" resolved "https://registry.yarnpkg.com/@visactor/vrender-kits/-/vrender-kits-1.0.31.tgz#3c57cd84b48208fe6c7a19f4f7f05ba60bca4409"
integrity sha512-4gaZtCxHXPx4njJq417UfiPp9WbtUsPOJ+NyenhqLghdQXcqI8t1GfrXg2QiGcmqSSn8XDsHsQL6poZR1+wdVw== integrity sha512-ZS1vslveNfK6MrkL0tMIzQWT9G/q+P7201nNA55YM89N1Tzpzm0X55YHQiIx9TnWTWQijMlqkz1PR5n3Xh+Hjg==
dependencies: dependencies:
"@resvg/resvg-js" "2.4.1" "@resvg/resvg-js" "2.4.1"
"@visactor/vrender-core" "1.0.24" "@visactor/vrender-core" "1.0.31"
"@visactor/vutils" "~1.0.12" "@visactor/vutils" "~1.0.12"
gifuct-js "2.1.2" gifuct-js "2.1.2"
lottie-web "^5.12.2" lottie-web "^5.12.2"
roughjs "4.5.2" roughjs "4.6.6"
"@visactor/vscale@1.0.16", "@visactor/vscale@~1.0.12": "@visactor/vscale@1.0.16", "@visactor/vscale@~1.0.12":
version "1.0.16" version "1.0.16"
@@ -2070,10 +2070,10 @@
dependencies: dependencies:
"@visactor/vutils" "1.0.16" "@visactor/vutils" "1.0.16"
"@visactor/vutils-extension@2.0.8": "@visactor/vutils-extension@2.0.10":
version "2.0.8" version "2.0.10"
resolved "https://registry.yarnpkg.com/@visactor/vutils-extension/-/vutils-extension-2.0.8.tgz#969380d2517358ac9b7702aa39b0a7a98a9bd99e" resolved "https://registry.yarnpkg.com/@visactor/vutils-extension/-/vutils-extension-2.0.10.tgz#512a65286cef0307bbddab06628da538021a043f"
integrity sha512-NzA1HRH9VnoiR5q2313+undU7IawdZozaytslE0HKoJmr3I7z6Eod7yDO8nQ7/4ssYboMIzvYNXgakzo3yJClA== integrity sha512-XKps9vwm3rLLuP/oY9CHP1RZMmnXroT1l1yi+Ny+CD6NUaZpe0dlAcXgtsS6j0NztUA9KmIHol7Rnv5hhFz/iA==
dependencies: dependencies:
"@visactor/vdataset" "~1.0.12" "@visactor/vdataset" "~1.0.12"
"@visactor/vutils" "~1.0.12" "@visactor/vutils" "~1.0.12"
@@ -2393,10 +2393,10 @@ basic-ftp@^5.0.2:
resolved "https://registry.yarnpkg.com/basic-ftp/-/basic-ftp-5.0.5.tgz#14a474f5fffecca1f4f406f1c26b18f800225ac0" resolved "https://registry.yarnpkg.com/basic-ftp/-/basic-ftp-5.0.5.tgz#14a474f5fffecca1f4f406f1c26b18f800225ac0"
integrity sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg== integrity sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==
better-sqlite3@^12.4.1: better-sqlite3@^12.5.0:
version "12.4.1" version "12.5.0"
resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-12.4.1.tgz#f78df6c80530d1a0b750b538033e6199b7d30d26" resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-12.5.0.tgz#c570873d9635b5d56baa52f7e72634c2c589f35f"
integrity sha512-3yVdyZhklTiNrtg+4WqHpJpFDd+WHTg2oM7UcR80GqL05AOV0xEJzc6qNvFYoEtE+hRp1n9MpN6/+4yhlGkDXQ== integrity sha512-WwCZ/5Diz7rsF29o27o0Gcc1Du+l7Zsv7SYtVPG0X3G/uUI1LqdxrQI7c9Hs2FWpqXXERjW9hp6g3/tH7DlVKg==
dependencies: dependencies:
bindings "^1.5.0" bindings "^1.5.0"
prebuild-install "^7.1.1" prebuild-install "^7.1.1"
@@ -2432,20 +2432,20 @@ bl@^4.0.3:
inherits "^2.0.4" inherits "^2.0.4"
readable-stream "^3.4.0" readable-stream "^3.4.0"
body-parser@2.2.0: body-parser@2.2.1:
version "2.2.0" version "2.2.1"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-2.2.0.tgz#f7a9656de305249a715b549b7b8fd1ab9dfddcfa" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-2.2.1.tgz#6df606b0eb0a6e3f783dde91dde182c24c82438c"
integrity sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg== integrity sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==
dependencies: dependencies:
bytes "^3.1.2" bytes "^3.1.2"
content-type "^1.0.5" content-type "^1.0.5"
debug "^4.4.0" debug "^4.4.3"
http-errors "^2.0.0" http-errors "^2.0.0"
iconv-lite "^0.6.3" iconv-lite "^0.7.0"
on-finished "^2.4.1" on-finished "^2.4.1"
qs "^6.14.0" qs "^6.14.0"
raw-body "^3.0.0" raw-body "^3.0.1"
type-is "^2.0.0" type-is "^2.0.1"
boolbase@^1.0.0: boolbase@^1.0.0:
version "1.0.0" version "1.0.0"
@@ -2507,7 +2507,7 @@ buffer@^5.5.0:
base64-js "^1.3.1" base64-js "^1.3.1"
ieee754 "^1.1.13" ieee754 "^1.1.13"
bytes@3.1.2, bytes@^3.1.2: bytes@^3.1.2, bytes@~3.1.2:
version "3.1.2" version "3.1.2"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==
@@ -2739,10 +2739,10 @@ commander@2:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
commander@^14.0.1: commander@^14.0.2:
version "14.0.1" version "14.0.2"
resolved "https://registry.yarnpkg.com/commander/-/commander-14.0.1.tgz#2f9225c19e6ebd0dc4404dd45821b2caa17ea09b" resolved "https://registry.yarnpkg.com/commander/-/commander-14.0.2.tgz#b71fd37fe4069e4c3c7c13925252ada4eba14e8e"
integrity sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A== integrity sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==
compute-scroll-into-view@^1.0.20: compute-scroll-into-view@^1.0.20:
version "1.0.20" version "1.0.20"
@@ -2957,7 +2957,7 @@ debug@3.2.7:
dependencies: dependencies:
ms "^2.1.1" ms "^2.1.1"
debug@4, debug@^4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@^4.4.0, debug@^4.4.1: debug@4, debug@^4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.3.5, debug@^4.4.1:
version "4.4.1" version "4.4.1"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b"
integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==
@@ -3064,10 +3064,10 @@ devlop@^1.0.0, devlop@^1.1.0:
dependencies: dependencies:
dequal "^2.0.0" dequal "^2.0.0"
devtools-protocol@0.0.1521046: devtools-protocol@0.0.1534754:
version "0.0.1521046" version "0.0.1534754"
resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1521046.tgz#918e6175ea83100fefcb2b78779f15a77aa8a41b" resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1534754.tgz#75fb0496ff133d8d7e73d2e49600b37fcb4f46a9"
integrity sha512-vhE6eymDQSKWUXwwA37NtTTVEzjtGVfDr3pRbsWEQ5onH/Snp2c+2xZHWJJawG/0hCCJLRGt4xVtEVUVILol4w== integrity sha512-26T91cV5dbOYnXdJi5qQHoTtUoNEqwkHcAyu/IKtjIAxiEqPMrDiRkDOPWVsGfNZGmlQVHQbZRSjD8sxagWVsQ==
diff@^7.0.0: diff@^7.0.0:
version "7.0.0" version "7.0.0"
@@ -4048,6 +4048,11 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0:
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" 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== integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
hachure-fill@^0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/hachure-fill/-/hachure-fill-0.5.2.tgz#d19bc4cc8750a5962b47fb1300557a85fcf934cc"
integrity sha512-3GKBOn+m2LX9iq+JC1064cSFprJY4jL1jCXTcpnfER5HYE2l/4EfWSGzkPa/ZDBmYI0ZOEj5VHV/eKnPGkHuOg==
handlebars@4.7.8: handlebars@4.7.8:
version "4.7.8" version "4.7.8"
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9"
@@ -4180,7 +4185,7 @@ htmlparser2@^10.0.0:
domutils "^3.2.1" domutils "^3.2.1"
entities "^6.0.0" entities "^6.0.0"
http-errors@2.0.0, http-errors@^2.0.0: http-errors@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==
@@ -4191,6 +4196,17 @@ http-errors@2.0.0, http-errors@^2.0.0:
statuses "2.0.1" statuses "2.0.1"
toidentifier "1.0.1" toidentifier "1.0.1"
http-errors@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.1.tgz#36d2f65bc909c8790018dd36fb4d93da6caae06b"
integrity sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==
dependencies:
depd "~2.0.0"
inherits "~2.0.4"
setprototypeof "~1.2.0"
statuses "~2.0.2"
toidentifier "~1.0.1"
http-proxy-agent@^7.0.0, http-proxy-agent@^7.0.1: http-proxy-agent@^7.0.0, http-proxy-agent@^7.0.1:
version "7.0.2" version "7.0.2"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e"
@@ -4226,6 +4242,13 @@ iconv-lite@0.6.3, iconv-lite@^0.6.3:
dependencies: dependencies:
safer-buffer ">= 2.1.2 < 3.0.0" safer-buffer ">= 2.1.2 < 3.0.0"
iconv-lite@^0.7.0, iconv-lite@~0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.7.0.tgz#c50cd80e6746ca8115eb98743afa81aa0e147a3e"
integrity sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==
dependencies:
safer-buffer ">= 2.1.2 < 3.0.0"
ieee754@^1.1.12, ieee754@^1.1.13: ieee754@^1.1.12, ieee754@^1.1.13:
version "1.2.1" version "1.2.1"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
@@ -4267,7 +4290,7 @@ inflight@^1.0.4:
once "^1.3.0" once "^1.3.0"
wrappy "1" wrappy "1"
inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1: inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.4:
version "2.0.4" version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@@ -4771,12 +4794,12 @@ linkify-it@^5.0.0:
dependencies: dependencies:
uc.micro "^2.0.0" uc.micro "^2.0.0"
lint-staged@16.2.6: lint-staged@16.2.7:
version "16.2.6" version "16.2.7"
resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-16.2.6.tgz#760675e80f4b53337083d3f8bdecdd1f88079bf5" resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-16.2.7.tgz#c4a635960c17b52fe774f1f40aee8ce1bd86531f"
integrity sha512-s1gphtDbV4bmW1eylXpVMk2u7is7YsrLl8hzrtvC70h4ByhcMLZFY01Fx05ZUDNuv1H8HO4E+e2zgejV1jVwNw== integrity sha512-lDIj4RnYmK7/kXMya+qJsmkRFkGolciXjrsZ6PC25GdTfWOAWetR0ZbsNXRAj1EHHImRSalc+whZFg56F5DVow==
dependencies: dependencies:
commander "^14.0.1" commander "^14.0.2"
listr2 "^9.0.5" listr2 "^9.0.5"
micromatch "^4.0.8" micromatch "^4.0.8"
nano-spawn "^2.0.0" nano-spawn "^2.0.0"
@@ -6107,10 +6130,10 @@ prelude-ls@^1.2.1:
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
prettier@3.6.2: prettier@3.7.4:
version "3.6.2" version "3.7.4"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.6.2.tgz#ccda02a1003ebbb2bfda6f83a074978f608b9393" resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.7.4.tgz#d2f8335d4b1cec47e1c8098645411b0c9dff9c0f"
integrity sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ== integrity sha512-v6UNi1+3hSlVvv8fSaoUbggEM5VErKmmpGA7Pl3HF8V6uKY7rvClBOJlH6yNwQtfTueNkGVpOv/mtWL9L4bgRA==
prismjs@^1.29.0: prismjs@^1.29.0:
version "1.30.0" version "1.30.0"
@@ -6342,17 +6365,17 @@ punycode@^2.1.0:
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5"
integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==
puppeteer-core@24.30.0: puppeteer-core@24.32.0:
version "24.30.0" version "24.32.0"
resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-24.30.0.tgz#7d0d15ce6aee4f1aa8a8f046bf0198f025ee6c81" resolved "https://registry.yarnpkg.com/puppeteer-core/-/puppeteer-core-24.32.0.tgz#6dfe044bff236e4047b7834d93a72940b3891c32"
integrity sha512-2S3Smy0t0W4wJnNvDe7W0bE7wDmZjfZ3ljfMgJd6hn2Hq/f0jgN+x9PULZo2U3fu5UUIJ+JP8cNUGllu8P91Pg== integrity sha512-MqzLLeJjqjtHK9J44+KE3kjtXXhFpPvg+AvXl/oy/jB8MeeNH66/4MNotOTqGZ6MPaxWi51YJ1ASga6OIff6xw==
dependencies: dependencies:
"@puppeteer/browsers" "2.10.13" "@puppeteer/browsers" "2.11.0"
chromium-bidi "11.0.0" chromium-bidi "11.0.0"
debug "^4.4.3" debug "^4.4.3"
devtools-protocol "0.0.1521046" devtools-protocol "0.0.1534754"
typed-query-selector "^2.12.0" typed-query-selector "^2.12.0"
webdriver-bidi-protocol "0.3.8" webdriver-bidi-protocol "0.3.9"
ws "^8.18.3" ws "^8.18.3"
puppeteer-extra-plugin-stealth@^2.11.2: puppeteer-extra-plugin-stealth@^2.11.2:
@@ -6402,16 +6425,16 @@ puppeteer-extra@^3.3.6:
debug "^4.1.1" debug "^4.1.1"
deepmerge "^4.2.2" deepmerge "^4.2.2"
puppeteer@^24.30.0: puppeteer@^24.32.0:
version "24.30.0" version "24.32.0"
resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-24.30.0.tgz#26ed830277d23c43fdc30104226d117be19e1a3d" resolved "https://registry.yarnpkg.com/puppeteer/-/puppeteer-24.32.0.tgz#0f0e20b8024b3fdc46c9f06afee69f0e450473d4"
integrity sha512-A5OtCi9WpiXBQgJ2vQiZHSyrAzQmO/WDsvghqlN4kgw21PhxA5knHUaUQq/N3EMt8CcvSS0RM+kmYLJmedR3TQ== integrity sha512-exyxHPV5DSsigIhM/pzLcyzl5XU4Dp5lNP+APwIeStDxAdYqpMnJ1qN0QHXghjJx+cQJczby+ySH5rgv/5GQLw==
dependencies: dependencies:
"@puppeteer/browsers" "2.10.13" "@puppeteer/browsers" "2.11.0"
chromium-bidi "11.0.0" chromium-bidi "11.0.0"
cosmiconfig "^9.0.0" cosmiconfig "^9.0.0"
devtools-protocol "0.0.1521046" devtools-protocol "0.0.1534754"
puppeteer-core "24.30.0" puppeteer-core "24.32.0"
typed-query-selector "^2.12.0" typed-query-selector "^2.12.0"
qs@^6.14.0: qs@^6.14.0:
@@ -6442,15 +6465,15 @@ range-parser@^1.2.1:
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
raw-body@^3.0.0: raw-body@^3.0.1:
version "3.0.0" version "3.0.2"
resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-3.0.0.tgz#25b3476f07a51600619dae3fe82ddc28a36e5e0f" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-3.0.2.tgz#3e3ada5ae5568f9095d84376fd3a49b8fb000a51"
integrity sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g== integrity sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==
dependencies: dependencies:
bytes "3.1.2" bytes "~3.1.2"
http-errors "2.0.0" http-errors "~2.0.1"
iconv-lite "0.6.3" iconv-lite "~0.7.0"
unpipe "1.0.0" unpipe "~1.0.0"
rc@^1.2.7: rc@^1.2.7:
version "1.2.8" version "1.2.8"
@@ -6501,17 +6524,17 @@ react-resizable@^3.0.5:
prop-types "15.x" prop-types "15.x"
react-draggable "^4.0.3" react-draggable "^4.0.3"
react-router-dom@7.9.6: react-router-dom@7.10.0:
version "7.9.6" version "7.10.0"
resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-7.9.6.tgz#f2a0d12961d67bd87ab48e5ef42fa1f45beae357" resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-7.10.0.tgz#88e706f9f09cc5039c3694b643993bd8ef93fc12"
integrity sha512-2MkC2XSXq6HjGcihnx1s0DBWQETI4mlis4Ux7YTLvP67xnGxCvq+BcCQSO81qQHVUTM1V53tl4iVVaY5sReCOA== integrity sha512-Q4haR150pN/5N75O30iIsRJcr3ef7p7opFaKpcaREy0GQit6uCRu1NEiIFIwnHJQy0bsziRFBweR/5EkmHgVUQ==
dependencies: dependencies:
react-router "7.9.6" react-router "7.10.0"
react-router@7.9.6: react-router@7.10.0:
version "7.9.6" version "7.10.0"
resolved "https://registry.yarnpkg.com/react-router/-/react-router-7.9.6.tgz#003c8de335fdd7390286a478dcfd9579c1826137" resolved "https://registry.yarnpkg.com/react-router/-/react-router-7.10.0.tgz#45b666036800a023997137ee6caef6d4b8c79f78"
integrity sha512-Y1tUp8clYRXpfPITyuifmSoE2vncSME18uVLgaqyxh9H35JWpIfzHo+9y3Fzh5odk/jxPW29IgLgzcdwxGqyNA== integrity sha512-FVyCOH4IZ0eDDRycODfUqoN8ZSR2LbTvtx6RPsBgzvJ8xAXlMZNCrOFpu+jb8QbtZnpAd/cEki2pwE848pNGxw==
dependencies: dependencies:
cookie "^1.0.1" cookie "^1.0.1"
set-cookie-parser "^2.6.0" set-cookie-parser "^2.6.0"
@@ -6831,11 +6854,12 @@ rope-sequence@^1.3.0:
resolved "https://registry.yarnpkg.com/rope-sequence/-/rope-sequence-1.3.4.tgz#df85711aaecd32f1e756f76e43a415171235d425" resolved "https://registry.yarnpkg.com/rope-sequence/-/rope-sequence-1.3.4.tgz#df85711aaecd32f1e756f76e43a415171235d425"
integrity sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ== integrity sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==
roughjs@4.5.2: roughjs@4.6.6:
version "4.5.2" version "4.6.6"
resolved "https://registry.yarnpkg.com/roughjs/-/roughjs-4.5.2.tgz#aab644dcb41e9a75826c8bd5a5b0a859095f2f10" resolved "https://registry.yarnpkg.com/roughjs/-/roughjs-4.6.6.tgz#1059f49a5e0c80dee541a005b20cc322b222158b"
integrity sha512-2xSlLDKdsWyFxrveYWk9YQ/Y9UfK38EAMRNkYkMqYBJvPX8abCa9PN0x3w02H8Oa6/0bcZICJU+U95VumPqseg== integrity sha512-ZUz/69+SYpFN/g/lUlo2FXcIjRkSu3nDarreVdGGndHEBJ6cXPdKguS8JGxwj5HA5xIbVKSmLgr5b3AWxtRfvQ==
dependencies: dependencies:
hachure-fill "^0.5.2"
path-data-parser "^0.1.0" path-data-parser "^0.1.0"
points-on-curve "^0.2.0" points-on-curve "^0.2.0"
points-on-path "^0.2.1" points-on-path "^0.2.1"
@@ -6992,7 +7016,7 @@ set-proto@^1.0.0:
es-errors "^1.3.0" es-errors "^1.3.0"
es-object-atoms "^1.0.0" es-object-atoms "^1.0.0"
setprototypeof@1.2.0: setprototypeof@1.2.0, setprototypeof@~1.2.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==
@@ -7197,7 +7221,7 @@ statuses@2.0.1:
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
statuses@^2.0.1: statuses@^2.0.1, statuses@~2.0.2:
version "2.0.2" version "2.0.2"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.2.tgz#8f75eecef765b5e1cfcdc080da59409ed424e382" resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.2.tgz#8f75eecef765b5e1cfcdc080da59409ed424e382"
integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==
@@ -7497,7 +7521,7 @@ to-regex-range@^5.0.1:
dependencies: dependencies:
is-number "^7.0.0" is-number "^7.0.0"
toidentifier@1.0.1: toidentifier@1.0.1, toidentifier@~1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35"
integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==
@@ -7562,7 +7586,7 @@ type-check@^0.4.0, type-check@~0.4.0:
dependencies: dependencies:
prelude-ls "^1.2.1" prelude-ls "^1.2.1"
type-is@^2.0.0: type-is@^2.0.1:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-2.0.1.tgz#64f6cf03f92fce4015c2b224793f6bdd4b068c97" resolved "https://registry.yarnpkg.com/type-is/-/type-is-2.0.1.tgz#64f6cf03f92fce4015c2b224793f6bdd4b068c97"
integrity sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw== integrity sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==
@@ -7752,7 +7776,7 @@ universalify@^2.0.0:
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d"
integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==
unpipe@1.0.0: unpipe@~1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
@@ -7808,10 +7832,10 @@ vfile@^6.0.0:
"@types/unist" "^3.0.0" "@types/unist" "^3.0.0"
vfile-message "^4.0.0" vfile-message "^4.0.0"
vite@7.2.2: vite@7.2.6:
version "7.2.2" version "7.2.6"
resolved "https://registry.yarnpkg.com/vite/-/vite-7.2.2.tgz#17dd62eac2d0ca0fa90131c5f56e4fefb8845362" resolved "https://registry.yarnpkg.com/vite/-/vite-7.2.6.tgz#91e05ba05bc7c667a7645595e21f2a0eb1057631"
integrity sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ== integrity sha512-tI2l/nFHC5rLh7+5+o7QjKjSR04ivXDF4jcgV0f/bTQ+OJiITy5S6gaynVsEM+7RqzufMnVbIon6Sr5x1SDYaQ==
dependencies: dependencies:
esbuild "^0.25.0" esbuild "^0.25.0"
fdir "^6.5.0" fdir "^6.5.0"
@@ -7832,10 +7856,10 @@ web-streams-polyfill@^3.0.3:
resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz#2073b91a2fdb1fbfbd401e7de0ac9f8214cecb4b" resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz#2073b91a2fdb1fbfbd401e7de0ac9f8214cecb4b"
integrity sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw== integrity sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==
webdriver-bidi-protocol@0.3.8: webdriver-bidi-protocol@0.3.9:
version "0.3.8" version "0.3.9"
resolved "https://registry.yarnpkg.com/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.3.8.tgz#9c822b2647fd16d22b1b6fd730d4a3b863c93b93" resolved "https://registry.yarnpkg.com/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.3.9.tgz#89abf021f2a557a2dd81772f9ce7172b01f8a0f0"
integrity sha512-21Yi2GhGntMc671vNBCjiAeEVknXjVRoyu+k+9xOMShu+ZQfpGQwnBqbNz/Sv4GXZ6JmutlPAi2nIJcrymAWuQ== integrity sha512-uIYvlRQ0PwtZR1EzHlTMol1G0lAlmOe6wPykF9a77AK3bkpvZHzIVxRE2ThOx5vjy2zISe0zhwf5rzuUfbo1PQ==
whatwg-encoding@^3.1.1: whatwg-encoding@^3.1.1:
version "3.1.1" version "3.1.1"
@@ -8039,10 +8063,10 @@ zod@^3.24.1:
resolved "https://registry.yarnpkg.com/zod/-/zod-3.25.76.tgz#26841c3f6fd22a6a2760e7ccb719179768471e34" resolved "https://registry.yarnpkg.com/zod/-/zod-3.25.76.tgz#26841c3f6fd22a6a2760e7ccb719179768471e34"
integrity sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ== integrity sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==
zustand@^5.0.8: zustand@^5.0.9:
version "5.0.8" version "5.0.9"
resolved "https://registry.yarnpkg.com/zustand/-/zustand-5.0.8.tgz#b998a0c088c7027a20f2709141a91cb07ac57f8a" resolved "https://registry.yarnpkg.com/zustand/-/zustand-5.0.9.tgz#389dcd0309b9c545d7a461bd3c54955962847654"
integrity sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw== integrity sha512-ALBtUj0AfjJt3uNRQoL1tL2tMvj6Gp/6e39dnfT6uzpelGru8v1tPOGBzayOWbPJvujM8JojDk3E1LxeFisBNg==
zwitch@^2.0.0: zwitch@^2.0.0:
version "2.0.4" version "2.0.4"