forked from mirrors/cursor-free-vip
Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
07bee3207d | ||
|
|
06a9d47dad | ||
|
|
048a69be8f | ||
|
|
0b2081175d | ||
|
|
eb31209b6a | ||
|
|
7a239d3348 | ||
|
|
a9eed9818c | ||
|
|
0260d6be04 | ||
|
|
cff7e05e4e | ||
|
|
9fe6d1ae2c | ||
|
|
b3f905acb6 | ||
|
|
492482199a | ||
|
|
846a044704 | ||
|
|
b131281515 | ||
|
|
b797d93db5 | ||
|
|
e0a7afd835 | ||
|
|
902f6bd6f8 | ||
|
|
56cdeaa116 | ||
|
|
225a24aad5 | ||
|
|
6464306958 | ||
|
|
5d70214a2f | ||
|
|
854e987927 | ||
|
|
8f47801dad | ||
|
|
05e4d7faa9 | ||
|
|
34f5c679a5 | ||
|
|
f90a2916b1 | ||
|
|
7b757c2d57 | ||
|
|
209c58e3f8 | ||
|
|
caa47fad03 | ||
|
|
47e4a752a3 | ||
|
|
bd254cb43c | ||
|
|
b5d50ac15a | ||
|
|
dd190fac8e | ||
|
|
7971b6449e | ||
|
|
e58acce44e | ||
|
|
dc8cbca8ce | ||
|
|
2385cc2b3f | ||
|
|
52348d565d | ||
|
|
93f4f05ac4 | ||
|
|
869f1e5225 | ||
|
|
f6c958ccbb | ||
|
|
8fd4235fba |
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
version:
|
||||
description: 'Version number (e.g. 1.0.9)'
|
||||
required: true
|
||||
default: '1.7.06'
|
||||
default: '1.7.16'
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
67
CHANGELOG.md
67
CHANGELOG.md
@@ -1,5 +1,72 @@
|
||||
# Change Log
|
||||
|
||||
## v1.7.16 (Pre-Release)
|
||||
1. Add bulgarian language | 增加保加利亚语
|
||||
2. Fix: Some Issues | 修復一些問題
|
||||
3. Add: Contributors | 增加貢獻者
|
||||
4. Fix: Total Reset Cursor | 修復完全重置 Cursor
|
||||
5. Add: Display Features and Warnings | 增加顯示功能與警告
|
||||
6. Fix: Totally Reset Cursor | 修復完全重置 Cursor
|
||||
7. Remake: Logo.py Center | 重做 Logo.py 居中
|
||||
|
||||
## v1.7.15
|
||||
1. Fix: Cant Verify the User is Human | 修復無法驗證用戶是否為人類
|
||||
2. Added temporary email & GitHub + Cursor AI registration automation | 增加临时邮箱 & GitHub + Cursor AI 注册自动化
|
||||
3. Added Turkish language support | 增加土耳其语支持
|
||||
4. Removed outdated temporary option in Option 2 | 移除选项2中的过期临时添加项
|
||||
5. Enhanced machine ID reset (Linux, Windows, macOS), bypasses Cursor free trial detection | 机器 ID 重置支持 Linux/Windows/macOS,绕过 Cursor 免费试用检测
|
||||
6. Expanded Cursor AI file detection, deep removal of leftover trial files | 扩展 Cursor AI 文件检测,深度清理残留试用文件
|
||||
7. Optimized logging, replaced print with logging module, added verification steps | 日志优化,统一采用 logging 模块,增加验证步骤提示
|
||||
8. Added retry mechanism for email verification | 增加邮箱验证重试机制
|
||||
9. Automated GitHub OAuth login for Cursor AI | 自动 GitHub OAuth 登录 Cursor AI
|
||||
10. Saved registered GitHub accounts and timestamps | 保存 GitHub 账户和注册时间戳
|
||||
11. Added user confirmation before execution | 添加用户确认步骤,防止误操作
|
||||
12. Displayed feature list & warnings before actions | 显示功能与风险警告
|
||||
13. Improved Selenium flow and error handling | 增强 Selenium 流程与错误处理
|
||||
14. Added Chrome process tracking and cleanup | 增加 Chrome 进程跟踪和清理
|
||||
|
||||
## v1.7.14
|
||||
1. Added a Russian locale to program, fixed a typo in readme.md. Also translated other files |
|
||||
為程式新增了俄語語系,修正了 readme.md 的拼寫錯誤,並翻譯了其他文件。
|
||||
|
||||
2. Changing the directory from ~/.config/Cursor to ~/.config/cursor |
|
||||
將目錄從 `~/.config/Cursor` 更改為 `~/.config/cursor`。
|
||||
|
||||
3. Changing the filename from machineId to machineid |
|
||||
將檔案名稱從 `machineId` 更改為 `machineid`。
|
||||
|
||||
4. Updated all related paths in: |
|
||||
更新了以下檔案中的相關路徑:
|
||||
- `reset_machine_manual.py`
|
||||
- `config.py`
|
||||
|
||||
5. Added Linux path note in README.md |
|
||||
在 `README.md` 中新增了 Linux 路徑的說明。
|
||||
|
||||
6. These changes align with Linux filesystem conventions and fix issues with Chrome/Chromium integration |
|
||||
這些變更符合 Linux 文件系統的規範,並修復了與 Chrome/Chromium 整合的問題。
|
||||
|
||||
7. This PR adds retry logic to handle the 'Can't verify the user is human' error during registration |
|
||||
此 PR 新增了重試機制,以處理註冊時的「無法驗證用戶是否為人類」錯誤。
|
||||
|
||||
8. Added max 5 retries for form submission when human verification fails |
|
||||
當人類驗證失敗時,最多允許 5 次表單提交重試。
|
||||
|
||||
9. Added random delays between retries (2-4 seconds) |
|
||||
在重試之間隨機延遲 2-4 秒。
|
||||
|
||||
10. Enhanced browser fingerprint randomization to better bypass detection |
|
||||
增強了瀏覽器指紋的隨機性,以更好地繞過檢測。
|
||||
|
||||
11. Added new translation strings for retry status messages |
|
||||
新增了重試狀態訊息的翻譯字串。
|
||||
|
||||
12. Improved error handling and user feedback |
|
||||
改進了錯誤處理和用戶回饋機制。
|
||||
|
||||
13. The changes ensure a more robust registration process by automatically retrying when human verification fails, while maintaining human-like behavior through randomized delays and improved browser fingerprinting |
|
||||
這些變更確保了更穩定的註冊流程,透過自動重試機制處理人類驗證失敗的情況,同時透過隨機延遲與增強的瀏覽器指紋技術,維持類似人類的行為模式。
|
||||
|
||||
## v1.7.13
|
||||
1. Added _delete_current_account method to handle account deletion via API | 新增 _delete_current_account 方法,透過 API 處理帳號刪除
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ Cursor's configuration.
|
||||
這是一個自動化工具,自動註冊,支持 Windows 和 macOS 系統,完成 Auth 驗證,重置 Cursor 的配置。
|
||||
|
||||
<p align="center">
|
||||
<img src="./images/new_2025-03-19_00-19-09.png" alt="new" width="400" style="border-radius: 6px;"/><br>
|
||||
<img src="./images/new_2025-03-22_19-53-10.png" alt="new" width="400" style="border-radius: 6px;"/><br>
|
||||
</p>
|
||||
|
||||
##### If you don't have Google Chrome, you can download it from [here](https://www.google.com/intl/en_pk/chrome/)
|
||||
@@ -121,6 +121,7 @@ storage_path = /Users/username/Library/Application Support/Cursor/User/globalSto
|
||||
sqlite_path = /Users/username/Library/Application Support/Cursor/User/globalStorage/state.vscdb
|
||||
# Machine ID Path | 機器ID路徑
|
||||
machine_id_path = /Users/username/Library/Application Support/Cursor/machineId
|
||||
# For Linux users: ~/.config/cursor/machineid
|
||||
|
||||
[Timing]
|
||||
# Min Random Time | 最小隨機時間
|
||||
@@ -168,14 +169,14 @@ max_timeout = 160
|
||||
| 如果遇到權限問題,請確保: | 此腳本以管理員身份運行 |
|
||||
|:--------------------------------------------------:|:------------------------------------------------:|
|
||||
| If you encounter permission issues, please ensure: | This script is run with administrator privileges |
|
||||
|
||||
| Error 'User is not authorized' | This means your account was banned for using temporary (disposal) mail. Ensure using a non-temporary mail service |
|
||||
## 🤩 Contribution | 貢獻
|
||||
|
||||
歡迎提交 Issue 和 Pull Request!
|
||||
|
||||
|
||||
<a href="https://github.com/yeongpin/cursor-free-vip/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=yeongpin/cursor-free-vip" />
|
||||
<img src="https://contrib.rocks/image?repo=yeongpin/cursor-free-vip&preview=true&max=&columns=" />
|
||||
</a>
|
||||
<br /><br />
|
||||
|
||||
|
||||
@@ -64,9 +64,9 @@ def setup_config(translator=None):
|
||||
actual_home = f"/home/{sudo_user}" if sudo_user else os.path.expanduser("~")
|
||||
|
||||
default_config['LinuxPaths'] = {
|
||||
'storage_path': os.path.abspath(os.path.join(actual_home, ".config/Cursor/User/globalStorage/storage.json")),
|
||||
'sqlite_path': os.path.abspath(os.path.join(actual_home, ".config/Cursor/User/globalStorage/state.vscdb")),
|
||||
'machine_id_path': os.path.expanduser("~/.config/Cursor/machineId"),
|
||||
'storage_path': os.path.abspath(os.path.join(actual_home, ".config/cursor/User/globalStorage/storage.json")),
|
||||
'sqlite_path': os.path.abspath(os.path.join(actual_home, ".config/cursor/User/globalStorage/state.vscdb")),
|
||||
'machine_id_path': os.path.expanduser("~/.config/cursor/machineid"),
|
||||
'cursor_path': get_linux_cursor_path(),
|
||||
'updater_path': os.path.expanduser("~/.config/cursor-updater")
|
||||
}
|
||||
|
||||
701
github_cursor_register.py
Normal file
701
github_cursor_register.py
Normal file
@@ -0,0 +1,701 @@
|
||||
import os
|
||||
import time
|
||||
import uuid
|
||||
import json
|
||||
import random
|
||||
import string
|
||||
import requests
|
||||
from selenium import webdriver
|
||||
from selenium.webdriver.common.by import By
|
||||
from selenium.webdriver.chrome.service import Service
|
||||
from selenium.webdriver.chrome.options import Options
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions as EC
|
||||
from webdriver_manager.chrome import ChromeDriverManager
|
||||
import logging
|
||||
import platform
|
||||
from colorama import Fore, Style, init
|
||||
from selenium.common.exceptions import TimeoutException, WebDriverException, NoSuchElementException
|
||||
import shutil
|
||||
|
||||
# Initialize colorama
|
||||
init()
|
||||
|
||||
# Set up logging
|
||||
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
|
||||
|
||||
# Define emoji constants
|
||||
EMOJI = {
|
||||
'START': '🚀',
|
||||
'FORM': '📝',
|
||||
'VERIFY': '🔄',
|
||||
'PASSWORD': '🔑',
|
||||
'CODE': '📱',
|
||||
'DONE': '✨',
|
||||
'ERROR': '❌',
|
||||
'WAIT': '⏳',
|
||||
'SUCCESS': '✅',
|
||||
'MAIL': '📧',
|
||||
'KEY': '🔐',
|
||||
'UPDATE': '🔄',
|
||||
'INFO': 'ℹ️',
|
||||
'EMAIL': '📧',
|
||||
'REFRESH': '🔄',
|
||||
'LINK': '🔗',
|
||||
'WARNING': '⚠️'
|
||||
}
|
||||
|
||||
class GitHubCursorRegistration:
|
||||
def __init__(self, translator=None):
|
||||
self.translator = translator
|
||||
# Set browser to visible mode
|
||||
os.environ['BROWSER_HEADLESS'] = 'False'
|
||||
self.browser = None
|
||||
self.email_address = None
|
||||
|
||||
# Generate random credentials
|
||||
self.github_username = ''.join(random.choices(string.ascii_lowercase + string.digits, k=10))
|
||||
self.github_password = ''.join(random.choices(string.ascii_letters + string.digits + string.punctuation, k=16))
|
||||
|
||||
def setup_browser(self):
|
||||
"""Setup and configure the web browser"""
|
||||
try:
|
||||
print(f"{Fore.CYAN}{EMOJI['START']} Setting up browser...{Style.RESET_ALL}")
|
||||
|
||||
options = Options()
|
||||
options.add_argument('--incognito')
|
||||
options.add_argument('--no-sandbox')
|
||||
options.add_argument('--disable-dev-shm-usage')
|
||||
options.add_argument('--window-size=1920,1080')
|
||||
options.add_argument('--disable-notifications')
|
||||
options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36')
|
||||
|
||||
self.browser = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
|
||||
self.browser.set_page_load_timeout(30)
|
||||
return True
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} Failed to setup browser: {str(e)}{Style.RESET_ALL}")
|
||||
return False
|
||||
|
||||
def get_temp_email(self):
|
||||
"""Get a temporary email address using YOPmail"""
|
||||
try:
|
||||
if not self.browser:
|
||||
if not self.setup_browser():
|
||||
return False
|
||||
|
||||
print(f"{Fore.CYAN}{EMOJI['MAIL']} Generating temporary email address...{Style.RESET_ALL}")
|
||||
self.browser.get("https://yopmail.com/")
|
||||
time.sleep(2)
|
||||
|
||||
# Generate a realistic username
|
||||
first_names = ["john", "sara", "michael", "emma", "david", "jennifer", "robert", "lisa"]
|
||||
last_names = ["smith", "johnson", "williams", "brown", "jones", "miller", "davis", "garcia"]
|
||||
|
||||
random_first = random.choice(first_names)
|
||||
random_last = random.choice(last_names)
|
||||
random_num = random.randint(100, 999)
|
||||
|
||||
username = f"{random_first}.{random_last}{random_num}"
|
||||
|
||||
# Enter the username and check inbox
|
||||
email_field = self.browser.find_element(By.XPATH, "//input[@id='login']")
|
||||
if email_field:
|
||||
email_field.clear()
|
||||
email_field.send_keys(username)
|
||||
time.sleep(1)
|
||||
|
||||
# Click the check button
|
||||
check_button = self.browser.find_element(By.XPATH, "//button[@title='Check Inbox' or @class='sbut' or contains(@onclick, 'ver')]")
|
||||
if check_button:
|
||||
check_button.click()
|
||||
time.sleep(2)
|
||||
self.email_address = f"{username}@yopmail.com"
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Temp email created: {self.email_address}{Style.RESET_ALL}")
|
||||
return True
|
||||
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} Failed to create YOPmail address{Style.RESET_ALL}")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} Error getting temporary email: {str(e)}{Style.RESET_ALL}")
|
||||
return False
|
||||
|
||||
def register_github(self):
|
||||
"""Register a new GitHub account"""
|
||||
if not self.email_address:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} No email address available{Style.RESET_ALL}")
|
||||
return False
|
||||
|
||||
if not self.browser:
|
||||
if not self.setup_browser():
|
||||
return False
|
||||
|
||||
try:
|
||||
print(f"{Fore.CYAN}{EMOJI['FORM']} Registering GitHub account...{Style.RESET_ALL}")
|
||||
self.browser.get("https://github.com/join")
|
||||
time.sleep(3)
|
||||
|
||||
# Fill in the registration form
|
||||
WebDriverWait(self.browser, 15).until(EC.visibility_of_element_located((By.ID, "user_login")))
|
||||
self.browser.find_element(By.ID, "user_login").send_keys(self.github_username)
|
||||
self.browser.find_element(By.ID, "user_email").send_keys(self.email_address)
|
||||
self.browser.find_element(By.ID, "user_password").send_keys(self.github_password)
|
||||
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} GitHub username: {self.github_username}{Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} GitHub password: {self.github_password}{Style.RESET_ALL}")
|
||||
|
||||
# Check for any notice or popup and handle it
|
||||
try:
|
||||
signup_button = self.browser.find_element(By.ID, "signup_button")
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} Clicking sign up button...{Style.RESET_ALL}")
|
||||
signup_button.click()
|
||||
except NoSuchElementException:
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} Signup button not found, trying alternative selector{Style.RESET_ALL}")
|
||||
buttons = self.browser.find_elements(By.TAG_NAME, "button")
|
||||
for button in buttons:
|
||||
if "Sign up" in button.text:
|
||||
button.click()
|
||||
break
|
||||
|
||||
# Wait for page transition and check for CAPTCHA
|
||||
time.sleep(5)
|
||||
|
||||
# Check if registration was successful or if CAPTCHA appeared
|
||||
current_url = self.browser.current_url
|
||||
|
||||
# Look for CAPTCHA in URL or on page
|
||||
if "captcha" in current_url.lower() or "are you a robot" in self.browser.page_source.lower():
|
||||
print(f"{Fore.YELLOW}{EMOJI['WAIT']} CAPTCHA detected, please complete it manually{Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} You have 60 seconds to solve the CAPTCHA...{Style.RESET_ALL}")
|
||||
|
||||
# Wait for user to solve CAPTCHA (60 seconds max)
|
||||
for i in range(60):
|
||||
current_url = self.browser.current_url
|
||||
if "captcha" not in current_url.lower() and "are you a robot" not in self.browser.page_source.lower():
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} CAPTCHA completed successfully{Style.RESET_ALL}")
|
||||
break
|
||||
time.sleep(1)
|
||||
if i % 10 == 0 and i > 0:
|
||||
print(f"{Fore.YELLOW}{EMOJI['WAIT']} Still waiting for CAPTCHA completion... {60-i} seconds remaining{Style.RESET_ALL}")
|
||||
|
||||
# Check if CAPTCHA was solved after waiting
|
||||
if "captcha" in self.browser.current_url.lower() or "are you a robot" in self.browser.page_source.lower():
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} CAPTCHA not solved within time limit{Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} Do you want more time to solve the CAPTCHA? (yes/no){Style.RESET_ALL}")
|
||||
response = input().lower().strip()
|
||||
if response in ['yes', 'y']:
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} Press Enter when you've completed the CAPTCHA...{Style.RESET_ALL}")
|
||||
input()
|
||||
if "captcha" in self.browser.current_url.lower() or "are you a robot" in self.browser.page_source.lower():
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} CAPTCHA still not solved{Style.RESET_ALL}")
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
# Wait for registration to complete
|
||||
time.sleep(5)
|
||||
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} GitHub account registered{Style.RESET_ALL}")
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} Failed to register GitHub account: {str(e)}{Style.RESET_ALL}")
|
||||
return False
|
||||
|
||||
def check_email_verification(self):
|
||||
"""Check for GitHub verification email and click the verification link"""
|
||||
if not self.email_address or not self.browser:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} Email or browser not available{Style.RESET_ALL}")
|
||||
return False
|
||||
|
||||
try:
|
||||
print(f"{Fore.CYAN}{EMOJI['EMAIL']} Checking for verification email...{Style.RESET_ALL}")
|
||||
|
||||
# Extract username from email for YOPmail
|
||||
username = self.email_address.split('@')[0]
|
||||
|
||||
max_attempts = 10
|
||||
for attempt in range(1, max_attempts + 1):
|
||||
print(f"{Fore.CYAN}{EMOJI['REFRESH']} Checking YOPmail inbox (attempt {attempt}/{max_attempts})...{Style.RESET_ALL}")
|
||||
|
||||
# Go to YOPmail inbox
|
||||
self.browser.get(f"https://yopmail.com/en/wm")
|
||||
time.sleep(2)
|
||||
|
||||
# Enter email address
|
||||
try:
|
||||
email_input = WebDriverWait(self.browser, 10).until(
|
||||
EC.presence_of_element_located((By.ID, "login"))
|
||||
)
|
||||
email_input.clear()
|
||||
email_input.send_keys(username)
|
||||
|
||||
# Click the check inbox button
|
||||
check_button = self.browser.find_element(By.CSS_SELECTOR, "button[onclick='verif()']")
|
||||
check_button.click()
|
||||
time.sleep(3)
|
||||
|
||||
# Switch to inbox frame
|
||||
iframe = WebDriverWait(self.browser, 10).until(
|
||||
EC.presence_of_element_located((By.ID, "ifinbox"))
|
||||
)
|
||||
self.browser.switch_to.frame(iframe)
|
||||
|
||||
# Look for GitHub email
|
||||
emails = self.browser.find_elements(By.CSS_SELECTOR, "div.m")
|
||||
github_email = None
|
||||
|
||||
for email in emails:
|
||||
if "github" in email.text.lower():
|
||||
github_email = email
|
||||
break
|
||||
|
||||
if github_email:
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} GitHub verification email found{Style.RESET_ALL}")
|
||||
github_email.click()
|
||||
time.sleep(2)
|
||||
|
||||
# Switch back to default content
|
||||
self.browser.switch_to.default_content()
|
||||
|
||||
# Switch to email content frame
|
||||
iframe = WebDriverWait(self.browser, 10).until(
|
||||
EC.presence_of_element_located((By.ID, "ifmail"))
|
||||
)
|
||||
self.browser.switch_to.frame(iframe)
|
||||
|
||||
# Find verification link
|
||||
try:
|
||||
# Look for the verification button or link
|
||||
verification_elements = self.browser.find_elements(By.XPATH, "//a[contains(text(), 'Verify') or contains(text(), 'verify') or contains(@href, 'verify')]")
|
||||
|
||||
if verification_elements:
|
||||
verification_link = verification_elements[0].get_attribute('href')
|
||||
print(f"{Fore.CYAN}{EMOJI['LINK']} Found verification link{Style.RESET_ALL}")
|
||||
|
||||
# Open the verification link in the same window
|
||||
self.browser.get(verification_link)
|
||||
time.sleep(5)
|
||||
|
||||
# Check if verification was successful
|
||||
if "verified" in self.browser.page_source.lower() or "successful" in self.browser.page_source.lower():
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Email verified successfully{Style.RESET_ALL}")
|
||||
return True
|
||||
else:
|
||||
print(f"{Fore.YELLOW}{EMOJI['WARNING']} Email verification page loaded but success not confirmed{Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} Please check if verification was successful manually and press Enter to continue...{Style.RESET_ALL}")
|
||||
input()
|
||||
return True
|
||||
else:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} No verification link found in email{Style.RESET_ALL}")
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} Error extracting verification link: {str(e)}{Style.RESET_ALL}")
|
||||
else:
|
||||
print(f"{Fore.YELLOW}{EMOJI['WAIT']} No GitHub verification email yet, waiting... ({attempt}/{max_attempts}){Style.RESET_ALL}")
|
||||
time.sleep(15) # Wait before checking again
|
||||
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} Error checking email: {str(e)}{Style.RESET_ALL}")
|
||||
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} No verification email received after {max_attempts} attempts{Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} Do you want to check manually? (yes/no){Style.RESET_ALL}")
|
||||
response = input().lower().strip()
|
||||
if response in ['yes', 'y']:
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} Please check your YOPmail inbox manually at: https://yopmail.com/en/wm")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} Username: {username}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} Press Enter when you've verified the email...{Style.RESET_ALL}")
|
||||
input()
|
||||
return True
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} Failed to check verification email: {str(e)}{Style.RESET_ALL}")
|
||||
return False
|
||||
|
||||
def register_cursor(self):
|
||||
"""Register with Cursor using GitHub"""
|
||||
if not self.browser:
|
||||
if not self.setup_browser():
|
||||
return False
|
||||
|
||||
try:
|
||||
print(f"{Fore.CYAN}{EMOJI['KEY']} Registering with Cursor using GitHub...{Style.RESET_ALL}")
|
||||
|
||||
# Navigate to Cursor login page
|
||||
self.browser.get("https://cursor.sh/login")
|
||||
time.sleep(3)
|
||||
|
||||
try:
|
||||
# Look for GitHub login button
|
||||
github_buttons = WebDriverWait(self.browser, 15).until(
|
||||
EC.presence_of_all_elements_located((By.XPATH, "//button[contains(., 'GitHub') or contains(@class, 'github')]"))
|
||||
)
|
||||
|
||||
if not github_buttons:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} GitHub login button not found{Style.RESET_ALL}")
|
||||
return False
|
||||
|
||||
# Click the first GitHub button
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} Clicking GitHub login button...{Style.RESET_ALL}")
|
||||
github_buttons[0].click()
|
||||
time.sleep(5)
|
||||
|
||||
# Check if we're redirected to GitHub login
|
||||
current_url = self.browser.current_url
|
||||
if "github.com" in current_url:
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} Redirected to GitHub login{Style.RESET_ALL}")
|
||||
|
||||
# Check if we need to log in to GitHub
|
||||
if "login" in current_url:
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} Logging into GitHub...{Style.RESET_ALL}")
|
||||
|
||||
try:
|
||||
# Enter GitHub credentials
|
||||
username_field = WebDriverWait(self.browser, 10).until(
|
||||
EC.presence_of_element_located((By.ID, "login_field"))
|
||||
)
|
||||
username_field.send_keys(self.github_username)
|
||||
|
||||
password_field = self.browser.find_element(By.ID, "password")
|
||||
password_field.send_keys(self.github_password)
|
||||
|
||||
# Click sign in
|
||||
signin_button = self.browser.find_element(By.CSS_SELECTOR, "input[type='submit']")
|
||||
signin_button.click()
|
||||
time.sleep(5)
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} Error during GitHub login: {str(e)}{Style.RESET_ALL}")
|
||||
return False
|
||||
|
||||
# Check if we're on the authorization page
|
||||
if "authorize" in self.browser.current_url:
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} Authorizing Cursor app...{Style.RESET_ALL}")
|
||||
|
||||
try:
|
||||
# Look for authorization button
|
||||
auth_buttons = self.browser.find_elements(By.XPATH, "//button[contains(., 'Authorize') or contains(@class, 'btn-primary')]")
|
||||
|
||||
if auth_buttons:
|
||||
auth_buttons[0].click()
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Cursor authorized with GitHub{Style.RESET_ALL}")
|
||||
time.sleep(5)
|
||||
else:
|
||||
print(f"{Fore.YELLOW}{EMOJI['WARNING']} No authorization button found, GitHub may be already authorized{Style.RESET_ALL}")
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} Error during GitHub authorization: {str(e)}{Style.RESET_ALL}")
|
||||
|
||||
# Wait for Cursor dashboard to load
|
||||
timeout = 30
|
||||
start_time = time.time()
|
||||
while time.time() - start_time < timeout:
|
||||
if "cursor.sh" in self.browser.current_url and not "login" in self.browser.current_url:
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Successfully logged into Cursor{Style.RESET_ALL}")
|
||||
break
|
||||
time.sleep(1)
|
||||
|
||||
if "login" in self.browser.current_url:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} Failed to log into Cursor after {timeout} seconds{Style.RESET_ALL}")
|
||||
return False
|
||||
|
||||
# Wait for dashboard elements to load
|
||||
time.sleep(3)
|
||||
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Cursor registered with GitHub successfully{Style.RESET_ALL}")
|
||||
|
||||
# Now reset the machine ID
|
||||
return self.reset_machine_id()
|
||||
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} Error during Cursor registration: {str(e)}{Style.RESET_ALL}")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} Failed to register with Cursor: {str(e)}{Style.RESET_ALL}")
|
||||
return False
|
||||
|
||||
def reset_machine_id(self):
|
||||
"""Reset the Cursor machine ID to bypass limitations"""
|
||||
try:
|
||||
print(f"{Fore.CYAN}{EMOJI['UPDATE']} Resetting Cursor machine ID...{Style.RESET_ALL}")
|
||||
|
||||
# Find Cursor app data location based on platform
|
||||
cursor_data_dir = None
|
||||
if platform.system() == "Windows":
|
||||
appdata = os.getenv('APPDATA')
|
||||
if appdata:
|
||||
cursor_data_dir = os.path.join(appdata, "cursor", "Local Storage", "leveldb")
|
||||
elif platform.system() == "Darwin": # macOS
|
||||
home = os.path.expanduser("~")
|
||||
cursor_data_dir = os.path.join(home, "Library", "Application Support", "cursor", "Local Storage", "leveldb")
|
||||
elif platform.system() == "Linux":
|
||||
home = os.path.expanduser("~")
|
||||
cursor_data_dir = os.path.join(home, ".config", "cursor", "Local Storage", "leveldb")
|
||||
|
||||
if not cursor_data_dir or not os.path.exists(cursor_data_dir):
|
||||
print(f"{Fore.YELLOW}{EMOJI['WARNING']} Cursor data directory not found at: {cursor_data_dir}{Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} You may need to reset the machine ID manually{Style.RESET_ALL}")
|
||||
|
||||
# Try to find the Cursor data directory
|
||||
if platform.system() == "Linux":
|
||||
possible_paths = [
|
||||
os.path.join(os.path.expanduser("~"), ".config", "cursor"),
|
||||
os.path.join(os.path.expanduser("~"), ".cursor")
|
||||
]
|
||||
for path in possible_paths:
|
||||
if os.path.exists(path):
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Found Cursor directory at: {path}{Style.RESET_ALL}")
|
||||
# Look for Local Storage subfolder
|
||||
for root, dirs, files in os.walk(path):
|
||||
if "Local Storage" in dirs:
|
||||
cursor_data_dir = os.path.join(root, "Local Storage", "leveldb")
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Found Cursor data directory at: {cursor_data_dir}{Style.RESET_ALL}")
|
||||
break
|
||||
break
|
||||
|
||||
if cursor_data_dir and os.path.exists(cursor_data_dir):
|
||||
# Generate a new UUID
|
||||
new_machine_id = str(uuid.uuid4())
|
||||
print(f"{Fore.CYAN}{EMOJI['KEY']} New machine ID: {new_machine_id}{Style.RESET_ALL}")
|
||||
|
||||
# Ask for permission to modify files
|
||||
print(f"{Fore.YELLOW}{EMOJI['WARNING']} This operation will modify Cursor app data files{Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} Do you want to continue? (yes/no){Style.RESET_ALL}")
|
||||
response = input().lower().strip()
|
||||
if response not in ['yes', 'y']:
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} Machine ID reset aborted{Style.RESET_ALL}")
|
||||
return False
|
||||
|
||||
# Backup the directory
|
||||
backup_dir = cursor_data_dir + "_backup_" + time.strftime("%Y%m%d%H%M%S")
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} Creating backup of data directory to: {backup_dir}{Style.RESET_ALL}")
|
||||
try:
|
||||
shutil.copytree(cursor_data_dir, backup_dir)
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Backup created successfully{Style.RESET_ALL}")
|
||||
except Exception as e:
|
||||
print(f"{Fore.YELLOW}{EMOJI['WARNING']} Failed to create backup: {str(e)}{Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} Continuing without backup...{Style.RESET_ALL}")
|
||||
|
||||
# Find and modify files containing the machine ID
|
||||
modified = False
|
||||
for filename in os.listdir(cursor_data_dir):
|
||||
if filename.endswith(".log") or filename.endswith(".ldb"):
|
||||
file_path = os.path.join(cursor_data_dir, filename)
|
||||
try:
|
||||
with open(file_path, "rb") as f:
|
||||
content = f.read()
|
||||
|
||||
# Look for patterns that might contain machine ID
|
||||
if b"machineId" in content:
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} Found machineId reference in: {filename}{Style.RESET_ALL}")
|
||||
modified = True
|
||||
|
||||
# For safety, don't modify the binary files directly
|
||||
# Instead, instruct user to uninstall and reinstall Cursor
|
||||
print(f"{Fore.YELLOW}{EMOJI['WARNING']} Binary files found that may contain machine ID{Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} For best results, please:{Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} 1. Close Cursor if it's running{Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} 2. Uninstall Cursor completely{Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} 3. Reinstall Cursor{Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} 4. Login with your new GitHub account{Style.RESET_ALL}")
|
||||
break
|
||||
|
||||
except Exception as e:
|
||||
print(f"{Fore.YELLOW}{EMOJI['WARNING']} Error processing file {filename}: {str(e)}{Style.RESET_ALL}")
|
||||
|
||||
if not modified:
|
||||
print(f"{Fore.YELLOW}{EMOJI['WARNING']} No machine ID references found in data files{Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} You may need to reinstall Cursor for a complete reset{Style.RESET_ALL}")
|
||||
|
||||
# Save credentials before returning
|
||||
self.save_credentials()
|
||||
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Machine ID reset process completed{Style.RESET_ALL}")
|
||||
return True
|
||||
else:
|
||||
print(f"{Fore.YELLOW}{EMOJI['WARNING']} Cursor data directory not found{Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} You may need to manually reset the machine ID by reinstalling Cursor{Style.RESET_ALL}")
|
||||
|
||||
# Still save credentials
|
||||
self.save_credentials()
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} Failed to reset machine ID: {str(e)}{Style.RESET_ALL}")
|
||||
# Still save credentials even if machine ID reset fails
|
||||
self.save_credentials()
|
||||
return False
|
||||
|
||||
def save_credentials(self):
|
||||
"""Save the generated credentials to a file"""
|
||||
try:
|
||||
if not self.email_address or not self.github_username or not self.github_password:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} No credentials to save{Style.RESET_ALL}")
|
||||
return False
|
||||
|
||||
output_file = "github_cursor_accounts.txt"
|
||||
timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
|
||||
|
||||
credentials = {
|
||||
"timestamp": timestamp,
|
||||
"github_username": self.github_username,
|
||||
"github_password": self.github_password,
|
||||
"email": self.email_address
|
||||
}
|
||||
|
||||
credentials_json = json.dumps(credentials)
|
||||
|
||||
# Check if file exists and create if not
|
||||
file_exists = os.path.exists(output_file)
|
||||
|
||||
with open(output_file, "a") as f:
|
||||
if not file_exists:
|
||||
f.write("# GitHub + Cursor AI Accounts\n")
|
||||
f.write("# Format: JSON with timestamp, github_username, github_password, email\n\n")
|
||||
|
||||
f.write(credentials_json + "\n")
|
||||
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} Credentials saved to: {output_file}{Style.RESET_ALL}")
|
||||
|
||||
# Print a summary
|
||||
print(f"\n{Fore.GREEN}{EMOJI['SUCCESS']} Registration Summary:{Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN} • GitHub Username: {self.github_username}{Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN} • GitHub Password: {self.github_password}{Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN} • Email Address: {self.email_address}{Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN} • Saved to: {output_file}{Style.RESET_ALL}\n")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} Failed to save credentials: {str(e)}{Style.RESET_ALL}")
|
||||
print(f"\n{Fore.YELLOW}{EMOJI['WARNING']} Make sure to copy these credentials manually:{Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN} • GitHub Username: {self.github_username}{Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN} • GitHub Password: {self.github_password}{Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN} • Email Address: {self.email_address}{Style.RESET_ALL}\n")
|
||||
return False
|
||||
|
||||
def cleanup(self):
|
||||
"""Clean up resources"""
|
||||
if self.browser:
|
||||
try:
|
||||
self.browser.quit()
|
||||
except:
|
||||
pass
|
||||
|
||||
def start_registration(self):
|
||||
"""Start the GitHub Cursor registration process"""
|
||||
try:
|
||||
# Step 1: Get temporary email
|
||||
if not self.get_temp_email():
|
||||
return False
|
||||
|
||||
# Step 2: Register GitHub account
|
||||
if not self.register_github():
|
||||
return False
|
||||
|
||||
# Step 3: Check and verify email
|
||||
if not self.check_email_verification():
|
||||
return False
|
||||
|
||||
# Step 4: Register Cursor with GitHub
|
||||
if not self.register_cursor():
|
||||
return False
|
||||
|
||||
# Step 5: Reset machine ID
|
||||
self.reset_machine_id()
|
||||
|
||||
return True
|
||||
finally:
|
||||
self.cleanup()
|
||||
|
||||
def display_features_and_warnings(translator=None):
|
||||
"""Display features and warnings before proceeding"""
|
||||
if translator:
|
||||
print(f"\n🚀 {translator.get('github_register.title')}")
|
||||
print("=====================================")
|
||||
print(f"{translator.get('github_register.features_header')}:")
|
||||
print(f" - {translator.get('github_register.feature1')}")
|
||||
print(f" - {translator.get('github_register.feature2')}")
|
||||
print(f" - {translator.get('github_register.feature3')}")
|
||||
print(f" - {translator.get('github_register.feature4')}")
|
||||
print(f" - {translator.get('github_register.feature5')}")
|
||||
print(f" - {translator.get('github_register.feature6')}")
|
||||
print(f"\n⚠️ {translator.get('github_register.warnings_header')}:")
|
||||
print(f" - {translator.get('github_register.warning1')}")
|
||||
print(f" - {translator.get('github_register.warning2')}")
|
||||
print(f" - {translator.get('github_register.warning3')}")
|
||||
print(f" - {translator.get('github_register.warning4')}")
|
||||
print("=====================================\n")
|
||||
else:
|
||||
print("\n🚀 GitHub + Cursor AI Registration Automation")
|
||||
print("=====================================")
|
||||
print("Features:")
|
||||
print(" - Creates a temporary email using YOPmail")
|
||||
print(" - Registers a new GitHub account with random credentials")
|
||||
print(" - Verifies the GitHub email automatically")
|
||||
print(" - Logs into Cursor AI using GitHub authentication")
|
||||
print(" - Resets the machine ID to bypass trial detection")
|
||||
print(" - Saves all credentials to a file")
|
||||
print("\n⚠️ Warnings:")
|
||||
print(" - This script automates account creation, which may violate GitHub/Cursor terms of service")
|
||||
print(" - Requires internet access and administrative privileges")
|
||||
print(" - CAPTCHA or additional verification may interrupt automation")
|
||||
print(" - Use responsibly and at your own risk")
|
||||
print("=====================================\n")
|
||||
|
||||
def get_user_confirmation(translator=None):
|
||||
"""Prompt the user for confirmation to proceed"""
|
||||
while True:
|
||||
if translator:
|
||||
response = input(f"{translator.get('github_register.confirm')} (yes/no): ").lower().strip()
|
||||
else:
|
||||
response = input("Do you want to proceed with GitHub + Cursor AI registration? (yes/no): ").lower().strip()
|
||||
|
||||
if response in ['yes', 'y']:
|
||||
return True
|
||||
elif response in ['no', 'n']:
|
||||
if translator:
|
||||
print(f"❌ {translator.get('github_register.cancelled')}")
|
||||
else:
|
||||
print("❌ Operation cancelled.")
|
||||
return False
|
||||
else:
|
||||
if translator:
|
||||
print(f"{translator.get('github_register.invalid_choice')}")
|
||||
else:
|
||||
print("Please enter 'yes' or 'no'.")
|
||||
|
||||
def main(translator=None):
|
||||
"""Main function to run the GitHub Cursor registration process"""
|
||||
logging.info(f"{Fore.CYAN} {translator.get('github_register.starting_automation')}{Style.RESET_ALL}")
|
||||
|
||||
# Display features and warnings
|
||||
display_features_and_warnings(translator)
|
||||
|
||||
# Get user confirmation
|
||||
if not get_user_confirmation(translator):
|
||||
return
|
||||
|
||||
# Start registration process
|
||||
registration = GitHubCursorRegistration(translator)
|
||||
success = registration.start_registration()
|
||||
|
||||
# Display final message
|
||||
if success:
|
||||
print(f"\n{Fore.GREEN}{EMOJI['DONE']} {translator.get('github_register.completed_successfully')}{Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('github_register.github_username')}: {registration.github_username}{Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('github_register.github_password')}: {registration.github_password}{Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('github_register.email')}: {registration.email_address}{Style.RESET_ALL}")
|
||||
print(f"\n{Fore.CYAN}{EMOJI['INFO']} {translator.get('github_register.credentials_saved')}{Style.RESET_ALL}")
|
||||
else:
|
||||
print(f"\n{Fore.RED}{EMOJI['ERROR']} {translator.get('github_register.registration_encountered_issues')}{Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('github_register.check_browser_windows_for_manual_intervention_or_try_again_later')}{Style.RESET_ALL}")
|
||||
|
||||
# Wait for user acknowledgment
|
||||
if translator:
|
||||
input(f"\n{EMOJI['INFO']} {translator.get('register.press_enter')}...")
|
||||
else:
|
||||
input(f"\n{EMOJI['INFO']} Press Enter to continue...")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
BIN
images/new_2025-03-22_19-53-10.png
Normal file
BIN
images/new_2025-03-22_19-53-10.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 112 KiB |
390
locales/bg.json
Normal file
390
locales/bg.json
Normal file
@@ -0,0 +1,390 @@
|
||||
{
|
||||
"menu": {
|
||||
"title": "Възможни избори",
|
||||
"exit": "Затвори програмата",
|
||||
"reset": "Нулирай ид-то на компютъра",
|
||||
"register": "Регистрирай нов Курсор акаунт",
|
||||
"register_google": "Регистрирай се с Google акаунт",
|
||||
"register_github": "Регистрирай се с GitHub акаунт",
|
||||
"register_manual": "Регистрирай се със свой имейл по избор",
|
||||
"quit": "Затвори приложението Курсор",
|
||||
"select_language": "Избери език",
|
||||
"input_choice": "Моля, въведете своя избор ({choices})",
|
||||
"invalid_choice": "Невалиден избор. Моля, въведете избор от {choices}.",
|
||||
"program_terminated": "Програмата беше затворена от вас",
|
||||
"error_occurred": "Възникна грешка: {error}. Опитайте отново",
|
||||
"press_enter": "Натиснете Enter, за да излезете",
|
||||
"disable_auto_update": "Спрете автоматичните ъпдейти на Курсор",
|
||||
"lifetime_access_enabled": "ДОЖИВОТЕН ДОСТЪП Е АКТИВИРАН",
|
||||
"totally_reset": "Нулирайте изцяло Курсор",
|
||||
"outdate": "Изтекъл срок",
|
||||
"temp_github_register": "Временно регистриране с GitHub",
|
||||
"coming_soon": "Очаквайте скоро"
|
||||
},
|
||||
"languages": {
|
||||
"en": "English",
|
||||
"zh_cn": "简体中文",
|
||||
"zh_tw": "繁體中文",
|
||||
"vi": "Vietnamese",
|
||||
"nl": "Dutch",
|
||||
"de": "German",
|
||||
"fr": "French",
|
||||
"pt": "Portuguese",
|
||||
"ru": "Russian",
|
||||
"tr": "Turkish",
|
||||
"bg": "Bulgarian"
|
||||
},
|
||||
"quit_cursor": {
|
||||
"start": "Започни излизането от Курсор",
|
||||
"no_process": "Няма съществуващ процес, засягащ Курсор",
|
||||
"terminating": "Прекратяване на процес {pid}",
|
||||
"waiting": "Изчакване на процеса да приключи",
|
||||
"success": "Всички процеси, свързани с Курсор, бяха прекратени",
|
||||
"timeout": "Таймаут на процеса: {pids}",
|
||||
"error": "Възникна грешка: {error}"
|
||||
},
|
||||
"reset": {
|
||||
"title": "",
|
||||
"checking": "Проверка на конфигурационния файл",
|
||||
"not_found": "Конфигурационният файл не беше намерен",
|
||||
"no_permission": "Конфигурационният файл не може да бъде прочетен или записан. Моля, проверете разрешенията на файла",
|
||||
"reading": "Четене на текущата конфигурация",
|
||||
"creating_backup": "Създаване на резервно копие на конфигурацията",
|
||||
"backup_exists": "Резервното копие вече съществува. Стъпката за резервно копие се пропуска",
|
||||
"generating": "Генериране на ново машинно ID",
|
||||
"saving_json": "Запазване на новата конфигурация в JSON",
|
||||
"success": "Машинното ID беше успешно нулирано",
|
||||
"new_id": "Ново машинно ID",
|
||||
"permission_error": "Грешка в разрешенията: {error}",
|
||||
"run_as_admin": "Моля, опитайте да стартирате тази програма като администратор",
|
||||
"process_error": "Грешка при нулиране: {error}",
|
||||
"updating_sqlite": "Актуализиране на SQLite базата данни",
|
||||
"updating_pair": "Актуализиране на двойката ключ-стойност",
|
||||
"sqlite_success": "SQLite базата данни беше успешно актуализирана",
|
||||
"sqlite_error": "Грешка при актуализиране на SQLite базата данни: {error}",
|
||||
"press_enter": "Натиснете Enter, за да излезете",
|
||||
"unsupported_os": "Неподдържана операционна система: {os}",
|
||||
"linux_path_not_found": "Linux пътят не беше намерен",
|
||||
"updating_system_ids": "Актуализиране на системните ID",
|
||||
"system_ids_updated": "Системните ID бяха успешно актуализирани",
|
||||
"system_ids_update_failed": "Грешка при актуализиране на системните ID: {error}",
|
||||
"windows_guid_updated": "Windows GUID беше успешно актуализиран",
|
||||
"windows_permission_denied": "Достъпът до Windows беше отказан",
|
||||
"windows_guid_update_failed": "Грешка при актуализиране на Windows GUID",
|
||||
"macos_uuid_updated": "macOS UUID беше успешно актуализиран",
|
||||
"plutil_command_failed": "Командата plutil не беше успешна",
|
||||
"start_patching": "Започване на прилагане на корекция за getMachineId",
|
||||
"macos_uuid_update_failed": "Грешка при актуализиране на macOS UUID",
|
||||
"current_version": "Текуща версия на Курсор: {version}",
|
||||
"patch_completed": "Корекцията на getMachineId беше успешно завършена",
|
||||
"patch_failed": "Грешка при прилагане на корекция за getMachineId: {error}",
|
||||
"version_check_passed": "Проверката на версията на Курсор беше успешна",
|
||||
"file_modified": "Файлът беше променен",
|
||||
"version_less_than_0_45": "Версията на Курсор е < 0.45.0, корекцията на getMachineId се пропуска",
|
||||
"detecting_version": "Откриване на версията на Курсор",
|
||||
"patching_getmachineid": "Прилагане на корекция за getMachineId",
|
||||
"version_greater_than_0_45": "Версията на Курсор е >= 0.45.0, прилага се корекция за getMachineId",
|
||||
"permission_denied": "Достъпът беше отказан: {error}",
|
||||
"backup_created": "Резервното копие беше създадено",
|
||||
"update_success": "Актуализацията беше успешна",
|
||||
"update_failed": "Грешка при актуализация: {error}",
|
||||
"windows_machine_guid_updated": "Windows машинното GUID беше успешно актуализирано",
|
||||
"reading_package_json": "Четене на package.json {path}",
|
||||
"invalid_json_object": "Невалиден JSON обект",
|
||||
"no_version_field": "Няма поле за версия в package.json",
|
||||
"version_field_empty": "Полето за версия е празно",
|
||||
"invalid_version_format": "Невалиден формат на версията: {version}",
|
||||
"found_version": "Намерена версия: {version}",
|
||||
"version_parse_error": "Грешка при анализ на версията: {error}",
|
||||
"package_not_found": "Package.json не беше намерен: {path}",
|
||||
"check_version_failed": "Грешка при проверка на версията: {error}",
|
||||
"stack_trace": "Проследяване на стека",
|
||||
"version_too_low": "Версията на Курсор е твърде ниска: {version} < 0.45.0"
|
||||
},
|
||||
"register": {
|
||||
"title": "Инструмент за регистрация в Курсор",
|
||||
"start": "Започване на процеса на регистрация...",
|
||||
"handling_turnstile": "Обработка на проверка за сигурност...",
|
||||
"retry_verification": "Опит за повторна проверка...",
|
||||
"detect_turnstile": "Проверка на защитната врата...",
|
||||
"verification_success": "Проверката за сигурност беше успешна",
|
||||
"starting_browser": "Стартиране на браузъра...",
|
||||
"form_success": "Формата беше успешно изпратена",
|
||||
"browser_started": "Браузърът беше успешно стартиран",
|
||||
"waiting_for_second_verification": "Изчакване на втората проверка по имейл...",
|
||||
"waiting_for_verification_code": "Изчакване на код за потвърждение...",
|
||||
"password_success": "Паролата беше успешно зададена",
|
||||
"password_error": "Грешка при задаване на парола: {error}. Моля, опитайте отново",
|
||||
"waiting_for_page_load": "Зареждане на страницата...",
|
||||
"first_verification_passed": "Първата проверка беше успешна",
|
||||
"mailbox": "Успешен достъп до пощенската кутия",
|
||||
"register_start": "Начало на регистрацията",
|
||||
"form_submitted": "Формата беше изпратена, започване на проверка...",
|
||||
"filling_form": "Попълване на формуляра",
|
||||
"visiting_url": "Посещение на URL",
|
||||
"basic_info": "Основните данни бяха изпратени",
|
||||
"handle_turnstile": "Обработка на защитната врата",
|
||||
"no_turnstile": "Няма защитна врата",
|
||||
"turnstile_passed": "Защитната врата беше премината",
|
||||
"verification_start": "Започване на получаване на код за потвърждение",
|
||||
"verification_timeout": "Времето за получаване на код за потвърждение изтече",
|
||||
"verification_not_found": "Кодът за потвърждение не беше намерен",
|
||||
"try_get_code": "Опит | {attempt} Получаване на код за потвърждение | Оставащо време: {time}s",
|
||||
"get_account": "Получаване на информация за акаунта",
|
||||
"get_token": "Получаване на токен за сесия на Курсор",
|
||||
"token_success": "Токенът беше успешно получен",
|
||||
"token_attempt": "Опит | {attempt} опита за получаване на токен | Ще бъде опит отново след {time}s",
|
||||
"token_max_attempts": "Достигнат максимален брой опити ({max}) | Неуспешно получаване на токен",
|
||||
"token_failed": "Грешка при получаване на токен: {error}",
|
||||
"account_error": "Грешка при получаване на информация за акаунта: {error}",
|
||||
"press_enter": "Натиснете Enter, за да излезете",
|
||||
"browser_start": "Стартиране на браузъра",
|
||||
"open_mailbox": "Отваряне на страницата на пощенската кутия",
|
||||
"email_error": "Грешка при получаване на имейл адрес",
|
||||
"setup_error": "Грешка при настройка на имейл: {error}",
|
||||
"start_getting_verification_code": "Започване на получаване на код за потвърждение, ще бъде опит след 60 секунди",
|
||||
"get_verification_code_timeout": "Времето за получаване на код за потвърждение изтече",
|
||||
"get_verification_code_success": "Кодът за потвърждение беше успешно получен",
|
||||
"try_get_verification_code": "Опит | {attempt} Получаване на код за потвърждение | Оставащо време: {remaining_time}s",
|
||||
"verification_code_filled": "Кодът за потвърждение беше попълнен",
|
||||
"login_success_and_jump_to_settings_page": "Успешен вход и преход към страницата с настройки",
|
||||
"detect_login_page": "Открита е страница за вход, започване на влизане...",
|
||||
"cursor_registration_completed": "Регистрацията в Курсор беше завършена!",
|
||||
"set_password": "Задаване на парола",
|
||||
"basic_info_submitted": "Основните данни бяха изпратени",
|
||||
"cursor_auth_info_updated": "Информацията за удостоверяване на Курсор беше актуализирана",
|
||||
"cursor_auth_info_update_failed": "Грешка при актуализиране на информацията за удостоверяване на Курсор",
|
||||
"reset_machine_id": "Нулиране на машинното ID",
|
||||
"account_info_saved": "Информацията за акаунта беше запазена",
|
||||
"save_account_info_failed": "Грешка при запазване на информацията за акаунта",
|
||||
"get_email_address": "Получаване на имейл адрес",
|
||||
"update_cursor_auth_info": "Актуализиране на информацията за удостоверяване на Курсор",
|
||||
"register_process_error": "Грешка в процеса на регистрация: {error}",
|
||||
"setting_password": "Задаване на парола",
|
||||
"manual_code_input": "Ръчно въвеждане на код",
|
||||
"manual_email_input": "Ръчно въвеждане на имейл",
|
||||
"password": "Парола",
|
||||
"first_name": "Име",
|
||||
"last_name": "Фамилия",
|
||||
"exit_signal": "Сигнал за изход",
|
||||
"email_address": "Имейл адрес",
|
||||
"config_created": "Конфигурацията беше създадена",
|
||||
"verification_failed": "Проверката беше неуспешна",
|
||||
"verification_error": "Грешка при проверка: {error}",
|
||||
"config_option_added": "Добавена е опция за конфигурация: {option}",
|
||||
"config_updated": "Конфигурацията беше актуализирана",
|
||||
"password_submitted": "Паролата беше изпратена",
|
||||
"total_usage": "Общо използване: {usage}",
|
||||
"setting_on_password": "Задаване на парола",
|
||||
"getting_code": "Получаване на код за потвърждение, ще бъде опит след 60 секунди",
|
||||
"human_verify_error": "Не може да се потвърди, че потребителят е човек. Опитва се отново...",
|
||||
"max_retries_reached": "Достигнат максимален брой опити. Регистрацията беше неуспешна."
|
||||
},
|
||||
"auth": {
|
||||
"title": "Управление на удостоверяването на Курсор",
|
||||
"checking_auth": "Проверка на файла за удостоверяване",
|
||||
"auth_not_found": "Файлът за удостоверяване не беше намерен",
|
||||
"auth_file_error": "Грешка във файла за удостоверяване: {error}",
|
||||
"reading_auth": "Четене на файла за удостоверяване",
|
||||
"updating_auth": "Актуализиране на информацията за удостоверяване",
|
||||
"auth_updated": "Информацията за удостоверяване беше успешно актуализирана",
|
||||
"auth_update_failed": "Грешка при актуализиране на информацията за удостоверяване: {error}",
|
||||
"auth_file_created": "Файлът за удостоверяване беше създаден",
|
||||
"auth_file_create_failed": "Грешка при създаване на файла за удостоверяване: {error}",
|
||||
"press_enter": "Натиснете Enter, за да излезете",
|
||||
"reset_machine_id": "Нулиране на машинното ID",
|
||||
"database_connection_closed": "Връзката с базата беше затворена",
|
||||
"database_updated_successfully": "Базата данни беше успешно актуализирана",
|
||||
"connected_to_database": "Успешно свързване с базата данни",
|
||||
"updating_pair": "Актуализиране на двойката ключ-стойност",
|
||||
"db_not_found": "Файлът на базата данни не беше намерен: {path}",
|
||||
"db_permission_error": "Няма достъп до файла на базата данни. Моля, проверете разрешенията",
|
||||
"db_connection_error": "Грешка при свързване с базата данни: {error}"
|
||||
},
|
||||
"control": {
|
||||
"generate_email": "Създаване на нов имейл",
|
||||
"blocked_domain": "Блокиран домейн",
|
||||
"select_domain": "Избиране на случаен домейн",
|
||||
"copy_email": "Копиране на имейл адрес",
|
||||
"enter_mailbox": "Влизане в пощенската кутия",
|
||||
"refresh_mailbox": "Опресняване на пощенската кутия",
|
||||
"check_verification": "Проверка на кода за потвърждение",
|
||||
"verification_found": "Кодът за потвърждение беше намерен",
|
||||
"verification_not_found": "Кодът за потвърждение не беше намерен",
|
||||
"browser_error": "Грешка при контрол на браузъра: {error}",
|
||||
"navigation_error": "Грешка при навигация: {error}",
|
||||
"email_copy_error": "Грешка при копиране на имейл: {error}",
|
||||
"mailbox_error": "Грешка в пощенската кутия: {error}",
|
||||
"token_saved_to_file": "Токенът беше запазен във файла cursor_tokens.txt",
|
||||
"navigate_to": "Навигиране към {url}",
|
||||
"generate_email_success": "Имейлът беше успешно създаден",
|
||||
"select_email_domain": "Избор на домейн за имейл",
|
||||
"select_email_domain_success": "Успешен избор на домейн за имейл",
|
||||
"get_email_name": "Получаване на име на имейл",
|
||||
"get_email_name_success": "Успешно получаване на име на имейл",
|
||||
"get_email_address": "Получаване на имейл адрес",
|
||||
"get_email_address_success": "Успешно получаване на имейл адрес",
|
||||
"enter_mailbox_success": "Успешно влизане в пощенската кутия",
|
||||
"found_verification_code": "Кодът за потвърждение беше намерен",
|
||||
"get_cursor_session_token": "Получаване на токен за сесия на Курсор",
|
||||
"get_cursor_session_token_success": "Успешно получаване на токен за сесия на Курсор",
|
||||
"get_cursor_session_token_failed": "Грешка при получаване на токен за сесия на Курсор",
|
||||
"save_token_failed": "Грешка при запазване на токен",
|
||||
"database_updated_successfully": "Базата данни беше успешно актуализирана",
|
||||
"database_connection_closed": "Връзката с базата данни беше затворена",
|
||||
"no_valid_verification_code": "Няма валиден код за потвърждение"
|
||||
},
|
||||
"email": {
|
||||
"starting_browser": "Стартиране на браузъра",
|
||||
"visiting_site": "Посещение на сайтове за имейл домейни",
|
||||
"create_success": "Имейлът беше успешно създаден",
|
||||
"create_failed": "Грешка при създаване на имейл",
|
||||
"create_error": "Грешка при създаване на имейл: {error}",
|
||||
"refreshing": "Опресняване на имейл",
|
||||
"refresh_success": "Имейлът беше успешно опреснен",
|
||||
"refresh_error": "Грешка при опресняване на имейл: {error}",
|
||||
"refresh_button_not_found": "Бутонът за опресняване не беше намерен",
|
||||
"verification_found": "Потвърждението беше намерено",
|
||||
"verification_not_found": "Потвърждението не беше намерено",
|
||||
"verification_error": "Грешка при потвърждение: {error}",
|
||||
"verification_code_found": "Кодът за потвърждение беше намерен",
|
||||
"verification_code_not_found": "Кодът за потвърждение не беше намерен",
|
||||
"verification_code_error": "Грешка при код за потвърждение: {error}",
|
||||
"address": "Имейл адрес",
|
||||
"all_domains_blocked": "Всички домейни са блокирани, смяна на услуга",
|
||||
"no_available_domains_after_filtering": "Няма налични домейни след филтриране",
|
||||
"switching_service": "Смяна на услугата {service}",
|
||||
"domains_list_error": "Грешка при получаване на списък с домейни: {error}",
|
||||
"failed_to_get_available_domains": "Неуспешно получаване на налични домейни",
|
||||
"domains_excluded": "Изключени домейни: {domains}",
|
||||
"failed_to_create_account": "Неуспешно създаване на акаунт",
|
||||
"account_creation_error": "Грешка при създаване на акаунт: {error}",
|
||||
"blocked_domains": "Блокирани домейни: {domains}",
|
||||
"blocked_domains_loaded": "Блокирани домейни са заредени: {count}",
|
||||
"blocked_domains_loaded_error": "Грешка при зареждане на блокирани домейни: {error}",
|
||||
"blocked_domains_loaded_success": "Блокираните домейни бяха успешно заредени",
|
||||
"blocked_domains_loaded_timeout": "Време за зареждане на блокирани домейни: {timeout}s",
|
||||
"blocked_domains_loaded_timeout_error": "Грешка при време за зареждане на блокирани домейни: {error}",
|
||||
"available_domains_loaded": "Налични домейни са заредени: {count}",
|
||||
"domains_filtered": "Филтрирани домейни: {count}",
|
||||
"trying_to_create_email": "Опит за създаване на имейл: {email}",
|
||||
"domain_blocked": "Домейнът е блокиран: {domain}"
|
||||
},
|
||||
"update": {
|
||||
"title": "Деактивиране на автоматичните актуализации на Курсор",
|
||||
"disable_success": "Автоматичните актуализации бяха успешно деактивирани",
|
||||
"disable_failed": "Грешка при деактивиране на автоматичните актуализации: {error}",
|
||||
"press_enter": "Натиснете Enter, за да излезете",
|
||||
"start_disable": "Започване на деактивиране на автоматичните актуализации",
|
||||
"killing_processes": "Прекратяване на процеси",
|
||||
"processes_killed": "Процесите бяха прекратени",
|
||||
"removing_directory": "Премахване на директория",
|
||||
"directory_removed": "Директорията беше премахната",
|
||||
"creating_block_file": "Създаване на блокиращ файл",
|
||||
"block_file_created": "Блокиращият файл беше създаден"
|
||||
},
|
||||
"updater": {
|
||||
"checking": "Проверка за актуализации...",
|
||||
"new_version_available": "Налична е нова версия! (Текуща: {current}, Последна: {latest})",
|
||||
"updating": "Актуализиране до последната версия. Програмата ще се рестартира автоматично.",
|
||||
"up_to_date": "Използвате последната версия.",
|
||||
"check_failed": "Грешка при проверка за актуализации: {error}",
|
||||
"continue_anyway": "Продължаване с текущата версия...",
|
||||
"update_confirm": "Искате ли да актуализирате до последната версия? (Y/n)",
|
||||
"update_skipped": "Актуализацията беше пропусната.",
|
||||
"invalid_choice": "Невалиден избор. Моля, въведете 'Y' или 'n'.",
|
||||
"development_version": "Версия за разработка {current} > {latest}",
|
||||
"changelog_title": "Списък с промени"
|
||||
},
|
||||
"totally_reset": {
|
||||
"title": "Пълно нулиране на Курсор",
|
||||
"checking_config": "Проверка на конфигурационния файл",
|
||||
"config_not_found": "Конфигурационният файл не беше намерен",
|
||||
"no_permission": "Конфигурационният файл не може да бъде прочетен или записан. Моля, проверете разрешенията на файла",
|
||||
"reading_config": "Четене на текущата конфигурация",
|
||||
"creating_backup": "Създаване на резервно копие на конфигурацията",
|
||||
"backup_exists": "Резервното копие вече съществува. Стъпката за резервно копие се пропуска",
|
||||
"generating_new_machine_id": "Генериране на ново машинно ID",
|
||||
"saving_new_config": "Запазване на новата конфигурация в JSON",
|
||||
"success": "Курсор беше успешно нулиран",
|
||||
"error": "Грешка при нулиране на Курсор: {error}",
|
||||
"press_enter": "Натиснете Enter, за да излезете",
|
||||
"reset_machine_id": "Нулиране на машинното ID",
|
||||
"database_connection_closed": "Връзката с базата данни беше затворена",
|
||||
"database_updated_successfully": "Базата данни беше успешно актуализирана",
|
||||
"connected_to_database": "Успешно свързване с базата данни",
|
||||
"updating_pair": "Актуализиране на двойката ключ-стойност",
|
||||
"db_not_found": "Файлът на базата данни не беше намерен: {path}",
|
||||
"db_permission_error": "Няма достъп до файла на базата данни. Моля, проверете разрешенията",
|
||||
"db_connection_error": "Грешка при свързване с базата данни: {error}",
|
||||
"feature_title": "ФУНКЦИИ",
|
||||
"feature_1": "Пълно премахване на настройките и конфигурациите на Курсор AI",
|
||||
"feature_2": "Изчистване на всички кеширани данни, включително историята и командите на AI",
|
||||
"feature_3": "Нулиране на машинното ID за заобикаляне на ограниченията за пробен период",
|
||||
"feature_4": "Генериране на нови случайни машинни идентификатори",
|
||||
"feature_5": "Премахване на персонализирани разширения и предпочитания",
|
||||
"feature_6": "Нулиране на информацията за пробния период и активиране",
|
||||
"feature_7": "Дълбоко сканиране за скрити файлове, свързани с лицензи и пробен период",
|
||||
"feature_8": "Безопасно запазване на файлове и приложения, които не са свързани с Курсор",
|
||||
"feature_9": "Съвместимост с Windows, macOS и Linux",
|
||||
"disclaimer_title": "ПРАВНО ИЗВЕСТВИЕ",
|
||||
"disclaimer_1": "Този инструмент ще изтрие за постоянно всички настройки на Курсор AI,",
|
||||
"disclaimer_2": "конфигурации и кеширани данни. Това действие е необратимо.",
|
||||
"disclaimer_3": "Вашите кодови файлове НЯМА да бъдат засегнати и този инструмент",
|
||||
"disclaimer_4": "е проектиран специално да се фокусира върху файловете на редактора на Курсор AI и механизмите за откриване на пробен период.",
|
||||
"disclaimer_5": "Другите приложения на вашата система няма да бъдат засегнати.",
|
||||
"disclaimer_6": "След като използвате този инструмент, ще трябва да преинсталирате Курсор AI.",
|
||||
"disclaimer_7": "Вие носите отговорността за използването му",
|
||||
"confirm_title": "Сигурни ли сте, че искате да продължите?",
|
||||
"confirm_1": "Това действие ще изтрие всички настройки на Курсор AI,",
|
||||
"confirm_2": "конфигурации и кеширани данни. Това действие е необратимо.",
|
||||
"confirm_3": "Вашите кодови файлове НЯМА да бъдат засегнати и този инструмент",
|
||||
"confirm_4": "е проектиран специално да се фокусира върху файловете на редактора на Курсор AI и механизмите за откриване на пробен период.",
|
||||
"confirm_5": "Другите приложения на вашата система няма да бъдат засегнати.",
|
||||
"confirm_6": "След като използвате този инструмент, ще трябва да преинсталирате Курсор AI.",
|
||||
"confirm_7": "Вие носите отговорността за използването му",
|
||||
"invalid_choice": "Моля, въведете 'Y' или 'n'",
|
||||
"skipped_for_safety": "Пропуснато за безопасност (не е свързано с Курсор): {path}",
|
||||
"deleted": "Изтрито: {path}",
|
||||
"error_deleting": "Грешка при изтриване на {path}: {error}",
|
||||
"not_found": "Файлът не беше намерен: {path}",
|
||||
"resetting_machine_id": "Нулиране на машинните идентификатори за заобикаляне на ограниченията за пробен период...",
|
||||
"created_machine_id": "Създадено е ново машинно ID: {path}",
|
||||
"error_creating_machine_id": "Грешка при създаване на файл за машинно ID {path}: {error}",
|
||||
"error_searching": "Грешка при търсене на файлове в {path}: {error}",
|
||||
"created_extended_trial_info": "Създадена е нова информация за удължен пробен период: {path}",
|
||||
"error_creating_trial_info": "Грешка при създаване на файл за информация за пробен период {path}: {error}",
|
||||
"resetting_cursor_ai_editor": "Нулиране на редактора на Курсор AI... Моля, изчакайте.",
|
||||
"reset_cancelled": "Нулирането беше отменено. Излизане без промени.",
|
||||
"windows_machine_id_modification_skipped": "Промяната на машинното ID на Windows беше пропусната: {error}",
|
||||
"linux_machine_id_modification_skipped": "Промяната на machine-id на Linux беше пропусната: {error}",
|
||||
"note_complete_machine_id_reset_may_require_running_as_administrator": "Забележка: Пълното нулиране на машинното ID може да изисква работа като администратор",
|
||||
"note_complete_system_machine_id_reset_may_require_sudo_privileges": "Забележка: Пълното нулиране на системното machine-id може да изисква sudo права",
|
||||
"windows_registry_instructions": "📝 ЗАБЕЛЕЖКА: За пълно нулиране на Windows може да се наложи да изчистите и записите в регистъра.",
|
||||
"windows_registry_instructions_2": " Стартирайте 'regedit' и потърсете и изтрийте ключове, съдържащи 'Cursor' или 'CursorAI' в HKEY_CURRENT_USER\\Software\\.\n",
|
||||
"reset_log_1": "Курсор AI беше напълно нулиран и ограниченията за пробен период бяха заобиколени!",
|
||||
"reset_log_2": "Моля, рестартирайте системата си, за да влязат в сила промените.",
|
||||
"reset_log_3": "Ще трябва да преинсталирате Курсор AI и сега трябва да имате нов пробен период.",
|
||||
"reset_log_4": "За най-добри резултати, помислете за следното:",
|
||||
"reset_log_5": "Използвайте различен имейл адрес при регистрация за нов пробен период",
|
||||
"reset_log_6": "Ако е възможно, използвайте VPN за промяна на IP адреса си",
|
||||
"reset_log_7": "Изчистете бисквитките и кеша на браузъра си, преди да посетите уебсайта на Курсор AI",
|
||||
"reset_log_8": "Ако проблемите продължават, опитайте да инсталирате Курсор AI на друго място",
|
||||
"reset_log_9": "Ако срещнете проблеми, посетете Github Issue Tracker и създайте проблем на https://github.com/yeongpin/cursor-free-vip/issues",
|
||||
"unexpected_error": "Възникна неочаквана грешка: {error}",
|
||||
"report_issue": "Моля, докладвайте този проблем в Github Issue Tracker на https://github.com/yeongpin/cursor-free-vip/issues",
|
||||
"keyboard_interrupt": "Процесът беше прекратен от потребителя. Излизане...",
|
||||
"return_to_main_menu": "Връщане към главното меню...",
|
||||
"process_interrupted": "Процесът беше прекратен. Излизане...",
|
||||
"press_enter_to_return_to_main_menu": "Натиснете Enter, за да се върнете към главното меню...",
|
||||
"removing_known": "Премахване на известни файлове за пробен период/лиценз",
|
||||
"performing_deep_scan": "Извършване на дълбоко сканиране за допълнителни файлове за пробен период/лиценз",
|
||||
"found_additional_potential_license_trial_files": "Намерени са {count} допълнителни потенциални файлове за лиценз/пробен период",
|
||||
"checking_for_electron_localstorage_files": "Проверка на Electron localStorage файлове",
|
||||
"no_additional_license_trial_files_found_in_deep_scan": "Няма намерени допълнителни файлове за лиценз/пробен период при дълбоко сканиране",
|
||||
"removing_electron_localstorage_files": "Премахване на Electron localStorage файлове",
|
||||
"electron_localstorage_files_removed": "Electron localStorage файлове бяха премахнати",
|
||||
"electron_localstorage_files_removal_error": "Грешка при премахване на Electron localStorage файлове: {error}",
|
||||
"removing_electron_localstorage_files_completed": "Премахването на Electron localStorage файлове беше завършено"
|
||||
}
|
||||
}
|
||||
@@ -16,17 +16,23 @@
|
||||
"press_enter": "Drücken Sie Enter zum Beenden",
|
||||
"disable_auto_update": "Cursor Auto-Update Deaktivieren",
|
||||
"lifetime_access_enabled": "LEBENSLANGER ZUGRIFF AKTIVIERT",
|
||||
"totally_reset": "Cursor Vollständig Zurücksetzen"
|
||||
"totally_reset": "Cursor Vollständig Zurücksetzen",
|
||||
"outdate": "Veraltet",
|
||||
"temp_github_register": "Temporäre GitHub-Registrierung",
|
||||
"admin_required": "Ausführen als ausführbare Datei, Administratorrechte erforderlich.",
|
||||
"admin_required_continue": "Mit der aktuellen Version fortfahren...",
|
||||
"coming_soon": "Bald verfügbar"
|
||||
},
|
||||
"languages": {
|
||||
"en": "English",
|
||||
"zh_cn": "简体中文",
|
||||
"zh_tw": "繁體中文",
|
||||
"vi": "Tiếng Việt",
|
||||
"nl": "Nederlands",
|
||||
"en": "Englisch",
|
||||
"zh_cn": "Vereinfachtes Chinesisch",
|
||||
"zh_tw": "Traditionelles Chinesisch",
|
||||
"vi": "Vietnamesisch",
|
||||
"nl": "Niederländisch",
|
||||
"de": "Deutsch",
|
||||
"fr": "Français",
|
||||
"pt": "Brazilian Portuguese"
|
||||
"fr": "Französisch",
|
||||
"pt": "Portugiesisch",
|
||||
"ru": "Russisch"
|
||||
},
|
||||
"quit_cursor": {
|
||||
"start": "Beginne Cursor zu Beenden",
|
||||
|
||||
@@ -16,7 +16,12 @@
|
||||
"press_enter": "Press Enter to Exit",
|
||||
"disable_auto_update": "Disable Cursor Auto-Update",
|
||||
"lifetime_access_enabled": "LIFETIME ACCESS ENABLED",
|
||||
"totally_reset": "Totally Reset Cursor"
|
||||
"totally_reset": "Totally Reset Cursor",
|
||||
"outdate": "Outdated",
|
||||
"temp_github_register": "Temporary GitHub Register",
|
||||
"admin_required": "Running as executable, administrator privileges required.",
|
||||
"admin_required_continue": "Continuing without administrator privileges.",
|
||||
"coming_soon": "Coming Soon"
|
||||
},
|
||||
"languages": {
|
||||
"en": "English",
|
||||
@@ -25,7 +30,11 @@
|
||||
"vi": "Vietnamese",
|
||||
"nl": "Dutch",
|
||||
"de": "German",
|
||||
"fr": "French"
|
||||
"fr": "French",
|
||||
"pt": "Portuguese",
|
||||
"ru": "Russian",
|
||||
"tr": "Turkish",
|
||||
"bg": "Bulgarian"
|
||||
},
|
||||
"quit_cursor": {
|
||||
"start": "Start Quitting Cursor",
|
||||
@@ -170,7 +179,9 @@
|
||||
"password_submitted": "Password Submitted",
|
||||
"total_usage": "Total Usage: {usage}",
|
||||
"setting_on_password": "Setting Password",
|
||||
"getting_code": "Getting Verification Code, Will Try in 60s"
|
||||
"getting_code": "Getting Verification Code, Will Try in 60s",
|
||||
"human_verify_error": "Can't verify the user is human. Retrying...",
|
||||
"max_retries_reached": "Maximum retry attempts reached. Registration failed."
|
||||
},
|
||||
"auth": {
|
||||
"title": "Cursor Auth Manager",
|
||||
@@ -377,6 +388,54 @@
|
||||
"removing_electron_localstorage_files": "Removing Electron localStorage files",
|
||||
"electron_localstorage_files_removed": "Electron localStorage files removed",
|
||||
"electron_localstorage_files_removal_error": "Error removing Electron localStorage files: {error}",
|
||||
"removing_electron_localstorage_files_completed": "Electron localStorage files removal completed"
|
||||
}
|
||||
}
|
||||
"removing_electron_localstorage_files_completed": "Electron localStorage files removal completed",
|
||||
"warning_title": "WARNING",
|
||||
"warning_1": "This action will delete all Cursor AI settings,",
|
||||
"warning_2": "configurations, and cached data. This action cannot be undone.",
|
||||
"warning_3": "Your code files will NOT be affected, and the tool is designed",
|
||||
"warning_4": "to only target Cursor AI editor files and trial detection mechanisms.",
|
||||
"warning_5": "Other applications on your system will not be affected.",
|
||||
"warning_6": "You will need to set up Cursor AI again after running this tool.",
|
||||
"warning_7": "Use at your own risk",
|
||||
"removed": "Removed: {path}",
|
||||
"failed_to_reset_machine_guid": "Failed to reset machine GUID",
|
||||
"failed_to_remove": "Failed to remove: {path}",
|
||||
"failed_to_delete_file": "Failed to delete file: {path}",
|
||||
"failed_to_delete_directory": "Failed to delete directory: {path}",
|
||||
"failed_to_delete_file_or_directory": "Failed to delete file or directory: {path}",
|
||||
"deep_scanning": "Performing deep scan for additional trial/license files",
|
||||
"resetting_cursor": "Resetting Cursor AI Editor... Please wait.",
|
||||
"completed_in": "Completed in {time} seconds",
|
||||
"cursor_reset_completed": "Cursor AI Editor has been fully reset and trial detection bypassed!",
|
||||
"cursor_reset_failed": "Cursor AI Editor reset failed: {error}",
|
||||
"cursor_reset_cancelled": "Cursor AI Editor reset cancelled. Exiting without making any changes.",
|
||||
"operation_cancelled": "Operation cancelled. Exiting without making any changes."
|
||||
},
|
||||
"github_register": {
|
||||
"title": "GitHub + Cursor AI Registration Automation",
|
||||
"features_header": "Features",
|
||||
"feature1": "Generates a temporary email using 1secmail.",
|
||||
"feature2": "Registers a new GitHub account with random credentials.",
|
||||
"feature3": "Verifies the GitHub email automatically.",
|
||||
"feature4": "Logs into Cursor AI using GitHub authentication.",
|
||||
"feature5": "Resets the machine ID to bypass trial detection.",
|
||||
"feature6": "Saves all credentials to a file.",
|
||||
"warnings_header": "Warnings",
|
||||
"warning1": "This script automates account creation, which may violate GitHub/Cursor terms of service.",
|
||||
"warning2": "Requires internet access and administrative privileges.",
|
||||
"warning3": "CAPTCHA or additional verification may interrupt automation.",
|
||||
"warning4": "Use responsibly and at your own risk.",
|
||||
"confirm": "Are you sure you want to proceed?",
|
||||
"invalid_choice": "Invalid choice. Please enter 'yes' or 'no'",
|
||||
"cancelled": "Operation cancelled",
|
||||
"program_terminated": "Program terminated by user",
|
||||
"starting_automation": "Starting automation...",
|
||||
"github_username": "GitHub Username",
|
||||
"github_password": "GitHub Password",
|
||||
"email_address": "Email Address",
|
||||
"credentials_saved": "These credentials have been saved to github_cursor_accounts.txt",
|
||||
"completed_successfully": "GitHub + Cursor registration completed successfully!",
|
||||
"registration_encountered_issues": "GitHub + Cursor registration encountered issues.",
|
||||
"check_browser_windows_for_manual_intervention_or_try_again_later": "Check browser windows for manual intervention or try again later."
|
||||
}
|
||||
}
|
||||
@@ -16,17 +16,21 @@
|
||||
"press_enter": "Appuyez sur Entrée pour quitter",
|
||||
"disable_auto_update": "Désactiver la Mise à Jour Automatique de Cursor",
|
||||
"lifetime_access_enabled": "ACCÈS À VIE ACTIVÉ",
|
||||
"totally_reset": "Réinitialisation Complète de Cursor"
|
||||
"totally_reset": "Réinitialisation Complète de Cursor",
|
||||
"outdate": "Obsolete",
|
||||
"temp_github_register": "Inscription GitHub temporaire",
|
||||
"coming_soon": "Bientôt"
|
||||
},
|
||||
"languages": {
|
||||
"en": "English",
|
||||
"zh_cn": "简体中文",
|
||||
"zh_tw": "繁體中文",
|
||||
"vi": "Tiếng Việt",
|
||||
"nl": "Nederlands",
|
||||
"de": "Deutsch",
|
||||
"en": "Anglais",
|
||||
"zh_cn": "Chinois simplifié",
|
||||
"zh_tw": "Chinois traditionnel",
|
||||
"vi": "Vietnamien",
|
||||
"nl": "Néerlandais",
|
||||
"de": "Allemand",
|
||||
"fr": "Français",
|
||||
"pt": "Brazilian Portuguese"
|
||||
"pt": "Portugais",
|
||||
"ru": "Russe"
|
||||
},
|
||||
"quit_cursor": {
|
||||
"start": "Début de la Fermeture de Cursor",
|
||||
|
||||
@@ -16,17 +16,21 @@
|
||||
"press_enter": "Druk op Enter om door te gaan.",
|
||||
"disable_auto_update": "Cursor automatische updates uitschakelen",
|
||||
"lifetime_access_enabled": "Levenslange toegang ingeschakeld",
|
||||
"totally_reset": "Cursor volledig resetten"
|
||||
"totally_reset": "Cursor volledig resetten",
|
||||
"outdate": "Verouderd",
|
||||
"temp_github_register": "Tijdelijke GitHub-registratie",
|
||||
"coming_soon": "Binnenkort"
|
||||
},
|
||||
"languages": {
|
||||
"en": "English",
|
||||
"zh_cn": "简体中文",
|
||||
"zh_tw": "繁體中文",
|
||||
"vi": "Tiếng Việt",
|
||||
"en": "Engels",
|
||||
"zh_cn": "Vereenvoudigd Chinees",
|
||||
"zh_tw": "Traditioneel Chinees",
|
||||
"vi": "Vietnamees",
|
||||
"nl": "Nederlands",
|
||||
"de": "Deutsch",
|
||||
"fr": "Français",
|
||||
"pt": "Brazilian Portuguese"
|
||||
"de": "Duits",
|
||||
"fr": "Frans",
|
||||
"pt": "Portugees",
|
||||
"ru": "Russisch"
|
||||
},
|
||||
"quit_cursor": {
|
||||
"start": "Start met afsluiten van Cursor",
|
||||
@@ -277,7 +281,7 @@
|
||||
"update_skipped": "Update overgeslagen.",
|
||||
"invalid_choice": "Ongeldige keuze. Voer 'Y' of 'n' in.",
|
||||
"development_version": "Ontwikkelversie {current} > {latest}",
|
||||
"changelog_title": "Changelog"
|
||||
"changelog_title": "Wijzigingslogboek"
|
||||
},
|
||||
"totally_reset": {
|
||||
"title": "Cursor volledig herstellen",
|
||||
|
||||
@@ -16,7 +16,10 @@
|
||||
"press_enter": "Pressione Enter para Sair",
|
||||
"disable_auto_update": "Desativar Atualização Automática do Cursor",
|
||||
"lifetime_access_enabled": "ACESSO VITALÍCIO HABILITADO",
|
||||
"totally_reset": "Redefinir Cursor Completamente"
|
||||
"totally_reset": "Redefinir Cursor Completamente",
|
||||
"outdate": "Obsoleto",
|
||||
"temp_github_register": "Registro temporário do GitHub",
|
||||
"coming_soon": "Em breve"
|
||||
},
|
||||
"languages": {
|
||||
"en": "Inglês",
|
||||
@@ -26,7 +29,8 @@
|
||||
"nl": "Holandês",
|
||||
"de": "Alemão",
|
||||
"fr": "Francês",
|
||||
"pt": "Português do Brasil"
|
||||
"pt": "Português do Brasil",
|
||||
"ru": "Russo"
|
||||
},
|
||||
"quit_cursor": {
|
||||
"start": "Iniciando fechamento do Cursor",
|
||||
@@ -286,7 +290,7 @@
|
||||
"update_skipped": "Atualização ignorada.",
|
||||
"invalid_choice": "Escolha inválida. Por favor, digite 'Y' ou 'n'.",
|
||||
"development_version": "Versão de desenvolvimento {current} > {latest}",
|
||||
"changelog_title": "Registro de mudanças"
|
||||
"changelog_title": "Registro de alterações"
|
||||
},
|
||||
"totally_reset": {
|
||||
"title": "Redefinir Cursor Completamente",
|
||||
|
||||
386
locales/ru.json
Normal file
386
locales/ru.json
Normal file
@@ -0,0 +1,386 @@
|
||||
{
|
||||
"menu": {
|
||||
"title": "Доступные опции",
|
||||
"exit": "Выйти из программы",
|
||||
"reset": "Сбросить ID машины",
|
||||
"register": "Зарегистрировать новый аккаунт Cursor",
|
||||
"register_google": "Зарегистрироваться через Google",
|
||||
"register_github": "Зарегистрироваться через GitHub",
|
||||
"register_manual": "Зарегистрировать Cursor используя свою почту",
|
||||
"quit": "Закрыть приложение Cursor",
|
||||
"select_language": "Выбрать язык",
|
||||
"input_choice": "Пожалуйста, введите ваш выбор ({choices})",
|
||||
"invalid_choice": "Неверный выбор. Пожалуйста, введите число из {choices}",
|
||||
"program_terminated": "Программа была завершена пользователем",
|
||||
"error_occurred": "Произошла ошибка: {error}. Пожалуйста, попробуйте снова",
|
||||
"press_enter": "Нажмите Enter для выхода",
|
||||
"disable_auto_update": "Отключить автоматическое обновление Cursor",
|
||||
"lifetime_access_enabled": "ВКЛЮЧЕН ПОЖИЗНЕННЫЙ ДОСТУП",
|
||||
"totally_reset": "Полностью сбросить Cursor",
|
||||
"outdate": "Устаревший",
|
||||
"temp_github_register": "Временная регистрация GitHub",
|
||||
"coming_soon": "Скоро"
|
||||
},
|
||||
"languages": {
|
||||
"en": "Английский",
|
||||
"zh_cn": "Упрощенный китайский",
|
||||
"zh_tw": "Традиционный китайский",
|
||||
"vi": "Вьетнамский",
|
||||
"nl": "Нидерландский",
|
||||
"de": "Немецкий",
|
||||
"fr": "Французский",
|
||||
"pt": "Бразильский португальский",
|
||||
"ru": "Русский"
|
||||
},
|
||||
"quit_cursor": {
|
||||
"start": "Начало закрытия Cursor",
|
||||
"no_process": "Нет запущенных процессов Cursor",
|
||||
"terminating": "Завершение процесса {pid}",
|
||||
"waiting": "Ожидание завершения процесса",
|
||||
"success": "Все процессы Cursor закрыты",
|
||||
"timeout": "Таймаут процесса: {pids}",
|
||||
"error": "Произошла ошибка: {error}"
|
||||
},
|
||||
"reset": {
|
||||
"title": "Инструмент сброса ID машины Cursor",
|
||||
"checking": "Проверка конфигурационного файла",
|
||||
"not_found": "Конфигурационный файл не найден",
|
||||
"no_permission": "Невозможно прочитать или записать конфигурационный файл, проверьте права доступа",
|
||||
"reading": "Чтение текущей конфигурации",
|
||||
"creating_backup": "Создание резервной копии конфигурации",
|
||||
"backup_exists": "Резервный файл уже существует, пропускаем шаг резервного копирования",
|
||||
"generating": "Генерация нового ID машины",
|
||||
"saving_json": "Сохранение новой конфигурации в JSON",
|
||||
"success": "ID машины успешно сброшен",
|
||||
"new_id": "Новый ID машины",
|
||||
"permission_error": "Ошибка прав доступа: {error}",
|
||||
"run_as_admin": "Пожалуйста, запустите программу от имени администратора",
|
||||
"process_error": "Ошибка процесса сброса: {error}",
|
||||
"updating_sqlite": "Обновление базы данных SQLite",
|
||||
"updating_pair": "Обновление пары ключ-значение",
|
||||
"sqlite_success": "База данных SQLite успешно обновлена",
|
||||
"sqlite_error": "Ошибка обновления базы данных SQLite: {error}",
|
||||
"press_enter": "Нажмите Enter для выхода",
|
||||
"unsupported_os": "Неподдерживаемая ОС: {os}",
|
||||
"linux_path_not_found": "Путь Linux не найден",
|
||||
"updating_system_ids": "Обновление системных ID",
|
||||
"system_ids_updated": "Системные ID успешно обновлены",
|
||||
"system_ids_update_failed": "Ошибка обновления системных ID: {error}",
|
||||
"windows_guid_updated": "Windows GUID успешно обновлен",
|
||||
"windows_permission_denied": "Отказано в доступе Windows",
|
||||
"windows_guid_update_failed": "Ошибка обновления Windows GUID",
|
||||
"macos_uuid_updated": "macOS UUID успешно обновлен",
|
||||
"plutil_command_failed": "Ошибка команды plutil",
|
||||
"start_patching": "Начало патчинга getMachineId",
|
||||
"macos_uuid_update_failed": "Ошибка обновления macOS UUID",
|
||||
"current_version": "Текущая версия Cursor: {version}",
|
||||
"patch_completed": "Патчинг getMachineId завершен",
|
||||
"patch_failed": "Ошибка патчинга getMachineId: {error}",
|
||||
"version_check_passed": "Проверка версии Cursor пройдена",
|
||||
"file_modified": "Файл изменен",
|
||||
"version_less_than_0_45": "Версия Cursor < 0.45.0, пропускаем патчинг getMachineId",
|
||||
"detecting_version": "Определение версии Cursor",
|
||||
"patching_getmachineid": "Патчинг getMachineId",
|
||||
"version_greater_than_0_45": "Версия Cursor >= 0.45.0, патчинг getMachineId",
|
||||
"permission_denied": "Отказано в доступе: {error}",
|
||||
"backup_created": "Резервная копия создана",
|
||||
"update_success": "Обновление успешно",
|
||||
"update_failed": "Ошибка обновления: {error}",
|
||||
"windows_machine_guid_updated": "Windows Machine GUID успешно обновлен",
|
||||
"reading_package_json": "Чтение package.json {path}",
|
||||
"invalid_json_object": "Неверный JSON объект",
|
||||
"no_version_field": "Поле версии не найдено в package.json",
|
||||
"version_field_empty": "Поле версии пусто",
|
||||
"invalid_version_format": "Неверный формат версии: {version}",
|
||||
"found_version": "Найдена версия: {version}",
|
||||
"version_parse_error": "Ошибка разбора версии: {error}",
|
||||
"package_not_found": "Package.json не найден: {path}",
|
||||
"check_version_failed": "Ошибка проверки версии: {error}",
|
||||
"stack_trace": "Трассировка стека",
|
||||
"version_too_low": "Версия Cursor слишком низкая: {version} < 0.45.0"
|
||||
},
|
||||
"register": {
|
||||
"title": "Инструмент регистрации Cursor",
|
||||
"start": "Запуск процесса регистрации...",
|
||||
"handling_turnstile": "Обработка проверки безопасности...",
|
||||
"retry_verification": "Повторная попытка проверки...",
|
||||
"detect_turnstile": "Проверка безопасности...",
|
||||
"verification_success": "Проверка безопасности успешна",
|
||||
"starting_browser": "Открытие браузера...",
|
||||
"form_success": "Форма успешно отправлена",
|
||||
"browser_started": "Браузер успешно открыт",
|
||||
"waiting_for_second_verification": "Ожидание проверки email...",
|
||||
"waiting_for_verification_code": "Ожидание кода подтверждения...",
|
||||
"password_success": "Пароль успешно установлен",
|
||||
"password_error": "Не удалось установить пароль: {error}. Пожалуйста, попробуйте снова",
|
||||
"waiting_for_page_load": "Загрузка страницы...",
|
||||
"first_verification_passed": "Первичная проверка успешна",
|
||||
"mailbox": "Успешный доступ к почтовому ящику",
|
||||
"register_start": "Начать регистрацию",
|
||||
"form_submitted": "Форма отправлена, начало проверки...",
|
||||
"filling_form": "Заполнение формы",
|
||||
"visiting_url": "Переход по URL",
|
||||
"basic_info": "Основная информация отправлена",
|
||||
"handle_turnstile": "Обработка Turnstile",
|
||||
"no_turnstile": "Turnstile не обнаружен",
|
||||
"turnstile_passed": "Turnstile пройден",
|
||||
"verification_start": "Начало получения кода подтверждения",
|
||||
"verification_timeout": "Таймаут получения кода подтверждения",
|
||||
"verification_not_found": "Код подтверждения не найден",
|
||||
"try_get_code": "Попытка | {attempt} Получение кода подтверждения | Осталось времени: {time}с",
|
||||
"get_account": "Получение информации об аккаунте",
|
||||
"get_token": "Получение токена сессии Cursor",
|
||||
"token_success": "Токен успешно получен",
|
||||
"token_attempt": "Попытка | {attempt} раз получить токен | Повторная попытка через {time}с",
|
||||
"token_max_attempts": "Достигнуто максимальное количество попыток ({max}) | Не удалось получить токен",
|
||||
"token_failed": "Ошибка получения токена: {error}",
|
||||
"account_error": "Ошибка получения информации об аккаунте: {error}",
|
||||
"press_enter": "Нажмите Enter для выхода",
|
||||
"browser_start": "Запуск браузера",
|
||||
"open_mailbox": "Открытие страницы почтового ящика",
|
||||
"email_error": "Не удалось получить email адрес",
|
||||
"setup_error": "Ошибка настройки email: {error}",
|
||||
"start_getting_verification_code": "Начало получения кода подтверждения, попытка через 60с",
|
||||
"get_verification_code_timeout": "Таймаут получения кода подтверждения",
|
||||
"get_verification_code_success": "Код подтверждения успешно получен",
|
||||
"try_get_verification_code": "Попытка | {attempt} Получение кода подтверждения | Осталось времени: {remaining_time}с",
|
||||
"verification_code_filled": "Код подтверждения введен",
|
||||
"login_success_and_jump_to_settings_page": "Успешный вход и переход на страницу настроек",
|
||||
"detect_login_page": "Обнаружена страница входа, начало входа...",
|
||||
"cursor_registration_completed": "Регистрация Cursor завершена!",
|
||||
"set_password": "Установка пароля",
|
||||
"basic_info_submitted": "Основная информация отправлена",
|
||||
"cursor_auth_info_updated": "Информация авторизации Cursor обновлена",
|
||||
"cursor_auth_info_update_failed": "Ошибка обновления информации авторизации Cursor",
|
||||
"reset_machine_id": "Сброс ID машины",
|
||||
"account_info_saved": "Информация об аккаунте сохранена",
|
||||
"save_account_info_failed": "Ошибка сохранения информации об аккаунте",
|
||||
"get_email_address": "Получение email адреса",
|
||||
"update_cursor_auth_info": "Обновление информации авторизации Cursor",
|
||||
"register_process_error": "Ошибка процесса регистрации: {error}",
|
||||
"setting_password": "Установка пароля",
|
||||
"manual_code_input": "Ручной ввод кода",
|
||||
"manual_email_input": "Ручной ввод email",
|
||||
"password": "Пароль",
|
||||
"first_name": "Имя",
|
||||
"last_name": "Фамилия",
|
||||
"exit_signal": "Сигнал выхода",
|
||||
"email_address": "Email адрес",
|
||||
"config_created": "Конфигурация создана",
|
||||
"verification_failed": "Проверка не пройдена",
|
||||
"verification_error": "Ошибка проверки: {error}",
|
||||
"config_option_added": "Опция конфигурации добавлена: {option}",
|
||||
"config_updated": "Конфигурация обновлена",
|
||||
"password_submitted": "Пароль отправлен",
|
||||
"total_usage": "Общее использование: {usage}",
|
||||
"setting_on_password": "Установка пароля",
|
||||
"getting_code": "Получение кода подтверждения, попытка через 60с"
|
||||
},
|
||||
"auth": {
|
||||
"title": "Менеджер авторизации Cursor",
|
||||
"checking_auth": "Проверка файла авторизации",
|
||||
"auth_not_found": "Файл авторизации не найден",
|
||||
"auth_file_error": "Ошибка файла авторизации: {error}",
|
||||
"reading_auth": "Чтение файла авторизации",
|
||||
"updating_auth": "Обновление информации авторизации",
|
||||
"auth_updated": "Информация авторизации успешно обновлена",
|
||||
"auth_update_failed": "Ошибка обновления информации авторизации: {error}",
|
||||
"auth_file_created": "Файл авторизации создан",
|
||||
"auth_file_create_failed": "Ошибка создания файла авторизации: {error}",
|
||||
"press_enter": "Нажмите Enter для выхода",
|
||||
"reset_machine_id": "Сброс ID машины",
|
||||
"database_connection_closed": "Соединение с базой данных закрыто",
|
||||
"database_updated_successfully": "База данных успешно обновлена",
|
||||
"connected_to_database": "Подключено к базе данных",
|
||||
"updating_pair": "Обновление пары ключ-значение",
|
||||
"db_not_found": "Файл базы данных не найден по пути: {path}",
|
||||
"db_permission_error": "Невозможно получить доступ к файлу базы данных. Проверьте права доступа",
|
||||
"db_connection_error": "Ошибка подключения к базе данных: {error}"
|
||||
},
|
||||
"control": {
|
||||
"generate_email": "Генерация нового email",
|
||||
"blocked_domain": "Заблокированный домен",
|
||||
"select_domain": "Выбор случайного домена",
|
||||
"copy_email": "Копирование email адреса",
|
||||
"enter_mailbox": "Вход в почтовый ящик",
|
||||
"refresh_mailbox": "Обновление почтового ящика",
|
||||
"check_verification": "Проверка кода подтверждения",
|
||||
"verification_found": "Код подтверждения найден",
|
||||
"verification_not_found": "Код подтверждения не найден",
|
||||
"browser_error": "Ошибка управления браузером: {error}",
|
||||
"navigation_error": "Ошибка навигации: {error}",
|
||||
"email_copy_error": "Ошибка копирования email: {error}",
|
||||
"mailbox_error": "Ошибка почтового ящика: {error}",
|
||||
"token_saved_to_file": "Токен сохранен в cursor_tokens.txt",
|
||||
"navigate_to": "Переход на {url}",
|
||||
"generate_email_success": "Email успешно сгенерирован",
|
||||
"select_email_domain": "Выбор домена email",
|
||||
"select_email_domain_success": "Домен email успешно выбран",
|
||||
"get_email_name": "Получение имени email",
|
||||
"get_email_name_success": "Имя email успешно получено",
|
||||
"get_email_address": "Получение email адреса",
|
||||
"get_email_address_success": "Email адрес успешно получен",
|
||||
"enter_mailbox_success": "Успешный вход в почтовый ящик",
|
||||
"found_verification_code": "Найден код подтверждения",
|
||||
"get_cursor_session_token": "Получение токена сессии Cursor",
|
||||
"get_cursor_session_token_success": "Токен сессии Cursor успешно получен",
|
||||
"get_cursor_session_token_failed": "Ошибка получения токена сессии Cursor",
|
||||
"save_token_failed": "Ошибка сохранения токена",
|
||||
"database_updated_successfully": "База данных успешно обновлена",
|
||||
"database_connection_closed": "Соединение с базой данных закрыто",
|
||||
"no_valid_verification_code": "Нет действительного кода подтверждения"
|
||||
},
|
||||
"email": {
|
||||
"starting_browser": "Запуск браузера",
|
||||
"visiting_site": "Переход на сайты почтовых доменов",
|
||||
"create_success": "Email успешно создан",
|
||||
"create_failed": "Не удалось создать email",
|
||||
"create_error": "Ошибка создания email: {error}",
|
||||
"refreshing": "Обновление email",
|
||||
"refresh_success": "Email успешно обновлен",
|
||||
"refresh_error": "Ошибка обновления email: {error}",
|
||||
"refresh_button_not_found": "Кнопка обновления не найдена",
|
||||
"verification_found": "Проверка найдена",
|
||||
"verification_not_found": "Проверка не найдена",
|
||||
"verification_error": "Ошибка проверки: {error}",
|
||||
"verification_code_found": "Код подтверждения найден",
|
||||
"verification_code_not_found": "Код подтверждения не найден",
|
||||
"verification_code_error": "Ошибка кода подтверждения: {error}",
|
||||
"address": "Email адрес",
|
||||
"all_domains_blocked": "Все домены заблокированы, переключение сервиса",
|
||||
"no_available_domains_after_filtering": "Нет доступных доменов после фильтрации",
|
||||
"switching_service": "Переключение на сервис {service}",
|
||||
"domains_list_error": "Не удалось получить список доменов: {error}",
|
||||
"failed_to_get_available_domains": "Не удалось получить доступные домены",
|
||||
"domains_excluded": "Исключенные домены: {domains}",
|
||||
"failed_to_create_account": "Не удалось создать аккаунт",
|
||||
"account_creation_error": "Ошибка создания аккаунта: {error}",
|
||||
"blocked_domains": "Заблокированные домены: {domains}",
|
||||
"blocked_domains_loaded": "Загружены заблокированные домены: {count}",
|
||||
"blocked_domains_loaded_error": "Ошибка загрузки заблокированных доменов: {error}",
|
||||
"blocked_domains_loaded_success": "Заблокированные домены успешно загружены",
|
||||
"blocked_domains_loaded_timeout": "Таймаут загрузки заблокированных доменов: {timeout}с",
|
||||
"blocked_domains_loaded_timeout_error": "Ошибка таймаута загрузки заблокированных доменов: {error}",
|
||||
"available_domains_loaded": "Загружены доступные домены: {count}",
|
||||
"domains_filtered": "Отфильтрованы домены: {count}",
|
||||
"trying_to_create_email": "Попытка создания email: {email}",
|
||||
"domain_blocked": "Домен заблокирован: {domain}"
|
||||
},
|
||||
"update": {
|
||||
"title": "Отключение автоматического обновления Cursor",
|
||||
"disable_success": "Автоматическое обновление успешно отключено",
|
||||
"disable_failed": "Ошибка отключения автоматического обновления: {error}",
|
||||
"press_enter": "Нажмите Enter для выхода",
|
||||
"start_disable": "Начало отключения автоматического обновления",
|
||||
"killing_processes": "Завершение процессов",
|
||||
"processes_killed": "Процессы завершены",
|
||||
"removing_directory": "Удаление директории",
|
||||
"directory_removed": "Директория удалена",
|
||||
"creating_block_file": "Создание файла блокировки",
|
||||
"block_file_created": "Файл блокировки создан"
|
||||
},
|
||||
"updater": {
|
||||
"checking": "Проверка обновлений...",
|
||||
"new_version_available": "Доступна новая версия! (Текущая: {current}, Последняя: {latest})",
|
||||
"updating": "Обновление до последней версии. Программа перезапустится автоматически.",
|
||||
"up_to_date": "У вас установлена последняя версия.",
|
||||
"check_failed": "Не удалось проверить обновления: {error}",
|
||||
"continue_anyway": "Продолжение работы с текущей версией...",
|
||||
"update_confirm": "Хотите обновить до последней версии? (Y/n)",
|
||||
"update_skipped": "Обновление пропущено.",
|
||||
"invalid_choice": "Неверный выбор. Пожалуйста, введите 'Y' или 'n'.",
|
||||
"development_version": "Версия разработки {current} > {latest}",
|
||||
"changelog_title": "Список изменений"
|
||||
},
|
||||
"totally_reset": {
|
||||
"title": "Полный сброс Cursor",
|
||||
"checking_config": "Проверка конфигурационного файла",
|
||||
"config_not_found": "Конфигурационный файл не найден",
|
||||
"no_permission": "Невозможно прочитать или записать конфигурационный файл, проверьте права доступа",
|
||||
"reading_config": "Чтение текущей конфигурации",
|
||||
"creating_backup": "Создание резервной копии конфигурации",
|
||||
"backup_exists": "Резервный файл уже существует, пропускаем шаг резервного копирования",
|
||||
"generating_new_machine_id": "Генерация нового ID машины",
|
||||
"saving_new_config": "Сохранение новой конфигурации в JSON",
|
||||
"success": "Cursor успешно сброшен",
|
||||
"error": "Ошибка сброса Cursor: {error}",
|
||||
"press_enter": "Нажмите Enter для выхода",
|
||||
"reset_machine_id": "Сброс ID машины",
|
||||
"database_connection_closed": "Соединение с базой данных закрыто",
|
||||
"database_updated_successfully": "База данных успешно обновлена",
|
||||
"connected_to_database": "Подключено к базе данных",
|
||||
"updating_pair": "Обновление пары ключ-значение",
|
||||
"db_not_found": "Файл базы данных не найден по пути: {path}",
|
||||
"db_permission_error": "Невозможно получить доступ к файлу базы данных. Проверьте права доступа",
|
||||
"db_connection_error": "Ошибка подключения к базе данных: {error}",
|
||||
"feature_title": "ФУНКЦИИ",
|
||||
"feature_1": "Полное удаление настроек и конфигураций Cursor AI",
|
||||
"feature_2": "Очистка всех кэшированных данных, включая историю AI и промпты",
|
||||
"feature_3": "Сброс ID машины для обхода обнаружения пробной версии",
|
||||
"feature_4": "Создание новых случайных идентификаторов машины",
|
||||
"feature_5": "Удаление пользовательских расширений и настроек",
|
||||
"feature_6": "Сброс информации о пробной версии и данных активации",
|
||||
"feature_7": "Глубокий поиск скрытых файлов лицензии и пробной версии",
|
||||
"feature_8": "Безопасное сохранение файлов и приложений, не относящихся к Cursor",
|
||||
"feature_9": "Совместимость с Windows, macOS и Linux",
|
||||
"disclaimer_title": "ПРЕДУПРЕЖДЕНИЕ",
|
||||
"disclaimer_1": "Этот инструмент навсегда удалит все настройки Cursor AI,",
|
||||
"disclaimer_2": "конфигурации и кэшированные данные. Это действие нельзя отменить.",
|
||||
"disclaimer_3": "Ваши файлы кода НЕ будут затронуты, и инструмент разработан",
|
||||
"disclaimer_4": "только для файлов редактора Cursor AI и механизмов обнаружения пробной версии.",
|
||||
"disclaimer_5": "Другие приложения на вашей системе не будут затронуты.",
|
||||
"disclaimer_6": "После запуска этого инструмента вам нужно будет настроить Cursor AI заново.",
|
||||
"disclaimer_7": "Используйте на свой страх и риск",
|
||||
"confirm_title": "Вы уверены, что хотите продолжить?",
|
||||
"confirm_1": "Это действие удалит все настройки Cursor AI,",
|
||||
"confirm_2": "конфигурации и кэшированные данные. Это действие нельзя отменить.",
|
||||
"confirm_3": "Ваши файлы кода НЕ будут затронуты, и инструмент разработан",
|
||||
"confirm_4": "только для файлов редактора Cursor AI и механизмов обнаружения пробной версии.",
|
||||
"confirm_5": "Другие приложения на вашей системе не будут затронуты.",
|
||||
"confirm_6": "После запуска этого инструмента вам нужно будет настроить Cursor AI заново.",
|
||||
"confirm_7": "Используйте на свой страх и риск",
|
||||
"invalid_choice": "Пожалуйста, введите 'Y' или 'n'",
|
||||
"skipped_for_safety": "Пропущено для безопасности (не относится к Cursor): {path}",
|
||||
"deleted": "Удалено: {path}",
|
||||
"error_deleting": "Ошибка удаления {path}: {error}",
|
||||
"not_found": "Файл не найден: {path}",
|
||||
"resetting_machine_id": "Сброс идентификаторов машины для обхода обнаружения пробной версии...",
|
||||
"created_machine_id": "Создан новый ID машины: {path}",
|
||||
"error_creating_machine_id": "Ошибка создания файла ID машины {path}: {error}",
|
||||
"error_searching": "Ошибка поиска файлов в {path}: {error}",
|
||||
"created_extended_trial_info": "Создана новая расширенная информация о пробной версии: {path}",
|
||||
"error_creating_trial_info": "Ошибка создания файла информации о пробной версии {path}: {error}",
|
||||
"resetting_cursor_ai_editor": "Сброс редактора Cursor AI... Пожалуйста, подождите.",
|
||||
"reset_cancelled": "Сброс отменен. Выход без внесения изменений.",
|
||||
"windows_machine_id_modification_skipped": "Изменение ID машины Windows пропущено: {error}",
|
||||
"linux_machine_id_modification_skipped": "Изменение machine-id Linux пропущено: {error}",
|
||||
"note_complete_machine_id_reset_may_require_running_as_administrator": "Примечание: полный сброс ID машины может потребовать запуска от имени администратора",
|
||||
"note_complete_system_machine_id_reset_may_require_sudo_privileges": "Примечание: полный сброс системного machine-id может потребовать прав sudo",
|
||||
"windows_registry_instructions": "📝 ПРИМЕЧАНИЕ: Для полного сброса в Windows может потребоваться очистка записей реестра.",
|
||||
"windows_registry_instructions_2": " Запустите 'regedit' и найдите ключи, содержащие 'Cursor' или 'CursorAI' в HKEY_CURRENT_USER\\Software\\ и удалите их.\n",
|
||||
"reset_log_1": "Cursor AI полностью сброшен и обнаружение пробной версии обойдено!",
|
||||
"reset_log_2": "Пожалуйста, перезагрузите систему для применения изменений.",
|
||||
"reset_log_3": "Вам нужно будет переустановить Cursor AI, и теперь у вас должен быть новый пробный период.",
|
||||
"reset_log_4": "Для лучших результатов рекомендуется также:",
|
||||
"reset_log_5": "Использовать другой email адрес при регистрации нового пробного периода",
|
||||
"reset_log_6": "Если возможно, использовать VPN для изменения IP адреса",
|
||||
"reset_log_7": "Очистить куки и кэш браузера перед посещением сайта Cursor AI",
|
||||
"reset_log_8": "Если проблемы сохраняются, попробуйте установить Cursor AI в другое место",
|
||||
"reset_log_9": "Если вы столкнулись с проблемами, перейдите на Github Issue Tracker и создайте issue на https://github.com/yeongpin/cursor-free-vip/issues",
|
||||
"unexpected_error": "Произошла непредвиденная ошибка: {error}",
|
||||
"report_issue": "Пожалуйста, сообщите об этой проблеме на Github Issue Tracker на https://github.com/yeongpin/cursor-free-vip/issues",
|
||||
"keyboard_interrupt": "Процесс прерван пользователем. Выход...",
|
||||
"return_to_main_menu": "Возврат в главное меню...",
|
||||
"process_interrupted": "Процесс прерван. Выход...",
|
||||
"press_enter_to_return_to_main_menu": "Нажмите Enter для возврата в главное меню...",
|
||||
"removing_known": "Удаление известных файлов лицензии/пробной версии",
|
||||
"performing_deep_scan": "Выполнение глубокого поиска дополнительных файлов лицензии/пробной версии",
|
||||
"found_additional_potential_license_trial_files": "Найдено {count} дополнительных потенциальных файлов лицензии/пробной версии",
|
||||
"checking_for_electron_localstorage_files": "Проверка файлов localStorage Electron",
|
||||
"no_additional_license_trial_files_found_in_deep_scan": "Дополнительные файлы лицензии/пробной версии не найдены при глубоком поиске",
|
||||
"removing_electron_localstorage_files": "Удаление файлов localStorage Electron",
|
||||
"electron_localstorage_files_removed": "Файлы localStorage Electron удалены",
|
||||
"electron_localstorage_files_removal_error": "Ошибка удаления файлов localStorage Electron: {error}",
|
||||
"removing_electron_localstorage_files_completed": "Удаление файлов localStorage Electron завершено"
|
||||
}
|
||||
}
|
||||
389
locales/tr.json
Normal file
389
locales/tr.json
Normal file
@@ -0,0 +1,389 @@
|
||||
{
|
||||
"menu": {
|
||||
"title": "Mevcut Seçenekler",
|
||||
"exit": "Programdan Çık",
|
||||
"reset": "Makine Kimliğini Sıfırla",
|
||||
"register": "Yeni Cursor Hesabı Kaydet",
|
||||
"register_google": "Google Hesabı ile Kayıt Ol",
|
||||
"register_github": "GitHub Hesabı ile Kayıt Ol",
|
||||
"register_manual": "Cursor'ı Özel E-posta ile Kaydet",
|
||||
"quit": "Cursor Uygulamasını Kapat",
|
||||
"select_language": "Dili Değiştir",
|
||||
"input_choice": "Lütfen seçiminizi girin ({choices})",
|
||||
"invalid_choice": "Geçersiz seçim. Lütfen {choices} arasından bir sayı girin",
|
||||
"program_terminated": "Program kullanıcı tarafından sonlandırıldı",
|
||||
"error_occurred": "Bir hata oluştu: {error}. Lütfen tekrar deneyin",
|
||||
"press_enter": "Çıkmak için Enter'a Basın",
|
||||
"disable_auto_update": "Cursor Otomatik Güncellemeyi Devre Dışı Bırak",
|
||||
"lifetime_access_enabled": "ÖMÜR BOYU ERİŞİM ETKİNLEŞTİRİLDİ",
|
||||
"totally_reset": "Cursor'ı Tamamen Sıfırla",
|
||||
"outdate": "güncel değil",
|
||||
"temp_github_register": "Geçici GitHub Kaydı",
|
||||
"coming_soon": "Yakında"
|
||||
},
|
||||
"languages": {
|
||||
"en": "English",
|
||||
"zh_cn": "简体中文",
|
||||
"zh_tw": "繁體中文",
|
||||
"vi": "Vietnamese",
|
||||
"nl": "Dutch",
|
||||
"de": "German",
|
||||
"fr": "French",
|
||||
"pt": "Portuguese",
|
||||
"ru": "Russian",
|
||||
"tr": "Turkish"
|
||||
},
|
||||
"quit_cursor": {
|
||||
"start": "Cursor'dan Çıkış Başlatılıyor",
|
||||
"no_process": "Çalışan Cursor İşlemi Yok",
|
||||
"terminating": "İşlem Sonlandırılıyor {pid}",
|
||||
"waiting": "İşlemin Çıkması Bekleniyor",
|
||||
"success": "Tüm Cursor İşlemleri Kapatıldı",
|
||||
"timeout": "İşlem Zaman Aşımı: {pids}",
|
||||
"error": "Hata Oluştu: {error}"
|
||||
},
|
||||
"reset": {
|
||||
"title": "Cursor Makine Kimliği Sıfırlama Aracı",
|
||||
"checking": "Yapılandırma Dosyası Kontrol Ediliyor",
|
||||
"not_found": "Yapılandırma Dosyası Bulunamadı",
|
||||
"no_permission": "Yapılandırma Dosyası Okunamıyor veya Yazılamıyor, Lütfen Dosya İzinlerini Kontrol Edin",
|
||||
"reading": "Mevcut Yapılandırma Okunuyor",
|
||||
"creating_backup": "Yapılandırma Yedeği Oluşturuluyor",
|
||||
"backup_exists": "Yedek Dosya Zaten Mevcut, Yedekleme Adımı Atlanıyor",
|
||||
"generating": "Yeni Makine Kimliği Oluşturuluyor",
|
||||
"saving_json": "Yeni Yapılandırma JSON'a Kaydediliyor",
|
||||
"success": "Makine Kimliği Başarıyla Sıfırlandı",
|
||||
"new_id": "Yeni Makine Kimliği",
|
||||
"permission_error": "İzin Hatası: {error}",
|
||||
"run_as_admin": "Lütfen Bu Programı Yönetici Olarak Çalıştırmayı Deneyin",
|
||||
"process_error": "Sıfırlama İşlemi Hatası: {error}",
|
||||
"updating_sqlite": "SQLite Veritabanı Güncelleniyor",
|
||||
"updating_pair": "Anahtar-Değer Çifti Güncelleniyor",
|
||||
"sqlite_success": "SQLite Veritabanı Başarıyla Güncellendi",
|
||||
"sqlite_error": "SQLite Veritabanı Güncellemesi Başarısız: {error}",
|
||||
"press_enter": "Çıkmak için Enter'a Basın",
|
||||
"unsupported_os": "Desteklenmeyen İşletim Sistemi: {os}",
|
||||
"linux_path_not_found": "Linux Yolu Bulunamadı",
|
||||
"updating_system_ids": "Sistem Kimlikleri Güncelleniyor",
|
||||
"system_ids_updated": "Sistem Kimlikleri Başarıyla Güncellendi",
|
||||
"system_ids_update_failed": "Sistem Kimlikleri Güncellemesi Başarısız: {error}",
|
||||
"windows_guid_updated": "Windows GUID Başarıyla Güncellendi",
|
||||
"windows_permission_denied": "Windows İzni Reddedildi",
|
||||
"windows_guid_update_failed": "Windows GUID Güncellemesi Başarısız",
|
||||
"macos_uuid_updated": "macOS UUID Başarıyla Güncellendi",
|
||||
"plutil_command_failed": "plutil Komutu Başarısız",
|
||||
"start_patching": "getMachineId Yamalanması Başlatılıyor",
|
||||
"macos_uuid_update_failed": "macOS UUID Güncellemesi Başarısız",
|
||||
"current_version": "Mevcut Cursor Sürümü: {version}",
|
||||
"patch_completed": "getMachineId Yamalama Tamamlandı",
|
||||
"patch_failed": "getMachineId Yamalama Başarısız: {error}",
|
||||
"version_check_passed": "Cursor Sürüm Kontrolü Geçildi",
|
||||
"file_modified": "Dosya Değiştirildi",
|
||||
"version_less_than_0_45": "Cursor Sürümü < 0.45.0, getMachineId Yamalama Atlanıyor",
|
||||
"detecting_version": "Cursor Sürümü Tespit Ediliyor",
|
||||
"patching_getmachineid": "getMachineId Yamalanıyor",
|
||||
"version_greater_than_0_45": "Cursor Sürümü >= 0.45.0, getMachineId Yamalanıyor",
|
||||
"permission_denied": "İzin Reddedildi: {error}",
|
||||
"backup_created": "Yedek Oluşturuldu",
|
||||
"update_success": "Güncelleme Başarılı",
|
||||
"update_failed": "Güncelleme Başarısız: {error}",
|
||||
"windows_machine_guid_updated": "Windows Makine GUID'si Başarıyla Güncellendi",
|
||||
"reading_package_json": "package.json Okunuyor {path}",
|
||||
"invalid_json_object": "Geçersiz JSON Nesnesi",
|
||||
"no_version_field": "package.json İçinde Sürüm Alanı Bulunamadı",
|
||||
"version_field_empty": "Sürüm Alanı Boş",
|
||||
"invalid_version_format": "Geçersiz Sürüm Formatı: {version}",
|
||||
"found_version": "Sürüm Bulundu: {version}",
|
||||
"version_parse_error": "Sürüm Ayrıştırma Hatası: {error}",
|
||||
"package_not_found": "Package.json Bulunamadı: {path}",
|
||||
"check_version_failed": "Sürüm Kontrolü Başarısız: {error}",
|
||||
"stack_trace": "Yığın İzleme",
|
||||
"version_too_low": "Cursor Sürümü Çok Düşük: {version} < 0.45.0"
|
||||
},
|
||||
"register": {
|
||||
"title": "Cursor Kayıt Aracı",
|
||||
"start": "Kayıt işlemi başlatılıyor...",
|
||||
"handling_turnstile": "Güvenlik doğrulaması işleniyor...",
|
||||
"retry_verification": "Doğrulama tekrar deneniyor...",
|
||||
"detect_turnstile": "Güvenlik doğrulaması kontrol ediliyor...",
|
||||
"verification_success": "Güvenlik doğrulaması başarılı",
|
||||
"starting_browser": "Tarayıcı açılıyor...",
|
||||
"form_success": "Form başarıyla gönderildi",
|
||||
"browser_started": "Tarayıcı başarıyla açıldı",
|
||||
"waiting_for_second_verification": "E-posta doğrulaması bekleniyor...",
|
||||
"waiting_for_verification_code": "Doğrulama kodu bekleniyor...",
|
||||
"password_success": "Şifre başarıyla ayarlandı",
|
||||
"password_error": "Şifre ayarlanamadı: {error}. Lütfen tekrar deneyin",
|
||||
"waiting_for_page_load": "Sayfa yükleniyor...",
|
||||
"first_verification_passed": "İlk doğrulama başarılı",
|
||||
"mailbox": "E-posta gelen kutusuna başarıyla erişildi",
|
||||
"register_start": "Kayıt Başlat",
|
||||
"form_submitted": "Form Gönderildi, Doğrulama Başlatılıyor...",
|
||||
"filling_form": "Form Dolduruluyor",
|
||||
"visiting_url": "URL Ziyaret Ediliyor",
|
||||
"basic_info": "Temel Bilgiler Gönderildi",
|
||||
"handle_turnstile": "Turnstile İşleniyor",
|
||||
"no_turnstile": "Turnstile Algılanmadı",
|
||||
"turnstile_passed": "Turnstile Geçildi",
|
||||
"verification_start": "Doğrulama Kodu Alma Başlatılıyor",
|
||||
"verification_timeout": "Doğrulama Kodu Alma Zaman Aşımı",
|
||||
"verification_not_found": "Doğrulama Kodu Bulunamadı",
|
||||
"try_get_code": "Deneme | {attempt} Doğrulama Kodu Al | Kalan Süre: {time}s",
|
||||
"get_account": "Hesap Bilgileri Alınıyor",
|
||||
"get_token": "Cursor Oturum Jetonu Alınıyor",
|
||||
"token_success": "Jeton Başarıyla Alındı",
|
||||
"token_attempt": "Deneme | {attempt} kez Jeton alma denemesi | {time}s içinde tekrar denenecek",
|
||||
"token_max_attempts": "Maksimum Deneme Sayısına Ulaşıldı ({max}) | Jeton alınamadı",
|
||||
"token_failed": "Jeton Alma Başarısız: {error}",
|
||||
"account_error": "Hesap Bilgisi Alma Başarısız: {error}",
|
||||
"press_enter": "Çıkmak için Enter'a Basın",
|
||||
"browser_start": "Tarayıcı Başlatılıyor",
|
||||
"open_mailbox": "Posta Kutusu Sayfası Açılıyor",
|
||||
"email_error": "E-posta Adresi Alınamadı",
|
||||
"setup_error": "E-posta Kurulum Hatası: {error}",
|
||||
"start_getting_verification_code": "Doğrulama Kodu Alma Başlatılıyor, 60 saniye içinde denenecek",
|
||||
"get_verification_code_timeout": "Doğrulama Kodu Alma Zaman Aşımı",
|
||||
"get_verification_code_success": "Doğrulama Kodu Alma Başarılı",
|
||||
"try_get_verification_code": "Deneme | {attempt} Doğrulama Kodu Al | Kalan Süre: {remaining_time}s",
|
||||
"verification_code_filled": "Doğrulama Kodu Dolduruldu",
|
||||
"login_success_and_jump_to_settings_page": "Giriş Başarılı ve Ayarlar Sayfasına Yönlendiriliyor",
|
||||
"detect_login_page": "Giriş Sayfası Algılandı, Giriş Başlatılıyor...",
|
||||
"cursor_registration_completed": "Cursor Kaydı Tamamlandı!",
|
||||
"set_password": "Şifre Belirle",
|
||||
"basic_info_submitted": "Temel Bilgiler Gönderildi",
|
||||
"cursor_auth_info_updated": "Cursor Kimlik Bilgileri Güncellendi",
|
||||
"cursor_auth_info_update_failed": "Cursor Kimlik Bilgileri Güncellemesi Başarısız",
|
||||
"reset_machine_id": "Makine Kimliğini Sıfırla",
|
||||
"account_info_saved": "Hesap Bilgileri Kaydedildi",
|
||||
"save_account_info_failed": "Hesap Bilgilerini Kaydetme Başarısız",
|
||||
"get_email_address": "E-posta Adresi Al",
|
||||
"update_cursor_auth_info": "Cursor Kimlik Bilgilerini Güncelle",
|
||||
"register_process_error": "Kayıt İşlemi Hatası: {error}",
|
||||
"setting_password": "Şifre Ayarlanıyor",
|
||||
"manual_code_input": "Manuel Kod Girişi",
|
||||
"manual_email_input": "Manuel E-posta Girişi",
|
||||
"password": "Şifre",
|
||||
"first_name": "Ad",
|
||||
"last_name": "Soyad",
|
||||
"exit_signal": "Çıkış Sinyali",
|
||||
"email_address": "E-posta Adresi",
|
||||
"config_created": "Yapılandırma Oluşturuldu",
|
||||
"verification_failed": "Doğrulama Başarısız",
|
||||
"verification_error": "Doğrulama Hatası: {error}",
|
||||
"config_option_added": "Yapılandırma Seçeneği Eklendi: {option}",
|
||||
"config_updated": "Yapılandırma Güncellendi",
|
||||
"password_submitted": "Şifre Gönderildi",
|
||||
"total_usage": "Toplam Kullanım: {usage}",
|
||||
"setting_on_password": "Şifre Ayarlanıyor",
|
||||
"getting_code": "Doğrulama Kodu Alınıyor, 60 saniye içinde denenecek",
|
||||
"human_verify_error": "Kullanıcının insan olduğu doğrulanamıyor. Tekrar deneniyor...",
|
||||
"max_retries_reached": "Maksimum deneme sayısına ulaşıldı. Kayıt başarısız."
|
||||
},
|
||||
"auth": {
|
||||
"title": "Cursor Kimlik Yöneticisi",
|
||||
"checking_auth": "Kimlik Dosyası Kontrol Ediliyor",
|
||||
"auth_not_found": "Kimlik Dosyası Bulunamadı",
|
||||
"auth_file_error": "Kimlik Dosyası Hatası: {error}",
|
||||
"reading_auth": "Kimlik Dosyası Okunuyor",
|
||||
"updating_auth": "Kimlik Bilgileri Güncelleniyor",
|
||||
"auth_updated": "Kimlik Bilgileri Başarıyla Güncellendi",
|
||||
"auth_update_failed": "Kimlik Bilgileri Güncellemesi Başarısız: {error}",
|
||||
"auth_file_created": "Kimlik Dosyası Oluşturuldu",
|
||||
"auth_file_create_failed": "Kimlik Dosyası Oluşturma Başarısız: {error}",
|
||||
"press_enter": "Çıkmak için Enter'a Basın",
|
||||
"reset_machine_id": "Makine Kimliğini Sıfırla",
|
||||
"database_connection_closed": "Veritabanı Bağlantısı Kapatıldı",
|
||||
"database_updated_successfully": "Veritabanı Başarıyla Güncellendi",
|
||||
"connected_to_database": "Veritabanına Bağlanıldı",
|
||||
"updating_pair": "Anahtar-Değer Çifti Güncelleniyor",
|
||||
"db_not_found": "Veritabanı dosyası bulunamadı: {path}",
|
||||
"db_permission_error": "Veritabanı dosyasına erişilemiyor. Lütfen izinleri kontrol edin",
|
||||
"db_connection_error": "Veritabanına bağlantı başarısız: {error}"
|
||||
},
|
||||
"control": {
|
||||
"generate_email": "Yeni E-posta Oluşturuluyor",
|
||||
"blocked_domain": "Engellenmiş Alan Adı",
|
||||
"select_domain": "Rastgele Alan Adı Seçiliyor",
|
||||
"copy_email": "E-posta Adresi Kopyalanıyor",
|
||||
"enter_mailbox": "Posta Kutusuna Giriliyor",
|
||||
"refresh_mailbox": "Posta Kutusu Yenileniyor",
|
||||
"check_verification": "Doğrulama Kodu Kontrol Ediliyor",
|
||||
"verification_found": "Doğrulama Kodu Bulundu",
|
||||
"verification_not_found": "Doğrulama Kodu Bulunamadı",
|
||||
"browser_error": "Tarayıcı Kontrol Hatası: {error}",
|
||||
"navigation_error": "Gezinme Hatası: {error}",
|
||||
"email_copy_error": "E-posta Kopyalama Hatası: {error}",
|
||||
"mailbox_error": "Posta Kutusu Hatası: {error}",
|
||||
"token_saved_to_file": "Jeton cursor_tokens.txt dosyasına kaydedildi",
|
||||
"navigate_to": "{url} adresine gidiliyor",
|
||||
"generate_email_success": "E-posta Oluşturma Başarılı",
|
||||
"select_email_domain": "E-posta Alan Adı Seç",
|
||||
"select_email_domain_success": "E-posta Alan Adı Seçimi Başarılı",
|
||||
"get_email_name": "E-posta Adı Al",
|
||||
"get_email_name_success": "E-posta Adı Alma Başarılı",
|
||||
"get_email_address": "E-posta Adresi Al",
|
||||
"get_email_address_success": "E-posta Adresi Alma Başarılı",
|
||||
"enter_mailbox_success": "Posta Kutusuna Giriş Başarılı",
|
||||
"found_verification_code": "Doğrulama Kodu Bulundu",
|
||||
"get_cursor_session_token": "Cursor Oturum Jetonu Al",
|
||||
"get_cursor_session_token_success": "Cursor Oturum Jetonu Alma Başarılı",
|
||||
"get_cursor_session_token_failed": "Cursor Oturum Jetonu Alma Başarısız",
|
||||
"save_token_failed": "Jeton Kaydetme Başarısız",
|
||||
"database_updated_successfully": "Veritabanı Başarıyla Güncellendi",
|
||||
"database_connection_closed": "Veritabanı Bağlantısı Kapatıldı",
|
||||
"no_valid_verification_code": "Geçerli Doğrulama Kodu Yok"
|
||||
},
|
||||
"email": {
|
||||
"starting_browser": "Tarayıcı Başlatılıyor",
|
||||
"visiting_site": "E-posta alan adları ziyaret ediliyor",
|
||||
"create_success": "E-posta Başarıyla Oluşturuldu",
|
||||
"create_failed": "E-posta Oluşturma Başarısız",
|
||||
"create_error": "E-posta Oluşturma Hatası: {error}",
|
||||
"refreshing": "E-posta Yenileniyor",
|
||||
"refresh_success": "E-posta Başarıyla Yenilendi",
|
||||
"refresh_error": "E-posta Yenileme Hatası: {error}",
|
||||
"refresh_button_not_found": "Yenileme Düğmesi Bulunamadı",
|
||||
"verification_found": "Doğrulama Bulundu",
|
||||
"verification_not_found": "Doğrulama Bulunamadı",
|
||||
"verification_error": "Doğrulama Hatası: {error}",
|
||||
"verification_code_found": "Doğrulama Kodu Bulundu",
|
||||
"verification_code_not_found": "Doğrulama Kodu Bulunamadı",
|
||||
"verification_code_error": "Doğrulama Kodu Hatası: {error}",
|
||||
"address": "E-posta Adresi",
|
||||
"all_domains_blocked": "Tüm Alan Adları Engellendi, Servis Değiştiriliyor",
|
||||
"no_available_domains_after_filtering": "Filtrelemeden Sonra Kullanılabilir Alan Adı Yok",
|
||||
"switching_service": "{service} Servisine Geçiliyor",
|
||||
"domains_list_error": "Alan Adları Listesi Alınamadı: {error}",
|
||||
"failed_to_get_available_domains": "Kullanılabilir Alan Adları Alınamadı",
|
||||
"domains_excluded": "Hariç Tutulan Alan Adları: {domains}",
|
||||
"failed_to_create_account": "Hesap Oluşturma Başarısız",
|
||||
"account_creation_error": "Hesap Oluşturma Hatası: {error}",
|
||||
"blocked_domains": "Engellenen Alan Adları: {domains}",
|
||||
"blocked_domains_loaded": "Engellenen Alan Adları Yüklendi: {count}",
|
||||
"blocked_domains_loaded_error": "Engellenen Alan Adları Yükleme Hatası: {error}",
|
||||
"blocked_domains_loaded_success": "Engellenen Alan Adları Başarıyla Yüklendi",
|
||||
"blocked_domains_loaded_timeout": "Engellenen Alan Adları Yükleme Zaman Aşımı: {timeout}s",
|
||||
"blocked_domains_loaded_timeout_error": "Engellenen Alan Adları Yükleme Zaman Aşımı Hatası: {error}",
|
||||
"available_domains_loaded": "Kullanılabilir Alan Adları Yüklendi: {count}",
|
||||
"domains_filtered": "Filtrelenen Alan Adları: {count}",
|
||||
"trying_to_create_email": "E-posta oluşturulmaya çalışılıyor: {email}",
|
||||
"domain_blocked": "Alan Adı Engellendi: {domain}"
|
||||
},
|
||||
"update": {
|
||||
"title": "Cursor Otomatik Güncellemeyi Devre Dışı Bırak",
|
||||
"disable_success": "Otomatik Güncelleme Başarıyla Devre Dışı Bırakıldı",
|
||||
"disable_failed": "Otomatik Güncellemeyi Devre Dışı Bırakma Başarısız: {error}",
|
||||
"press_enter": "Çıkmak için Enter'a Basın",
|
||||
"start_disable": "Otomatik Güncellemeyi Devre Dışı Bırakma Başlatılıyor",
|
||||
"killing_processes": "İşlemler Sonlandırılıyor",
|
||||
"processes_killed": "İşlemler Sonlandırıldı",
|
||||
"removing_directory": "Dizin Kaldırılıyor",
|
||||
"directory_removed": "Dizin Kaldırıldı",
|
||||
"creating_block_file": "Engelleme Dosyası Oluşturuluyor",
|
||||
"block_file_created": "Engelleme Dosyası Oluşturuldu"
|
||||
},
|
||||
"updater": {
|
||||
"checking": "Güncellemeler kontrol ediliyor...",
|
||||
"new_version_available": "Yeni sürüm mevcut! (Mevcut: {current}, En son: {latest})",
|
||||
"updating": "En son sürüme güncelleniyor. Program otomatik olarak yeniden başlatılacak.",
|
||||
"up_to_date": "En son sürümü kullanıyorsunuz.",
|
||||
"check_failed": "Güncellemeler kontrol edilemedi: {error}",
|
||||
"continue_anyway": "Mevcut sürümle devam ediliyor...",
|
||||
"update_confirm": "En son sürüme güncellemek istiyor musunuz? (Y/n)",
|
||||
"update_skipped": "Güncelleme atlanıyor.",
|
||||
"invalid_choice": "Geçersiz seçim. Lütfen 'Y' veya 'n' girin.",
|
||||
"development_version": "Geliştirme Sürümü {current} > {latest}",
|
||||
"changelog_title": "Değişiklik günlüğü"
|
||||
},
|
||||
"totally_reset": {
|
||||
"title": "Cursor'ı Tamamen Sıfırla",
|
||||
"checking_config": "Yapılandırma Dosyası Kontrol Ediliyor",
|
||||
"config_not_found": "Yapılandırma Dosyası Bulunamadı",
|
||||
"no_permission": "Yapılandırma Dosyası Okunamıyor veya Yazılamıyor, Lütfen Dosya İzinlerini Kontrol Edin",
|
||||
"reading_config": "Mevcut Yapılandırma Okunuyor",
|
||||
"creating_backup": "Yapılandırma Yedeği Oluşturuluyor",
|
||||
"backup_exists": "Yedek Dosya Zaten Mevcut, Yedekleme Adımı Atlanıyor",
|
||||
"generating_new_machine_id": "Yeni Makine Kimliği Oluşturuluyor",
|
||||
"saving_new_config": "Yeni Yapılandırma JSON'a Kaydediliyor",
|
||||
"success": "Cursor Başarıyla Sıfırlandı",
|
||||
"error": "Cursor Sıfırlama Başarısız: {error}",
|
||||
"press_enter": "Çıkmak için Enter'a Basın",
|
||||
"reset_machine_id": "Makine Kimliğini Sıfırla",
|
||||
"database_connection_closed": "Veritabanı Bağlantısı Kapatıldı",
|
||||
"database_updated_successfully": "Veritabanı Başarıyla Güncellendi",
|
||||
"connected_to_database": "Veritabanına Bağlanıldı",
|
||||
"updating_pair": "Anahtar-Değer Çifti Güncelleniyor",
|
||||
"db_not_found": "Veritabanı dosyası bulunamadı: {path}",
|
||||
"db_permission_error": "Veritabanı dosyasına erişilemiyor. Lütfen izinleri kontrol edin",
|
||||
"db_connection_error": "Veritabanına bağlantı başarısız: {error}",
|
||||
"feature_title": "ÖZELLİKLER",
|
||||
"feature_1": "Cursor AI ayarları ve yapılandırmalarının tamamen kaldırılması",
|
||||
"feature_2": "AI geçmişi ve komutları dahil tüm önbelleğe alınmış verileri temizler",
|
||||
"feature_3": "Deneme süresini aşma tespitini atlatmak için makine kimliğini sıfırlar",
|
||||
"feature_4": "Rastgele yeni makine tanımlayıcıları oluşturur",
|
||||
"feature_5": "Özel uzantıları ve tercihleri kaldırır",
|
||||
"feature_6": "Deneme süresi bilgilerini ve aktivasyon verilerini sıfırlar",
|
||||
"feature_7": "Gizli lisans ve deneme süresiyle ilgili dosyalar için derin tarama",
|
||||
"feature_8": "Cursor olmayan dosyaları ve uygulamaları güvenle korur",
|
||||
"feature_9": "Windows, macOS ve Linux ile uyumludur",
|
||||
"disclaimer_title": "YASAL UYARI",
|
||||
"disclaimer_1": "Bu araç, tüm Cursor AI ayarlarını,",
|
||||
"disclaimer_2": "yapılandırmalarını ve önbelleğe alınmış verileri kalıcı olarak silecektir. Bu işlem geri alınamaz.",
|
||||
"disclaimer_3": "Kod dosyalarınız ETKİLENMEYECEK ve bu araç",
|
||||
"disclaimer_4": "yalnızca Cursor AI editör dosyalarını ve deneme süresi algılama mekanizmalarını hedef almak için tasarlanmıştır.",
|
||||
"disclaimer_5": "Sisteminizde bulunan diğer uygulamalar etkilenmeyecektir.",
|
||||
"disclaimer_6": "Bu aracı çalıştırdıktan sonra Cursor AI'yi yeniden kurmanız gerekecektir.",
|
||||
"disclaimer_7": "Kullanım sorumluluğu size aittir",
|
||||
"confirm_title": "Devam etmek istediğinizden emin misiniz?",
|
||||
"confirm_1": "Bu işlem, tüm Cursor AI ayarlarını,",
|
||||
"confirm_2": "yapılandırmalarını ve önbelleğe alınmış verileri silecektir. Bu işlem geri alınamaz.",
|
||||
"confirm_3": "Kod dosyalarınız ETKİLENMEYECEK ve bu araç",
|
||||
"confirm_4": "yalnızca Cursor AI editör dosyalarını ve deneme süresi algılama mekanizmalarını hedef almak için tasarlanmıştır.",
|
||||
"confirm_5": "Sisteminizde bulunan diğer uygulamalar etkilenmeyecektir.",
|
||||
"confirm_6": "Bu aracı çalıştırdıktan sonra Cursor AI'yi yeniden kurmanız gerekecektir.",
|
||||
"confirm_7": "Kullanım sorumluluğu size aittir",
|
||||
"invalid_choice": "Lütfen 'Y' veya 'n' girin",
|
||||
"skipped_for_safety": "Güvenlik için atlandı (Cursor ile ilgili değil): {path}",
|
||||
"deleted": "Silindi: {path}",
|
||||
"error_deleting": "{path} silinirken hata: {error}",
|
||||
"not_found": "Dosya bulunamadı: {path}",
|
||||
"resetting_machine_id": "Deneme süresi algılamasını atlatmak için makine tanımlayıcıları sıfırlanıyor...",
|
||||
"created_machine_id": "Yeni makine kimliği oluşturuldu: {path}",
|
||||
"error_creating_machine_id": "Makine kimliği dosyası oluşturulurken hata {path}: {error}",
|
||||
"error_searching": "{path} içindeki dosyalar aranırken hata: {error}",
|
||||
"created_extended_trial_info": "Yeni genişletilmiş deneme bilgisi oluşturuldu: {path}",
|
||||
"error_creating_trial_info": "Deneme bilgisi dosyası oluşturulurken hata {path}: {error}",
|
||||
"resetting_cursor_ai_editor": "Cursor AI Editor sıfırlanıyor... Lütfen bekleyin.",
|
||||
"reset_cancelled": "Sıfırlama iptal edildi. Herhangi bir değişiklik yapmadan çıkılıyor.",
|
||||
"windows_machine_id_modification_skipped": "Windows makine kimliği değişikliği atlandı: {error}",
|
||||
"linux_machine_id_modification_skipped": "Linux machine-id değişikliği atlandı: {error}",
|
||||
"note_complete_machine_id_reset_may_require_running_as_administrator": "Not: Tam makine kimliği sıfırlaması yönetici olarak çalıştırmayı gerektirebilir",
|
||||
"note_complete_system_machine_id_reset_may_require_sudo_privileges": "Not: Tam sistem machine-id sıfırlaması sudo ayrıcalıkları gerektirebilir",
|
||||
"windows_registry_instructions": "📝 NOT: Windows'ta tam sıfırlama için kayıt defteri girdilerini de temizlemeniz gerekebilir.",
|
||||
"windows_registry_instructions_2": " 'regedit' çalıştırın ve HKEY_CURRENT_USER\\Software\\ altında 'Cursor' veya 'CursorAI' içeren anahtarları arayıp silin.\n",
|
||||
"reset_log_1": "Cursor AI tamamen sıfırlandı ve deneme süresi algılaması atlatıldı!",
|
||||
"reset_log_2": "Değişikliklerin etkili olması için lütfen sisteminizi yeniden başlatın.",
|
||||
"reset_log_3": "Cursor AI'yi yeniden kurmanız gerekecek ve şimdi yeni bir deneme süreniz olmalı.",
|
||||
"reset_log_4": "En iyi sonuçlar için şunları da düşünün:",
|
||||
"reset_log_5": "Yeni bir deneme süresi için kaydolurken farklı bir e-posta adresi kullanın",
|
||||
"reset_log_6": "Mümkünse, IP adresinizi değiştirmek için VPN kullanın",
|
||||
"reset_log_7": "Cursor AI'nin web sitesini ziyaret etmeden önce tarayıcı çerezlerinizi ve önbelleği temizleyin",
|
||||
"reset_log_8": "Sorunlar devam ederse, Cursor AI'yi farklı bir konuma kurmayı deneyin",
|
||||
"reset_log_9": "Herhangi bir sorunla karşılaşırsanız, Github Sorun Takibine gidin ve https://github.com/yeongpin/cursor-free-vip/issues adresinde bir sorun oluşturun",
|
||||
"unexpected_error": "Beklenmeyen bir hata oluştu: {error}",
|
||||
"report_issue": "Lütfen bu sorunu https://github.com/yeongpin/cursor-free-vip/issues adresindeki Github Sorun Takibine bildirin",
|
||||
"keyboard_interrupt": "İşlem kullanıcı tarafından kesildi. Çıkılıyor...",
|
||||
"return_to_main_menu": "Ana menüye dönülüyor...",
|
||||
"process_interrupted": "İşlem kesildi. Çıkılıyor...",
|
||||
"press_enter_to_return_to_main_menu": "Ana menüye dönmek için Enter'a basın...",
|
||||
"removing_known": "Bilinen deneme/lisans dosyaları kaldırılıyor",
|
||||
"performing_deep_scan": "Ek deneme/lisans dosyaları için derin tarama yapılıyor",
|
||||
"found_additional_potential_license_trial_files": "{count} ek potansiyel lisans/deneme dosyası bulundu",
|
||||
"checking_for_electron_localstorage_files": "Electron localStorage dosyaları kontrol ediliyor",
|
||||
"no_additional_license_trial_files_found_in_deep_scan": "Derin taramada ek lisans/deneme dosyası bulunamadı",
|
||||
"removing_electron_localstorage_files": "Electron localStorage dosyaları kaldırılıyor",
|
||||
"electron_localstorage_files_removed": "Electron localStorage dosyaları kaldırıldı",
|
||||
"electron_localstorage_files_removal_error": "Electron localStorage dosyaları kaldırılırken hata: {error}",
|
||||
"removing_electron_localstorage_files_completed": "Electron localStorage dosyaları kaldırma işlemi tamamlandı"
|
||||
}
|
||||
}
|
||||
@@ -14,17 +14,21 @@
|
||||
"press_enter": "Nhấn Enter để Thoát",
|
||||
"disable_auto_update": "Tắt tự động cập nhật Cursor",
|
||||
"lifetime_access_enabled": "ĐÃ BẬT TRUY CẬP TRỌN ĐỜI",
|
||||
"totally_reset": "Đặt lại hoàn toàn Cursor"
|
||||
"totally_reset": "Đặt lại hoàn toàn Cursor",
|
||||
"outdate": "Quá cũ",
|
||||
"temp_github_register": "Đăng ký GitHub tạm thời",
|
||||
"coming_soon": "Sắp ra mắt"
|
||||
},
|
||||
"languages": {
|
||||
"en": "English",
|
||||
"zh_cn": "简体中文",
|
||||
"zh_tw": "繁體中文",
|
||||
"en": "Tiếng Anh",
|
||||
"zh_cn": "Tiếng Trung Giản Thể",
|
||||
"zh_tw": "Tiếng Trung Phồn Thể",
|
||||
"vi": "Tiếng Việt",
|
||||
"nl": "Dutch",
|
||||
"de": "Germa",
|
||||
"fr": "French",
|
||||
"pt": "Brazilian Portuguese"
|
||||
"nl": "Tiếng Hà Lan",
|
||||
"de": "Tiếng Đức",
|
||||
"fr": "Tiếng Pháp",
|
||||
"pt": "Tiếng Bồ Đào Nha",
|
||||
"ru": "Tiếng Nga"
|
||||
},
|
||||
"quit_cursor": {
|
||||
"start": "Bắt Đầu Thoát Cursor",
|
||||
@@ -92,7 +96,6 @@
|
||||
"check_version_failed": "Kiểm Tra Phiên Bản Thất Bại: {error}",
|
||||
"stack_trace": "Dấu Vết Ngăn Xếp",
|
||||
"version_too_low": "Phiên Bản Cursor Quá Thấp: {version} < 0.45.0"
|
||||
|
||||
},
|
||||
"register": {
|
||||
"title": "Công Cụ Đăng Ký Cursor",
|
||||
@@ -285,7 +288,7 @@
|
||||
"update_skipped": "Bỏ Qua Cập Nhật.",
|
||||
"invalid_choice": "Lựa Chọn Không Hợp Lệ. Vui Lòng Nhập 'Y' Hoặc 'n'.",
|
||||
"development_version": "Phiên Bản Phát Triển {current} > {latest}",
|
||||
"changelog_title": "Changelog"
|
||||
"changelog_title": "Nhật ký thay đổi"
|
||||
},
|
||||
"totally_reset": {
|
||||
"title": "Đặt lại hoàn toàn Cursor",
|
||||
|
||||
@@ -16,17 +16,25 @@
|
||||
"press_enter": "按回车键退出",
|
||||
"disable_auto_update": "禁用 Cursor 自动更新",
|
||||
"lifetime_access_enabled": "永久订阅",
|
||||
"totally_reset": "完全重置 Cursor"
|
||||
"totally_reset": "完全重置 Cursor",
|
||||
"outdate": "过时",
|
||||
"temp_github_register": "临时GitHub注册",
|
||||
"admin_required": "运行可执行文件,需要管理员权限",
|
||||
"admin_required_continue": "继续使用当前版本...",
|
||||
"coming_soon": "即将推出"
|
||||
},
|
||||
"languages": {
|
||||
"en": "English",
|
||||
"en": "英语",
|
||||
"zh_cn": "简体中文",
|
||||
"zh_tw": "繁體中文",
|
||||
"vi": "Vietnamese",
|
||||
"nl": "Dutch",
|
||||
"de": "German",
|
||||
"fr": "French",
|
||||
"pt": "Brazilian Portuguese"
|
||||
"zh_tw": "繁体中文",
|
||||
"vi": "越南语",
|
||||
"nl": "荷兰语",
|
||||
"de": "德语",
|
||||
"fr": "法语",
|
||||
"pt": "葡萄牙语",
|
||||
"ru": "俄语",
|
||||
"tr": "土耳其语",
|
||||
"bg": "保加利亚语"
|
||||
},
|
||||
"quit_cursor": {
|
||||
"start": "开始退出 Cursor",
|
||||
@@ -374,6 +382,54 @@
|
||||
"removing_electron_localstorage_files": "正在移除 Electron localStorage 文件",
|
||||
"electron_localstorage_files_removed": "Electron localStorage 文件已移除",
|
||||
"electron_localstorage_files_removal_error": "移除 Electron localStorage 文件时出错:{error}",
|
||||
"removing_electron_localstorage_files_completed": "Electron localStorage 文件移除完成"
|
||||
"removing_electron_localstorage_files_completed": "Electron localStorage 文件移除完成",
|
||||
"warning_title": "警告",
|
||||
"warning_1": "此操作将删除所有 Cursor AI 设置、",
|
||||
"warning_2": "配置和缓存数据。此操作无法撤销。",
|
||||
"warning_3": "您的代码文件 **不会** 受到影响,工具设计为",
|
||||
"warning_4": "仅针对 Cursor AI 编辑器文件和试用检测机制。",
|
||||
"warning_5": "系统中的其他应用程序不会受到影响。",
|
||||
"warning_6": "运行此工具后,您需要重新设置 Cursor AI。",
|
||||
"warning_7": "请自行承担风险",
|
||||
"removed": "已删除:{path}",
|
||||
"failed_to_reset_machine_guid": "无法重置机器 GUID",
|
||||
"failed_to_remove": "无法删除:{path}",
|
||||
"failed_to_delete_file": "无法删除文件:{path}",
|
||||
"failed_to_delete_directory": "无法删除目录:{path}",
|
||||
"failed_to_delete_file_or_directory": "无法删除文件或目录:{path}",
|
||||
"deep_scanning": "正在进行深度扫描以查找其他试用/授权文件",
|
||||
"resetting_cursor": "正在重置 Cursor AI 编辑器... 请稍候。",
|
||||
"completed_in": "完成时间:{time} 秒",
|
||||
"cursor_reset_completed": "Cursor AI 编辑器已完全重置且绕过试用检测!",
|
||||
"cursor_reset_failed": "Cursor AI 编辑器重置失败:{error}",
|
||||
"cursor_reset_cancelled": "Cursor AI 编辑器重置已取消,未进行任何更改。",
|
||||
"operation_cancelled": "操作已取消,未进行任何更改。"
|
||||
},
|
||||
"github_register": {
|
||||
"title": "GitHub + Cursor AI 注册自动化",
|
||||
"features_header": "功能",
|
||||
"feature1": "使用 1secmail 生成临时邮箱",
|
||||
"feature2": "使用随机凭证注册新的 GitHub 账户",
|
||||
"feature3": "自动验证 GitHub 邮箱",
|
||||
"feature4": "使用 GitHub 认证登录 Cursor AI",
|
||||
"feature5": "重置机器 ID 以绕过试用检测",
|
||||
"feature6": "保存所有凭证到文件",
|
||||
"warnings_header": "警告",
|
||||
"warning1": "此脚本自动化账户创建,可能违反 GitHub/Cursor 服务条款",
|
||||
"warning2": "需要互联网访问和管理员权限",
|
||||
"warning3": "CAPTCHA 或额外验证可能会中断自动化",
|
||||
"warning4": "请负责任地使用,风险自负",
|
||||
"confirm": "您确定要继续吗?",
|
||||
"invalid_choice": "无效选择。请输入 'yes' 或 'no'",
|
||||
"cancelled": "操作已取消",
|
||||
"program_terminated": "程序已由用户终止",
|
||||
"starting_automation": "开始自动化...",
|
||||
"github_username": "GitHub 用户名",
|
||||
"github_password": "GitHub 密码",
|
||||
"email_address": "邮箱地址",
|
||||
"credentials_saved": "这些凭证已保存到 github_cursor_accounts.txt",
|
||||
"completed_successfully": "GitHub + Cursor 注册成功",
|
||||
"registration_encountered_issues": "GitHub + Cursor 注册遇到问题",
|
||||
"check_browser_windows_for_manual_intervention_or_try_again_later": "检查浏览器窗口进行手动干预或稍后再试"
|
||||
}
|
||||
}
|
||||
@@ -14,17 +14,25 @@
|
||||
"press_enter": "按返回鍵退出",
|
||||
"disable_auto_update": "禁用 Cursor 自動更新",
|
||||
"lifetime_access_enabled": "終身訪問已啟用",
|
||||
"totally_reset": "完全重置 Cursor"
|
||||
"totally_reset": "完全重置 Cursor",
|
||||
"outdate": "過時",
|
||||
"temp_github_register": "臨時GitHub註冊",
|
||||
"admin_required": "運行可執行文件,需要管理員權限",
|
||||
"admin_required_continue": "繼續使用當前版本...",
|
||||
"coming_soon": "即將推出"
|
||||
},
|
||||
"languages": {
|
||||
"en": "English",
|
||||
"zh_cn": "简体中文",
|
||||
"en": "英文",
|
||||
"zh_cn": "簡體中文",
|
||||
"zh_tw": "繁體中文",
|
||||
"vi": "Vietnamese",
|
||||
"nl": "Dutch",
|
||||
"de": "German",
|
||||
"fr": "French",
|
||||
"pt": "Brazilian Portuguese"
|
||||
"vi": "越南文",
|
||||
"nl": "荷蘭文",
|
||||
"de": "德文",
|
||||
"fr": "法文",
|
||||
"pt": "葡萄牙文",
|
||||
"ru": "俄文",
|
||||
"tr": "土耳其文",
|
||||
"bg": "保加利亞文"
|
||||
},
|
||||
"quit_cursor": {
|
||||
"start": "開始退出 Cursor",
|
||||
@@ -262,7 +270,7 @@
|
||||
"update_skipped": "跳過更新。",
|
||||
"invalid_choice": "選擇無效。請輸入 'Y' 或 'n'.",
|
||||
"development_version": "開發版本 {current} > {latest}",
|
||||
"changelog_title": "更新日志"
|
||||
"changelog_title": "更新日誌"
|
||||
},
|
||||
"totally_reset": {
|
||||
"title": "完全重置 Cursor",
|
||||
@@ -353,6 +361,54 @@
|
||||
"removing_electron_localstorage_files": "正在移除 Electron localStorage 檔案",
|
||||
"electron_localstorage_files_removed": "已移除 Electron localStorage 檔案",
|
||||
"electron_localstorage_files_removal_error": "移除 Electron localStorage 檔案時出錯:{error}",
|
||||
"removing_electron_localstorage_files_completed": "Electron localStorage 檔案移除完成"
|
||||
}
|
||||
"removing_electron_localstorage_files_completed": "Electron localStorage 檔案移除完成",
|
||||
"warning_title": "警告",
|
||||
"warning_1": "此操作將刪除所有 Cursor AI 設定、",
|
||||
"warning_2": "配置與快取資料。此操作無法還原。",
|
||||
"warning_3": "您的程式碼檔案將 **不會** 受到影響,且此工具僅針對",
|
||||
"warning_4": "Cursor AI 編輯器檔案與試用偵測機制。",
|
||||
"warning_5": "系統中的其他應用程式不會受到影響。",
|
||||
"warning_6": "執行此工具後,您需要重新設定 Cursor AI。",
|
||||
"warning_7": "請自行承擔風險",
|
||||
"removed": "已刪除:{path}",
|
||||
"failed_to_reset_machine_guid": "無法重置機器 GUID",
|
||||
"failed_to_remove": "無法刪除:{path}",
|
||||
"failed_to_delete_file": "無法刪除檔案:{path}",
|
||||
"failed_to_delete_directory": "無法刪除目錄:{path}",
|
||||
"failed_to_delete_file_or_directory": "無法刪除檔案或目錄:{path}",
|
||||
"deep_scanning": "正在進行深度掃描以查找其他試用/授權檔案",
|
||||
"resetting_cursor": "正在重置 Cursor AI 編輯器... 請稍候。",
|
||||
"completed_in": "完成時間:{time} 秒",
|
||||
"cursor_reset_completed": "Cursor AI 編輯器已完全重置且繞過試用偵測!",
|
||||
"cursor_reset_failed": "Cursor AI 編輯器重置失敗:{error}",
|
||||
"cursor_reset_cancelled": "Cursor AI 編輯器重置已取消,未進行任何更改。",
|
||||
"operation_cancelled": "操作已取消,未進行任何更改。"
|
||||
},
|
||||
"github_register": {
|
||||
"title": "GitHub + Cursor AI 注册自动化",
|
||||
"features_header": "功能",
|
||||
"feature1": "使用 1secmail 生成临时邮箱",
|
||||
"feature2": "使用随机凭证注册新的 GitHub 账户",
|
||||
"feature3": "自动验证 GitHub 邮箱",
|
||||
"feature4": "使用 GitHub 认证登录 Cursor AI",
|
||||
"feature5": "重置机器 ID 以绕过试用检测",
|
||||
"feature6": "保存所有凭证到文件",
|
||||
"warnings_header": "警告",
|
||||
"warning1": "此脚本自动化账户创建,可能违反 GitHub/Cursor 服务条款",
|
||||
"warning2": "需要互联网访问和管理员权限",
|
||||
"warning3": "CAPTCHA 或额外验证可能会中断自动化",
|
||||
"warning4": "请负责任地使用,风险自负",
|
||||
"confirm": "您确定要继续吗?",
|
||||
"invalid_choice": "无效选择。请输入 'yes' 或 'no'",
|
||||
"cancelled": "操作已取消",
|
||||
"program_terminated": "程序已由用户终止",
|
||||
"starting_automation": "開始自動化...",
|
||||
"github_username": "GitHub 用戶名",
|
||||
"github_password": "GitHub 密碼",
|
||||
"email_address": "郵箱地址",
|
||||
"credentials_saved": "這些憑證已保存到 github_cursor_accounts.txt",
|
||||
"completed_successfully": "GitHub + Cursor 註冊成功",
|
||||
"registration_encountered_issues": "GitHub + Cursor 註冊遇到問題",
|
||||
"check_browser_windows_for_manual_intervention_or_try_again_later": "檢查瀏覽器視窗進行手動干預或稍後再試"
|
||||
}
|
||||
}
|
||||
82
logo.py
82
logo.py
@@ -1,6 +1,8 @@
|
||||
from colorama import Fore, Style, init
|
||||
from dotenv import load_dotenv
|
||||
import os
|
||||
import shutil
|
||||
import re
|
||||
|
||||
# Get the current script directory
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
@@ -15,27 +17,85 @@ version = os.getenv('VERSION', '1.0.0')
|
||||
# Initialize colorama
|
||||
init()
|
||||
|
||||
CURSOR_LOGO = f"""
|
||||
{Fore.CYAN}
|
||||
# get terminal width
|
||||
def get_terminal_width():
|
||||
try:
|
||||
columns, _ = shutil.get_terminal_size()
|
||||
return columns
|
||||
except:
|
||||
return 80 # default width
|
||||
|
||||
# center display text (not handling Chinese characters)
|
||||
def center_multiline_text(text, handle_chinese=False):
|
||||
width = get_terminal_width()
|
||||
lines = text.split('\n')
|
||||
centered_lines = []
|
||||
|
||||
for line in lines:
|
||||
# calculate actual display width (remove ANSI color codes)
|
||||
clean_line = line
|
||||
for color in [Fore.CYAN, Fore.YELLOW, Fore.GREEN, Fore.RED, Style.RESET_ALL]:
|
||||
clean_line = clean_line.replace(color, '')
|
||||
|
||||
# remove all ANSI escape sequences to get the actual length
|
||||
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
|
||||
clean_line = ansi_escape.sub('', clean_line)
|
||||
|
||||
# calculate display width
|
||||
if handle_chinese:
|
||||
# consider Chinese characters occupying two positions
|
||||
display_width = 0
|
||||
for char in clean_line:
|
||||
if ord(char) > 127: # non-ASCII characters
|
||||
display_width += 2
|
||||
else:
|
||||
display_width += 1
|
||||
else:
|
||||
# not handling Chinese characters
|
||||
display_width = len(clean_line)
|
||||
|
||||
# calculate the number of spaces to add
|
||||
padding = max(0, (width - display_width) // 2)
|
||||
centered_lines.append(' ' * padding + line)
|
||||
|
||||
return '\n'.join(centered_lines)
|
||||
|
||||
# original LOGO text
|
||||
LOGO_TEXT = f"""{Fore.CYAN}
|
||||
██████╗██╗ ██╗██████╗ ███████╗ ██████╗ ██████╗ ██████╗ ██████╗ ██████╗
|
||||
██╔════╝██║ ██║██╔══██╗██╔════╝██╔═══██╗██╔══██╗ ██╔══██╗██╔══██╗██╔═══██╗
|
||||
██║ ██║ ██║██████╔╝███████╗██║ ██║██████╔╝ ██████╔╝██████╔╝██║ ██║
|
||||
██║ ██║ ██║██╔══██╗╚════██║██║ ██║██╔══██╗ ██╔═══╝ ██╔══██╗██║ ██║
|
||||
╚██████╗╚██████╔╝██║ ██║███████║╚██████╔╝██║ ██║ ██║ ██║ ██║╚██████╔╝
|
||||
╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝
|
||||
{Fore.YELLOW}
|
||||
Pro Version Activator v{version}
|
||||
{Fore.GREEN}
|
||||
Author: Pin Studios | yeongpin
|
||||
{Style.RESET_ALL}"""
|
||||
|
||||
Github: https://github.com/yeongpin/cursor-free-vip
|
||||
{Fore.RED}
|
||||
Press 7 to change language | 按下 7 键切换语言 | Pressione 7 para alterar o idioma
|
||||
{Style.RESET_ALL}
|
||||
"""
|
||||
DESCRIPTION_TEXT = f"""{Fore.YELLOW}
|
||||
Pro Version Activator v{version}{Fore.GREEN}
|
||||
Author: Pin Studios (yeongpin)"""
|
||||
|
||||
CONTRIBUTORS_TEXT = f"""{Fore.BLUE}
|
||||
Contributors:
|
||||
BasaiCorp aliensb handwerk2016 Nigel1992
|
||||
UntaDotMy RenjiYuusei imbajin ahmed98Osama
|
||||
bingoohuang mALIk-sHAHId MFaiqKhan httpmerak
|
||||
muhammedfurkan plamkatawe
|
||||
"""
|
||||
OTHER_INFO_TEXT = f"""{Fore.YELLOW}
|
||||
Github: https://github.com/yeongpin/cursor-free-vip{Fore.RED}
|
||||
Press 7 to change language | 按下 7 键切换语言{Style.RESET_ALL}"""
|
||||
|
||||
# center display LOGO and DESCRIPTION
|
||||
CURSOR_LOGO = center_multiline_text(LOGO_TEXT, handle_chinese=False)
|
||||
CURSOR_DESCRIPTION = center_multiline_text(DESCRIPTION_TEXT, handle_chinese=False)
|
||||
CURSOR_CONTRIBUTORS = center_multiline_text(CONTRIBUTORS_TEXT, handle_chinese=False)
|
||||
CURSOR_OTHER_INFO = center_multiline_text(OTHER_INFO_TEXT, handle_chinese=True)
|
||||
|
||||
def print_logo():
|
||||
print(CURSOR_LOGO)
|
||||
print(CURSOR_DESCRIPTION)
|
||||
print(CURSOR_CONTRIBUTORS)
|
||||
print(CURSOR_OTHER_INFO)
|
||||
|
||||
if __name__ == "__main__":
|
||||
print_logo()
|
||||
48
main.py
48
main.py
@@ -108,6 +108,9 @@ class Translator:
|
||||
0x0404: 'zh_tw', # Traditional Chinese
|
||||
0x0804: 'zh_cn', # Simplified Chinese
|
||||
0x0422: 'vi', # Vietnamese
|
||||
0x0419: 'ru', # Russian
|
||||
0x0415: 'tr', # Turkish
|
||||
0x0402: 'bg', # Bulgarian
|
||||
}
|
||||
|
||||
return language_map.get(layout_id, 'en')
|
||||
@@ -141,9 +144,12 @@ class Translator:
|
||||
return 'fr'
|
||||
elif system_locale.startswith('pt'):
|
||||
return 'pt'
|
||||
|
||||
|
||||
|
||||
elif system_locale.startswith('ru'):
|
||||
return 'ru'
|
||||
elif system_locale.startswith('tr'):
|
||||
return 'tr'
|
||||
elif system_locale.startswith('bg'):
|
||||
return 'bg'
|
||||
# Try to get language from LANG environment variable as fallback
|
||||
env_lang = os.getenv('LANG', '').lower()
|
||||
if 'tw' in env_lang or 'hk' in env_lang:
|
||||
@@ -160,6 +166,12 @@ class Translator:
|
||||
return 'fr'
|
||||
elif 'pt' in env_lang:
|
||||
return 'pt'
|
||||
elif 'ru' in env_lang:
|
||||
return 'ru'
|
||||
elif 'tr' in env_lang:
|
||||
return 'tr'
|
||||
elif 'bg' in env_lang:
|
||||
return 'bg'
|
||||
|
||||
return 'en'
|
||||
except:
|
||||
@@ -234,16 +246,17 @@ def print_menu():
|
||||
print(f"{Fore.YELLOW}{'─' * 40}{Style.RESET_ALL}")
|
||||
print(f"{Fore.GREEN}0{Style.RESET_ALL}. {EMOJI['ERROR']} {translator.get('menu.exit')}")
|
||||
print(f"{Fore.GREEN}1{Style.RESET_ALL}. {EMOJI['RESET']} {translator.get('menu.reset')}")
|
||||
print(f"{Fore.GREEN}2{Style.RESET_ALL}. {EMOJI['SUCCESS']} {translator.get('menu.register')}")
|
||||
print(f"{Fore.GREEN}2{Style.RESET_ALL}. {EMOJI['SUCCESS']} {translator.get('menu.register')} ({Fore.RED}{translator.get('menu.outdate')}{Style.RESET_ALL})")
|
||||
print(f"{Fore.GREEN}3{Style.RESET_ALL}. 🌟 {translator.get('menu.register_google')}")
|
||||
print(f"{Fore.YELLOW} ┗━━ 🔥 {translator.get('menu.lifetime_access_enabled')} 🔥{Style.RESET_ALL}")
|
||||
print(f"{Fore.GREEN}4{Style.RESET_ALL}. ⭐ {translator.get('menu.register_github')}")
|
||||
print(f"{Fore.YELLOW} ┗━━ 🚀 {translator.get('menu.lifetime_access_enabled')} 🚀{Style.RESET_ALL}")
|
||||
print(f"{Fore.GREEN}5{Style.RESET_ALL}. {EMOJI['SUCCESS']} {translator.get('menu.register_manual')}")
|
||||
print(f"{Fore.GREEN}6{Style.RESET_ALL}. {EMOJI['ERROR']} {translator.get('menu.quit')}")
|
||||
print(f"{Fore.GREEN}7{Style.RESET_ALL}. {EMOJI['LANG']} {translator.get('menu.select_language')}")
|
||||
print(f"{Fore.GREEN}8{Style.RESET_ALL}. {EMOJI['UPDATE']} {translator.get('menu.disable_auto_update')}")
|
||||
print(f"{Fore.GREEN}9{Style.RESET_ALL}. {EMOJI['RESET']} {translator.get('menu.totally_reset')}")
|
||||
print(f"{Fore.GREEN}6{Style.RESET_ALL}. {EMOJI['RESET']} {translator.get('menu.temp_github_register')}")
|
||||
print(f"{Fore.GREEN}7{Style.RESET_ALL}. {EMOJI['ERROR']} {translator.get('menu.quit')}")
|
||||
print(f"{Fore.GREEN}8{Style.RESET_ALL}. {EMOJI['LANG']} {translator.get('menu.select_language')}")
|
||||
print(f"{Fore.GREEN}9{Style.RESET_ALL}. {EMOJI['UPDATE']} {translator.get('menu.disable_auto_update')}")
|
||||
print(f"{Fore.GREEN}10{Style.RESET_ALL}. {EMOJI['RESET']} {translator.get('menu.totally_reset')}")
|
||||
print(f"{Fore.YELLOW}{'─' * 40}{Style.RESET_ALL}")
|
||||
|
||||
def select_language():
|
||||
@@ -421,11 +434,11 @@ def check_latest_version():
|
||||
def main():
|
||||
# Check for admin privileges if running as executable on Windows only
|
||||
if platform.system() == 'Windows' and is_frozen() and not is_admin():
|
||||
print(f"{Fore.YELLOW}{EMOJI['ADMIN']} Running as executable, administrator privileges required.{Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['ADMIN']} {translator.get('menu.admin_required')}{Style.RESET_ALL}")
|
||||
if run_as_admin():
|
||||
sys.exit(0) # Exit after requesting admin privileges
|
||||
else:
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} Continuing without administrator privileges.{Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('menu.admin_required_continue')}{Style.RESET_ALL}")
|
||||
|
||||
print_logo()
|
||||
|
||||
@@ -440,7 +453,7 @@ def main():
|
||||
|
||||
while True:
|
||||
try:
|
||||
choice = input(f"\n{EMOJI['ARROW']} {Fore.CYAN}{translator.get('menu.input_choice', choices='0-9')}: {Style.RESET_ALL}")
|
||||
choice = input(f"\n{EMOJI['ARROW']} {Fore.CYAN}{translator.get('menu.input_choice', choices='0-10')}: {Style.RESET_ALL}")
|
||||
|
||||
if choice == "0":
|
||||
print(f"\n{Fore.YELLOW}{EMOJI['INFO']} {translator.get('menu.exit')}...{Style.RESET_ALL}")
|
||||
@@ -467,20 +480,25 @@ def main():
|
||||
cursor_register_manual.main(translator)
|
||||
print_menu()
|
||||
elif choice == "6":
|
||||
import github_cursor_register
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('menu.coming_soon')}{Style.RESET_ALL}")
|
||||
# github_cursor_register.main(translator)
|
||||
print_menu()
|
||||
elif choice == "7":
|
||||
import quit_cursor
|
||||
quit_cursor.quit_cursor(translator)
|
||||
print_menu()
|
||||
elif choice == "7":
|
||||
elif choice == "8":
|
||||
if select_language():
|
||||
print_menu()
|
||||
continue
|
||||
elif choice == "8":
|
||||
elif choice == "9":
|
||||
import disable_auto_update
|
||||
disable_auto_update.run(translator)
|
||||
print_menu()
|
||||
elif choice == "9":
|
||||
elif choice == "10":
|
||||
import totally_reset_cursor
|
||||
totally_reset_cursor.run(translator)
|
||||
totally_reset_cursor.main(translator)
|
||||
print_menu()
|
||||
else:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('menu.invalid_choice')}{Style.RESET_ALL}")
|
||||
|
||||
@@ -12,16 +12,32 @@ from config import get_config
|
||||
# Add global variable at the beginning of the file
|
||||
_translator = None
|
||||
|
||||
# Add global variable to track our Chrome processes
|
||||
_chrome_process_ids = []
|
||||
|
||||
def cleanup_chrome_processes(translator=None):
|
||||
"""Clean all Chrome related processes"""
|
||||
print("\nCleaning Chrome processes...")
|
||||
"""Clean only Chrome processes launched by this script"""
|
||||
global _chrome_process_ids
|
||||
|
||||
if not _chrome_process_ids:
|
||||
print("\nNo Chrome processes to clean...")
|
||||
return
|
||||
|
||||
print("\nCleaning Chrome processes launched by this script...")
|
||||
try:
|
||||
if os.name == 'nt':
|
||||
os.system('taskkill /F /IM chrome.exe /T 2>nul')
|
||||
os.system('taskkill /F /IM chromedriver.exe /T 2>nul')
|
||||
for pid in _chrome_process_ids:
|
||||
try:
|
||||
os.system(f'taskkill /F /PID {pid} /T 2>nul')
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
os.system('pkill -f chrome')
|
||||
os.system('pkill -f chromedriver')
|
||||
for pid in _chrome_process_ids:
|
||||
try:
|
||||
os.kill(pid, signal.SIGTERM)
|
||||
except:
|
||||
pass
|
||||
_chrome_process_ids = [] # Reset the list after cleanup
|
||||
except Exception as e:
|
||||
if translator:
|
||||
print(f"{Fore.RED}❌ {translator.get('register.cleanup_error', error=str(e))}{Style.RESET_ALL}")
|
||||
@@ -164,6 +180,8 @@ def get_random_wait_time(config, timing_type='page_load_wait'):
|
||||
|
||||
def setup_driver(translator=None):
|
||||
"""Setup browser driver"""
|
||||
global _chrome_process_ids
|
||||
|
||||
try:
|
||||
# Get config
|
||||
config = get_config(translator)
|
||||
@@ -211,7 +229,35 @@ def setup_driver(translator=None):
|
||||
else:
|
||||
print("Starting browser...")
|
||||
|
||||
# Record Chrome processes before launching
|
||||
before_pids = []
|
||||
try:
|
||||
import psutil
|
||||
before_pids = [p.pid for p in psutil.process_iter() if 'chrome' in p.name().lower()]
|
||||
except:
|
||||
pass
|
||||
|
||||
# Launch browser
|
||||
page = ChromiumPage(co)
|
||||
|
||||
# Wait a moment for Chrome to fully launch
|
||||
time.sleep(1)
|
||||
|
||||
# Record Chrome processes after launching and find new ones
|
||||
try:
|
||||
import psutil
|
||||
after_pids = [p.pid for p in psutil.process_iter() if 'chrome' in p.name().lower()]
|
||||
# Find new Chrome processes
|
||||
new_pids = [pid for pid in after_pids if pid not in before_pids]
|
||||
_chrome_process_ids.extend(new_pids)
|
||||
|
||||
if _chrome_process_ids:
|
||||
print(f"Tracking {len(_chrome_process_ids)} Chrome processes")
|
||||
else:
|
||||
print(f"{Fore.YELLOW}Warning: No new Chrome processes detected to track{Style.RESET_ALL}")
|
||||
except Exception as e:
|
||||
print(f"Warning: Could not track Chrome processes: {e}")
|
||||
|
||||
return config, page
|
||||
|
||||
except Exception as e:
|
||||
@@ -563,7 +609,9 @@ def handle_sign_in(browser_tab, email, password, translator=None):
|
||||
def main(email=None, password=None, first_name=None, last_name=None, email_tab=None, controller=None, translator=None):
|
||||
"""Main function, can receive account information, email tab, and translator"""
|
||||
global _translator
|
||||
global _chrome_process_ids
|
||||
_translator = translator # Save to global variable
|
||||
_chrome_process_ids = [] # Reset the process IDs list
|
||||
|
||||
signal.signal(signal.SIGINT, signal_handler)
|
||||
signal.signal(signal.SIGTERM, signal_handler)
|
||||
|
||||
@@ -131,45 +131,45 @@ class NewTempEmail:
|
||||
return False
|
||||
|
||||
def create_email(self):
|
||||
"""创建临时邮箱"""
|
||||
"""create temporary email"""
|
||||
try:
|
||||
if self.translator:
|
||||
print(f"{Fore.CYAN}ℹ️ {self.translator.get('email.visiting_site')}{Style.RESET_ALL}")
|
||||
else:
|
||||
print(f"{Fore.CYAN}ℹ️ 正在访问 smailpro.com...{Style.RESET_ALL}")
|
||||
|
||||
# 加载被屏蔽域名列表
|
||||
# load blocked domains list
|
||||
self.blocked_domains = self.get_blocked_domains()
|
||||
|
||||
# 访问网站
|
||||
# visit website
|
||||
self.page.get("https://smailpro.com/")
|
||||
time.sleep(2)
|
||||
|
||||
# 点击创建邮箱按钮
|
||||
# click create email button
|
||||
create_button = self.page.ele('xpath://button[@title="Create temporary email"]')
|
||||
if create_button:
|
||||
create_button.click()
|
||||
time.sleep(1)
|
||||
|
||||
# 点击弹窗中的 Create 按钮
|
||||
# click Create button in popup
|
||||
modal_create_button = self.page.ele('xpath://button[contains(text(), "Create")]')
|
||||
if modal_create_button:
|
||||
modal_create_button.click()
|
||||
time.sleep(2)
|
||||
|
||||
# 获取邮箱地址 - 修改选择器
|
||||
# get email address - modify selector
|
||||
email_div = self.page.ele('xpath://div[@class="text-base sm:text-lg md:text-xl text-gray-700"]')
|
||||
if email_div:
|
||||
email = email_div.text.strip()
|
||||
if '@' in email: # 验证是否是有效的邮箱地址
|
||||
# 检查域名是否被屏蔽
|
||||
if '@' in email: # check if it's a valid email address
|
||||
# check if domain is blocked
|
||||
domain = email.split('@')[1]
|
||||
if self.blocked_domains and domain in self.blocked_domains:
|
||||
if self.translator:
|
||||
print(f"{Fore.YELLOW}⚠️ {self.translator.get('email.domain_blocked')}: {domain}{Style.RESET_ALL}")
|
||||
else:
|
||||
print(f"{Fore.YELLOW}⚠️ 域名已被屏蔽: {domain},尝试重新创建邮箱{Style.RESET_ALL}")
|
||||
# 重新创建邮箱
|
||||
# create email again
|
||||
return self.create_email()
|
||||
|
||||
if self.translator:
|
||||
@@ -191,23 +191,23 @@ class NewTempEmail:
|
||||
return None
|
||||
|
||||
def close(self):
|
||||
"""关闭浏览器"""
|
||||
"""close browser"""
|
||||
if self.page:
|
||||
self.page.quit()
|
||||
|
||||
def refresh_inbox(self):
|
||||
"""刷新邮箱"""
|
||||
"""refresh inbox"""
|
||||
try:
|
||||
if self.translator:
|
||||
print(f"{Fore.CYAN}🔄 {self.translator.get('email.refreshing')}{Style.RESET_ALL}")
|
||||
else:
|
||||
print(f"{Fore.CYAN}🔄 正在刷新邮箱...{Style.RESET_ALL}")
|
||||
|
||||
# 点击刷新按钮
|
||||
# click refresh button
|
||||
refresh_button = self.page.ele('xpath://button[@id="refresh"]')
|
||||
if refresh_button:
|
||||
refresh_button.click()
|
||||
time.sleep(2) # 等待刷新完成
|
||||
time.sleep(2) # wait for refresh to complete
|
||||
if self.translator:
|
||||
print(f"{Fore.GREEN}✅ {self.translator.get('email.refresh_success')}{Style.RESET_ALL}")
|
||||
else:
|
||||
@@ -230,16 +230,16 @@ class NewTempEmail:
|
||||
def check_for_cursor_email(self):
|
||||
"""检查是否有 Cursor 的验证邮件"""
|
||||
try:
|
||||
# 查找验证邮件 - 使用更精确的选择器
|
||||
# find verification email - use more accurate selector
|
||||
email_div = self.page.ele('xpath://div[contains(@class, "p-2") and contains(@class, "cursor-pointer") and contains(@class, "bg-white") and contains(@class, "shadow") and .//b[text()="no-reply@cursor.sh"] and .//span[text()="Verify your email address"]]')
|
||||
if email_div:
|
||||
if self.translator:
|
||||
print(f"{Fore.GREEN}✅ {self.translator.get('email.verification_found')}{Style.RESET_ALL}")
|
||||
else:
|
||||
print(f"{Fore.GREEN}✅ 找到验证邮件{Style.RESET_ALL}")
|
||||
# 使用 JavaScript 点击元素
|
||||
# use JavaScript to click element
|
||||
self.page.run_js('arguments[0].click()', email_div)
|
||||
time.sleep(2) # 等待邮件内容加载
|
||||
time.sleep(2) # wait for email content to load
|
||||
return True
|
||||
if self.translator:
|
||||
print(f"{Fore.YELLOW}⚠️ {self.translator.get('email.verification_not_found')}{Style.RESET_ALL}")
|
||||
@@ -257,7 +257,7 @@ class NewTempEmail:
|
||||
def get_verification_code(self):
|
||||
"""获取验证码"""
|
||||
try:
|
||||
# 查找验证码元素
|
||||
# find verification code element
|
||||
code_element = self.page.ele('xpath://td//div[contains(@style, "font-size:28px") and contains(@style, "letter-spacing:2px")]')
|
||||
if code_element:
|
||||
code = code_element.text.strip()
|
||||
@@ -291,7 +291,7 @@ def main(translator=None):
|
||||
else:
|
||||
print(f"\n{Fore.CYAN}📧 临时邮箱地址: {email}{Style.RESET_ALL}")
|
||||
|
||||
# 测试刷新功能
|
||||
# test refresh function
|
||||
while True:
|
||||
if translator:
|
||||
choice = input(f"\n{translator.get('email.refresh_prompt')}: ").lower()
|
||||
|
||||
@@ -5,4 +5,6 @@ requests
|
||||
psutil>=5.8.0
|
||||
pywin32; platform_system == "Windows"
|
||||
pyinstaller
|
||||
DrissionPage>=4.0.0
|
||||
DrissionPage>=4.0.0
|
||||
selenium
|
||||
webdriver_manager
|
||||
|
||||
@@ -96,7 +96,7 @@ def get_cursor_machine_id_path(translator=None) -> str:
|
||||
if not config.has_section('LinuxPaths'):
|
||||
config.add_section('LinuxPaths')
|
||||
config.set('LinuxPaths', 'machine_id_path',
|
||||
os.path.expanduser("~/.config/Cursor/machineId"))
|
||||
os.path.expanduser("~/.config/cursor/machineid"))
|
||||
return config.get('LinuxPaths', 'machine_id_path')
|
||||
|
||||
elif sys.platform == "darwin": # macOS
|
||||
@@ -451,11 +451,11 @@ class MachineIDResetter:
|
||||
|
||||
config.set('LinuxPaths', 'storage_path', os.path.abspath(os.path.join(
|
||||
actual_home,
|
||||
".config/Cursor/User/globalStorage/storage.json"
|
||||
".config/cursor/User/globalStorage/storage.json"
|
||||
)))
|
||||
config.set('LinuxPaths', 'sqlite_path', os.path.abspath(os.path.join(
|
||||
actual_home,
|
||||
".config/Cursor/User/globalStorage/state.vscdb"
|
||||
".config/cursor/User/globalStorage/state.vscdb"
|
||||
)))
|
||||
|
||||
self.db_path = config.get('LinuxPaths', 'storage_path')
|
||||
|
||||
@@ -2,508 +2,195 @@ import os
|
||||
import shutil
|
||||
import platform
|
||||
import time
|
||||
import sys
|
||||
import glob
|
||||
import json
|
||||
import uuid
|
||||
import random
|
||||
import string
|
||||
import re
|
||||
from datetime import datetime
|
||||
import subprocess
|
||||
from colorama import Fore, Style, init
|
||||
from main import translator
|
||||
from main import EMOJI
|
||||
|
||||
# Initialize colorama
|
||||
init()
|
||||
|
||||
# Define emoji and color constants
|
||||
EMOJI = {
|
||||
"FILE": "📄",
|
||||
"BACKUP": "💾",
|
||||
"SUCCESS": "✅",
|
||||
"ERROR": "❌",
|
||||
"INFO": "ℹ️",
|
||||
"RESET": "🔄",
|
||||
"MENU": "📋",
|
||||
"ARROW": "➜",
|
||||
"LANG": "🌐",
|
||||
"UPDATE": "🔄",
|
||||
"ADMIN": "🔐",
|
||||
"STOP": "🛑",
|
||||
"DISCLAIMER": "⚠️",
|
||||
"WARNING": "⚠️"
|
||||
}
|
||||
|
||||
def display_banner():
|
||||
"""Displays a stylized banner for the tool."""
|
||||
print(f"\n{Fore.CYAN}{'='*50}{Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN}{EMOJI['STOP']} {translator.get('totally_reset.title')} {Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN}{'='*50}{Style.RESET_ALL}")
|
||||
|
||||
def display_features():
|
||||
"""Displays the features of the Cursor AI Reset Tool."""
|
||||
print(f"\n{Fore.CYAN}{EMOJI['MENU']} {translator.get('totally_reset.feature_title')}{Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.feature_1')} {Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.feature_2')} {Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.feature_3')} {Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.feature_4')} {Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.feature_5')} {Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.feature_6')} {Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.feature_7')} {Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.feature_8')} {Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.feature_9')} {Style.RESET_ALL}\n")
|
||||
|
||||
def display_disclaimer():
|
||||
"""Displays a disclaimer for the user."""
|
||||
print(f"\n{Fore.RED}{EMOJI['DISCLAIMER']} {translator.get('totally_reset.disclaimer_title')}{Style.RESET_ALL}")
|
||||
print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.disclaimer_1')} {Style.RESET_ALL}")
|
||||
print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.disclaimer_2')} {Style.RESET_ALL}")
|
||||
print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.disclaimer_3')} {Style.RESET_ALL}")
|
||||
print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.disclaimer_4')} {Style.RESET_ALL}")
|
||||
print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.disclaimer_5')} {Style.RESET_ALL}")
|
||||
print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.disclaimer_6')} {Style.RESET_ALL}")
|
||||
print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.disclaimer_7')} {Style.RESET_ALL} \n")
|
||||
|
||||
def get_confirmation():
|
||||
"""Gets confirmation from the user to proceed."""
|
||||
while True:
|
||||
choice = input(f"{Fore.RED}{EMOJI['WARNING']} {translator.get('totally_reset.confirm_title')} (Y/n): ").strip().lower()
|
||||
if choice == "y" or choice == "":
|
||||
return True
|
||||
elif choice == "n":
|
||||
return False
|
||||
else:
|
||||
print(f"{EMOJI['ERROR']} {translator.get('totally_reset.invalid_choice')}")
|
||||
|
||||
def remove_dir(path):
|
||||
"""Removes a directory if it exists and logs the action."""
|
||||
# Safety check to ensure we're only deleting Cursor-related directories
|
||||
if not is_cursor_related(path):
|
||||
print(f"{Fore.RED}{EMOJI['WARNING']} {translator.get('totally_reset.skipped_for_safety', path=path)} {Style.RESET_ALL}")
|
||||
return
|
||||
|
||||
def delete_directory(path, translator=None):
|
||||
"""Deletes a directory and all its contents."""
|
||||
if os.path.exists(path):
|
||||
try:
|
||||
shutil.rmtree(path, ignore_errors=True)
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('totally_reset.deleted', path=path)} {Style.RESET_ALL}")
|
||||
shutil.rmtree(path)
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('totally_reset.removed', path=path)}{Style.RESET_ALL}")
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('totally_reset.error_deleting', path=path, error=str(e))} {Style.RESET_ALL}")
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('totally_reset.failed_to_remove', path=path, error=e)}{Style.RESET_ALL}")
|
||||
else:
|
||||
print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.not_found', path=path)} {Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('totally_reset.not_found', path=path)}{Style.RESET_ALL}")
|
||||
|
||||
def remove_file(path):
|
||||
"""Removes a file if it exists and logs the action."""
|
||||
# Safety check to ensure we're only deleting Cursor-related files
|
||||
if not is_cursor_related(path):
|
||||
print(f"{Fore.RED}{EMOJI['WARNING']} {translator.get('totally_reset.skipped_for_safety', path=path)} {Style.RESET_ALL}")
|
||||
return
|
||||
|
||||
def delete_file(path, translator=None):
|
||||
"""Deletes a file if it exists."""
|
||||
if os.path.isfile(path):
|
||||
try:
|
||||
os.remove(path)
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('totally_reset.deleted', path=path)} {Style.RESET_ALL}")
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('totally_reset.removed', path=path)}{Style.RESET_ALL}")
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('totally_reset.error_deleting', path=path, error=str(e))} {Style.RESET_ALL}")
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('totally_reset.failed_to_remove', path=path, error=e)}{Style.RESET_ALL}")
|
||||
else:
|
||||
print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.not_found', path=path)} {Style.RESET_ALL}")
|
||||
print(f"{Fore.YELLOW}{EMOJI['INFO']} {translator.get('totally_reset.not_found', path=path)}{Style.RESET_ALL}")
|
||||
|
||||
def is_cursor_related(path):
|
||||
"""
|
||||
Safety function to verify a path is related to Cursor before deletion.
|
||||
Returns True if the path appears to be related to Cursor AI.
|
||||
"""
|
||||
# Skip .vscode check as it's shared with VS Code
|
||||
if path.endswith(".vscode"):
|
||||
return False
|
||||
|
||||
# Check if path contains cursor-related terms
|
||||
cursor_terms = ["cursor", "cursorai", "cursor-electron"]
|
||||
|
||||
# Convert path to lowercase for case-insensitive matching
|
||||
lower_path = path.lower()
|
||||
|
||||
# Return True if any cursor term is present in the path
|
||||
for term in cursor_terms:
|
||||
if term in lower_path:
|
||||
return True
|
||||
|
||||
# Check specific known Cursor file patterns
|
||||
cursor_patterns = [
|
||||
r"\.cursor_.*$",
|
||||
r"cursor-.*\.json$",
|
||||
r"cursor_.*\.json$",
|
||||
r"cursor-machine-id$",
|
||||
r"trial_info\.json$",
|
||||
r"license\.json$"
|
||||
]
|
||||
|
||||
for pattern in cursor_patterns:
|
||||
if re.search(pattern, lower_path):
|
||||
return True
|
||||
|
||||
# If it's a specific file that we know is only for Cursor
|
||||
if os.path.basename(lower_path) in [
|
||||
"cursor_trial_data",
|
||||
"cursor-state.json",
|
||||
"cursor-machine-id",
|
||||
"ai-settings.json",
|
||||
"cursor.desktop"
|
||||
]:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def find_cursor_license_files(base_path, pattern):
|
||||
"""Finds files matching a pattern that might contain license information."""
|
||||
try:
|
||||
matches = []
|
||||
for root, dirnames, filenames in os.walk(base_path):
|
||||
for filename in filenames:
|
||||
# Check if filename matches any pattern before adding to matches
|
||||
if any(p.lower() in filename.lower() for p in pattern):
|
||||
full_path = os.path.join(root, filename)
|
||||
# Extra safety check to ensure it's cursor-related
|
||||
if is_cursor_related(full_path):
|
||||
matches.append(full_path)
|
||||
return matches
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.error_searching', path=base_path, error=str(e))} {Style.RESET_ALL}")
|
||||
return []
|
||||
|
||||
def generate_new_machine_id():
|
||||
"""Generates a new random machine ID."""
|
||||
return str(uuid.uuid4())
|
||||
|
||||
def create_fake_machine_id(path):
|
||||
"""Creates a new machine ID file with random ID."""
|
||||
if not is_cursor_related(path):
|
||||
return
|
||||
|
||||
try:
|
||||
new_id = generate_new_machine_id()
|
||||
directory = os.path.dirname(path)
|
||||
|
||||
# Ensure directory exists
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
|
||||
with open(path, 'w') as f:
|
||||
f.write(new_id)
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('totally_reset.created_machine_id', path=path)} {Style.RESET_ALL}")
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('totally_reset.error_creating_machine_id', path=path, error=str(e))} {Style.RESET_ALL}")
|
||||
|
||||
def reset_machine_id(system, home):
|
||||
"""Resets machine ID in all possible locations."""
|
||||
print(f"\n{Fore.CYAN}{EMOJI['RESET']} {translator.get('totally_reset.resetting_machine_id')} {Style.RESET_ALL}")
|
||||
|
||||
# Common machine ID locations based on OS
|
||||
if system == "Windows":
|
||||
machine_id_paths = [
|
||||
os.path.join(home, "AppData", "Roaming", "Cursor", "cursor-machine-id"),
|
||||
os.path.join(home, "AppData", "Local", "Cursor", "cursor-machine-id"),
|
||||
os.path.join(home, "AppData", "Roaming", "cursor-electron", "cursor-machine-id"),
|
||||
os.path.join(home, "AppData", "Local", "cursor-electron", "cursor-machine-id"),
|
||||
os.path.join(home, ".cursor-machine-id"),
|
||||
]
|
||||
elif system == "Darwin": # macOS
|
||||
machine_id_paths = [
|
||||
os.path.join(home, "Library", "Application Support", "Cursor", "cursor-machine-id"),
|
||||
os.path.join(home, "Library", "Application Support", "cursor-electron", "cursor-machine-id"),
|
||||
os.path.join(home, ".cursor-machine-id"),
|
||||
]
|
||||
elif system == "Linux":
|
||||
machine_id_paths = [
|
||||
os.path.join(home, ".config", "Cursor", "cursor-machine-id"),
|
||||
os.path.join(home, ".config", "cursor-electron", "cursor-machine-id"),
|
||||
os.path.join(home, ".cursor-machine-id"),
|
||||
]
|
||||
|
||||
# First remove existing machine IDs
|
||||
for path in machine_id_paths:
|
||||
remove_file(path)
|
||||
|
||||
# Then create new randomized IDs
|
||||
for path in machine_id_paths:
|
||||
create_fake_machine_id(path)
|
||||
|
||||
# Try to reset system machine ID if possible (with appropriate permissions)
|
||||
if system == "Windows":
|
||||
def reset_machine_id(translator=None):
|
||||
"""Resets the machine ID to a new UUID."""
|
||||
new_id = str(uuid.uuid4())
|
||||
if platform.system() == "Windows":
|
||||
try:
|
||||
# Windows: Create a temporary VBS script to reset machine GUID
|
||||
print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.note_complete_machine_id_reset_may_require_running_as_administrator')} {Style.RESET_ALL}")
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.windows_machine_id_modification_skipped', error=str(e))} {Style.RESET_ALL}")
|
||||
|
||||
elif system == "Linux":
|
||||
try:
|
||||
# Linux: Create a random machine-id in /etc/ (needs sudo)
|
||||
print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.note_complete_system_machine_id_reset_may_require_sudo_privileges')} {Style.RESET_ALL}")
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.linux_machine_id_modification_skipped', error=str(e))} {Style.RESET_ALL}")
|
||||
|
||||
def create_fake_trial_info(path, system, home):
|
||||
"""Creates fake trial information to extend trial period."""
|
||||
if not is_cursor_related(path):
|
||||
return
|
||||
|
||||
try:
|
||||
# Generate future expiry date (90 days from now)
|
||||
future_date = (datetime.now().timestamp() + (90 * 24 * 60 * 60)) * 1000 # milliseconds
|
||||
|
||||
# Create fake trial info
|
||||
fake_trial = {
|
||||
"trialStartTimestamp": datetime.now().timestamp() * 1000,
|
||||
"trialEndTimestamp": future_date,
|
||||
"hasUsedTrial": False,
|
||||
"machineId": generate_new_machine_id()
|
||||
}
|
||||
|
||||
directory = os.path.dirname(path)
|
||||
|
||||
# Ensure directory exists
|
||||
if not os.path.exists(directory):
|
||||
os.makedirs(directory)
|
||||
|
||||
with open(path, 'w') as f:
|
||||
json.dump(fake_trial, f)
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('totally_reset.created_extended_trial_info', path=path)} {Style.RESET_ALL}")
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('totally_reset.error_creating_trial_info', path=path, error=str(e))} {Style.RESET_ALL}")
|
||||
|
||||
def reset_cursor():
|
||||
"""Completely resets Cursor AI by removing all settings, caches, and extensions."""
|
||||
system = platform.system()
|
||||
home = os.path.expanduser("~")
|
||||
|
||||
display_banner()
|
||||
display_features()
|
||||
display_disclaimer()
|
||||
|
||||
if not get_confirmation():
|
||||
print(f"\n{Fore.CYAN}{EMOJI['STOP']} {translator.get('totally_reset.reset_cancelled')} {Style.RESET_ALL}")
|
||||
return
|
||||
|
||||
print(f"\n{Fore.CYAN}{EMOJI['RESET']} {translator.get('totally_reset.resetting_cursor_ai_editor')} {Style.RESET_ALL}")
|
||||
|
||||
# Define paths based on OS
|
||||
if system == "Windows":
|
||||
cursor_paths = [
|
||||
os.path.join(home, "AppData", "Roaming", "Cursor"),
|
||||
os.path.join(home, "AppData", "Local", "Cursor"),
|
||||
os.path.join(home, "AppData", "Roaming", "cursor-electron"),
|
||||
os.path.join(home, "AppData", "Local", "cursor-electron"),
|
||||
os.path.join(home, "AppData", "Local", "CursorAI"),
|
||||
os.path.join(home, "AppData", "Roaming", "CursorAI"),
|
||||
# os.path.join(home, ".vscode"), # Removed to avoid affecting VS Code
|
||||
os.path.join(home, "AppData", "Local", "Temp", "Cursor"), # Temporary data
|
||||
os.path.join(home, "AppData", "Local", "Temp", "cursor-updater"),
|
||||
os.path.join(home, "AppData", "Local", "Programs", "cursor"),
|
||||
]
|
||||
|
||||
# Additional locations for license/trial files on Windows
|
||||
license_search_paths = [
|
||||
os.path.join(home, "AppData", "Roaming"),
|
||||
os.path.join(home, "AppData", "Local"),
|
||||
os.path.join(home, "AppData", "LocalLow"),
|
||||
]
|
||||
|
||||
# Registry instructions for Windows
|
||||
print(f"\n{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.windows_registry_instructions')} {Style.RESET_ALL}")
|
||||
print(f"{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.windows_registry_instructions_2')} {Style.RESET_ALL}")
|
||||
|
||||
elif system == "Darwin": # macOS
|
||||
cursor_paths = [
|
||||
os.path.join(home, "Library", "Application Support", "Cursor"),
|
||||
os.path.join(home, "Library", "Application Support", "cursor-electron"),
|
||||
os.path.join(home, "Library", "Caches", "Cursor"),
|
||||
os.path.join(home, "Library", "Caches", "cursor-electron"),
|
||||
os.path.join(home, "Library", "Preferences", "Cursor"),
|
||||
os.path.join(home, "Library", "Preferences", "cursor-electron"),
|
||||
os.path.join(home, "Library", "Saved Application State", "com.cursor.Cursor.savedState"),
|
||||
os.path.join(home, "Library", "HTTPStorages", "com.cursor.Cursor"),
|
||||
os.path.join(home, "Library", "WebKit", "com.cursor.Cursor"),
|
||||
# os.path.join(home, ".vscode"), # Removed to avoid affecting VS Code
|
||||
"/Applications/Cursor.app", # Main application location
|
||||
]
|
||||
|
||||
# Additional locations for license/trial files on macOS
|
||||
license_search_paths = [
|
||||
os.path.join(home, "Library", "Application Support"),
|
||||
os.path.join(home, "Library", "Preferences"),
|
||||
os.path.join(home, "Library", "Caches"),
|
||||
]
|
||||
|
||||
elif system == "Linux":
|
||||
cursor_paths = [
|
||||
os.path.join(home, ".config", "Cursor"),
|
||||
os.path.join(home, ".config", "cursor-electron"),
|
||||
os.path.join(home, ".cache", "Cursor"),
|
||||
os.path.join(home, ".cache", "cursor-electron"),
|
||||
os.path.join(home, ".local", "share", "Cursor"),
|
||||
os.path.join(home, ".local", "share", "cursor-electron"),
|
||||
# os.path.join(home, ".vscode"), # Removed to avoid affecting VS Code
|
||||
os.path.join(home, ".local", "share", "applications", "cursor.desktop"),
|
||||
os.path.join("/usr", "share", "applications", "cursor.desktop"),
|
||||
os.path.join("/opt", "Cursor"),
|
||||
]
|
||||
|
||||
# Additional locations for license/trial files on Linux
|
||||
license_search_paths = [
|
||||
os.path.join(home, ".config"),
|
||||
os.path.join(home, ".local", "share"),
|
||||
os.path.join(home, ".cache"),
|
||||
]
|
||||
|
||||
subprocess.run(
|
||||
["reg", "add", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography", "/v", "MachineGuid", "/d", new_id, "/f"],
|
||||
check=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE
|
||||
)
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('totally_reset.machine_guid_reset', new_id=new_id)}{Style.RESET_ALL}")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('totally_reset.failed_to_reset_machine_guid', error=e)}{Style.RESET_ALL}")
|
||||
elif platform.system() == "Linux":
|
||||
machine_id_paths = ["/etc/machine-id", "/var/lib/dbus/machine-id"]
|
||||
for path in machine_id_paths:
|
||||
if os.path.exists(path):
|
||||
try:
|
||||
with open(path, 'w') as f:
|
||||
f.write(new_id)
|
||||
print(f"{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('totally_reset.machine_id_reset', path=path)}{Style.RESET_ALL}")
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('totally_reset.failed_to_reset_machine_id', path=path, error=e)}{Style.RESET_ALL}")
|
||||
elif platform.system() == "Darwin": # macOS
|
||||
print("ℹ️ macOS does not use a machine-id file. Skipping machine ID reset.")
|
||||
else:
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('totally_reset.unsupported_os')} {Style.RESET_ALL}")
|
||||
return
|
||||
print(f"{Fore.RED}{EMOJI['ERROR']} {translator.get('totally_reset.unsupported_os')}{Style.RESET_ALL}")
|
||||
|
||||
# Remove main Cursor directories
|
||||
print(f"\n{Fore.CYAN}{EMOJI['RESET']} {translator.get('totally_reset.removing_main_cursor_directories_and_files')} {Style.RESET_ALL}")
|
||||
for path in cursor_paths:
|
||||
remove_dir(path)
|
||||
def display_features_and_warnings(translator=None):
|
||||
"""Displays features and warnings before proceeding."""
|
||||
print(f"\n{Fore.GREEN}{EMOJI['MENU']} {translator.get('totally_reset.title')}")
|
||||
print("=====================================")
|
||||
print(f"{translator.get('totally_reset.feature_title')}")
|
||||
print(f"{Fore.GREEN}{translator.get('totally_reset.feature_1')}")
|
||||
print(f"{Fore.GREEN}{translator.get('totally_reset.feature_2')}")
|
||||
print(f"{Fore.GREEN}{translator.get('totally_reset.feature_3')}")
|
||||
print(f"{Fore.GREEN}{translator.get('totally_reset.feature_4')}")
|
||||
print(f"{Fore.GREEN}{translator.get('totally_reset.feature_5')}")
|
||||
print(f"{Fore.GREEN}{translator.get('totally_reset.feature_6')}")
|
||||
print(f"{Fore.GREEN}{translator.get('totally_reset.feature_7')}")
|
||||
print(f"{Fore.GREEN}{translator.get('totally_reset.feature_8')}")
|
||||
print(f"{Fore.GREEN}{translator.get('totally_reset.feature_9')}")
|
||||
print(f"\n{Fore.YELLOW}{EMOJI['WARNING']} {translator.get('totally_reset.warning_title')}")
|
||||
print(f"{Fore.YELLOW}{translator.get('totally_reset.warning_1')}")
|
||||
print(f"{Fore.YELLOW}{translator.get('totally_reset.warning_2')}")
|
||||
print(f"{Fore.YELLOW}{translator.get('totally_reset.warning_3')}")
|
||||
print(f"{Fore.YELLOW}{translator.get('totally_reset.warning_4')}")
|
||||
print(f"{Fore.YELLOW}{translator.get('totally_reset.warning_5')}")
|
||||
print(f"{Fore.YELLOW}{translator.get('totally_reset.warning_6')}")
|
||||
print(f"{Fore.YELLOW}{translator.get('totally_reset.warning_7')}")
|
||||
print("=====================================\n")
|
||||
|
||||
# Reset machine identifiers (this creates new ones)
|
||||
reset_machine_id(system, home)
|
||||
def get_user_confirmation(translator=None):
|
||||
"""Prompts the user for confirmation to proceed."""
|
||||
while True:
|
||||
response = input(f"{Fore.YELLOW} {translator.get('totally_reset.confirm_title')} {translator.get('totally_reset.invalid_choice')}: ").lower().strip()
|
||||
if response in ['yes', 'y']:
|
||||
return True
|
||||
elif response in ['no', 'n']:
|
||||
return False
|
||||
else:
|
||||
print(f"{Fore.RED}{translator.get('totally_reset.invalid_choice')}{Style.RESET_ALL}")
|
||||
|
||||
# Known trial/license file patterns
|
||||
file_patterns = [
|
||||
".cursor_trial_data",
|
||||
"trial_info.json",
|
||||
"license.json",
|
||||
"cursor-license",
|
||||
"cursor_license",
|
||||
"cursor-auth",
|
||||
"cursor_auth",
|
||||
"cursor_subscription",
|
||||
"cursor-subscription",
|
||||
"cursor-state",
|
||||
"cursorstate",
|
||||
"cursorsettings",
|
||||
"cursor-settings",
|
||||
"ai-settings.json",
|
||||
"cursor-machine-id",
|
||||
"cursor_machine_id",
|
||||
"cursor-storage"
|
||||
def reset_cursor(translator=None):
|
||||
print(f"\n{Fore.GREEN}{EMOJI['RESET']} {translator.get('totally_reset.resetting_cursor')}\n")
|
||||
|
||||
# Platform-specific paths
|
||||
paths = []
|
||||
if platform.system() == "Linux":
|
||||
paths = [
|
||||
os.path.expanduser("~/.cursor"),
|
||||
os.path.expanduser("~/.local/share/cursor"),
|
||||
os.path.expanduser("~/.config/cursor"),
|
||||
os.path.expanduser("~/.cache/cursor"),
|
||||
"/usr/local/bin/cursor",
|
||||
"/opt/cursor",
|
||||
"/usr/bin/cursor",
|
||||
os.path.expanduser("~/.cursor/machine-id.db"),
|
||||
os.path.expanduser("~/.local/share/Cursor"),
|
||||
os.path.expanduser("~/.config/Cursor"),
|
||||
os.path.expanduser("~/.cache/Cursor")
|
||||
]
|
||||
elif platform.system() == "Darwin": # macOS
|
||||
paths = [
|
||||
os.path.expanduser("~/Library/Application Support/Cursor"),
|
||||
os.path.expanduser("~/Library/Caches/Cursor"),
|
||||
"/Applications/Cursor.app",
|
||||
os.path.expanduser("~/Library/Preferences/com.cursor.app.plist"),
|
||||
]
|
||||
elif platform.system() == "Windows":
|
||||
paths = [
|
||||
os.path.expanduser("~\\AppData\\Local\\Cursor"),
|
||||
os.path.expanduser("~\\AppData\\Roaming\\Cursor"),
|
||||
os.path.expanduser("~\\.cursor"),
|
||||
os.path.expanduser("~\\.config\\Cursor"),
|
||||
os.path.expanduser("~\\.cache\\Cursor"),
|
||||
"C:\\Program Files\\Cursor",
|
||||
"C:\\Program Files (x86)\\Cursor",
|
||||
"C:\\Users\\%USERNAME%\\AppData\\Local\\Cursor",
|
||||
"C:\\Users\\%USERNAME%\\AppData\\Roaming\\Cursor",
|
||||
]
|
||||
|
||||
# Remove directories
|
||||
for path in paths:
|
||||
delete_directory(path, translator)
|
||||
|
||||
# Remove common files related to Cursor
|
||||
files = [
|
||||
os.path.expanduser("~/.cursor/machine-id.db"),
|
||||
os.path.expanduser("~/.local/share/cursor.db"),
|
||||
os.path.expanduser("~/.config/cursor/preferences.json"),
|
||||
os.path.expanduser("~/.cache/cursor.log"),
|
||||
]
|
||||
|
||||
# Direct known trial file paths
|
||||
cursor_trial_files = [
|
||||
os.path.join(home, ".cursor_trial_data"),
|
||||
os.path.join(home, ".cursor_license"),
|
||||
os.path.join(home, ".cursor-machine-id"),
|
||||
os.path.join(home, ".cursor-state.json"),
|
||||
]
|
||||
for file in files:
|
||||
delete_file(file, translator)
|
||||
|
||||
# OS-specific known trial/license files
|
||||
if system == "Windows":
|
||||
cursor_trial_files.extend([
|
||||
os.path.join(home, "AppData", "Local", "Cursor", "trial_info.json"),
|
||||
os.path.join(home, "AppData", "Local", "Cursor", "license.json"),
|
||||
os.path.join(home, "AppData", "Roaming", "Cursor", "trial_info.json"),
|
||||
os.path.join(home, "AppData", "Roaming", "Cursor", "license.json"),
|
||||
os.path.join(home, "AppData", "Roaming", "Cursor", "cursor-machine-id"),
|
||||
os.path.join(home, "AppData", "Local", "Cursor", "cursor-machine-id"),
|
||||
os.path.join(home, "AppData", "Local", "Cursor", "ai-settings.json"),
|
||||
os.path.join(home, "AppData", "Roaming", "Cursor", "ai-settings.json"),
|
||||
])
|
||||
elif system == "Darwin": # macOS
|
||||
cursor_trial_files.extend([
|
||||
os.path.join(home, "Library", "Application Support", "Cursor", "trial_info.json"),
|
||||
os.path.join(home, "Library", "Application Support", "Cursor", "license.json"),
|
||||
os.path.join(home, "Library", "Preferences", "Cursor", "trial_info.json"),
|
||||
os.path.join(home, "Library", "Preferences", "Cursor", "license.json"),
|
||||
os.path.join(home, "Library", "Application Support", "Cursor", "cursor-machine-id"),
|
||||
os.path.join(home, "Library", "Application Support", "Cursor", "ai-settings.json"),
|
||||
])
|
||||
elif system == "Linux":
|
||||
cursor_trial_files.extend([
|
||||
os.path.join(home, ".config", "Cursor", "trial_info.json"),
|
||||
os.path.join(home, ".config", "Cursor", "license.json"),
|
||||
os.path.join(home, ".local", "share", "Cursor", "trial_info.json"),
|
||||
os.path.join(home, ".local", "share", "Cursor", "license.json"),
|
||||
os.path.join(home, ".config", "Cursor", "cursor-machine-id"),
|
||||
os.path.join(home, ".config", "Cursor", "ai-settings.json"),
|
||||
])
|
||||
# Extra cleanup (wildcard search)
|
||||
print(f"\n{Fore.YELLOW}{EMOJI['INFO']} {translator.get('totally_reset.deep_scanning')}")
|
||||
base_dirs = ["/tmp", "/var/tmp", os.path.expanduser("~")] # Linux and macOS
|
||||
if platform.system() == "Windows":
|
||||
base_dirs = ["C:\\Temp", "C:\\Windows\\Temp", os.path.expanduser("~")] # Windows
|
||||
|
||||
# Remove known trial/license files
|
||||
print(f"\n{Fore.CYAN}{EMOJI['RESET']} {translator.get('totally_reset.removing_known')} {Style.RESET_ALL}")
|
||||
for path in cursor_trial_files:
|
||||
remove_file(path)
|
||||
for base in base_dirs:
|
||||
for root, dirs, files in os.walk(base):
|
||||
for dir in dirs:
|
||||
if "cursor" in dir.lower():
|
||||
delete_directory(os.path.join(root, dir), translator)
|
||||
for file in files:
|
||||
if "cursor" in file.lower():
|
||||
delete_file(os.path.join(root, file), translator)
|
||||
|
||||
# Deep search for additional trial/license files
|
||||
print(f"\n{Fore.CYAN}{EMOJI['RESET']} {translator.get('totally_reset.performing_deep_scan')} {Style.RESET_ALL}")
|
||||
all_found_files = []
|
||||
for base_path in license_search_paths:
|
||||
if os.path.exists(base_path):
|
||||
found_files = find_cursor_license_files(base_path, file_patterns)
|
||||
all_found_files.extend(found_files)
|
||||
# Reset machine ID
|
||||
reset_machine_id(translator)
|
||||
|
||||
print(f"\n{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('totally_reset.cursor_reset_completed')}")
|
||||
|
||||
def main(translator=None):
|
||||
start_time = time.time()
|
||||
|
||||
if all_found_files:
|
||||
print(f"\n🔎 {translator.get('totally_reset.found_additional_potential_license_trial_files', count=len(all_found_files))}\n")
|
||||
for file_path in all_found_files:
|
||||
remove_file(file_path)
|
||||
# Display features and warnings
|
||||
display_features_and_warnings(translator)
|
||||
|
||||
# Get user confirmation
|
||||
if get_user_confirmation(translator):
|
||||
reset_cursor(translator)
|
||||
end_time = time.time()
|
||||
print(f"\n{Fore.GREEN}⏱️ {translator.get('totally_reset.completed_in', time=f'{end_time - start_time:.2f} seconds')}{Style.RESET_ALL}")
|
||||
else:
|
||||
print(f"\n{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.no_additional_license_trial_files_found_in_deep_scan')} {Style.RESET_ALL}")
|
||||
print(f"\n{Fore.RED}❌ {translator.get('totally_reset.operation_cancelled')}{Style.RESET_ALL}")
|
||||
|
||||
# Check for and remove localStorage files that might contain settings
|
||||
print(f"\n{Fore.CYAN}{EMOJI['RESET']} {translator.get('totally_reset.checking_for_electron_localstorage_files')} {Style.RESET_ALL}")
|
||||
if system == "Windows":
|
||||
local_storage_paths = glob.glob(os.path.join(home, "AppData", "Roaming", "*cursor*", "Local Storage", "leveldb", "*"))
|
||||
local_storage_paths += glob.glob(os.path.join(home, "AppData", "Local", "*cursor*", "Local Storage", "leveldb", "*"))
|
||||
elif system == "Darwin":
|
||||
local_storage_paths = glob.glob(os.path.join(home, "Library", "Application Support", "*cursor*", "Local Storage", "leveldb", "*"))
|
||||
elif system == "Linux":
|
||||
local_storage_paths = glob.glob(os.path.join(home, ".config", "*cursor*", "Local Storage", "leveldb", "*"))
|
||||
|
||||
for path in local_storage_paths:
|
||||
if is_cursor_related(path):
|
||||
remove_file(path)
|
||||
|
||||
# Create new trial files with extended expiration
|
||||
print(f"\n{Fore.CYAN}{EMOJI['RESET']} {translator.get('totally_reset.creating_new_trial_information_with_extended_period')} {Style.RESET_ALL}")
|
||||
if system == "Windows":
|
||||
create_fake_trial_info(os.path.join(home, "AppData", "Local", "Cursor", "trial_info.json"), system, home)
|
||||
create_fake_trial_info(os.path.join(home, "AppData", "Roaming", "Cursor", "trial_info.json"), system, home)
|
||||
elif system == "Darwin":
|
||||
create_fake_trial_info(os.path.join(home, "Library", "Application Support", "Cursor", "trial_info.json"), system, home)
|
||||
elif system == "Linux":
|
||||
create_fake_trial_info(os.path.join(home, ".config", "Cursor", "trial_info.json"), system, home)
|
||||
|
||||
print(f"\n{Fore.GREEN}{EMOJI['SUCCESS']} {translator.get('totally_reset.reset_log_1')}")
|
||||
print(f" {translator.get('totally_reset.reset_log_2')}")
|
||||
print(f" {translator.get('totally_reset.reset_log_3')}")
|
||||
|
||||
print(f"\n{Fore.GREEN}{EMOJI['INFO']} {translator.get('totally_reset.reset_log_4')} {Style.RESET_ALL}")
|
||||
print(f" {translator.get('totally_reset.reset_log_5')} {Style.RESET_ALL}")
|
||||
print(f" {translator.get('totally_reset.reset_log_6')} {Style.RESET_ALL}")
|
||||
print(f" {translator.get('totally_reset.reset_log_7')} {Style.RESET_ALL}")
|
||||
print(f" {translator.get('totally_reset.reset_log_8')} {Style.RESET_ALL}")
|
||||
|
||||
print(f"\n{Fore.RED}{EMOJI['INFO']} {translator.get('totally_reset.reset_log_9')} {Style.RESET_ALL}")
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
reset_cursor()
|
||||
except KeyboardInterrupt:
|
||||
print(f"\n\n{Fore.RED}{EMOJI['STOP']} {translator.get('totally_reset.keyboard_interrupt')} {Style.RESET_ALL}")
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print(f"\n{Fore.RED}{EMOJI['ERROR']} {translator.get('totally_reset.unexpected_error', error=str(e))}{Style.RESET_ALL}")
|
||||
print(f" {translator.get('totally_reset.report_issue')}")
|
||||
sys.exit(1)
|
||||
|
||||
def run(translator=None):
|
||||
"""Entry point for the totally reset cursor functionality when called from the main menu."""
|
||||
try:
|
||||
reset_cursor()
|
||||
input(f"\n\n{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.return_to_main_menu')} {Style.RESET_ALL}")
|
||||
except KeyboardInterrupt:
|
||||
print(f"\n\n{Fore.RED}{EMOJI['STOP']} {translator.get('totally_reset.process_interrupted')} {Style.RESET_ALL}")
|
||||
except Exception as e:
|
||||
print(f"\n{Fore.RED}{EMOJI['ERROR']} {translator.get('totally_reset.unexpected_error', error=str(e))}{Style.RESET_ALL}")
|
||||
print(f" {translator.get('totally_reset.report_issue')}")
|
||||
input(f"\n{Fore.CYAN}{EMOJI['INFO']} {translator.get('totally_reset.press_enter_to_return_to_main_menu')} {Style.RESET_ALL}")
|
||||
if __name__ == '__main__':
|
||||
from main import translator
|
||||
main(translator)
|
||||
|
||||
Reference in New Issue
Block a user