From 5cc538f4e8b68f73387184435d87a5d40f26c3d3 Mon Sep 17 00:00:00 2001 From: taqin Date: Thu, 9 Jan 2025 04:50:45 +0700 Subject: [PATCH] new version is coming up with typescript base code and more clean --- .gitignore | 3 + README.md | 120 +---------------- bun.lockb | Bin 189754 -> 153224 bytes index.ts | 1 - package-lock.json | 7 + package.json | 14 +- src/config/index.ts | 31 +++++ src/index.ts | 27 ++++ src/lib/Bot/YoutubeBot.ts | 138 ++++++++++++++++++++ src/lib/Browser.ts | 45 +++++++ src/lib/LoginYoutube.ts | 77 +++++++++++ src/main.ts | 5 + src/utils/Logger.ts | 50 +++++++ src/utils/banner.ts | 15 +++ src/utils/delay.ts | 8 ++ src/utils/randomDelay.ts | 7 + src/utils/scrollToBottom.ts | 26 ++++ src/utils/scrollToComments.ts | 30 +++++ tsconfig.json | 21 +++ yarn.lock | 237 ++++++++++++++++++---------------- 20 files changed, 627 insertions(+), 235 deletions(-) delete mode 100644 index.ts create mode 100644 src/config/index.ts create mode 100644 src/index.ts create mode 100644 src/lib/Bot/YoutubeBot.ts create mode 100644 src/lib/Browser.ts create mode 100644 src/lib/LoginYoutube.ts create mode 100644 src/main.ts create mode 100644 src/utils/Logger.ts create mode 100644 src/utils/banner.ts create mode 100644 src/utils/delay.ts create mode 100644 src/utils/randomDelay.ts create mode 100644 src/utils/scrollToBottom.ts create mode 100644 src/utils/scrollToComments.ts create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore index a18b592..ce7d603 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,6 @@ ublock succesCommenting.log errorCommenting.log package-lock.json +bin +tmp +.env diff --git a/README.md b/README.md index 19b0d51..32f04ed 100644 --- a/README.md +++ b/README.md @@ -7,125 +7,7 @@ Youtube Bot Auto Commenter Using Puppeter and NodeJS

-## Quick Links - -* [Demo](https://www.youtube.com/watch?v=tkeWv0z8bqM) -* [Installation](#run--installation) -* [Feature](#feature) -* [Configuration](#configuration) - - - -## Demo - - -```bash -$ see this DEMO in here > https://www.youtube.com/watch?v=C7AOauxguSc - -``` - -## Run / Installation -How to run ? - -```bash -> git clone https://github.com/tegal1337/Youtube-Auto-Commenter/ -> cd Youtube-Auto-Commenter -> npm install -> node main.js -``` - -dont forget to change the google username and password in ` config.js` - -```javascript -module.exports = { - keywords: "keywords", - usernamegoogle: "username", - passwordgoogle: "pass", -}; - -``` -## Feature - - Feature | Status | -| -------------:|------------- | -| Random Copy Comment | Ok| -| Manual Comment | Ok| -| AI Comment (GPT BASED) | Ok| -| Comment On Trending | Ok | -| Comment based on Keyword | Ok | -| Multi Account | Ok| - -## Requirements - - - Windows / Linux - - Google Chrome - - a Youtube account - -## Running on android - -yes of course the bot is still works on android -but you need ubuntu installed on your android , use Termux for it! -and install ubuntu desktop with Andronix -i prefer ubuntu 20 , cuz it's more stable than 18 - -command for installing inside the ubuntu - -copy and paste one by one , don't be lazy dude 🤨 - -```bash -> apt instal -> apt update -> apt upgrade -> apt install chromium-browser -> apt install npm -> npm install -g n -> n install lts -> hash -r -> apt install curl -> curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - -> echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list -> apt install yarn -``` - -go to directory of this project , then install the dependency - -```bash -yarn -``` - - -also you need to change `executableFilePath` in `main.js` -you can set to /usr/bin/chromium - -## Configuration - - Config | Info | -| -------------:|------------- | -| keyword | fill the keyword , for searching videos of course| -| comments | list of the comment | -| usernamegoogle | your username google | -| password | your google password| -| delaycomment | delay commenting / seconds | -| trending | Comment based on trending videos on your location| -| multiaccount | Multiple account account | -| ai | Auto commenting with AI| - -## Support this project by - -- Give me an idea to create something amazing with this -or - -- support by donating -( i won't use your money , i will give to charity to kitabisa.com , or you dont have to send any money to me , do it by yourself .. it also supporting me :) ) - -# Contact -cp@imtaqin.id - -[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/fdciabdul) - - - - +New Version is developing ~ diff --git a/bun.lockb b/bun.lockb index 14bd2591b8e919665060085952af8d97c0b13eba..188563200a408f48b811b30f9a9400ee1db93283 100644 GIT binary patch delta 29170 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�##;oL`2sDF(?8=6|p)3#03(zNDwxW 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 delta 50157 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

ZO@V0&jQX3;z(nbz^vH|?fC&Ib{Z(k< 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 l@^`yRhSI2R()1RBf_n^ { + return anchors.map(anchor => anchor.href).filter(href => href); + }); + + Logger.success(`Collected ${videoLinks.length} video links.`); + + const convertedUrls = videoLinks.map(url => url.replace(/^https:\/\/www\.youtube\.com\/shorts\/([\w-]+)/, 'https://www.youtube.com/watch?v=$1')); + return convertedUrls; + } catch (error) { + Logger.error(`Failed to search keyword: ${error.message}`); + } + } + + /** + * Collect all comments from a video page. + */ + async collectAllComments() { + Logger.info('Starting to collect comments from the video...'); + return await this.page.evaluate(async () => { + const comments = new Set(); + + await new Promise((resolve) => { + let lastScrollHeight = document.body.scrollHeight; + let attempts = 0; + const maxAttempts = 20; + const interval = 400; + + const timer = setInterval(() => { + window.scrollBy(0, window.innerHeight); + + document.querySelectorAll( + 'span.yt-core-attributed-string.yt-core-attributed-string--white-space-pre-wrap' + ).forEach((comment) => { + if (comment && comment.textContent) { + comments.add(comment.textContent.trim()); + } + }); + + if (document.body.scrollHeight > lastScrollHeight) { + lastScrollHeight = document.body.scrollHeight; + attempts = 0; + } else { + attempts++; + } + + if (attempts >= maxAttempts) { + clearInterval(timer); + resolve(); + } + }, interval); + }); + + return Array.from(comments); + }); + } + + /** + * Navigate to a video, collect comments, and post a random one. + * @param videoLink - The URL of the video. + */ + async goToVideo(videoLink: string) { + try { + Logger.info(`Navigating to video page: ${videoLink}`); + await this.page.goto(videoLink); + + Logger.info('Collecting all comments from the video...'); + const comments = await this.collectAllComments(); + + if (comments.length === 0) { + Logger.warn('No comments found on this video.'); + return; + } + + Logger.success(`Collected ${comments.length} comments.`); + + const randomComment = comments[Math.floor(Math.random() * comments.length)]; + Logger.info(`Random comment selected: "${randomComment}"`); + + Logger.info('Scrolling to the comment input box...'); + await this.page.waitForSelector('#simple-box', { visible: true }); + await this.page.evaluate(() => { + const commentBox = document.querySelector('#simple-box'); + if (commentBox) { + commentBox.scrollIntoView({ behavior: 'smooth', block: 'center' }); + } + }); + + Logger.info('Clicking on the comment box...'); + await this.page.waitForSelector('#placeholder-area', { visible: true }); + await this.page.click('#placeholder-area'); + + Logger.info('Waiting for the text input box to be ready...'); + await this.page.waitForSelector('#contenteditable-root', { visible: true }); + + Logger.info('Typing the selected random comment...'); + await this.page.type('#contenteditable-root', randomComment); + + Logger.info('Submitting the comment...'); + await this.page.keyboard.press('Enter'); + + Logger.success('Comment posted successfully!'); + await this.page.click("#submit-button > yt-button-shape > button > yt-touch-feedback-shape > div"); + await delay(5000); + } catch (e) { + Logger.error(`Failed to interact with the video: ${e.message}`); + } + } +} diff --git a/src/lib/Browser.ts b/src/lib/Browser.ts new file mode 100644 index 0000000..0c37714 --- /dev/null +++ b/src/lib/Browser.ts @@ -0,0 +1,45 @@ +import UndetectableBrowser from "undetected-browser"; +import puppeteer from "puppeteer"; + + +export class LaunchBrowser { + + public browser: any; + public page: any; + + constructor() { + this.browser = null; + } + + async init() { + const UndetectableBMS = await new UndetectableBrowser(await puppeteer.launch({ + headless: false, + executablePath: "bin/chrome.exe", + userDataDir: "tmp", + args : [ + '--no-sandbox', + '--disable-setuid-sandbox', + '--disable-dev-shm-usage', + '--disable-accelerated-2d-canvas', + '--disable-gpu', + '--disable-features=IsolateOrigins,site-per-process', + '--disable-blink-features=AutomationControlled', + '--disable-features=SiteIsolation', + '--disable-site-isolation-trials', + '--no-default-browser-check', + '--no-first-run', + '--no-zygote', + '--no-zygote-forced', + '--no-zygote-forced-for-chrome', + '--disable-web-security', + ] + })); + this.browser = await UndetectableBMS.getBrowser(); + this.page = await this.browser.newPage(); + await this.page.setViewport({ width: 1375, height: 3812 }); + } + + async close() { + await this.browser.close(); + } +} \ No newline at end of file diff --git a/src/lib/LoginYoutube.ts b/src/lib/LoginYoutube.ts new file mode 100644 index 0000000..ad2c7ab --- /dev/null +++ b/src/lib/LoginYoutube.ts @@ -0,0 +1,77 @@ +import { getEnv } from "#config/index"; +import { randomDelay,randomNumber } from "#utils/randomDelay"; + + +export default class LoginYoutube { + page: any; + constructor(pages) { + this.page = pages; + } + + async login() { + try { + + await this.page.setExtraHTTPHeaders({ + 'Accept-Language': 'en-US,en;q=0.8', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36', + 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', + }) + await this.page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'); + await this.page.goto("https://myaccount.google.com/personal-info?pli=1",{ + waitUntil: 'networkidle0' + }) + try { + await this.page.waitForFunction(() => { + const textToFind = ['Basic info', 'Info dasar']; + return Array.from(document.querySelectorAll('*')) + .some(element => textToFind.some(text => element?.textContent?.includes(text)) as any); + }, { timeout: 5000 }); + + + console.log('Login Success'); + } catch (error) { + + await this.page.goto("https://accounts.google.com/v3/signin/identifier?continue=https%3A%2F%2Fwww.youtube.com%2Fsignin%3Faction_handle_signin%3Dtrue%26app%3Ddesktop%26hl%3Den%26next%3Dhttps%253A%252F%252Fwww.youtube.com%252F%253FthemeRefresh%253D1&ec=65620&hl=en&ifkv=AeZLP9_9zvAmir7Pg7TsXbdot1JS1Aihdz4-s09f1W0AHcGAlUl7JArUSY0p8rHx3W1azNTqcUtbfg&passive=true&service=youtube&uilel=3&flowName=GlifWebSignIn&flowEntry=ServiceLogin&dsh=S-99093102%3A1736179702641005&ddm=1"); + + const xp = '#identifierId'; + const el = await this.page.waitForSelector(xp, { + visible: true, + timeout: 10000 + }); + await randomDelay(1000, 2000); + await el.type(getEnv('USERNAME_GOOGLE'), { delay: randomNumber(1000, 2000) }); + await this.page.keyboard.press('Enter'); + await randomDelay(1000, 2000); + const xp2 = '#password'; + const el2 = await this.page.waitForSelector(xp2, { + visible: true, + timeout: 10000 + }) + + await el2.click(); + await randomDelay(1000, 2000); + await el2.type(getEnv('PASSWORD_GOOGLE'), { delay: randomNumber(1000, 2000) }); + + await this.page.keyboard.press('Enter'); + await this.page.waitForNavigation(); + await this.page.goto("https://myaccount.google.com/personal-info?pli=1",{ + waitUntil: 'networkidle0' + }) + try { + await this.page.waitForFunction(() => { + const textToFind = ['Basic info', 'Info dasar']; + return Array.from(document.querySelectorAll('*')) + .some(element => textToFind.some(text => element?.textContent?.includes(text)) as any); + }, { timeout: 5000 }); + + + console.log('Login Success'); + } catch (error) { + console.log('Login Failed'); + } + } + } catch (error) { + + } + } +} \ No newline at end of file diff --git a/src/main.ts b/src/main.ts new file mode 100644 index 0000000..af4f5dd --- /dev/null +++ b/src/main.ts @@ -0,0 +1,5 @@ +import puppeteer from "puppeteer"; +import UndetectableBrowser from "undetected-browser"; + + + diff --git a/src/utils/Logger.ts b/src/utils/Logger.ts new file mode 100644 index 0000000..cae03e9 --- /dev/null +++ b/src/utils/Logger.ts @@ -0,0 +1,50 @@ +// logger.js +import chalk from 'chalk'; + +export default class Logger { + static logTime() { + return chalk.dim(`[${new Date().toLocaleTimeString()}]`); + } + + static info(message) { + console.log( + `${this.logTime()} ${chalk.bold.blue('❯ ')} ${chalk.blueBright(message)}` + ); + } + + static warn(message) { + console.log( + `${this.logTime()} ${chalk.bold.yellow('⚠ ')} ${chalk.yellowBright(message)}` + ); + } + + static error(message) { + console.log( + `${this.logTime()} ${chalk.bold.red('✖ ')} ${chalk.redBright(message)}` + ); + } + + static success(message) { + console.log( + `${this.logTime()} ${chalk.bold.green('✔ ')} ${chalk.greenBright(message)}` + ); + } + + static custom(label, color, icon, message) { + console.log( + `${this.logTime()} ${chalk.hex(color).bold(`${icon} ${label}`)} ${chalk.hex(color)(message)}` + ); + } + + static divider() { + console.log( + chalk.dim('────────────────────────────────────────────────────') + ); + } + + static banner(text) { + console.log( + chalk.whiteBright.bold(` ${text} `) + ); + } +} diff --git a/src/utils/banner.ts b/src/utils/banner.ts new file mode 100644 index 0000000..16a0534 --- /dev/null +++ b/src/utils/banner.ts @@ -0,0 +1,15 @@ +export const banner = ` +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⠤⠒⠈⠉⠉⠉⠉⠒⠀⠀⠤⣀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⠁⠀⠀⠀⠀⠀⠀⢀⣄⠀⠀⠀⠀⠑⡄⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠰⠿⠿⠿⠣⣶⣿⡏⣶⣿⣿⠷⠶⠆⠀⠀⠘⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠠⠴⡅⠀⠀⠠⢶⣿⣿⣷⡄⣀⡀⡀⠀⠀⠀⠀⠀⡇⠀⠀⠀⠀ +⠀⣰⡶⣦⠀⠀⠀⡰⠀⠀⠸⠟⢸⣿⣿⣷⡆⠢⣉⢀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⢹⣧⣿⣇⠀⠀⡇⠀⢠⣷⣲⣺⣿⣿⣇⠤⣤⣿⣿⠀⢸⠀⣤⣶⠦⠀⠀⠀⠀ +⠀⠀⠙⢿⣿⣦⡀⢇⠀⠸⣿⣿⣿⣿⣿⣿⣿⣿⣿⠇⠀⡜⣾⣿⡃⠇⢀⣤⡀⠀ +⠀⠀⠀⠀⠙⢿⣿⣮⡆⠀⠙⠿⣿⣿⣾⣿⡿⡿⠋⢀⠞⢀⣿⣿⣿⣿⣿⡟⠁⠀ +⠀⠀⠀⠀⠀⠀⠛⢿⠇⣶⣤⣄⢀⣰⣷⣶⣿⠁⡰⢃⣴⣿⡿⢋⠏⠉⠁⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠠⢾⣿⣿⣿⣞⠿⣿⣿⢿⢸⣷⣌⠛⠋⠀⠘⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠙⣿⣿⣿⣶⣶⣿⣯⣿⣿⣿⣆⠀⠇⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣿⣿⣿⣿⣿⣯⡙⢿⣿⣿⠟⡁⠰⡀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣸⣿⣿⣿⣿⣿⣿⡟⠈⢩⣥⣾⣷⠐⡌⠙⠃⠀ + YOMEN v2` \ No newline at end of file diff --git a/src/utils/delay.ts b/src/utils/delay.ts new file mode 100644 index 0000000..5189131 --- /dev/null +++ b/src/utils/delay.ts @@ -0,0 +1,8 @@ +import Logger from "./Logger"; + +export const delay = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)); + +export const randomDelay = async (min: number, max: number) => { + Logger.info(`Delaying for ${Math.floor(Math.random() * (max - min + 1) + min)}ms...`); + await delay(Math.floor(Math.random() * (max - min + 1) + min)) +} \ No newline at end of file diff --git a/src/utils/randomDelay.ts b/src/utils/randomDelay.ts new file mode 100644 index 0000000..5fa7881 --- /dev/null +++ b/src/utils/randomDelay.ts @@ -0,0 +1,7 @@ +export async function randomDelay(min: number, max: number) { + await new Promise(resolve => setTimeout(resolve, Math.floor(Math.random() * (max - min + 1) + min))) +} + +export async function randomNumber(min: number, max: number) { + return Math.floor(Math.random() * (max - min + 1) + min) +} \ No newline at end of file diff --git a/src/utils/scrollToBottom.ts b/src/utils/scrollToBottom.ts new file mode 100644 index 0000000..c343c18 --- /dev/null +++ b/src/utils/scrollToBottom.ts @@ -0,0 +1,26 @@ +export default async function scrollToBottom(pages,attempts = 10, maxAttempts = 30, interval = 500) { + + await pages.evaluate(async () => { + await new Promise((resolve) => { + let lastScrollHeight = document.body.scrollHeight; + let attempts = 5; + const maxAttempts = 10; + const interval = 500; + + const timer = setInterval(() => { + window.scrollBy(0, window.innerHeight); + if (document.body.scrollHeight > lastScrollHeight) { + lastScrollHeight = document.body.scrollHeight; + attempts = 0; + } else { + attempts++; + } + + if (attempts >= maxAttempts) { + clearInterval(timer); + resolve(); + } + }, interval); + }); + }); +} \ No newline at end of file diff --git a/src/utils/scrollToComments.ts b/src/utils/scrollToComments.ts new file mode 100644 index 0000000..830f445 --- /dev/null +++ b/src/utils/scrollToComments.ts @@ -0,0 +1,30 @@ +export default async function scrollToComment(page) { + // Scroll down incrementally until the comment box is in view + await page.evaluate(async () => { + await new Promise((resolve) => { + let attempts = 0; + const maxAttempts = 10; // Max scrolling attempts + const interval = 500; // Time between scrolls in ms + + const timer = setInterval(() => { + window.scrollBy(0, window.innerHeight); // Scroll down by one screen height + attempts++; + + const commentBox = document.querySelector('#simple-box'); + if (commentBox && commentBox.getBoundingClientRect().top < window.innerHeight) { + // If the comment box is visible in the viewport, stop scrolling + clearInterval(timer); + resolve(); + } + + if (attempts >= maxAttempts) { + // Stop after max attempts + clearInterval(timer); + resolve(); + } + }, interval); + }); + }); + + +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..226cb93 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "ESNext", + "module": "CommonJS", + "baseUrl": "./src", + "paths": { + "#lib/*": ["lib/*"], + "#src/*": ["src/*"], + "#test/*": ["test/*"], + "#utils/*": ["utils/*"], + "#types/*": ["types/*"], + "#config/*": ["config/*"], + + }, + "outDir": "./dist", + "strict": false, + "esModuleInterop": true + }, + "include": ["src/**/*"], + "exclude": ["node_modules"] +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index f1efb69..4e73383 100644 --- a/yarn.lock +++ b/yarn.lock @@ -176,16 +176,11 @@ acorn-jsx@^5.3.2: resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.9.0: +acorn@^8.9.0: version "8.11.3" resolved "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz" integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== -agent-base@^7.1.0, agent-base@^7.1.2: - version "7.1.3" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz" - integrity sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw== - agent-base@6: version "6.0.2" resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" @@ -193,6 +188,11 @@ agent-base@6: dependencies: debug "4" +agent-base@^7.1.0, agent-base@^7.1.2: + version "7.1.3" + resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz" + integrity sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw== + ajv@^6.12.4: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" @@ -461,6 +461,11 @@ chainsaw@~0.1.0: dependencies: traverse ">=0.3.0 <0.4" +chalk@5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.4.1.tgz#1b48bf0963ec158dce2aacf69c093ae2dd2092d8" + integrity sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w== + chalk@^2.4.2: version "2.4.2" resolved "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz" @@ -551,16 +556,16 @@ color-convert@^2.0.1: dependencies: color-name "~1.1.4" -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - color-name@1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz" integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" @@ -655,14 +660,7 @@ date-format@^4.0.13: resolved "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz" integrity sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg== -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.0, debug@4: +debug@4, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@^4.4.0: version "4.4.0" resolved "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz" integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== @@ -676,6 +674,13 @@ debug@4.3.1: dependencies: ms "2.1.2" +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + deep-is@^0.1.3: version "0.1.4" resolved "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz" @@ -713,7 +718,7 @@ delayed-stream@~1.0.0: resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== -devtools-protocol@*, devtools-protocol@0.0.1367902: +devtools-protocol@0.0.1367902: version "0.0.1367902" resolved "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1367902.tgz" integrity sha512-XxtPuC3PGakY6PD7dG66/o8KwJ/LkH2/EKe19Dcw58w53dv4/vSQEkn/SzuyhHE2q4zPgCkxQBxus3VV4ql+Pg== @@ -767,6 +772,11 @@ domutils@^3.0.1: domelementtype "^2.3.0" domhandler "^5.0.3" +dotenv@^16.4.7: + version "16.4.7" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.7.tgz#0e20c5b82950140aa99be360a8a5f52335f53c26" + integrity sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ== + emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" @@ -944,7 +954,7 @@ eslint-module-utils@^2.8.0: dependencies: debug "^3.2.7" -eslint-plugin-import@^2.25.2, eslint-plugin-import@^2.27.5: +eslint-plugin-import@^2.27.5: version "2.29.1" resolved "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz" integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== @@ -992,7 +1002,7 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -"eslint@^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8", "eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.32.0 || ^8.2.0", eslint@^8.0.0, eslint@^8.33.0: +eslint@^8.33.0: version "8.57.0" resolved "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz" integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ== @@ -1074,7 +1084,7 @@ esutils@^2.0.2: resolved "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -extract-zip@^2.0.1, extract-zip@2.0.1: +extract-zip@2.0.1, extract-zip@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz" integrity sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg== @@ -1187,6 +1197,11 @@ fs.realpath@^1.0.0: resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== +fsevents@^2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + fstream@~1.0.12: version "1.0.12" resolved "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz" @@ -1382,14 +1397,6 @@ http-proxy-agent@^7.0.0, http-proxy-agent@^7.0.1: agent-base "^7.1.0" debug "^4.3.4" -https-proxy-agent@^7.0.6: - version "7.0.6" - resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz" - integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw== - dependencies: - agent-base "^7.1.2" - debug "4" - https-proxy-agent@5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz" @@ -1398,6 +1405,14 @@ https-proxy-agent@5.0.0: agent-base "6" debug "4" +https-proxy-agent@^7.0.6: + version "7.0.6" + resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz" + integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw== + dependencies: + agent-base "^7.1.2" + debug "4" + ieee754@^1.1.13: version "1.2.1" resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" @@ -1429,7 +1444,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1, inherits@2: +inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.0, inherits@~2.0.1: version "2.0.4" resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -1582,16 +1597,16 @@ is-weakref@^1.0.2: dependencies: call-bind "^1.0.2" -isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - isarray@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== +isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" @@ -1739,23 +1754,28 @@ mitt@3.0.1: resolved "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz" integrity sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw== -mkdirp@^0.5.1, "mkdirp@>=0.5 0": +"mkdirp@>=0.5 0", mkdirp@^0.5.1: version "0.5.6" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== dependencies: minimist "^1.2.6" -ms@^2.1.1, ms@^2.1.3: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +module-alias@^2.2.3: + version "2.2.3" + resolved "https://registry.npmjs.org/module-alias/-/module-alias-2.2.3.tgz" + integrity sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q== ms@2.1.2: version "2.1.2" resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@^2.1.1, ms@^2.1.3: + version "2.1.3" + resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" @@ -2020,16 +2040,16 @@ prelude-ls@^1.2.1: resolved "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -progress@^2.0.3: - version "2.0.3" - resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - progress@2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz" integrity sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg== +progress@^2.0.3: + version "2.0.3" + resolved "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + proxy-agent@^6.5.0: version "6.5.0" resolved "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz" @@ -2044,7 +2064,7 @@ proxy-agent@^6.5.0: proxy-from-env "^1.1.0" socks-proxy-agent "^8.0.5" -proxy-from-env@^1.1.0, proxy-from-env@1.1.0: +proxy-from-env@1.1.0, proxy-from-env@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== @@ -2072,6 +2092,18 @@ punycode@^2.1.0: resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== +puppeteer-core@23.11.1: + version "23.11.1" + resolved "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.11.1.tgz" + integrity sha512-3HZ2/7hdDKZvZQ7dhhITOUg4/wOrDRjyK2ZBllRB0ZCOi9u0cwq1ACHDjBB+nX+7+kltHjQvBRdeY7+W0T+7Gg== + dependencies: + "@puppeteer/browsers" "2.6.1" + chromium-bidi "0.11.0" + debug "^4.4.0" + devtools-protocol "0.0.1367902" + typed-query-selector "^2.12.0" + ws "^8.18.0" + puppeteer-core@^10.2.0: version "10.4.0" resolved "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-10.4.0.tgz" @@ -2090,18 +2122,6 @@ puppeteer-core@^10.2.0: unbzip2-stream "1.3.3" ws "7.4.6" -puppeteer-core@23.11.1: - version "23.11.1" - resolved "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-23.11.1.tgz" - integrity sha512-3HZ2/7hdDKZvZQ7dhhITOUg4/wOrDRjyK2ZBllRB0ZCOi9u0cwq1ACHDjBB+nX+7+kltHjQvBRdeY7+W0T+7Gg== - dependencies: - "@puppeteer/browsers" "2.6.1" - chromium-bidi "0.11.0" - debug "^4.4.0" - devtools-protocol "0.0.1367902" - typed-query-selector "^2.12.0" - ws "^8.18.0" - puppeteer@^23.11.1: version "23.11.1" resolved "https://registry.npmjs.org/puppeteer/-/puppeteer-23.11.1.tgz" @@ -2124,16 +2144,7 @@ queue-tick@^1.0.1: resolved "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz" integrity sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag== -readable-stream@^3.1.1: - version "3.6.2" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readable-stream@^3.4.0: +readable-stream@^3.1.1, readable-stream@^3.4.0: version "3.6.2" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -2194,13 +2205,6 @@ reusify@^1.0.4: resolved "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rimraf@^3.0.2, rimraf@3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - rimraf@2: version "2.7.1" resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz" @@ -2208,6 +2212,13 @@ rimraf@2: dependencies: glob "^7.1.3" +rimraf@3.0.2, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" @@ -2362,18 +2373,6 @@ streamx@^2.15.0, streamx@^2.21.0: optionalDependencies: bare-events "^2.2.0" -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~0.10.x: - version "0.10.31" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" - integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== - string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" @@ -2411,6 +2410,18 @@ string.prototype.trimstart@^1.0.8: define-properties "^1.2.1" es-object-atoms "^1.0.0" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== + strip-ansi@^5.2.0: version "5.2.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz" @@ -2454,6 +2465,16 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +tar-fs@2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz" + integrity sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA== + dependencies: + chownr "^1.1.1" + mkdirp "^0.5.1" + pump "^3.0.0" + tar-stream "^2.0.0" + tar-fs@^3.0.6: version "3.0.6" resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.6.tgz" @@ -2465,16 +2486,6 @@ tar-fs@^3.0.6: bare-fs "^2.1.1" bare-path "^2.1.0" -tar-fs@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz" - integrity sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA== - dependencies: - chownr "^1.1.1" - mkdirp "^0.5.1" - pump "^3.0.0" - tar-stream "^2.0.0" - tar-stream@^2.0.0: version "2.2.0" resolved "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz" @@ -2608,14 +2619,6 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" -unbzip2-stream@^1.4.3: - version "1.4.3" - resolved "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz" - integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== - dependencies: - buffer "^5.2.1" - through "^2.3.8" - unbzip2-stream@1.3.3: version "1.3.3" resolved "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz" @@ -2624,6 +2627,14 @@ unbzip2-stream@1.3.3: buffer "^5.2.1" through "^2.3.8" +unbzip2-stream@^1.4.3: + version "1.4.3" + resolved "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz" + integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== + dependencies: + buffer "^5.2.1" + through "^2.3.8" + undetected-browser@^2.0.4: version "2.0.4" resolved "https://registry.npmjs.org/undetected-browser/-/undetected-browser-2.0.4.tgz" @@ -2704,16 +2715,16 @@ wrappy@1: resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== -ws@^8.18.0: - version "8.18.0" - resolved "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz" - integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== - ws@7.4.6: version "7.4.6" resolved "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== +ws@^8.18.0: + version "8.18.0" + resolved "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz" + integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw== + y18n@^5.0.5: version "5.0.8" resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" @@ -2765,7 +2776,7 @@ zip-lib@^0.7.3: yauzl "^2.10.0" yazl "^2.5.1" -zod@^3.7.1, zod@3.23.8: +zod@3.23.8, zod@^3.7.1: version "3.23.8" resolved "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz" integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==