diff --git a/package.json b/package.json index 1661639da..03dc46539 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "redux-logger": "^3.0.6", "redux-persist": "^6.0.0", "socket.io-client": "^4.8.3", + "telegram": "^2.26.22", "zustand": "^5.0.10" }, "devDependencies": { diff --git a/src/services/mtprotoService.ts b/src/services/mtprotoService.ts new file mode 100644 index 000000000..651fe2138 --- /dev/null +++ b/src/services/mtprotoService.ts @@ -0,0 +1,209 @@ +import { TelegramClient } from 'telegram'; +import { StringSession } from 'telegram/sessions'; +import type { UserAuthParams, BotAuthParams } from 'telegram/client/auth'; + +type LoginOptions = UserAuthParams | BotAuthParams; + +class MTProtoService { + private static instance: MTProtoService | undefined; + private client: TelegramClient | undefined; + private isInitialized = false; + private isConnected = false; + private sessionString = ''; + + private constructor() { + // Private constructor to enforce singleton + } + + static getInstance(): MTProtoService { + if (!MTProtoService.instance) { + MTProtoService.instance = new MTProtoService(); + } + return MTProtoService.instance; + } + + /** + * Initialize the MTProto client with API credentials + */ + async initialize(): Promise { + if (this.isInitialized && this.client) { + console.log('MTProto client already initialized'); + return; + } + + const apiId = import.meta.env.VITE_TELEGRAM_API_ID; + const apiHash = import.meta.env.VITE_TELEGRAM_API_HASH; + const sessionString = this.loadSession() || ''; + + if (!apiId || !apiHash) { + throw new Error('VITE_TELEGRAM_API_ID and VITE_TELEGRAM_API_HASH must be configured'); + } + + try { + const stringSession = new StringSession(sessionString); + this.sessionString = sessionString; + + this.client = new TelegramClient(stringSession, Number(apiId), String(apiHash), { + connectionRetries: 5, + }); + + this.isInitialized = true; + console.log('MTProto client initialized successfully'); + } catch (error) { + console.error('Failed to initialize MTProto client:', error); + throw error; + } + } + + /** + * Connect to Telegram servers + */ + async connect(): Promise { + if (!this.client) { + throw new Error('MTProto client not initialized. Call initialize() first.'); + } + + if (this.isConnected) { + console.log('Already connected to Telegram'); + return; + } + + try { + await this.client.connect(); + this.isConnected = true; + console.log('Connected to Telegram successfully'); + + // Save session string if it changed + const newSessionString = this.client.session.save(); + if (newSessionString && newSessionString !== this.sessionString) { + this.sessionString = newSessionString; + this.saveSession(newSessionString); + console.log('Session updated and saved'); + } + } catch (error) { + console.error('Failed to connect to Telegram:', error); + throw error; + } + } + + /** + * Start authentication/login process + */ + async start(options: LoginOptions): Promise { + if (!this.client) { + throw new Error('MTProto client not initialized. Call initialize() first.'); + } + + try { + await this.client.start(options); + + // Save session after successful login + const newSessionString = this.client.session.save(); + if (newSessionString && newSessionString !== this.sessionString) { + this.sessionString = newSessionString; + this.saveSession(newSessionString); + console.log('Authentication successful, session saved'); + } + } catch (error) { + console.error('Authentication failed:', error); + throw error; + } + } + + /** + * Get the Telegram client instance + * @throws Error if client is not initialized + */ + getClient(): TelegramClient { + if (!this.client || !this.isInitialized) { + throw new Error('MTProto client not initialized. Call initialize() first.'); + } + return this.client; + } + + /** + * Check if the client is initialized + */ + isReady(): boolean { + return this.isInitialized && this.client !== undefined; + } + + /** + * Check if the client is connected + */ + isClientConnected(): boolean { + return this.isConnected && this.isReady(); + } + + /** + * Get the current session string + */ + getSessionString(): string { + return this.sessionString; + } + + /** + * Disconnect from Telegram + */ + async disconnect(): Promise { + if (this.client && this.isConnected) { + try { + await this.client.disconnect(); + this.isConnected = false; + console.log('Disconnected from Telegram'); + } catch (error) { + console.error('Error disconnecting from Telegram:', error); + throw error; + } + } + } + + /** + * Send a message using the client + */ + async sendMessage(entity: string, message: string): Promise { + const client = this.getClient(); + if (!this.isClientConnected()) { + await this.connect(); + } + await client.sendMessage(entity, { message }); + } + + /** + * Invoke a raw Telegram API method + */ + async invoke(request: Parameters[0]): Promise { + const client = this.getClient(); + if (!this.isClientConnected()) { + await this.connect(); + } + return client.invoke(request) as Promise; + } + + /** + * Load session from localStorage + */ + private loadSession(): string | null { + try { + return localStorage.getItem('telegram_session'); + } catch (error) { + console.error('Failed to load session from localStorage:', error); + return null; + } + } + + /** + * Save session to localStorage + */ + private saveSession(session: string): void { + try { + localStorage.setItem('telegram_session', session); + } catch (error) { + console.error('Failed to save session to localStorage:', error); + } + } +} + +// Export singleton instance +export const mtprotoService = MTProtoService.getInstance(); +export default mtprotoService; diff --git a/src/store/telegramSlice.ts b/src/store/telegramSlice.ts new file mode 100644 index 000000000..9014480a9 --- /dev/null +++ b/src/store/telegramSlice.ts @@ -0,0 +1,551 @@ +import { createSlice, PayloadAction, createAsyncThunk } from '@reduxjs/toolkit'; +import { mtprotoService } from '../services/mtprotoService'; +import type { Api } from 'telegram/tl'; + +// Types for Telegram entities +export type TelegramConnectionStatus = 'disconnected' | 'connecting' | 'connected' | 'error'; +export type TelegramAuthStatus = 'not_authenticated' | 'authenticating' | 'authenticated' | 'error'; + +export interface TelegramUser { + id: string; + firstName: string; + lastName?: string; + username?: string; + phoneNumber?: string; + isBot: boolean; + isVerified?: boolean; + isPremium?: boolean; + accessHash?: string; +} + +export interface TelegramChat { + id: string; + title?: string; + type: 'private' | 'group' | 'supergroup' | 'channel'; + username?: string; + accessHash?: string; + unreadCount: number; + lastMessage?: TelegramMessage; + lastMessageDate?: number; + isPinned: boolean; + photo?: { + smallFileId?: string; + bigFileId?: string; + }; + participantsCount?: number; +} + +export interface TelegramMessage { + id: string; + chatId: string; + threadId?: string; + date: number; + message: string; + fromId?: string; + fromName?: string; + isOutgoing: boolean; + isEdited: boolean; + isForwarded: boolean; + replyToMessageId?: string; + media?: { + type: string; + [key: string]: unknown; + }; + reactions?: Array<{ + emoticon: string; + count: number; + }>; + views?: number; +} + +export interface TelegramThread { + id: string; + chatId: string; + title: string; + messageCount: number; + lastMessage?: TelegramMessage; + lastMessageDate?: number; + unreadCount: number; + isPinned: boolean; +} + +interface TelegramState { + // Connection state + connectionStatus: TelegramConnectionStatus; + connectionError: string | null; + + // Authentication state + authStatus: TelegramAuthStatus; + authError: string | null; + isInitialized: boolean; + phoneNumber: string | null; + sessionString: string | null; + + // User data + currentUser: TelegramUser | null; + + // Chats + chats: Record; + chatsOrder: string[]; // Ordered list of chat IDs + selectedChatId: string | null; + + // Messages (organized by chatId) + messages: Record>; // [chatId][messageId] = message + messagesOrder: Record; // [chatId] = [messageId, ...] + + // Threads (organized by chatId) + threads: Record>; // [chatId][threadId] = thread + threadsOrder: Record; // [chatId] = [threadId, ...] + selectedThreadId: string | null; + + // Loading states + isLoadingChats: boolean; + isLoadingMessages: boolean; + isLoadingThreads: boolean; + + // Pagination + hasMoreChats: boolean; + hasMoreMessages: Record; // [chatId] = hasMore + hasMoreThreads: Record; // [chatId] = hasMore + + // Filters and search + searchQuery: string | null; + filteredChatIds: string[] | null; +} + +const initialState: TelegramState = { + // Connection + connectionStatus: 'disconnected', + connectionError: null, + + // Authentication + authStatus: 'not_authenticated', + authError: null, + isInitialized: false, + phoneNumber: null, + sessionString: null, + + // User + currentUser: null, + + // Chats + chats: {}, + chatsOrder: [], + selectedChatId: null, + + // Messages + messages: {}, + messagesOrder: {}, + + // Threads + threads: {}, + threadsOrder: {}, + selectedThreadId: null, + + // Loading + isLoadingChats: false, + isLoadingMessages: false, + isLoadingThreads: false, + + // Pagination + hasMoreChats: true, + hasMoreMessages: {}, + hasMoreThreads: {}, + + // Search + searchQuery: null, + filteredChatIds: null, +}; + +// Async thunks +export const initializeTelegram = createAsyncThunk( + 'telegram/initialize', + async (_, { rejectWithValue }) => { + try { + await mtprotoService.initialize(); + const sessionString = mtprotoService.getSessionString(); + return { sessionString }; + } catch (error) { + return rejectWithValue( + error instanceof Error ? error.message : 'Failed to initialize Telegram client' + ); + } + } +); + +export const connectTelegram = createAsyncThunk( + 'telegram/connect', + async (_, { rejectWithValue }) => { + try { + await mtprotoService.connect(); + return true; + } catch (error) { + return rejectWithValue( + error instanceof Error ? error.message : 'Failed to connect to Telegram' + ); + } + } +); + +export const checkAuthStatus = createAsyncThunk( + 'telegram/checkAuthStatus', + async (_, { rejectWithValue }) => { + try { + const client = mtprotoService.getClient(); + const isAuthorized = await client.checkAuthorization(); + + if (isAuthorized) { + const me = await client.getMe(); + return me; + } + return null; + } catch (error) { + return rejectWithValue( + error instanceof Error ? error.message : 'Failed to check auth status' + ); + } + } +); + +export const fetchChats = createAsyncThunk( + 'telegram/fetchChats', + async (_, { rejectWithValue }) => { + try { + const client = mtprotoService.getClient(); + const dialogs = await client.getDialogs({ limit: 100 }); + return dialogs; + } catch (error) { + return rejectWithValue( + error instanceof Error ? error.message : 'Failed to fetch chats' + ); + } + } +); + +export const fetchMessages = createAsyncThunk( + 'telegram/fetchMessages', + async ( + { chatId, limit = 50, offsetId }: { chatId: string; limit?: number; offsetId?: number }, + { rejectWithValue } + ) => { + try { + const client = mtprotoService.getClient(); + // Implementation depends on GramJS API + // This is a placeholder - adjust based on actual API + const messages = await client.getMessages(chatId, { limit, offsetId }); + return { chatId, messages }; + } catch (error) { + return rejectWithValue( + error instanceof Error ? error.message : 'Failed to fetch messages' + ); + } + } +); + +const telegramSlice = createSlice({ + name: 'telegram', + initialState, + reducers: { + // Connection actions + setConnectionStatus: (state, action: PayloadAction) => { + state.connectionStatus = action.payload; + if (action.payload !== 'error') { + state.connectionError = null; + } + }, + setConnectionError: (state, action: PayloadAction) => { + state.connectionError = action.payload; + if (action.payload) { + state.connectionStatus = 'error'; + } + }, + + // Authentication actions + setAuthStatus: (state, action: PayloadAction) => { + state.authStatus = action.payload; + if (action.payload !== 'error') { + state.authError = null; + } + }, + setAuthError: (state, action: PayloadAction) => { + state.authError = action.payload; + if (action.payload) { + state.authStatus = 'error'; + } + }, + setPhoneNumber: (state, action: PayloadAction) => { + state.phoneNumber = action.payload; + }, + setSessionString: (state, action: PayloadAction) => { + state.sessionString = action.payload; + }, + + // User actions + setCurrentUser: (state, action: PayloadAction) => { + state.currentUser = action.payload; + }, + + // Chat actions + setChats: (state, action: PayloadAction>) => { + state.chats = action.payload; + }, + addChat: (state, action: PayloadAction) => { + const chat = action.payload; + state.chats[chat.id] = chat; + if (!state.chatsOrder.includes(chat.id)) { + state.chatsOrder.unshift(chat.id); + } + }, + updateChat: (state, action: PayloadAction & { id: string }>) => { + const { id, ...updates } = action.payload; + if (state.chats[id]) { + state.chats[id] = { ...state.chats[id], ...updates }; + } + }, + removeChat: (state, action: PayloadAction) => { + const chatId = action.payload; + delete state.chats[chatId]; + state.chatsOrder = state.chatsOrder.filter((id) => id !== chatId); + if (state.selectedChatId === chatId) { + state.selectedChatId = null; + } + }, + setSelectedChat: (state, action: PayloadAction) => { + state.selectedChatId = action.payload; + // Clear selected thread when changing chat + if (action.payload !== state.selectedChatId) { + state.selectedThreadId = null; + } + }, + setChatsOrder: (state, action: PayloadAction) => { + state.chatsOrder = action.payload; + }, + + // Message actions + addMessage: (state, action: PayloadAction) => { + const message = action.payload; + const { chatId, id } = message; + + if (!state.messages[chatId]) { + state.messages[chatId] = {}; + state.messagesOrder[chatId] = []; + } + + if (!state.messages[chatId][id]) { + state.messages[chatId][id] = message; + state.messagesOrder[chatId].push(id); + } + }, + addMessages: (state, action: PayloadAction<{ chatId: string; messages: TelegramMessage[] }>) => { + const { chatId, messages } = action.payload; + + if (!state.messages[chatId]) { + state.messages[chatId] = {}; + state.messagesOrder[chatId] = []; + } + + messages.forEach((message) => { + if (!state.messages[chatId][message.id]) { + state.messages[chatId][message.id] = message; + state.messagesOrder[chatId].push(message.id); + } + }); + }, + updateMessage: ( + state, + action: PayloadAction<{ chatId: string; messageId: string; updates: Partial }> + ) => { + const { chatId, messageId, updates } = action.payload; + if (state.messages[chatId]?.[messageId]) { + state.messages[chatId][messageId] = { + ...state.messages[chatId][messageId], + ...updates, + }; + } + }, + removeMessage: (state, action: PayloadAction<{ chatId: string; messageId: string }>) => { + const { chatId, messageId } = action.payload; + if (state.messages[chatId]?.[messageId]) { + delete state.messages[chatId][messageId]; + state.messagesOrder[chatId] = state.messagesOrder[chatId].filter( + (id) => id !== messageId + ); + } + }, + clearMessages: (state, action: PayloadAction) => { + const chatId = action.payload; + delete state.messages[chatId]; + delete state.messagesOrder[chatId]; + }, + + // Thread actions + addThread: (state, action: PayloadAction) => { + const thread = action.payload; + const { chatId, id } = thread; + + if (!state.threads[chatId]) { + state.threads[chatId] = {}; + state.threadsOrder[chatId] = []; + } + + if (!state.threads[chatId][id]) { + state.threads[chatId][id] = thread; + state.threadsOrder[chatId].push(id); + } + }, + updateThread: ( + state, + action: PayloadAction<{ chatId: string; threadId: string; updates: Partial }> + ) => { + const { chatId, threadId, updates } = action.payload; + if (state.threads[chatId]?.[threadId]) { + state.threads[chatId][threadId] = { + ...state.threads[chatId][threadId], + ...updates, + }; + } + }, + setSelectedThread: (state, action: PayloadAction) => { + state.selectedThreadId = action.payload; + }, + + // Search actions + setSearchQuery: (state, action: PayloadAction) => { + state.searchQuery = action.payload; + }, + setFilteredChatIds: (state, action: PayloadAction) => { + state.filteredChatIds = action.payload; + }, + + // Reset actions + resetTelegram: (state) => { + return initialState; + }, + resetChats: (state) => { + state.chats = {}; + state.chatsOrder = []; + state.selectedChatId = null; + }, + resetMessages: (state) => { + state.messages = {}; + state.messagesOrder = {}; + }, + }, + extraReducers: (builder) => { + // Initialize + builder + .addCase(initializeTelegram.pending, (state) => { + state.isInitialized = false; + }) + .addCase(initializeTelegram.fulfilled, (state, action) => { + state.isInitialized = true; + state.sessionString = action.payload.sessionString; + }) + .addCase(initializeTelegram.rejected, (state, action) => { + state.isInitialized = false; + state.connectionError = action.payload as string; + }); + + // Connect + builder + .addCase(connectTelegram.pending, (state) => { + state.connectionStatus = 'connecting'; + state.connectionError = null; + }) + .addCase(connectTelegram.fulfilled, (state) => { + state.connectionStatus = 'connected'; + state.connectionError = null; + }) + .addCase(connectTelegram.rejected, (state, action) => { + state.connectionStatus = 'error'; + state.connectionError = action.payload as string; + }); + + // Check auth + builder + .addCase(checkAuthStatus.pending, (state) => { + state.authStatus = 'authenticating'; + }) + .addCase(checkAuthStatus.fulfilled, (state, action) => { + if (action.payload) { + state.authStatus = 'authenticated'; + // Convert Api.User to TelegramUser + // This is a placeholder - adjust based on actual API response + state.currentUser = { + id: String(action.payload.id), + firstName: action.payload.firstName || '', + lastName: action.payload.lastName, + username: action.payload.username, + isBot: Boolean(action.payload.bot), + accessHash: action.payload.accessHash?.toString(), + }; + } else { + state.authStatus = 'not_authenticated'; + state.currentUser = null; + } + }) + .addCase(checkAuthStatus.rejected, (state, action) => { + state.authStatus = 'error'; + state.authError = action.payload as string; + }); + + // Fetch chats + builder + .addCase(fetchChats.pending, (state) => { + state.isLoadingChats = true; + }) + .addCase(fetchChats.fulfilled, (state, action) => { + state.isLoadingChats = false; + // Convert dialogs to chats + // This is a placeholder - adjust based on actual API response + // action.payload should be an array of dialogs + }) + .addCase(fetchChats.rejected, (state) => { + state.isLoadingChats = false; + }); + + // Fetch messages + builder + .addCase(fetchMessages.pending, (state) => { + state.isLoadingMessages = true; + }) + .addCase(fetchMessages.fulfilled, (state, action) => { + state.isLoadingMessages = false; + // Messages will be added via addMessages action + }) + .addCase(fetchMessages.rejected, (state) => { + state.isLoadingMessages = false; + }); + }, +}); + +export const { + setConnectionStatus, + setConnectionError, + setAuthStatus, + setAuthError, + setPhoneNumber, + setSessionString, + setCurrentUser, + setChats, + addChat, + updateChat, + removeChat, + setSelectedChat, + setChatsOrder, + addMessage, + addMessages, + updateMessage, + removeMessage, + clearMessages, + addThread, + updateThread, + setSelectedThread, + setSearchQuery, + setFilteredChatIds, + resetTelegram, + resetChats, + resetMessages, +} = telegramSlice.actions; + +export default telegramSlice.reducer; diff --git a/src/utils/config.ts b/src/utils/config.ts index e03317437..9fbe0b133 100644 --- a/src/utils/config.ts +++ b/src/utils/config.ts @@ -7,5 +7,12 @@ export const TELEGRAM_BOT_USERNAME = export const TELEGRAM_BOT_ID = import.meta.env.VITE_TELEGRAM_BOT_ID || "8043922470"; +export const TELEGRAM_API_ID = import.meta.env.VITE_TELEGRAM_API_ID + ? Number(import.meta.env.VITE_TELEGRAM_API_ID) + : undefined; + +export const TELEGRAM_API_HASH = + import.meta.env.VITE_TELEGRAM_API_HASH || undefined; + export const IS_DEV = Boolean(import.meta.env.DEV) || import.meta.env.MODE === "development"; diff --git a/yarn.lock b/yarn.lock index 644cf3ed6..97f159695 100644 --- a/yarn.lock +++ b/yarn.lock @@ -165,6 +165,11 @@ "@babel/helper-string-parser" "^7.27.1" "@babel/helper-validator-identifier" "^7.28.5" +"@cryptography/aes@^0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@cryptography/aes/-/aes-0.1.1.tgz#0096726a6a2a2cfc2e8bddf3997e98e49f1a224d" + integrity sha512-PcYz4FDGblO6tM2kSC+VzhhK62vml6k6/YAkiWtyPvrgJVfnDRoHGDtKn5UiaRRUrvUTTocBpvc2rRgTCqxjsg== + "@esbuild/aix-ppc64@0.27.2": version "0.27.2" resolved "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz" @@ -726,6 +731,13 @@ arg@^5.0.2: resolved "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz" integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== +async-mutex@^0.3.0: + version "0.3.2" + resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.3.2.tgz#1485eda5bda1b0ec7c8df1ac2e815757ad1831df" + integrity sha512-HuTK7E7MT7jZEh1P9GtRW9+aTWiDWWi9InbZ5hjxrnRa39KS4BW04+xLBhYNS2aXhHUIKZSw3gj4Pn1pj+qGAA== + dependencies: + tslib "^2.3.1" + autoprefixer@^10.4.23: version "10.4.23" resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.23.tgz" @@ -737,11 +749,21 @@ autoprefixer@^10.4.23: picocolors "^1.1.1" postcss-value-parser "^4.2.0" +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + baseline-browser-mapping@^2.9.0: version "2.9.18" resolved "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.18.tgz" integrity sha512-e23vBV1ZLfjb9apvfPk4rHVu2ry6RIr2Wfs+O324okSidrX7pTAnEJPCh/O5BtRlr7QtZI7ktOP3vsqr7Z5XoA== +big-integer@^1.6.48: + version "1.6.52" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" + integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== + binary-extensions@^2.0.0: version "2.3.0" resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz" @@ -765,6 +787,21 @@ browserslist@^4.24.0, browserslist@^4.28.1: node-releases "^2.0.27" update-browserslist-db "^1.2.0" +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + +bufferutil@^4.0.1, bufferutil@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.1.0.tgz#a4623541dd23867626bb08a051ec0d2ec0b70294" + integrity sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw== + dependencies: + node-gyp-build "^4.3.0" + camelcase-css@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz" @@ -815,6 +852,21 @@ csstype@^3.2.2: resolved "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz" integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ== +d@1, d@^1.0.1, d@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.2.tgz#2aefd554b81981e7dccf72d6842ae725cb17e5de" + integrity sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw== + dependencies: + es5-ext "^0.10.64" + type "^2.7.2" + +debug@^2.2.0: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + debug@^4.1.0, debug@^4.3.1, debug@~4.4.1: version "4.4.3" resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" @@ -837,6 +889,36 @@ dlv@^1.1.3: resolved "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz" integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== +dom-serializer@^1.0.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" + integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + +domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^4.0.0, domhandler@^4.2.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" + integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== + dependencies: + domelementtype "^2.2.0" + +domutils@^2.5.2: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + electron-to-chromium@^1.5.263: version "1.5.279" resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.279.tgz" @@ -858,6 +940,38 @@ engine.io-parser@~5.2.1: resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.2.3.tgz#00dc5b97b1f233a23c9398d0209504cf5f94d92f" integrity sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q== +entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + +es5-ext@^0.10.35, es5-ext@^0.10.62, es5-ext@^0.10.63, es5-ext@^0.10.64, es5-ext@~0.10.14: + version "0.10.64" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714" + integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + esniff "^2.0.1" + next-tick "^1.1.0" + +es6-iterator@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-symbol@^3.1.1, es6-symbol@^3.1.3: + version "3.1.4" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.4.tgz#f4e7d28013770b4208ecbf3e0bf14d3bcb557b8c" + integrity sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg== + dependencies: + d "^1.0.2" + ext "^1.7.0" + esbuild@^0.27.0: version "0.27.2" resolved "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz" @@ -895,6 +1009,31 @@ escalade@^3.2.0: resolved "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz" integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== +esniff@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308" + integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg== + dependencies: + d "^1.0.1" + es5-ext "^0.10.62" + event-emitter "^0.3.5" + type "^2.7.2" + +event-emitter@^0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA== + dependencies: + d "1" + es5-ext "~0.10.14" + +ext@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" + integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== + dependencies: + type "^2.7.2" + fast-glob@^3.3.2: version "3.3.3" resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz" @@ -959,6 +1098,11 @@ glob-parent@^6.0.2: dependencies: is-glob "^4.0.3" +graceful-fs@^4.1.11: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + hasown@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz" @@ -966,11 +1110,36 @@ hasown@^2.0.2: dependencies: function-bind "^1.1.2" +htmlparser2@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" + +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + immer@^11.0.0: version "11.1.3" resolved "https://registry.yarnpkg.com/immer/-/immer-11.1.3.tgz#78681e1deb6cec39753acf04eb16d7576c04f4d6" integrity sha512-6jQTc5z0KJFtr1UgFpIL3N9XSC3saRaI9PwWtzM2pSqkNGtiNkYY2OSwkOGDK2XcTRcLb1pi/aNkKZz0nxVH4Q== +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +ip-address@^10.0.1: + version "10.1.0" + resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-10.1.0.tgz#d8dcffb34d0e02eb241427444a6e23f5b0595aa4" + integrity sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q== + is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" @@ -1002,6 +1171,11 @@ is-number@^7.0.0: resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-typedarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== + jiti@^1.21.7: version "1.21.7" resolved "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz" @@ -1064,11 +1238,21 @@ micromatch@^4.0.8: braces "^3.0.3" picomatch "^2.3.1" +mime@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7" + integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== + mini-svg-data-uri@^1.2.3: version "1.4.4" resolved "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz" integrity sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg== +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + ms@^2.1.3: version "2.1.3" resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" @@ -1088,6 +1272,23 @@ nanoid@^3.3.11: resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz" integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== +next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + +node-gyp-build@^4.3.0: + version "4.8.4" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.4.tgz#8a70ee85464ae52327772a90d66c6077a900cfc8" + integrity sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ== + +node-localstorage@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-localstorage/-/node-localstorage-2.2.1.tgz#869723550a4883e426cb391d2df0b563a51c7c1c" + integrity sha512-vv8fJuOUCCvSPjDjBLlMqYMHob4aGjkmrkaE42/mZr0VT+ZAU10jRF8oTnX9+pgU9/vYJ8P7YT3Vd6ajkmzSCw== + dependencies: + write-file-atomic "^1.1.4" + node-releases@^2.0.27: version "2.0.27" resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz" @@ -1108,6 +1309,16 @@ object-hash@^3.0.0: resolved "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz" integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== +pako@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== + +path-browserify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + path-parse@^1.0.7: version "1.0.7" resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" @@ -1257,6 +1468,11 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +real-cancellable-promise@^1.1.1: + version "1.2.3" + resolved "https://registry.yarnpkg.com/real-cancellable-promise/-/real-cancellable-promise-1.2.3.tgz#6df13b7db40cbff9969975d6194c11e2356c4a13" + integrity sha512-hBI5Gy/55VEeeMtImMgEirD7eq5UmqJf1J8dFZtbJZA/3rB0pYFZ7PayMGueb6v4UtUtpKpP+05L0VwyE1hI9Q== + redux-logger@^3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/redux-logger/-/redux-logger-3.0.6.tgz#f7555966f3098f3c88604c449cf0baf5778274bf" @@ -1354,6 +1570,16 @@ set-cookie-parser@^2.6.0: resolved "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz" integrity sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw== +slide@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + integrity sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw== + +smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + socket.io-client@^4.8.3: version "4.8.3" resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-4.8.3.tgz#62717edd46a318c918125b57e92dc7f8bb71c34c" @@ -1372,11 +1598,24 @@ socket.io-parser@~4.2.4: "@socket.io/component-emitter" "~3.1.0" debug "~4.4.1" +socks@^2.6.2: + version "2.8.7" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.7.tgz#e2fb1d9a603add75050a2067db8c381a0b5669ea" + integrity sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A== + dependencies: + ip-address "^10.0.1" + smart-buffer "^4.2.0" + source-map-js@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz" integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== +store2@^2.13.0: + version "2.14.4" + resolved "https://registry.yarnpkg.com/store2/-/store2-2.14.4.tgz#81b313abaddade4dcd7570c5cc0e3264a8f7a242" + integrity sha512-srTItn1GOvyvOycgxjAnPA63FZNwy0PTyUBFMHRM+hVFltAeoh0LmNBz9SZqUS9mMqGk8rfyWyXn3GH5ReJ8Zw== + sucrase@^3.35.0: version "3.35.1" resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.35.1.tgz" @@ -1423,6 +1662,29 @@ tailwindcss@^3.4.19: resolve "^1.22.8" sucrase "^3.35.0" +telegram@^2.26.22: + version "2.26.22" + resolved "https://registry.yarnpkg.com/telegram/-/telegram-2.26.22.tgz#16beb73e52403b5d5bcc4602226e39dc24217333" + integrity sha512-EIj7Yrjiu0Yosa3FZ/7EyPg9s6UiTi/zDQrFmR/2Mg7pIUU+XjAit1n1u9OU9h2oRnRM5M+67/fxzQluZpaJJg== + dependencies: + "@cryptography/aes" "^0.1.1" + async-mutex "^0.3.0" + big-integer "^1.6.48" + buffer "^6.0.3" + htmlparser2 "^6.1.0" + mime "^3.0.0" + node-localstorage "^2.2.1" + pako "^2.0.3" + path-browserify "^1.0.1" + real-cancellable-promise "^1.1.1" + socks "^2.6.2" + store2 "^2.13.0" + ts-custom-error "^3.2.0" + websocket "^1.0.34" + optionalDependencies: + bufferutil "^4.0.3" + utf-8-validate "^5.0.5" + thenify-all@^1.0.0: version "1.6.0" resolved "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz" @@ -1452,11 +1714,33 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +ts-custom-error@^3.2.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/ts-custom-error/-/ts-custom-error-3.3.1.tgz#8bd3c8fc6b8dc8e1cb329267c45200f1e17a65d1" + integrity sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A== + ts-interface-checker@^0.1.9: version "0.1.13" resolved "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz" integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== +tslib@^2.3.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" + integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== + +type@^2.7.2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/type/-/type-2.7.3.tgz#436981652129285cc3ba94f392886c2637ea0486" + integrity sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ== + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + typescript@~5.8.3: version "5.8.3" resolved "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz" @@ -1475,6 +1759,13 @@ use-sync-external-store@^1.4.0: resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz#b174bfa65cb2b526732d9f2ac0a408027876f32d" integrity sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w== +utf-8-validate@^5.0.2, utf-8-validate@^5.0.5: + version "5.0.10" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" + integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== + dependencies: + node-gyp-build "^4.3.0" + util-deprecate@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" @@ -1494,6 +1785,27 @@ vite@^7.0.4: optionalDependencies: fsevents "~2.3.3" +websocket@^1.0.34: + version "1.0.35" + resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.35.tgz#374197207d7d4cc4c36cbf8a1bb886ee52a07885" + integrity sha512-/REy6amwPZl44DDzvRCkaI1q1bIiQB0mEFQLUrhz3z2EK91cp3n72rAjUlrTP0zV22HJIUOVHQGPxhFRjxjt+Q== + dependencies: + bufferutil "^4.0.1" + debug "^2.2.0" + es5-ext "^0.10.63" + typedarray-to-buffer "^3.1.5" + utf-8-validate "^5.0.2" + yaeti "^0.0.6" + +write-file-atomic@^1.1.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" + integrity sha512-SdrHoC/yVBPpV0Xq/mUZQIpW2sWXAShb/V4pomcJXh92RuaO+f3UTWItiR3Px+pLnV2PvC2/bfn5cwr5X6Vfxw== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + slide "^1.1.5" + ws@~8.18.3: version "8.18.3" resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.3.tgz#b56b88abffde62791c639170400c93dcb0c95472" @@ -1504,6 +1816,11 @@ xmlhttprequest-ssl@~2.1.1: resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.1.2.tgz#e9e8023b3f29ef34b97a859f584c5e6c61418e23" integrity sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ== +yaeti@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" + integrity sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug== + yallist@^3.0.2: version "3.1.1" resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz"