export default { // Home Page home: { viewOnGithub: 'View on GitHub', viewDocs: 'View Documentation', docs: 'Docs', switchToLight: 'Switch to Light Mode', switchToDark: 'Switch to Dark Mode', dashboard: 'Dashboard', login: 'Login', getStarted: 'Get Started', goToDashboard: 'Go to Dashboard', tags: { subscriptionToApi: 'Subscription to API', stickySession: 'Sticky Session', realtimeBilling: 'Real-time Billing' }, features: { unifiedGateway: 'Unified API Gateway', unifiedGatewayDesc: 'Convert Claude subscriptions to API endpoints. Access AI capabilities through standard /v1/messages interface.', multiAccount: 'Multi-Account Pool', multiAccountDesc: 'Manage multiple upstream accounts with smart load balancing. Support OAuth and API Key authentication.', balanceQuota: 'Balance & Quota', balanceQuotaDesc: 'Token-based billing with precise usage tracking. Manage quotas and recharge with redeem codes.' }, providers: { title: 'Supported Providers', description: 'Unified API interface for AI services', supported: 'Supported', soon: 'Soon', claude: 'Claude', gemini: 'Gemini', more: 'More' }, footer: { allRightsReserved: 'All rights reserved.' } }, // Setup Wizard setup: { title: 'Sub2API Setup', description: 'Configure your Sub2API instance', database: { title: 'Database Configuration', host: 'Host', port: 'Port', username: 'Username', password: 'Password', databaseName: 'Database Name', sslMode: 'SSL Mode', passwordPlaceholder: 'Password', ssl: { disable: 'Disable', require: 'Require', verifyCa: 'Verify CA', verifyFull: 'Verify Full' } }, redis: { title: 'Redis Configuration', host: 'Host', port: 'Port', password: 'Password (optional)', database: 'Database', passwordPlaceholder: 'Password' }, admin: { title: 'Admin Account', email: 'Email', password: 'Password', confirmPassword: 'Confirm Password', passwordPlaceholder: 'Min 6 characters', confirmPasswordPlaceholder: 'Confirm password', passwordMismatch: 'Passwords do not match' }, ready: { title: 'Ready to Install', database: 'Database', redis: 'Redis', adminEmail: 'Admin Email' } }, // Common common: { loading: 'Loading...', save: 'Save', cancel: 'Cancel', delete: 'Delete', edit: 'Edit', create: 'Create', update: 'Update', confirm: 'Confirm', reset: 'Reset', search: 'Search', filter: 'Filter', export: 'Export', import: 'Import', actions: 'Actions', status: 'Status', name: 'Name', email: 'Email', password: 'Password', submit: 'Submit', back: 'Back', next: 'Next', yes: 'Yes', no: 'No', all: 'All', none: 'None', noData: 'No data', success: 'Success', error: 'Error', warning: 'Warning', info: 'Info', active: 'Active', inactive: 'Inactive', more: 'More', close: 'Close', enabled: 'Enabled', disabled: 'Disabled', total: 'Total', balance: 'Balance', available: 'Available', copiedToClipboard: 'Copied to clipboard', copyFailed: 'Failed to copy', contactSupport: 'Contact Support', selectOption: 'Select an option', searchPlaceholder: 'Search...', noOptionsFound: 'No options found', saving: 'Saving...', refresh: 'Refresh', time: { never: 'Never', justNow: 'Just now', minutesAgo: '{n}m ago', hoursAgo: '{n}h ago', daysAgo: '{n}d ago' } }, // Navigation nav: { dashboard: 'Dashboard', apiKeys: 'API Keys', usage: 'Usage', redeem: 'Redeem', profile: 'Profile', users: 'Users', groups: 'Groups', subscriptions: 'Subscriptions', accounts: 'Accounts', proxies: 'Proxies', redeemCodes: 'Redeem Codes', settings: 'Settings', myAccount: 'My Account', lightMode: 'Light Mode', darkMode: 'Dark Mode', collapse: 'Collapse', expand: 'Expand', logout: 'Logout', github: 'GitHub', mySubscriptions: 'My Subscriptions' }, // Auth auth: { welcomeBack: 'Welcome Back', signInToAccount: 'Sign in to your account to continue', signIn: 'Sign In', signingIn: 'Signing in...', createAccount: 'Create Account', signUpToStart: 'Sign up to start using {siteName}', signUp: 'Sign up', processing: 'Processing...', continue: 'Continue', rememberMe: 'Remember me', dontHaveAccount: "Don't have an account?", alreadyHaveAccount: 'Already have an account?', registrationDisabled: 'Registration is currently disabled. Please contact the administrator.', emailLabel: 'Email', emailPlaceholder: 'Enter your email', passwordLabel: 'Password', passwordPlaceholder: 'Enter your password', createPasswordPlaceholder: 'Create a strong password', passwordHint: 'At least 6 characters', emailRequired: 'Email is required', invalidEmail: 'Please enter a valid email address', passwordRequired: 'Password is required', passwordMinLength: 'Password must be at least 6 characters', loginFailed: 'Login failed. Please check your credentials and try again.', registrationFailed: 'Registration failed. Please try again.', loginSuccess: 'Login successful! Welcome back.', accountCreatedSuccess: 'Account created successfully! Welcome to {siteName}.', turnstileExpired: 'Verification expired, please try again', turnstileFailed: 'Verification failed, please try again', completeVerification: 'Please complete the verification', verifyYourEmail: 'Verify Your Email', sessionExpired: 'Session expired', sessionExpiredDesc: 'Please go back to the registration page and start again.', verificationCode: 'Verification Code', verificationCodeHint: 'Enter the 6-digit code sent to your email', sendingCode: 'Sending...', clickToResend: 'Click to resend code', resendCode: 'Resend verification code', oauth: { code: 'Code', state: 'State', fullUrl: 'Full URL' } }, // Dashboard dashboard: { title: 'Dashboard', welcomeMessage: "Welcome back! Here's an overview of your account.", balance: 'Balance', apiKeys: 'API Keys', todayRequests: 'Today Requests', todayCost: 'Today Cost', todayTokens: 'Today Tokens', totalTokens: 'Total Tokens', cacheToday: 'Cache (Today)', performance: 'Performance', avgResponse: 'Avg Response', averageTime: 'Average time', timeRange: 'Time Range', granularity: 'Granularity', day: 'Day', hour: 'Hour', modelDistribution: 'Model Distribution', tokenUsageTrend: 'Token Usage Trend', noDataAvailable: 'No data available', model: 'Model', requests: 'Requests', tokens: 'Tokens', actual: 'Actual', standard: 'Standard', input: 'Input', output: 'Output', cache: 'Cache', recentUsage: 'Recent Usage', last7Days: 'Last 7 days', noUsageRecords: 'No usage records', startUsingApi: 'Start using the API to see your usage history here.', viewAllUsage: 'View all usage', quickActions: 'Quick Actions', createApiKey: 'Create API Key', generateNewKey: 'Generate a new API key', viewUsage: 'View Usage', checkDetailedLogs: 'Check detailed usage logs', redeemCode: 'Redeem Code', addBalanceWithCode: 'Add balance with a code' }, // Groups (shared) groups: { subscription: 'Sub' }, // API Keys keys: { title: 'API Keys', description: 'Manage your API keys and access tokens', createKey: 'Create API Key', editKey: 'Edit API Key', deleteKey: 'Delete API Key', deleteConfirmMessage: "Are you sure you want to delete '{name}'? This action cannot be undone.", apiKey: 'API Key', group: 'Group', noGroup: 'No group', created: 'Created', copyToClipboard: 'Copy to clipboard', copied: 'Copied!', importToCcSwitch: 'Import to CCS', enable: 'Enable', disable: 'Disable', nameLabel: 'Name', namePlaceholder: 'My API Key', groupLabel: 'Group', selectGroup: 'Select a group', statusLabel: 'Status', selectStatus: 'Select status', saving: 'Saving...', noKeysYet: 'No API keys yet', createFirstKey: 'Create your first API key to get started with the API.', keyCreatedSuccess: 'API key created successfully', keyUpdatedSuccess: 'API key updated successfully', keyDeletedSuccess: 'API key deleted successfully', keyEnabledSuccess: 'API key enabled successfully', keyDisabledSuccess: 'API key disabled successfully', failedToLoad: 'Failed to load API keys', failedToSave: 'Failed to save API key', failedToDelete: 'Failed to delete API key', failedToUpdateStatus: 'Failed to update API key status', clickToChangeGroup: 'Click to change group', groupChangedSuccess: 'Group changed successfully', failedToChangeGroup: 'Failed to change group', groupRequired: 'Please select a group', usage: 'Usage', today: 'Today', total: 'Total', useKey: 'Use Key', useKeyModal: { title: 'Use API Key', description: 'Add the following environment variables to your terminal profile or run directly in terminal to configure API access.', copy: 'Copy', copied: 'Copied', note: 'These environment variables will be active in the current terminal session. For permanent configuration, add them to ~/.bashrc, ~/.zshrc, or the appropriate configuration file.', noGroupTitle: 'Please assign a group first', noGroupDescription: 'This API key has not been assigned to a group. Please click the group column in the key list to assign one before viewing the configuration.', openai: { description: 'Add the following configuration files to your Codex CLI config directory.', configTomlHint: 'Make sure the following content is at the beginning of the config.toml file', note: 'Make sure the config directory exists. macOS/Linux users can run mkdir -p ~/.codex to create it.', noteWindows: 'Press Win+R and enter %userprofile%\\.codex to open the config directory. Create it manually if it does not exist.', }, }, customKeyLabel: 'Custom Key', customKeyPlaceholder: 'Enter your custom key (min 16 chars)', customKeyHint: 'Only letters, numbers, underscores and hyphens allowed. Minimum 16 characters.', customKeyTooShort: 'Custom key must be at least 16 characters', customKeyInvalidChars: 'Custom key can only contain letters, numbers, underscores, and hyphens', customKeyRequired: 'Please enter a custom key' }, // Usage usage: { title: 'Usage Records', description: 'View and analyze your API usage history', totalRequests: 'Total Requests', totalTokens: 'Total Tokens', totalCost: 'Total Cost', standardCost: 'Standard', actualCost: 'Actual', avgDuration: 'Avg Duration', inSelectedRange: 'in selected range', perRequest: 'per request', apiKeyFilter: 'API Key', allApiKeys: 'All API Keys', timeRange: 'Time Range', exportCsv: 'Export CSV', exporting: 'Exporting...', preparingExport: 'Preparing export...', model: 'Model', type: 'Type', tokens: 'Tokens', cost: 'Cost', firstToken: 'First Token', duration: 'Duration', time: 'Time', stream: 'Stream', sync: 'Sync', in: 'In', out: 'Out', cacheRead: 'Read', cacheWrite: 'Write', rate: 'Rate', original: 'Original', billed: 'Billed', noRecords: 'No usage records found. Try adjusting your filters.', failedToLoad: 'Failed to load usage logs', noDataToExport: 'No data to export', exportSuccess: 'Usage data exported successfully', exportFailed: 'Failed to export usage data', billingType: 'Billing', balance: 'Balance', subscription: 'Subscription' }, // Redeem redeem: { title: 'Redeem Code', description: 'Enter your redeem code to add balance or increase concurrency', currentBalance: 'Current Balance', concurrency: 'Concurrency', requests: 'requests', redeemCodeLabel: 'Redeem Code', redeemCodePlaceholder: 'Enter your redeem code', redeemCodeHint: 'Redeem codes are case-sensitive', redeeming: 'Redeeming...', redeemButton: 'Redeem Code', redeemSuccess: 'Code Redeemed Successfully!', redeemFailed: 'Redemption Failed', added: 'Added', concurrentRequests: 'concurrent requests', newBalance: 'New Balance', newConcurrency: 'New Concurrency', aboutCodes: 'About Redeem Codes', codeRule1: 'Each code can only be used once', codeRule2: 'Codes may add balance, increase concurrency, or grant trial access', codeRule3: 'Contact support if you have issues redeeming a code', codeRule4: 'Balance and concurrency updates are immediate', recentActivity: 'Recent Activity', historyWillAppear: 'Your redemption history will appear here', balanceAddedRedeem: 'Balance Added (Redeem)', balanceAddedAdmin: 'Balance Added (Admin)', balanceDeductedAdmin: 'Balance Deducted (Admin)', concurrencyAddedRedeem: 'Concurrency Added (Redeem)', concurrencyAddedAdmin: 'Concurrency Added (Admin)', concurrencyReducedAdmin: 'Concurrency Reduced (Admin)', adminAdjustment: 'Admin Adjustment', subscriptionAssigned: 'Subscription Assigned', subscriptionAssignedDesc: 'You have been granted access to {groupName}', subscriptionDays: '{days} days', days: ' days', codeRedeemSuccess: 'Code redeemed successfully!', failedToRedeem: 'Failed to redeem code. Please check the code and try again.', subscriptionRefreshFailed: 'Redeemed successfully, but failed to refresh subscription status.' }, // Profile profile: { title: 'Profile Settings', description: 'Manage your account information and settings', accountBalance: 'Account Balance', concurrencyLimit: 'Concurrency Limit', memberSince: 'Member Since', administrator: 'Administrator', user: 'User', username: 'Username', wechat: 'WeChat ID', enterUsername: 'Enter username', enterWechat: 'Enter WeChat ID', editProfile: 'Edit Profile', updateProfile: 'Update Profile', updating: 'Updating...', updateSuccess: 'Profile updated successfully', updateFailed: 'Failed to update profile', usernameRequired: 'Username is required', changePassword: 'Change Password', currentPassword: 'Current Password', newPassword: 'New Password', confirmNewPassword: 'Confirm New Password', passwordHint: 'Password must be at least 8 characters long', changingPassword: 'Changing...', changePasswordButton: 'Change Password', passwordsNotMatch: 'New passwords do not match', passwordTooShort: 'Password must be at least 8 characters long', passwordChangeSuccess: 'Password changed successfully', passwordChangeFailed: 'Failed to change password' }, // Empty States empty: { noData: 'No data found' }, // Table table: { expandActions: 'Expand More Actions', collapseActions: 'Collapse Actions' }, // Pagination pagination: { showing: 'Showing', to: 'to', of: 'of', results: 'results', page: 'Page', pageOf: 'Page {page} of {total}', previous: 'Previous', next: 'Next', perPage: 'Per page', goToPage: 'Go to page {page}' }, // Errors errors: { somethingWentWrong: 'Something went wrong', pageNotFound: 'Page not found', unauthorized: 'Unauthorized', forbidden: 'Forbidden', serverError: 'Server error', networkError: 'Network error', timeout: 'Request timeout', tryAgain: 'Please try again' }, // Dates dates: { today: 'Today', yesterday: 'Yesterday', thisWeek: 'This Week', lastWeek: 'Last Week', thisMonth: 'This Month', lastMonth: 'Last Month', last7Days: 'Last 7 Days', last14Days: 'Last 14 Days', last30Days: 'Last 30 Days', custom: 'Custom', startDate: 'Start Date', endDate: 'End Date', apply: 'Apply', selectDateRange: 'Select date range' }, // Admin admin: { // Dashboard dashboard: { title: 'Admin Dashboard', description: 'System overview and real-time statistics', apiKeys: 'API Keys', accounts: 'Accounts', users: 'Users', todayRequests: 'Today Requests', newUsersToday: 'New Users Today', todayTokens: 'Today Tokens', totalTokens: 'Total Tokens', cacheToday: 'Cache (Today)', performance: 'Performance', avgResponse: 'Avg Response', active: 'active', ok: 'ok', err: 'err', activeUsers: 'active users', create: 'Create', timeRange: 'Time Range', granularity: 'Granularity', day: 'Day', hour: 'Hour', modelDistribution: 'Model Distribution', tokenUsageTrend: 'Token Usage Trend', userUsageTrend: 'User Usage Trend (Top 12)', model: 'Model', requests: 'Requests', tokens: 'Tokens', actual: 'Actual', standard: 'Standard', noDataAvailable: 'No data available', recentUsage: 'Recent Usage', failedToLoad: 'Failed to load dashboard statistics' }, // Users users: { title: 'User Management', description: 'Manage users and their permissions', createUser: 'Create User', editUser: 'Edit User', deleteUser: 'Delete User', searchUsers: 'Search users...', allRoles: 'All Roles', allStatus: 'All Status', admin: 'Admin', user: 'User', disabled: 'Disabled', email: 'Email', password: 'Password', username: 'Username', wechat: 'WeChat ID', notes: 'Notes', enterEmail: 'Enter email', enterPassword: 'Enter password', enterUsername: 'Enter username (optional)', enterWechat: 'Enter WeChat ID (optional)', enterNotes: 'Enter notes (admin only)', notesHint: 'This note is only visible to administrators', enterNewPassword: 'Enter new password (optional)', leaveEmptyToKeep: 'Leave empty to keep current password', generatePassword: 'Generate random password', copyPassword: 'Copy password', creating: 'Creating...', updating: 'Updating...', columns: { user: 'User', username: 'Username', wechat: 'WeChat ID', notes: 'Notes', role: 'Role', subscriptions: 'Subscriptions', balance: 'Balance', usage: 'Usage', concurrency: 'Concurrency', status: 'Status', created: 'Created', actions: 'Actions' }, today: 'Today', total: 'Total', noSubscription: 'No subscription', daysRemaining: '{days}d', expired: 'Expired', disable: 'Disable', enable: 'Enable', disableUser: 'Disable User', enableUser: 'Enable User', viewApiKeys: 'View API Keys', groups: 'Groups', apiKeys: 'API Keys', userApiKeys: 'User API Keys', noApiKeys: 'This user has no API keys', group: 'Group', none: 'None', noUsersYet: 'No users yet', createFirstUser: 'Create your first user to get started.', userCreated: 'User created successfully', userUpdated: 'User updated successfully', userDeleted: 'User deleted successfully', userEnabled: 'User enabled successfully', userDisabled: 'User disabled successfully', failedToLoad: 'Failed to load users', failedToCreate: 'Failed to create user', failedToUpdate: 'Failed to update user', failedToDelete: 'Failed to delete user', failedToToggle: 'Failed to update user status', failedToLoadApiKeys: 'Failed to load user API keys', deleteConfirm: "Are you sure you want to delete '{email}'? This action cannot be undone.", setAllowedGroups: 'Set Allowed Groups', allowedGroupsHint: 'Select which standard groups this user can use. Subscription groups are managed separately.', noStandardGroups: 'No standard groups available', allowAllGroups: 'Allow All Groups', allowAllGroupsHint: 'User can use any non-exclusive group', allowedGroupsUpdated: 'Allowed groups updated successfully', failedToLoadGroups: 'Failed to load groups', failedToUpdateAllowedGroups: 'Failed to update allowed groups', deposit: 'Deposit', withdraw: 'Withdraw', depositAmount: 'Deposit Amount', withdrawAmount: 'Withdraw Amount', currentBalance: 'Current Balance', depositNotesPlaceholder: 'e.g., New user registration bonus, promotional credit, compensation, etc.', withdrawNotesPlaceholder: 'e.g., Service issue refund, incorrect charge reversal, account closure refund, etc.', notesOptional: 'Notes are optional but helpful for record keeping', amountHint: 'Please enter a positive amount', newBalance: 'New Balance', depositing: 'Depositing...', withdrawing: 'Withdrawing...', confirmDeposit: 'Confirm Deposit', confirmWithdraw: 'Confirm Withdraw', depositSuccess: 'Deposit successful', withdrawSuccess: 'Withdraw successful', failedToDeposit: 'Failed to deposit', failedToWithdraw: 'Failed to withdraw', useDepositWithdrawButtons: 'Please use deposit/withdraw buttons to adjust balance', insufficientBalance: 'Insufficient balance, balance cannot be negative after withdrawal' }, // Groups groups: { title: 'Group Management', description: 'Manage API key groups and rate multipliers', createGroup: 'Create Group', editGroup: 'Edit Group', deleteGroup: 'Delete Group', allPlatforms: 'All Platforms', allStatus: 'All Status', allGroups: 'All Groups', exclusive: 'Exclusive', nonExclusive: 'Non-Exclusive', public: 'Public', columns: { name: 'Name', platform: 'Platform', rateMultiplier: 'Rate Multiplier', type: 'Type', accounts: 'Accounts', status: 'Status', actions: 'Actions', billingType: 'Billing Type' }, rateAndAccounts: '{rate}x rate · {count} accounts', accountsCount: '{count} accounts', form: { name: 'Name', description: 'Description', platform: 'Platform', rateMultiplier: 'Rate Multiplier', status: 'Status' }, enterGroupName: 'Enter group name', optionalDescription: 'Optional description', platformHint: 'Select the platform this group is associated with', platformNotEditable: 'Platform cannot be changed after creation', rateMultiplierHint: 'Cost multiplier for this group (e.g., 1.5 = 150% of base cost)', exclusiveHint: 'Exclusive (requires explicit user access)', noGroupsYet: 'No groups yet', createFirstGroup: 'Create your first group to organize API keys.', creating: 'Creating...', updating: 'Updating...', limitDay: 'd', limitWeek: 'w', limitMonth: 'mo', groupCreated: 'Group created successfully', groupUpdated: 'Group updated successfully', groupDeleted: 'Group deleted successfully', failedToLoad: 'Failed to load groups', failedToCreate: 'Failed to create group', failedToUpdate: 'Failed to update group', failedToDelete: 'Failed to delete group', deleteConfirm: "Are you sure you want to delete '{name}'? All associated API keys will no longer belong to any group.", deleteConfirmSubscription: "Are you sure you want to delete subscription group '{name}'? This will invalidate all API keys bound to this subscription and delete all related subscription records. This action cannot be undone.", subscription: { title: 'Subscription Settings', type: 'Billing Type', typeHint: 'Standard billing deducts from user balance. Subscription mode uses quota limits instead.', typeNotEditable: 'Billing type cannot be changed after group creation.', standard: 'Standard (Balance)', subscription: 'Subscription (Quota)', dailyLimit: 'Daily Limit (USD)', weeklyLimit: 'Weekly Limit (USD)', monthlyLimit: 'Monthly Limit (USD)', defaultValidityDays: 'Default Validity (Days)', validityHint: 'Number of days the subscription is valid when assigned to a user', noLimit: 'No limit' } }, // Subscriptions subscriptions: { title: 'Subscription Management', description: 'Manage user subscriptions and quota limits', assignSubscription: 'Assign Subscription', extendSubscription: 'Extend Subscription', revokeSubscription: 'Revoke Subscription', allStatus: 'All Status', allGroups: 'All Groups', daily: 'Daily', weekly: 'Weekly', monthly: 'Monthly', noLimits: 'No limits configured', resetNow: 'Resetting soon', windowNotActive: 'Window not active', resetInMinutes: 'Resets in {minutes}m', resetInHoursMinutes: 'Resets in {hours}h {minutes}m', resetInDaysHours: 'Resets in {days}d {hours}h', daysRemaining: 'days remaining', noExpiration: 'No expiration', status: { active: 'Active', expired: 'Expired', revoked: 'Revoked' }, columns: { user: 'User', group: 'Group', usage: 'Usage', expires: 'Expires', status: 'Status', actions: 'Actions' }, form: { user: 'User', group: 'Subscription Group', validityDays: 'Validity (Days)', extendDays: 'Extend by (Days)' }, selectUser: 'Select a user', selectGroup: 'Select a subscription group', groupHint: 'Only groups with subscription billing type are shown', validityHint: 'Number of days the subscription will be valid', extendingFor: 'Extending subscription for', currentExpiration: 'Current expiration', assign: 'Assign', assigning: 'Assigning...', extend: 'Extend', extending: 'Extending...', revoke: 'Revoke', noSubscriptionsYet: 'No subscriptions yet', assignFirstSubscription: 'Assign a subscription to get started.', subscriptionAssigned: 'Subscription assigned successfully', subscriptionExtended: 'Subscription extended successfully', subscriptionRevoked: 'Subscription revoked successfully', failedToLoad: 'Failed to load subscriptions', failedToAssign: 'Failed to assign subscription', failedToExtend: 'Failed to extend subscription', failedToRevoke: 'Failed to revoke subscription', revokeConfirm: "Are you sure you want to revoke the subscription for '{user}'? This action cannot be undone." }, // Accounts accounts: { title: 'Account Management', description: 'Manage AI platform accounts and credentials', createAccount: 'Create Account', syncFromCrs: 'Sync from CRS', syncFromCrsTitle: 'Sync Accounts from CRS', syncFromCrsDesc: 'Sync accounts from claude-relay-service (CRS) into this system (CRS is called server-to-server).', crsVersionRequirement: '⚠️ Note: CRS version must be ≥ v1.1.240 to support this feature', crsBaseUrl: 'CRS Base URL', crsBaseUrlPlaceholder: 'e.g. http://127.0.0.1:3000', crsUsername: 'Username', crsPassword: 'Password', syncProxies: 'Also sync proxies (match by host/port/auth or create)', syncNow: 'Sync Now', syncing: 'Syncing...', syncMissingFields: 'Please fill base URL, username and password', syncResult: 'Sync Result', syncResultSummary: 'Created {created}, updated {updated}, skipped {skipped}, failed {failed}', syncErrors: 'Errors / Skipped Details', syncCompleted: 'Sync completed: created {created}, updated {updated}', syncCompletedWithErrors: 'Sync completed with errors: failed {failed} (created {created}, updated {updated})', syncFailed: 'Sync failed', editAccount: 'Edit Account', deleteAccount: 'Delete Account', searchAccounts: 'Search accounts...', allPlatforms: 'All Platforms', allTypes: 'All Types', allStatus: 'All Status', oauthType: 'OAuth', setupToken: 'Setup Token', apiKey: 'API Key', // Schedulable toggle schedulable: 'Schedulable', schedulableHint: 'Enable to include this account in API request scheduling', schedulableEnabled: 'Scheduling enabled', schedulableDisabled: 'Scheduling disabled', failedToToggleSchedulable: 'Failed to toggle scheduling status', platforms: { anthropic: 'Anthropic', claude: 'Claude', openai: 'OpenAI', gemini: 'Gemini', antigravity: 'Antigravity' }, types: { oauth: 'OAuth', chatgptOauth: 'ChatGPT OAuth', responsesApi: 'Responses API', googleOauth: 'Google OAuth', codeAssist: 'Code Assist', antigravityOauth: 'Antigravity OAuth' }, columns: { name: 'Name', platformType: 'Platform/Type', platform: 'Platform', type: 'Type', concurrencyStatus: 'Concurrency', status: 'Status', schedulable: 'Schedule', todayStats: "Today's Stats", groups: 'Groups', usageWindows: 'Usage Windows', priority: 'Priority', lastUsed: 'Last Used', actions: 'Actions' }, clearRateLimit: 'Clear Rate Limit', testConnection: 'Test Connection', reAuthorize: 'Re-Authorize', refreshToken: 'Refresh Token', noAccountsYet: 'No accounts yet', createFirstAccount: 'Create your first account to start using AI services.', tokenRefreshed: 'Token refreshed successfully', accountDeleted: 'Account deleted successfully', rateLimitCleared: 'Rate limit cleared successfully', bulkActions: { selected: '{count} account(s) selected', selectCurrentPage: 'Select this page', clear: 'Clear selection', edit: 'Bulk Edit', delete: 'Bulk Delete' }, bulkEdit: { title: 'Bulk Edit Accounts', selectionInfo: '{count} account(s) selected. Only checked or filled fields will be updated; others stay unchanged.', baseUrlPlaceholder: 'https://api.anthropic.com or https://api.openai.com', baseUrlNotice: 'Applies to API Key accounts only; leave empty to keep existing value', submit: 'Update Accounts', updating: 'Updating...', success: 'Updated {count} account(s)', partialSuccess: 'Partially updated: {success} succeeded, {failed} failed', failed: 'Bulk update failed', noSelection: 'Please select accounts to edit', noFieldsSelected: 'Select at least one field to update' }, bulkDeleteTitle: 'Bulk Delete Accounts', bulkDeleteConfirm: 'Delete the selected {count} account(s)? This action cannot be undone.', bulkDeleteSuccess: 'Deleted {count} account(s)', bulkDeletePartial: 'Partially deleted: {success} succeeded, {failed} failed', bulkDeleteFailed: 'Bulk delete failed', resetStatus: 'Reset Status', statusReset: 'Account status reset successfully', failedToResetStatus: 'Failed to reset account status', failedToLoad: 'Failed to load accounts', failedToRefresh: 'Failed to refresh token', failedToDelete: 'Failed to delete account', failedToClearRateLimit: 'Failed to clear rate limit', deleteConfirm: "Are you sure you want to delete '{name}'? This action cannot be undone.", // Create/Edit Account Modal platform: 'Platform', accountName: 'Account Name', enterAccountName: 'Enter account name', accountType: 'Account Type', claudeCode: 'Claude Code', claudeConsole: 'Claude Console', oauthSetupToken: 'OAuth / Setup Token', addMethod: 'Add Method', setupTokenLongLived: 'Setup Token (Long-lived)', baseUrl: 'Base URL', baseUrlHint: 'Leave default for official Anthropic API', apiKeyRequired: 'API Key *', apiKeyPlaceholder: 'sk-ant-api03-...', apiKeyHint: 'Your Claude Console API Key', modelRestriction: 'Model Restriction (Optional)', modelWhitelist: 'Model Whitelist', modelMapping: 'Model Mapping', selectAllowedModels: 'Select allowed models. Leave empty to support all models.', mapRequestModels: 'Map request models to actual models. Left is the requested model, right is the actual model sent to API.', selectedModels: 'Selected {count} model(s)', supportsAllModels: '(supports all models)', requestModel: 'Request model', actualModel: 'Actual model', addMapping: 'Add Mapping', mappingExists: 'Mapping for {model} already exists', customErrorCodes: 'Custom Error Codes', customErrorCodesHint: 'Only stop scheduling for selected error codes', customErrorCodesWarning: 'Only selected error codes will stop scheduling. Other errors will return 500.', selectedErrorCodes: 'Selected', noneSelectedUsesDefault: 'None selected (uses default policy)', enterErrorCode: 'Enter error code (100-599)', invalidErrorCode: 'Please enter a valid HTTP error code (100-599)', errorCodeExists: 'This error code is already selected', interceptWarmupRequests: 'Intercept Warmup Requests', interceptWarmupRequestsDesc: 'When enabled, warmup requests like title generation will return mock responses without consuming upstream tokens', proxy: 'Proxy', noProxy: 'No Proxy', concurrency: 'Concurrency', priority: 'Priority', priorityHint: 'Higher priority accounts are used first', higherPriorityFirst: 'Higher value means higher priority', creating: 'Creating...', updating: 'Updating...', accountCreated: 'Account created successfully', accountUpdated: 'Account updated successfully', failedToCreate: 'Failed to create account', failedToUpdate: 'Failed to update account', pleaseEnterAccountName: 'Please enter account name', pleaseEnterApiKey: 'Please enter API Key', apiKeyIsRequired: 'API Key is required', leaveEmptyToKeep: 'Leave empty to keep current key', // OAuth flow oauth: { title: 'Claude Account Authorization', authMethod: 'Authorization Method', manualAuth: 'Manual Authorization', cookieAutoAuth: 'Cookie Auto-Auth', cookieAutoAuthDesc: 'Use claude.ai sessionKey to automatically complete OAuth authorization without manually opening browser.', sessionKey: 'sessionKey', keysCount: '{count} keys', batchCreateAccounts: 'Will batch create {count} accounts', sessionKeyPlaceholder: 'One sessionKey per line, e.g.:\nsk-ant-sid01-xxxxx...\nsk-ant-sid01-yyyyy...', sessionKeyPlaceholderSingle: 'sk-ant-sid01-xxxxx...', howToGetSessionKey: 'How to get sessionKey', step1: 'Login to claude.ai in your browser', step2: 'Press F12 to open Developer Tools', step3: 'Go to Application tab', step4: 'Find Cookieshttps://claude.ai', step5: 'Find the row with key sessionKey', step6: 'Copy the Value', sessionKeyFormat: 'sessionKey usually starts with sk-ant-sid01-', startAutoAuth: 'Start Auto-Auth', authorizing: 'Authorizing...', followSteps: 'Follow these steps to authorize your Claude account:', step1GenerateUrl: 'Click the button below to generate the authorization URL', generateAuthUrl: 'Generate Auth URL', generating: 'Generating...', regenerate: 'Regenerate', step2OpenUrl: 'Open the URL in your browser and complete authorization', openUrlDesc: 'Open the authorization URL in a new tab, log in to your Claude account and authorize.', proxyWarning: 'Note: If you configured a proxy, make sure your browser uses the same proxy to access the authorization page.', step3EnterCode: 'Enter the Authorization Code', authCodeDesc: 'After authorization is complete, the page will display an Authorization Code. Copy and paste it below:', authCode: 'Authorization Code', authCodePlaceholder: 'Paste the Authorization Code from Claude page...', authCodeHint: 'Paste the Authorization Code copied from the Claude page', completeAuth: 'Complete Authorization', verifying: 'Verifying...', pleaseEnterSessionKey: 'Please enter at least one valid sessionKey', authFailed: 'Authorization failed', cookieAuthFailed: 'Cookie authorization failed', keyAuthFailed: 'Key {index}: {error}', successCreated: 'Successfully created {count} account(s)', // OpenAI specific openai: { title: 'OpenAI Account Authorization', followSteps: 'Follow these steps to complete OpenAI account authorization:', step1GenerateUrl: 'Click the button below to generate the authorization URL', generateAuthUrl: 'Generate Auth URL', step2OpenUrl: 'Open the URL in your browser and complete authorization', openUrlDesc: 'Open the authorization URL in a new tab, log in to your OpenAI account and authorize.', importantNotice: 'Important: The page may take a while to load after authorization. Please wait patiently. When the browser address bar changes to http://localhost..., the authorization is complete.', step3EnterCode: 'Enter Authorization URL or Code', authCodeDesc: 'After authorization is complete, when the page URL becomes http://localhost:xxx/auth/callback?code=...:', authCode: 'Authorization URL or Code', authCodePlaceholder: 'Option 1: Copy the complete URL\n(http://localhost:xxx/auth/callback?code=...)\nOption 2: Copy only the code parameter value', authCodeHint: 'You can copy the entire URL or just the code parameter value, the system will auto-detect' }, // Gemini specific gemini: { title: 'Gemini Account Authorization', followSteps: 'Follow these steps to authorize your Gemini account:', step1GenerateUrl: 'Generate the authorization URL', generateAuthUrl: 'Generate Auth URL', projectIdLabel: 'Project ID (optional)', projectIdPlaceholder: 'e.g. my-gcp-project or cloud-ai-companion-xxxxx', projectIdHint: 'Leave empty to auto-detect after code exchange. If auto-detection fails, fill it in and re-generate the auth URL to try again.', howToGetProjectId: 'How to get', step2OpenUrl: 'Open the URL in your browser and complete authorization', openUrlDesc: 'Open the authorization URL in a new tab, log in to your Google account and authorize.', step3EnterCode: 'Enter Authorization URL or Code', authCodeDesc: 'After authorization, copy the callback URL (recommended) or just the code and paste it below.', authCode: 'Callback URL or Code', authCodePlaceholder: 'Option 1 (recommended): Paste the callback URL\nOption 2: Paste only the code value', authCodeHint: 'The system will auto-extract code/state from the URL.', redirectUri: 'Redirect URI', redirectUriHint: 'This must be configured in your Google OAuth client and must match exactly.', confirmRedirectUri: 'I have configured this Redirect URI in the Google OAuth client (must match exactly)', invalidRedirectUri: 'Redirect URI must be a valid http(s) URL', redirectUriNotConfirmed: 'Please confirm the Redirect URI is configured correctly', missingRedirectUri: 'Missing redirect URI', failedToGenerateUrl: 'Failed to generate Gemini auth URL', missingExchangeParams: 'Missing auth code, session ID, or state', failedToExchangeCode: 'Failed to exchange Gemini auth code', modelPassthrough: 'Gemini Model Passthrough', modelPassthroughDesc: 'All model requests are forwarded directly to the Gemini API without model restrictions or mappings.', stateWarningTitle: 'Note', stateWarningDesc: 'Recommended: paste the full callback URL (includes code & state).', oauthTypeLabel: 'OAuth Type', needsProjectId: 'For GCP Developers', needsProjectIdDesc: 'Requires GCP project', noProjectIdNeeded: 'For Regular Users', noProjectIdNeededDesc: 'Requires admin-configured OAuth client', aiStudioNotConfiguredShort: 'Not configured', aiStudioNotConfiguredTip: 'AI Studio OAuth is not configured: set GEMINI_OAUTH_CLIENT_ID / GEMINI_OAUTH_CLIENT_SECRET and add Redirect URI: http://localhost:1455/auth/callback (Consent screen scopes must include https://www.googleapis.com/auth/generative-language.retriever)', aiStudioNotConfigured: 'AI Studio OAuth is not configured: set GEMINI_OAUTH_CLIENT_ID / GEMINI_OAUTH_CLIENT_SECRET and add Redirect URI: http://localhost:1455/auth/callback' }, // Antigravity specific antigravity: { title: 'Antigravity Account Authorization', followSteps: 'Follow these steps to authorize your Antigravity account:', step1GenerateUrl: 'Generate the authorization URL', generateAuthUrl: 'Generate Auth URL', step2OpenUrl: 'Open the URL in your browser and complete authorization', openUrlDesc: 'Open the authorization URL in a new tab, log in to your Google account and authorize.', importantNotice: 'Important: The page may take a while to load after authorization. Please wait patiently. When the browser address bar shows http://localhost..., authorization is complete.', step3EnterCode: 'Enter Authorization URL or Code', authCodeDesc: 'After authorization, when the page URL becomes http://localhost:xxx/auth/callback?code=...:', authCode: 'Authorization URL or Code', authCodePlaceholder: 'Option 1: Copy the complete URL\n(http://localhost:xxx/auth/callback?code=...)\nOption 2: Copy only the code parameter value', authCodeHint: 'You can copy the entire URL or just the code parameter value, the system will auto-detect', failedToGenerateUrl: 'Failed to generate Antigravity auth URL', missingExchangeParams: 'Missing code, session ID, or state', failedToExchangeCode: 'Failed to exchange Antigravity auth code' } }, // Gemini specific (platform-wide) gemini: { modelPassthrough: 'Gemini Model Passthrough', modelPassthroughDesc: 'All model requests are forwarded directly to the Gemini API without model restrictions or mappings.', apiKeyHint: 'Your Gemini API Key (starts with AIza)' }, // Re-Auth Modal reAuthorizeAccount: 'Re-Authorize Account', claudeCodeAccount: 'Claude Code Account', openaiAccount: 'OpenAI Account', geminiAccount: 'Gemini Account', antigravityAccount: 'Antigravity Account', inputMethod: 'Input Method', reAuthorizedSuccess: 'Account re-authorized successfully', // Test Modal testAccountConnection: 'Test Account Connection', account: 'Account', readyToTest: 'Ready to test. Click "Start Test" to begin...', connectingToApi: 'Connecting to API...', testCompleted: 'Test completed successfully!', testFailed: 'Test failed', connectedToApi: 'Connected to API', usingModel: 'Using model: {model}', sendingTestMessage: 'Sending test message: "hi"', response: 'Response:', startTest: 'Start Test', testing: 'Testing...', retry: 'Retry', copyOutput: 'Copy output', startingTestForAccount: 'Starting test for account: {name}', testAccountTypeLabel: 'Account type: {type}', selectTestModel: 'Select Test Model', testModel: 'Test model', testPrompt: 'Prompt: "hi"', // Stats Modal viewStats: 'View Stats', usageStatistics: 'Usage Statistics', last30DaysUsage: 'Last 30 days usage statistics (based on actual usage days)', stats: { totalCost: '30-Day Total Cost', accumulatedCost: 'Accumulated cost', standardCost: 'Standard', totalRequests: '30-Day Total Requests', totalCalls: 'Total API calls', avgDailyCost: 'Daily Avg Cost', basedOnActualDays: 'Based on {days} actual usage days', avgDailyRequests: 'Daily Avg Requests', avgDailyUsage: 'Average daily usage', todayOverview: 'Today Overview', cost: 'Cost', requests: 'Requests', tokens: 'Tokens', highestCostDay: 'Highest Cost Day', highestRequestDay: 'Highest Request Day', date: 'Date', accumulatedTokens: 'Accumulated Tokens', totalTokens: '30-Day Total', dailyAvgTokens: 'Daily Average', performance: 'Performance', avgResponseTime: 'Avg Response', daysActive: 'Days Active', recentActivity: 'Recent Activity', todayRequests: 'Today Requests', todayTokens: 'Today Tokens', todayCost: 'Today Cost', usageTrend: '30-Day Cost & Request Trend', noData: 'No usage data available for this account' }, usageWindow: { statsTitle: '5-Hour Window Usage Statistics', gemini3Pro: 'G3P', gemini3Flash: 'G3F', gemini3Image: 'G3I', claude45: 'C4.5' } }, // Proxies proxies: { title: 'Proxy Management', description: 'Manage proxy servers for accounts', createProxy: 'Create Proxy', editProxy: 'Edit Proxy', deleteProxy: 'Delete Proxy', searchProxies: 'Search proxies...', allProtocols: 'All Protocols', allStatus: 'All Status', columns: { name: 'Name', protocol: 'Protocol', address: 'Address', status: 'Status', actions: 'Actions' }, testConnection: 'Test Connection', batchTest: 'Test All Proxies', testFailed: 'Failed', name: 'Name', protocol: 'Protocol', host: 'Host', port: 'Port', username: 'Username (Optional)', password: 'Password (Optional)', status: 'Status', enterProxyName: 'Enter proxy name', leaveEmptyToKeep: 'Leave empty to keep current', optionalAuth: 'Optional authentication', form: { hostPlaceholder: 'proxy.example.com', portPlaceholder: '8080' }, noProxiesYet: 'No proxies yet', createFirstProxy: 'Create your first proxy to route traffic through it.', // Batch import standardAdd: 'Standard Add', batchAdd: 'Quick Add', batchInput: 'Proxy List', batchInputPlaceholder: "Enter one proxy per line in the following formats:\nsocks5://user:pass@192.168.1.1:1080\nhttp://192.168.1.1:8080\nhttps://user:pass@proxy.example.com:443", batchInputHint: "Supports http, https, socks5 protocols. Format: protocol://[user:pass@]host:port", parsedCount: '{count} valid', invalidCount: '{count} invalid', duplicateCount: '{count} duplicate', importing: 'Importing...', importProxies: 'Import {count} proxies', batchImportSuccess: 'Successfully imported {created} proxies, skipped {skipped} duplicates', batchImportAllSkipped: 'All {skipped} proxies already exist, skipped import', failedToImport: 'Failed to batch import', // Other messages creating: 'Creating...', updating: 'Updating...', proxyCreated: 'Proxy created successfully', proxyUpdated: 'Proxy updated successfully', proxyDeleted: 'Proxy deleted successfully', proxyWorking: 'Proxy is working!', proxyWorkingWithLatency: 'Proxy is working! Latency: {latency}ms', proxyTestFailed: 'Proxy test failed', failedToLoad: 'Failed to load proxies', failedToCreate: 'Failed to create proxy', failedToUpdate: 'Failed to update proxy', failedToDelete: 'Failed to delete proxy', failedToTest: 'Failed to test proxy', deleteConfirm: "Are you sure you want to delete '{name}'? Accounts using this proxy will have their proxy removed." }, // Redeem Codes redeem: { title: 'Redeem Code Management', description: 'Generate and manage redeem codes', generateCodes: 'Generate Codes', searchCodes: 'Search codes...', allTypes: 'All Types', allStatus: 'All Status', balance: 'Balance', concurrency: 'Concurrency', subscription: 'Subscription', unused: 'Unused', used: 'Used', columns: { code: 'Code', type: 'Type', value: 'Value', status: 'Status', usedBy: 'Used By', usedAt: 'Used At', actions: 'Actions' }, userPrefix: 'User #{id}', exportCsv: 'Export CSV', deleteAllUnused: 'Delete All Unused Codes', deleteCode: 'Delete Redeem Code', deleteCodeConfirm: 'Are you sure you want to delete this redeem code? This action cannot be undone.', deleteAllUnusedConfirm: 'Are you sure you want to delete all unused (active) redeem codes? This action cannot be undone.', deleteAll: 'Delete All', generateCodesTitle: 'Generate Redeem Codes', generatedSuccessfully: 'Generated Successfully', codesCreated: '{count} redeem code(s) created', codeType: 'Code Type', amount: 'Amount ($)', value: 'Value', count: 'Count', generating: 'Generating...', generate: 'Generate', copyAll: 'Copy All', copied: 'Copied!', download: 'Download', codesExported: 'Codes exported successfully', codeDeleted: 'Redeem code deleted successfully', codesDeleted: 'Successfully deleted {count} unused code(s)', noUnusedCodes: 'No unused codes to delete', failedToLoad: 'Failed to load redeem codes', failedToGenerate: 'Failed to generate codes', failedToExport: 'Failed to export codes', failedToDelete: 'Failed to delete code', failedToDeleteUnused: 'Failed to delete unused codes', failedToCopy: 'Failed to copy codes', selectGroup: 'Select Group', selectGroupPlaceholder: 'Choose a subscription group', validityDays: 'Validity Days', groupRequired: 'Please select a subscription group', days: ' days' }, // Usage Records usage: { title: 'Usage Records', description: 'View and manage all user usage records', userFilter: 'User', searchUserPlaceholder: 'Search user by email...', selectedUser: 'Selected', user: 'User', account: 'Account', group: 'Group', requestId: 'Request ID', allModels: 'All Models', allAccounts: 'All Accounts', allGroups: 'All Groups', allTypes: 'All Types', allBillingTypes: 'All Billing', inputCost: 'Input Cost', outputCost: 'Output Cost', cacheCreationCost: 'Cache Creation Cost', cacheReadCost: 'Cache Read Cost', failedToLoad: 'Failed to load usage records' }, // Settings settings: { title: 'System Settings', description: 'Manage registration, email verification, default values, and SMTP settings', registration: { title: 'Registration Settings', description: 'Control user registration and verification', enableRegistration: 'Enable Registration', enableRegistrationHint: 'Allow new users to register', emailVerification: 'Email Verification', emailVerificationHint: 'Require email verification for new registrations' }, turnstile: { title: 'Cloudflare Turnstile', description: 'Bot protection for login and registration', enableTurnstile: 'Enable Turnstile', enableTurnstileHint: 'Require Cloudflare Turnstile verification', siteKey: 'Site Key', secretKey: 'Secret Key', siteKeyHint: 'Get this from your Cloudflare Dashboard', secretKeyHint: 'Server-side verification key (keep this secret)' }, defaults: { title: 'Default User Settings', description: 'Default values for new users', defaultBalance: 'Default Balance', defaultBalanceHint: 'Initial balance for new users', defaultConcurrency: 'Default Concurrency', defaultConcurrencyHint: 'Maximum concurrent requests for new users' }, site: { title: 'Site Settings', description: 'Customize site branding', siteName: 'Site Name', siteNamePlaceholder: 'Sub2API', siteNameHint: 'Displayed in emails and page titles', siteSubtitle: 'Site Subtitle', siteSubtitlePlaceholder: 'Subscription to API Conversion Platform', siteSubtitleHint: 'Displayed on login and register pages', apiBaseUrl: 'API Base URL', apiBaseUrlPlaceholder: 'https://api.example.com', apiBaseUrlHint: 'Used for "Use Key" and "Import to CC Switch" features. Leave empty to use current site URL.', contactInfo: 'Contact Info', contactInfoPlaceholder: 'e.g., QQ: 123456789', contactInfoHint: 'Customer support contact info, displayed on redeem page, profile, etc.', docUrl: 'Documentation URL', docUrlPlaceholder: 'https://docs.example.com', docUrlHint: 'Link to your documentation site. Leave empty to hide the documentation link.', siteLogo: 'Site Logo', uploadImage: 'Upload Image', remove: 'Remove', logoHint: 'PNG, JPG, or SVG. Max 300KB. Recommended: 80x80px square image.', logoSizeError: 'Image size exceeds 300KB limit ({size}KB)', logoTypeError: 'Please select an image file', logoReadError: 'Failed to read the image file' }, smtp: { title: 'SMTP Settings', description: 'Configure email sending for verification codes', testConnection: 'Test Connection', testing: 'Testing...', host: 'SMTP Host', hostPlaceholder: 'smtp.gmail.com', port: 'SMTP Port', portPlaceholder: '587', username: 'SMTP Username', usernamePlaceholder: "your-email{'@'}gmail.com", password: 'SMTP Password', passwordPlaceholder: '********', passwordHint: 'Leave empty to keep existing password', fromEmail: 'From Email', fromEmailPlaceholder: "noreply{'@'}example.com", fromName: 'From Name', fromNamePlaceholder: 'Sub2API', useTls: 'Use TLS', useTlsHint: 'Enable TLS encryption for SMTP connection' }, testEmail: { title: 'Send Test Email', description: 'Send a test email to verify your SMTP configuration', recipientEmail: 'Recipient Email', recipientEmailPlaceholder: "test{'@'}example.com", sendTestEmail: 'Send Test Email', sending: 'Sending...', enterRecipientHint: 'Please enter a recipient email address' }, adminApiKey: { title: 'Admin API Key', description: 'Global API key for external system integration with full admin access', notConfigured: 'Admin API key not configured', configured: 'Admin API key is active', currentKey: 'Current Key', regenerate: 'Regenerate', regenerating: 'Regenerating...', delete: 'Delete', deleting: 'Deleting...', create: 'Create Key', creating: 'Creating...', regenerateConfirm: 'Are you sure? The current key will be immediately invalidated.', deleteConfirm: 'Are you sure you want to delete the admin API key? External integrations will stop working.', keyGenerated: 'New admin API key generated', keyDeleted: 'Admin API key deleted', copyKey: 'Copy Key', keyCopied: 'Key copied to clipboard', keyWarning: 'This key will only be shown once. Please copy it now.', securityWarning: 'Warning: This key provides full admin access. Keep it secure.', usage: 'Usage: Add to request header - x-api-key: ' }, saveSettings: 'Save Settings', saving: 'Saving...', settingsSaved: 'Settings saved successfully', smtpConnectionSuccess: 'SMTP connection successful', testEmailSent: 'Test email sent successfully', failedToLoad: 'Failed to load settings', failedToSave: 'Failed to save settings', failedToTestSmtp: 'SMTP connection test failed', failedToSendTestEmail: 'Failed to send test email' } }, // Subscription Progress (Header component) subscriptionProgress: { title: 'My Subscriptions', viewDetails: 'View subscription details', activeCount: '{count} active subscription(s)', daily: 'Daily', weekly: 'Weekly', monthly: 'Monthly', daysRemaining: '{days} days left', expired: 'Expired', expiresToday: 'Expires today', expiresTomorrow: 'Expires tomorrow', viewAll: 'View all subscriptions', noSubscriptions: 'No active subscriptions' }, // Version Badge version: { currentVersion: 'Current Version', latestVersion: 'Latest Version', upToDate: "You're running the latest version.", updateAvailable: 'A new version is available!', releaseNotes: 'Release Notes', noReleaseNotes: 'No release notes', viewUpdate: 'View Update', viewRelease: 'View Release', viewChangelog: 'View Changelog', refresh: 'Refresh', sourceMode: 'Source Build', sourceModeHint: 'Source build, use git pull to update', updateNow: 'Update Now', updating: 'Updating...', updateComplete: 'Update Complete', updateFailed: 'Update Failed', restartRequired: 'Please restart the service to apply the update', restartNow: 'Restart Now', restarting: 'Restarting...', retry: 'Retry' }, // User Subscriptions Page userSubscriptions: { title: 'My Subscriptions', description: 'View your subscription plans and usage', noActiveSubscriptions: 'No Active Subscriptions', noActiveSubscriptionsDesc: "You don't have any active subscriptions. Contact administrator to get one.", status: { active: 'Active', expired: 'Expired', revoked: 'Revoked' }, usage: 'Usage', expires: 'Expires', noExpiration: 'No expiration', unlimited: 'Unlimited', daily: 'Daily', weekly: 'Weekly', monthly: 'Monthly', daysRemaining: '{days} days remaining', expiresOn: 'Expires on {date}', resetIn: 'Resets in {time}', windowNotActive: 'Awaiting first use', usageOf: '{used} of {limit}' } }