refactor(mobile): Remove i18n, expand core screens, update plan
BREAKING: Removed multi-language support (i18n) - will be re-added later Changes: - Removed i18n system (6 language files, LanguageContext) - Expanded WalletScreen, SettingsScreen, SwapScreen with more features - Added KurdistanSun component, HEZ/PEZ token icons - Added EditProfileScreen, WalletSetupScreen - Added button e2e tests (Profile, Settings, Wallet) - Updated plan: honest assessment - 42 nav buttons with mock data - Fixed terminology: Polkadot→Pezkuwi, Substrate→Bizinikiwi Reality check: UI complete with mock data, converting to production one-by-one
@@ -1,70 +1,25 @@
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { View, ActivityIndicator, StyleSheet } from 'react-native';
|
||||
import React from 'react';
|
||||
import { StatusBar } from 'expo-status-bar';
|
||||
import { initializeI18n } from './src/i18n';
|
||||
import { ErrorBoundary } from './src/components/ErrorBoundary';
|
||||
import { LanguageProvider } from './src/contexts/LanguageContext';
|
||||
import { AuthProvider } from './src/contexts/AuthContext';
|
||||
import { PezkuwiProvider } from './src/contexts/PezkuwiContext';
|
||||
import { BiometricAuthProvider } from './src/contexts/BiometricAuthContext';
|
||||
import { ThemeProvider } from './src/contexts/ThemeContext';
|
||||
import AppNavigator from './src/navigation/AppNavigator';
|
||||
import { KurdistanColors } from './src/theme/colors';
|
||||
|
||||
export default function App() {
|
||||
const [isI18nInitialized, setIsI18nInitialized] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// Initialize i18n on app start
|
||||
const initApp = async () => {
|
||||
try {
|
||||
console.log('🚀 App starting...');
|
||||
console.log('🔧 Initializing i18n...');
|
||||
await initializeI18n();
|
||||
console.log('✅ i18n initialized');
|
||||
setIsI18nInitialized(true);
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to initialize i18n:', error);
|
||||
// Fallback: Still show app but with default language
|
||||
setIsI18nInitialized(true);
|
||||
}
|
||||
};
|
||||
|
||||
initApp();
|
||||
}, []);
|
||||
|
||||
if (!isI18nInitialized) {
|
||||
return (
|
||||
<View style={styles.loadingContainer}>
|
||||
<ActivityIndicator size="large" color={KurdistanColors.kesk} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<ErrorBoundary>
|
||||
<ThemeProvider>
|
||||
<AuthProvider>
|
||||
<PezkuwiProvider>
|
||||
<LanguageProvider>
|
||||
<BiometricAuthProvider>
|
||||
<StatusBar style="auto" />
|
||||
<AppNavigator />
|
||||
</BiometricAuthProvider>
|
||||
</LanguageProvider>
|
||||
<BiometricAuthProvider>
|
||||
<StatusBar style="auto" />
|
||||
<AppNavigator />
|
||||
</BiometricAuthProvider>
|
||||
</PezkuwiProvider>
|
||||
</AuthProvider>
|
||||
</ThemeProvider>
|
||||
</ErrorBoundary>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
loadingContainer: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
backgroundColor: KurdistanColors.spi,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -1,408 +0,0 @@
|
||||
# ✅ PHASE 1 COMPLETE - Settings Screen Full Implementation
|
||||
|
||||
**Date:** 2026-01-14
|
||||
**Duration:** ~3 hours
|
||||
**Status:** COMPLETE
|
||||
|
||||
---
|
||||
|
||||
## Objective
|
||||
|
||||
Make ALL features in Settings screen fully functional - no "Coming Soon" alerts.
|
||||
|
||||
---
|
||||
|
||||
## Changes Made
|
||||
|
||||
### 1. Dark Mode ✅
|
||||
|
||||
**Files:**
|
||||
- `/home/mamostehp/pwap/shared/theme/colors.ts` - Added LightColors & DarkColors
|
||||
- `/home/mamostehp/pwap/mobile/src/contexts/ThemeContext.tsx` - Added colors export
|
||||
- `/home/mamostehp/pwap/mobile/src/screens/SettingsScreen.tsx` - Connected theme
|
||||
|
||||
**Features:**
|
||||
- Toggle switches between light/dark theme
|
||||
- Theme persists in AsyncStorage (`@pezkuwi/theme`)
|
||||
- All screens use dynamic colors from `useTheme().colors`
|
||||
- StatusBar adapts to theme (light-content / dark-content)
|
||||
|
||||
**Colors:**
|
||||
```typescript
|
||||
LightColors: {
|
||||
background: '#F5F5F5',
|
||||
surface: '#FFFFFF',
|
||||
text: '#000000',
|
||||
textSecondary: '#666666',
|
||||
border: '#E0E0E0',
|
||||
}
|
||||
|
||||
DarkColors: {
|
||||
background: '#121212',
|
||||
surface: '#1E1E1E',
|
||||
text: '#FFFFFF',
|
||||
textSecondary: '#B0B0B0',
|
||||
border: '#333333',
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2. Font Size ✅
|
||||
|
||||
**Files:**
|
||||
- `/home/mamostehp/pwap/mobile/src/contexts/ThemeContext.tsx` - Added fontSize state
|
||||
|
||||
**Features:**
|
||||
- 3 sizes: Small (87.5%), Medium (100%), Large (112.5%)
|
||||
- Persists in AsyncStorage (`@pezkuwi/font_size`)
|
||||
- Exposes `fontScale` multiplier for responsive text
|
||||
- Alert dialog for selection
|
||||
|
||||
**Usage:**
|
||||
```typescript
|
||||
const { fontSize, setFontSize, fontScale } = useTheme();
|
||||
// fontScale: 0.875 | 1 | 1.125
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. Biometric Authentication ✅
|
||||
|
||||
**Files:**
|
||||
- `/home/mamostehp/pwap/mobile/src/screens/SettingsScreen.tsx` - Connected BiometricAuthContext
|
||||
|
||||
**Features:**
|
||||
- Fingerprint / Face ID support via `expo-local-authentication`
|
||||
- Checks hardware availability
|
||||
- Verifies enrollment before enabling
|
||||
- Displays biometric type in subtitle (fingerprint/facial/iris)
|
||||
- Full context already existed in BiometricAuthContext.tsx
|
||||
|
||||
**Flow:**
|
||||
1. User toggles ON → Check if biometric available → Prompt for authentication
|
||||
2. If success → Save to AsyncStorage → Show "Enabled (fingerprint)"
|
||||
3. User toggles OFF → Disable → Show "Disabled"
|
||||
|
||||
---
|
||||
|
||||
### 4. Change Password ✅
|
||||
|
||||
**Files:**
|
||||
- `/home/mamostehp/pwap/mobile/src/contexts/AuthContext.tsx` - Updated changePassword signature
|
||||
- `/home/mamostehp/pwap/mobile/src/components/ChangePasswordModal.tsx` - NEW
|
||||
|
||||
**Features:**
|
||||
- **Current Password verification** - Re-authenticates with Supabase before changing
|
||||
- **New Password** - Minimum 6 characters
|
||||
- **Confirm Password** - Must match new password
|
||||
- **Forgot Password link** - Sends reset email via Supabase
|
||||
- Full validation with error messages
|
||||
|
||||
**Implementation:**
|
||||
```typescript
|
||||
// AuthContext
|
||||
changePassword(newPassword, currentPassword) {
|
||||
// 1. Verify current password by sign in
|
||||
// 2. If correct, update to new password
|
||||
// 3. Return error or success
|
||||
}
|
||||
|
||||
resetPassword(email) {
|
||||
// Send password reset email
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. Email Notifications ✅
|
||||
|
||||
**Files:**
|
||||
- `/home/mamostehp/pwap/mobile/src/components/EmailNotificationsModal.tsx` - NEW
|
||||
|
||||
**Features:**
|
||||
- 4 categories with toggle switches:
|
||||
- 💸 Transaction Updates
|
||||
- 🗳️ Governance Alerts
|
||||
- 🔒 Security Alerts
|
||||
- 📢 Marketing & Updates
|
||||
- Persists preferences in AsyncStorage (`@pezkuwi/email_notifications`)
|
||||
- Professional modal design with save/cancel
|
||||
|
||||
---
|
||||
|
||||
### 6. Push Notifications ✅
|
||||
|
||||
**Features:**
|
||||
- Toggle switch (state only, no actual push setup yet)
|
||||
- Ready for expo-notifications integration
|
||||
|
||||
---
|
||||
|
||||
### 7. Terms & Privacy ✅
|
||||
|
||||
**Files:**
|
||||
- `/home/mamostehp/pwap/mobile/src/components/TermsOfServiceModal.tsx` - EXISTING
|
||||
- `/home/mamostehp/pwap/mobile/src/components/PrivacyPolicyModal.tsx` - EXISTING
|
||||
|
||||
**Features:**
|
||||
- Both modals already existed from Phase 0
|
||||
- Connected to Settings buttons
|
||||
- Full legal text with Accept button
|
||||
|
||||
---
|
||||
|
||||
### 8. About & Help ✅
|
||||
|
||||
**Features:**
|
||||
- **About** - Shows app name + version 1.0.0
|
||||
- **Help** - Shows support email: support@pezkuwichain.io
|
||||
- Simple Alert dialogs
|
||||
|
||||
---
|
||||
|
||||
### 9. Removed Features
|
||||
|
||||
**Two-Factor Auth** - Removed (too complex for current scope)
|
||||
|
||||
---
|
||||
|
||||
## Code Quality Improvements
|
||||
|
||||
### Fixed Deprecation Warnings
|
||||
|
||||
**Issue:** `shadow*" style props are deprecated. Use "boxShadow"`
|
||||
|
||||
**Fix:**
|
||||
```typescript
|
||||
// BEFORE
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowOpacity: 0.05,
|
||||
shadowRadius: 4,
|
||||
|
||||
// AFTER
|
||||
boxShadow: '0 2px 4px rgba(0, 0, 0, 0.05)',
|
||||
```
|
||||
|
||||
**Files Fixed:**
|
||||
- SettingsScreen.tsx
|
||||
|
||||
### Fixed React Native Web Compatibility
|
||||
|
||||
**Issue:** Alert.alert() with button arrays doesn't work properly on React Native Web
|
||||
|
||||
**Fix:**
|
||||
- Created FontSizeModal.tsx to replace Alert-based font size selector
|
||||
- Simplified biometric toggle to avoid button arrays
|
||||
- Now all interactive elements use proper modals or simple alerts
|
||||
|
||||
**Files Fixed:**
|
||||
- SettingsScreen.tsx - Replaced Alert.alert() with modal
|
||||
- FontSizeModal.tsx - NEW professional font size selector
|
||||
|
||||
### Fixed TypeScript Errors
|
||||
|
||||
**Issue:** TermsOfServiceModal and PrivacyPolicyModal don't accept `onAccept` prop
|
||||
|
||||
**Fix:**
|
||||
- Removed `onAccept` prop from modal calls in SettingsScreen
|
||||
- Modals now only use `visible` and `onClose` props
|
||||
|
||||
**Files Fixed:**
|
||||
- SettingsScreen.tsx
|
||||
|
||||
---
|
||||
|
||||
## Files Created
|
||||
|
||||
1. `/home/mamostehp/pwap/mobile/src/components/EmailNotificationsModal.tsx` - 350 lines
|
||||
2. `/home/mamostehp/pwap/mobile/src/components/ChangePasswordModal.tsx` - 350 lines
|
||||
3. `/home/mamostehp/pwap/mobile/src/components/FontSizeModal.tsx` - 200 lines
|
||||
|
||||
**Total:** 3 new files, 900 lines of code
|
||||
|
||||
---
|
||||
|
||||
## Files Modified
|
||||
|
||||
1. `/home/mamostehp/pwap/shared/theme/colors.ts` - Added DarkColors
|
||||
2. `/home/mamostehp/pwap/mobile/src/contexts/ThemeContext.tsx` - Added fontSize + colors
|
||||
3. `/home/mamostehp/pwap/mobile/src/contexts/AuthContext.tsx` - Added changePassword + resetPassword
|
||||
4. `/home/mamostehp/pwap/mobile/src/screens/SettingsScreen.tsx` - Connected all features
|
||||
5. `/home/mamostehp/pwap/mobile/App.tsx` - Added ThemeProvider
|
||||
|
||||
**Total:** 5 files modified
|
||||
|
||||
---
|
||||
|
||||
## Settings Screen - Complete Feature List
|
||||
|
||||
### APPEARANCE ✅
|
||||
- **Dark Mode** - Light/Dark theme toggle
|
||||
- **Font Size** - Small/Medium/Large selection
|
||||
|
||||
### SECURITY ✅
|
||||
- **Biometric Auth** - Fingerprint/Face ID
|
||||
- **Change Password** - With current password verification
|
||||
|
||||
### NOTIFICATIONS ✅
|
||||
- **Push Notifications** - Toggle (ready for implementation)
|
||||
- **Email Notifications** - 4 category preferences
|
||||
|
||||
### ABOUT ✅
|
||||
- **About** - App version info
|
||||
- **Terms of Service** - Full legal text modal
|
||||
- **Privacy Policy** - Full privacy text modal
|
||||
- **Help & Support** - Support email
|
||||
|
||||
---
|
||||
|
||||
## User Experience
|
||||
|
||||
### Before Phase 1:
|
||||
❌ Dark Mode - Alert "Coming Soon"
|
||||
❌ Font Size - Alert with no persistence
|
||||
❌ Biometric Auth - Partial implementation
|
||||
❌ Change Password - Alert.prompt (doesn't work on Android)
|
||||
❌ Email Notifications - Alert "Coming Soon"
|
||||
❌ Two-Factor Auth - Alert "Coming Soon"
|
||||
|
||||
### After Phase 1:
|
||||
✅ Dark Mode - Fully functional, theme changes entire app
|
||||
✅ Font Size - 3 sizes, persists, ready for implementation
|
||||
✅ Biometric Auth - Fully functional with device hardware
|
||||
✅ Change Password - Professional modal with current password verification
|
||||
✅ Email Notifications - 4-category modal with persistence
|
||||
✅ Push Notifications - Toggle ready
|
||||
✅ Terms/Privacy - Full modals
|
||||
✅ About/Help - Info displayed
|
||||
|
||||
---
|
||||
|
||||
## Technical Architecture
|
||||
|
||||
### State Management
|
||||
|
||||
**ThemeContext:**
|
||||
```typescript
|
||||
{
|
||||
isDarkMode: boolean,
|
||||
toggleDarkMode: () => Promise<void>,
|
||||
colors: LightColors | DarkColors,
|
||||
fontSize: 'small' | 'medium' | 'large',
|
||||
setFontSize: (size) => Promise<void>,
|
||||
fontScale: 0.875 | 1 | 1.125,
|
||||
}
|
||||
```
|
||||
|
||||
**BiometricAuthContext:**
|
||||
```typescript
|
||||
{
|
||||
isBiometricSupported: boolean,
|
||||
isBiometricEnrolled: boolean,
|
||||
isBiometricAvailable: boolean,
|
||||
biometricType: 'fingerprint' | 'facial' | 'iris' | 'none',
|
||||
isBiometricEnabled: boolean,
|
||||
authenticate: () => Promise<boolean>,
|
||||
enableBiometric: () => Promise<boolean>,
|
||||
disableBiometric: () => Promise<void>,
|
||||
}
|
||||
```
|
||||
|
||||
**AuthContext:**
|
||||
```typescript
|
||||
{
|
||||
user: User | null,
|
||||
changePassword: (newPassword, currentPassword) => Promise<{error}>,
|
||||
resetPassword: (email) => Promise<{error}>,
|
||||
}
|
||||
```
|
||||
|
||||
### AsyncStorage Keys
|
||||
|
||||
- `@pezkuwi/theme` - 'light' | 'dark'
|
||||
- `@pezkuwi/font_size` - 'small' | 'medium' | 'large'
|
||||
- `@biometric_enabled` - 'true' | 'false'
|
||||
- `@pezkuwi/email_notifications` - JSON preferences object
|
||||
|
||||
---
|
||||
|
||||
## Testing Checklist
|
||||
|
||||
### Manual Testing:
|
||||
|
||||
1. **Dark Mode:**
|
||||
- [ ] Toggle ON → Theme changes to dark
|
||||
- [ ] Restart app → Theme persists
|
||||
- [ ] Toggle OFF → Theme changes to light
|
||||
|
||||
2. **Font Size:**
|
||||
- [ ] Select Small → Text shrinks
|
||||
- [ ] Select Large → Text grows
|
||||
- [ ] Restart app → Font size persists
|
||||
|
||||
3. **Biometric Auth:**
|
||||
- [ ] Toggle ON → Fingerprint prompt appears
|
||||
- [ ] Authenticate → Enabled
|
||||
- [ ] Toggle OFF → Disabled
|
||||
|
||||
4. **Change Password:**
|
||||
- [ ] Open modal → 3 inputs visible
|
||||
- [ ] Enter wrong current password → Error
|
||||
- [ ] Passwords don't match → Error
|
||||
- [ ] Valid inputs → Success
|
||||
- [ ] Click "Forgot Password" → Email sent
|
||||
|
||||
5. **Email Notifications:**
|
||||
- [ ] Open modal → 4 categories visible
|
||||
- [ ] Toggle switches → State updates
|
||||
- [ ] Click Save → Preferences persist
|
||||
- [ ] Reopen modal → Toggles show saved state
|
||||
|
||||
6. **Terms/Privacy:**
|
||||
- [ ] Click Terms → Modal opens with full text
|
||||
- [ ] Click Privacy → Modal opens with full text
|
||||
|
||||
7. **About/Help:**
|
||||
- [ ] Click About → Shows version 1.0.0
|
||||
- [ ] Click Help → Shows support email
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria: MET ✅
|
||||
|
||||
- ✅ All Settings features functional
|
||||
- ✅ No "Coming Soon" alerts
|
||||
- ✅ Theme system implemented
|
||||
- ✅ Font size system ready
|
||||
- ✅ Biometric auth working
|
||||
- ✅ Password change with verification
|
||||
- ✅ Email preferences modal
|
||||
- ✅ Terms/Privacy accessible
|
||||
- ✅ Code quality (no deprecated props)
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
**Phase 2:** Finance Features
|
||||
- Wallet screen implementation
|
||||
- Transfer/Receive modals
|
||||
- Transaction history
|
||||
- Token management
|
||||
|
||||
**Ready to proceed with Phase 2!**
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
**Phase 1 delivered a FULLY FUNCTIONAL Settings screen.** Every button works, every toggle persists, every modal is professional. No placeholders, no "Coming Soon" alerts.
|
||||
|
||||
**Lines of Code Added:** ~700 lines
|
||||
**Files Created:** 2 modals
|
||||
**Files Modified:** 5 core files
|
||||
**Features Delivered:** 10 complete features
|
||||
|
||||
**Phase 1: COMPLETE** 🎉
|
||||
@@ -194,29 +194,6 @@ jest.mock('../shared/lib/p2p-fiat', () => ({
|
||||
acceptOffer: jest.fn(() => Promise.resolve(true)),
|
||||
}));
|
||||
|
||||
// Mock shared i18n module
|
||||
jest.mock('../shared/i18n', () => ({
|
||||
translations: {
|
||||
en: { welcome: 'Welcome' },
|
||||
tr: { welcome: 'Hoş geldiniz' },
|
||||
kmr: { welcome: 'Bi xêr hatî' },
|
||||
ckb: { welcome: 'بەخێربێن' },
|
||||
ar: { welcome: 'مرحبا' },
|
||||
fa: { welcome: 'خوش آمدید' },
|
||||
},
|
||||
LANGUAGES: [
|
||||
{ code: 'en', name: 'English', nativeName: 'English', rtl: false },
|
||||
{ code: 'tr', name: 'Turkish', nativeName: 'Türkçe', rtl: false },
|
||||
{ code: 'kmr', name: 'Kurdish Kurmanji', nativeName: 'Kurmancî', rtl: false },
|
||||
{ code: 'ckb', name: 'Kurdish Sorani', nativeName: 'سۆرانی', rtl: true },
|
||||
{ code: 'ar', name: 'Arabic', nativeName: 'العربية', rtl: true },
|
||||
{ code: 'fa', name: 'Persian', nativeName: 'فارسی', rtl: true },
|
||||
],
|
||||
DEFAULT_LANGUAGE: 'en',
|
||||
LANGUAGE_STORAGE_KEY: '@language',
|
||||
isRTL: jest.fn((code) => ['ckb', 'ar', 'fa'].includes(code)),
|
||||
}));
|
||||
|
||||
// Mock shared wallet utilities (handles import.meta)
|
||||
jest.mock('../shared/lib/wallet', () => ({
|
||||
formatBalance: jest.fn((amount, decimals) => '0.00'),
|
||||
@@ -241,33 +218,6 @@ jest.mock('../shared/lib/citizenship-workflow', () => ({
|
||||
createCitizenshipRequest: jest.fn(() => Promise.resolve({ id: '123' })),
|
||||
}));
|
||||
|
||||
// Mock react-i18next for i18n initialization
|
||||
jest.mock('react-i18next', () => ({
|
||||
...jest.requireActual('react-i18next'),
|
||||
useTranslation: () => ({
|
||||
t: (key) => key,
|
||||
i18n: {
|
||||
language: 'en',
|
||||
changeLanguage: jest.fn(() => Promise.resolve()),
|
||||
isInitialized: true,
|
||||
},
|
||||
}),
|
||||
initReactI18next: {
|
||||
type: '3rdParty',
|
||||
init: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
// Mock i18next
|
||||
jest.mock('i18next', () => ({
|
||||
...jest.requireActual('i18next'),
|
||||
init: jest.fn(() => Promise.resolve()),
|
||||
changeLanguage: jest.fn(() => Promise.resolve()),
|
||||
use: jest.fn(function () { return this; }),
|
||||
language: 'en',
|
||||
isInitialized: true,
|
||||
}));
|
||||
|
||||
// Note: Alert is mocked in individual test files where needed
|
||||
|
||||
// Silence console warnings in tests
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Reset Wallet Script
|
||||
*
|
||||
* Clears all wallet data from AsyncStorage for testing purposes.
|
||||
* Run with: node scripts/reset-wallet.js
|
||||
*
|
||||
* Note: This only works in development. For the actual app,
|
||||
* you need to clear the app data or use the in-app reset.
|
||||
*/
|
||||
|
||||
console.log('='.repeat(50));
|
||||
console.log('WALLET RESET INSTRUCTIONS');
|
||||
console.log('='.repeat(50));
|
||||
console.log('');
|
||||
console.log('To reset wallet data in the app, do ONE of these:');
|
||||
console.log('');
|
||||
console.log('1. Clear App Data (Easiest):');
|
||||
console.log(' - iOS Simulator: Device > Erase All Content and Settings');
|
||||
console.log(' - Android: Settings > Apps > Pezkuwi > Clear Data');
|
||||
console.log(' - Expo Go: Shake device > Clear AsyncStorage');
|
||||
console.log('');
|
||||
console.log('2. In Expo Go, run this in the console:');
|
||||
console.log(' AsyncStorage.multiRemove([');
|
||||
console.log(' "@pezkuwi_wallets",');
|
||||
console.log(' "@pezkuwi_selected_account",');
|
||||
console.log(' "@pezkuwi_selected_network"');
|
||||
console.log(' ])');
|
||||
console.log('');
|
||||
console.log('3. Add temp reset button (already added to Settings)');
|
||||
console.log('');
|
||||
console.log('='.repeat(50));
|
||||
@@ -22,7 +22,7 @@ const mockUser: User = {
|
||||
created_at: new Date().toISOString(),
|
||||
};
|
||||
|
||||
const mockAuthContext: AuthContextType = {
|
||||
export const mockAuthContext: AuthContextType = {
|
||||
user: mockUser,
|
||||
session: null,
|
||||
loading: false,
|
||||
|
||||
@@ -7,20 +7,36 @@ interface BiometricAuthContextType {
|
||||
isBiometricAvailable: boolean;
|
||||
biometricType: 'fingerprint' | 'facial' | 'iris' | 'none';
|
||||
isBiometricEnabled: boolean;
|
||||
isLocked: boolean;
|
||||
autoLockTimer: number;
|
||||
authenticate: () => Promise<boolean>;
|
||||
enableBiometric: () => Promise<boolean>;
|
||||
disableBiometric: () => Promise<void>;
|
||||
setPinCode: (pin: string) => Promise<void>;
|
||||
verifyPinCode: (pin: string) => Promise<boolean>;
|
||||
setAutoLockTimer: (minutes: number) => Promise<void>;
|
||||
lock: () => void;
|
||||
unlock: () => void;
|
||||
checkAutoLock: () => Promise<void>;
|
||||
}
|
||||
|
||||
const mockBiometricContext: BiometricAuthContextType = {
|
||||
export const mockBiometricContext: BiometricAuthContextType = {
|
||||
isBiometricSupported: true,
|
||||
isBiometricEnrolled: true,
|
||||
isBiometricAvailable: true,
|
||||
biometricType: 'fingerprint',
|
||||
isBiometricEnabled: false,
|
||||
isLocked: false,
|
||||
autoLockTimer: 5,
|
||||
authenticate: jest.fn().mockResolvedValue(true),
|
||||
enableBiometric: jest.fn().mockResolvedValue(true),
|
||||
disableBiometric: jest.fn().mockResolvedValue(undefined),
|
||||
setPinCode: jest.fn().mockResolvedValue(undefined),
|
||||
verifyPinCode: jest.fn().mockResolvedValue(true),
|
||||
setAutoLockTimer: jest.fn().mockResolvedValue(undefined),
|
||||
lock: jest.fn(),
|
||||
unlock: jest.fn(),
|
||||
checkAutoLock: jest.fn().mockResolvedValue(undefined),
|
||||
};
|
||||
|
||||
const BiometricAuthContext = createContext<BiometricAuthContextType>(mockBiometricContext);
|
||||
|
||||
@@ -19,7 +19,7 @@ interface ThemeContextType {
|
||||
fontScale: number;
|
||||
}
|
||||
|
||||
const mockThemeContext: ThemeContextType = {
|
||||
export const mockThemeContext: ThemeContextType = {
|
||||
isDarkMode: false,
|
||||
toggleDarkMode: jest.fn().mockResolvedValue(undefined),
|
||||
colors: LightColors,
|
||||
|
||||
@@ -0,0 +1,634 @@
|
||||
/**
|
||||
* ProfileButton E2E Tests
|
||||
*
|
||||
* Tests the Profile button in BottomTabNavigator and all features
|
||||
* within ProfileScreen and EditProfileScreen.
|
||||
*
|
||||
* Test Coverage:
|
||||
* - Profile screen rendering and loading state
|
||||
* - Profile data display (name, email, avatar)
|
||||
* - Avatar picker modal
|
||||
* - Edit Profile navigation
|
||||
* - About Pezkuwi alert
|
||||
* - Logout flow
|
||||
* - Referrals navigation
|
||||
* - EditProfileScreen rendering
|
||||
* - EditProfileScreen form interactions
|
||||
* - EditProfileScreen save/cancel flows
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render, fireEvent, waitFor, act } from '@testing-library/react-native';
|
||||
import { Alert } from 'react-native';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
|
||||
// Mock contexts
|
||||
jest.mock('../../contexts/ThemeContext', () => require('../../__mocks__/contexts/ThemeContext'));
|
||||
jest.mock('../../contexts/AuthContext', () => require('../../__mocks__/contexts/AuthContext'));
|
||||
jest.mock('../../contexts/PezkuwiContext', () => ({
|
||||
usePezkuwi: () => ({
|
||||
endpoint: 'wss://rpc.pezkuwichain.io:9944',
|
||||
setEndpoint: jest.fn(),
|
||||
api: null,
|
||||
isApiReady: false,
|
||||
selectedAccount: null,
|
||||
}),
|
||||
}));
|
||||
|
||||
// Mock navigation - extended from jest.setup.cjs
|
||||
const mockNavigate = jest.fn();
|
||||
const mockGoBack = jest.fn();
|
||||
jest.mock('@react-navigation/native', () => {
|
||||
const actualNav = jest.requireActual('@react-navigation/native');
|
||||
const ReactModule = require('react');
|
||||
return {
|
||||
...actualNav,
|
||||
useNavigation: () => ({
|
||||
navigate: mockNavigate,
|
||||
goBack: mockGoBack,
|
||||
setOptions: jest.fn(),
|
||||
addListener: jest.fn(),
|
||||
removeListener: jest.fn(),
|
||||
}),
|
||||
useFocusEffect: (callback: () => (() => void) | void) => {
|
||||
// Use useEffect to properly handle the callback lifecycle
|
||||
ReactModule.useEffect(() => {
|
||||
const unsubscribe = callback();
|
||||
return unsubscribe;
|
||||
}, [callback]);
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
// Mock Alert
|
||||
const mockAlert = jest.spyOn(Alert, 'alert');
|
||||
|
||||
// Mock Supabase with profile data
|
||||
const mockSupabaseFrom = jest.fn();
|
||||
const mockProfileData = {
|
||||
id: 'test-user-id',
|
||||
full_name: 'Test User',
|
||||
avatar_url: 'avatar5',
|
||||
wallet_address: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',
|
||||
created_at: '2026-01-01T00:00:00.000Z',
|
||||
referral_code: 'TESTCODE',
|
||||
referral_count: 5,
|
||||
};
|
||||
|
||||
jest.mock('../../lib/supabase', () => ({
|
||||
supabase: {
|
||||
from: (table: string) => {
|
||||
mockSupabaseFrom(table);
|
||||
return {
|
||||
select: jest.fn().mockReturnThis(),
|
||||
update: jest.fn().mockReturnThis(),
|
||||
eq: jest.fn().mockReturnThis(),
|
||||
single: jest.fn().mockResolvedValue({
|
||||
data: mockProfileData,
|
||||
error: null,
|
||||
}),
|
||||
};
|
||||
},
|
||||
storage: {
|
||||
from: jest.fn().mockReturnValue({
|
||||
upload: jest.fn().mockResolvedValue({ data: { path: 'test.jpg' }, error: null }),
|
||||
getPublicUrl: jest.fn().mockReturnValue({ data: { publicUrl: 'https://test.com/avatar.jpg' } }),
|
||||
}),
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
import ProfileScreen from '../../screens/ProfileScreen';
|
||||
import EditProfileScreen from '../../screens/EditProfileScreen';
|
||||
import { MockThemeProvider, mockThemeContext } from '../../__mocks__/contexts/ThemeContext';
|
||||
import { MockAuthProvider, mockAuthContext } from '../../__mocks__/contexts/AuthContext';
|
||||
|
||||
// ============================================================
|
||||
// TEST HELPERS
|
||||
// ============================================================
|
||||
|
||||
const renderProfileScreen = (overrides: {
|
||||
theme?: Partial<typeof mockThemeContext>;
|
||||
auth?: Partial<typeof mockAuthContext>;
|
||||
} = {}) => {
|
||||
return render(
|
||||
<MockAuthProvider value={overrides.auth}>
|
||||
<MockThemeProvider value={overrides.theme}>
|
||||
<ProfileScreen />
|
||||
</MockThemeProvider>
|
||||
</MockAuthProvider>
|
||||
);
|
||||
};
|
||||
|
||||
const renderEditProfileScreen = (overrides: {
|
||||
theme?: Partial<typeof mockThemeContext>;
|
||||
auth?: Partial<typeof mockAuthContext>;
|
||||
} = {}) => {
|
||||
return render(
|
||||
<MockAuthProvider value={overrides.auth}>
|
||||
<MockThemeProvider value={overrides.theme}>
|
||||
<EditProfileScreen />
|
||||
</MockThemeProvider>
|
||||
</MockAuthProvider>
|
||||
);
|
||||
};
|
||||
|
||||
// ============================================================
|
||||
// TESTS
|
||||
// ============================================================
|
||||
|
||||
describe('ProfileButton E2E Tests', () => {
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks();
|
||||
await AsyncStorage.clear();
|
||||
mockAlert.mockClear();
|
||||
mockNavigate.mockClear();
|
||||
mockGoBack.mockClear();
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 1. PROFILE SCREEN RENDERING TESTS
|
||||
// ----------------------------------------------------------
|
||||
describe('1. ProfileScreen Rendering', () => {
|
||||
it('renders Profile screen with main container', async () => {
|
||||
const { getByTestId } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('profile-screen')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders header gradient section', async () => {
|
||||
const { getByTestId } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('profile-header-gradient')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders profile cards container', async () => {
|
||||
const { getByTestId } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('profile-cards-container')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders scroll view', async () => {
|
||||
const { getByTestId } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('profile-scroll-view')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders footer with version info', async () => {
|
||||
const { getByTestId, getByText } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('profile-footer')).toBeTruthy();
|
||||
expect(getByText('Version 1.0.0')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 2. PROFILE DATA DISPLAY TESTS
|
||||
// ----------------------------------------------------------
|
||||
describe('2. Profile Data Display', () => {
|
||||
it('displays user name from profile data', async () => {
|
||||
const { getByTestId } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
const nameElement = getByTestId('profile-name');
|
||||
expect(nameElement).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('displays user email', async () => {
|
||||
const { getByTestId } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
const emailElement = getByTestId('profile-email');
|
||||
expect(emailElement).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('displays email card', async () => {
|
||||
const { getByTestId } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('profile-card-email')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('displays member since card', async () => {
|
||||
const { getByTestId } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('profile-card-member-since')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('displays referrals card with count', async () => {
|
||||
const { getByTestId, getByText } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('profile-card-referrals')).toBeTruthy();
|
||||
expect(getByText('5 people')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('displays referral code when available', async () => {
|
||||
const { getByTestId, getByText } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('profile-card-referral-code')).toBeTruthy();
|
||||
expect(getByText('TESTCODE')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('displays wallet address when available', async () => {
|
||||
const { getByTestId } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('profile-card-wallet')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 3. AVATAR TESTS
|
||||
// ----------------------------------------------------------
|
||||
describe('3. Avatar Display and Interaction', () => {
|
||||
it('renders avatar button', async () => {
|
||||
const { getByTestId } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('profile-avatar-button')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('displays emoji avatar when avatar_url is emoji ID', async () => {
|
||||
const { getByTestId } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
// avatar5 = 👩🏻
|
||||
expect(getByTestId('profile-avatar-emoji-container')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('opens avatar picker modal when avatar button is pressed', async () => {
|
||||
const { getByTestId, getByText } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
const avatarButton = getByTestId('profile-avatar-button');
|
||||
fireEvent.press(avatarButton);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
// AvatarPickerModal displays "Choose Your Avatar" as title
|
||||
expect(getByText('Choose Your Avatar')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 4. ACTION BUTTONS TESTS
|
||||
// ----------------------------------------------------------
|
||||
describe('4. Action Buttons', () => {
|
||||
it('renders Edit Profile button', async () => {
|
||||
const { getByTestId } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('profile-edit-button')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders About Pezkuwi button', async () => {
|
||||
const { getByTestId } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('profile-about-button')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('navigates to EditProfile when Edit Profile button is pressed', async () => {
|
||||
const { getByTestId } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
const editButton = getByTestId('profile-edit-button');
|
||||
fireEvent.press(editButton);
|
||||
});
|
||||
|
||||
expect(mockNavigate).toHaveBeenCalledWith('EditProfile');
|
||||
});
|
||||
|
||||
it('shows About Pezkuwi alert when button is pressed', async () => {
|
||||
const { getByTestId } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
const aboutButton = getByTestId('profile-about-button');
|
||||
fireEvent.press(aboutButton);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockAlert).toHaveBeenCalledWith(
|
||||
'About Pezkuwi',
|
||||
expect.stringContaining('Pezkuwi is a decentralized blockchain platform'),
|
||||
expect.any(Array)
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 5. REFERRALS NAVIGATION TEST
|
||||
// ----------------------------------------------------------
|
||||
describe('5. Referrals Navigation', () => {
|
||||
it('navigates to Referral screen when referrals card is pressed', async () => {
|
||||
const { getByTestId } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
const referralsCard = getByTestId('profile-card-referrals');
|
||||
fireEvent.press(referralsCard);
|
||||
});
|
||||
|
||||
expect(mockNavigate).toHaveBeenCalledWith('Referral');
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 6. LOGOUT TESTS
|
||||
// ----------------------------------------------------------
|
||||
describe('6. Logout Flow', () => {
|
||||
it('renders logout button', async () => {
|
||||
const { getByTestId } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('profile-logout-button')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('shows confirmation alert when logout button is pressed', async () => {
|
||||
const { getByTestId } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
const logoutButton = getByTestId('profile-logout-button');
|
||||
fireEvent.press(logoutButton);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockAlert).toHaveBeenCalledWith(
|
||||
'Logout',
|
||||
'Are you sure you want to logout?',
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ text: 'Cancel' }),
|
||||
expect.objectContaining({ text: 'Logout', style: 'destructive' }),
|
||||
])
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('calls signOut when logout is confirmed', async () => {
|
||||
const mockSignOut = jest.fn();
|
||||
const { getByTestId } = renderProfileScreen({
|
||||
auth: { signOut: mockSignOut },
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
const logoutButton = getByTestId('profile-logout-button');
|
||||
fireEvent.press(logoutButton);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
// Get the alert call arguments
|
||||
const alertCall = mockAlert.mock.calls[0];
|
||||
const buttons = alertCall[2];
|
||||
const logoutAction = buttons.find((b: any) => b.text === 'Logout');
|
||||
|
||||
// Simulate pressing Logout
|
||||
if (logoutAction?.onPress) {
|
||||
logoutAction.onPress();
|
||||
}
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockSignOut).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 7. DARK MODE SUPPORT TESTS
|
||||
// ----------------------------------------------------------
|
||||
describe('7. Dark Mode Support', () => {
|
||||
it('applies dark mode colors when enabled', async () => {
|
||||
const darkColors = {
|
||||
background: '#1A1A1A',
|
||||
surface: '#2A2A2A',
|
||||
text: '#FFFFFF',
|
||||
textSecondary: '#CCCCCC',
|
||||
border: '#404040',
|
||||
};
|
||||
|
||||
const { getByTestId } = renderProfileScreen({
|
||||
theme: { isDarkMode: true, colors: darkColors },
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('profile-screen')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 8. EDIT PROFILE SCREEN RENDERING
|
||||
// ----------------------------------------------------------
|
||||
describe('8. EditProfileScreen Rendering', () => {
|
||||
it('renders EditProfile screen with main container', async () => {
|
||||
const { getByTestId } = renderEditProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('edit-profile-screen')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders header with Cancel and Save buttons', async () => {
|
||||
const { getByTestId, getByText } = renderEditProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('edit-profile-header')).toBeTruthy();
|
||||
expect(getByTestId('edit-profile-cancel-button')).toBeTruthy();
|
||||
expect(getByTestId('edit-profile-save-button')).toBeTruthy();
|
||||
expect(getByText('Edit Profile')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders avatar section', async () => {
|
||||
const { getByTestId, getByText } = renderEditProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('edit-profile-avatar-section')).toBeTruthy();
|
||||
expect(getByText('Change Avatar')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders name input field', async () => {
|
||||
const { getByTestId, getByText } = renderEditProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('edit-profile-name-group')).toBeTruthy();
|
||||
expect(getByTestId('edit-profile-name-input')).toBeTruthy();
|
||||
expect(getByText('Display Name')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders read-only email field', async () => {
|
||||
const { getByTestId, getByText } = renderEditProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('edit-profile-email-group')).toBeTruthy();
|
||||
expect(getByText('Email cannot be changed')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 9. EDIT PROFILE FORM INTERACTIONS
|
||||
// ----------------------------------------------------------
|
||||
describe('9. EditProfileScreen Form Interactions', () => {
|
||||
it('allows editing name field', async () => {
|
||||
const { getByTestId } = renderEditProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
const nameInput = getByTestId('edit-profile-name-input');
|
||||
fireEvent.changeText(nameInput, 'New Name');
|
||||
});
|
||||
});
|
||||
|
||||
it('opens avatar modal when avatar button is pressed', async () => {
|
||||
const { getByTestId, getByText } = renderEditProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
const avatarButton = getByTestId('edit-profile-avatar-button');
|
||||
fireEvent.press(avatarButton);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByText('Change Avatar')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 10. EDIT PROFILE CANCEL FLOW
|
||||
// ----------------------------------------------------------
|
||||
describe('10. EditProfileScreen Cancel Flow', () => {
|
||||
it('goes back without alert when no changes made', async () => {
|
||||
const { getByTestId } = renderEditProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
const cancelButton = getByTestId('edit-profile-cancel-button');
|
||||
fireEvent.press(cancelButton);
|
||||
});
|
||||
|
||||
// Should navigate back directly without showing alert
|
||||
await waitFor(() => {
|
||||
expect(mockGoBack).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('shows discard alert when changes exist', async () => {
|
||||
const { getByTestId } = renderEditProfileScreen();
|
||||
|
||||
await waitFor(async () => {
|
||||
// Make a change
|
||||
const nameInput = getByTestId('edit-profile-name-input');
|
||||
fireEvent.changeText(nameInput, 'Changed Name');
|
||||
|
||||
// Try to cancel
|
||||
const cancelButton = getByTestId('edit-profile-cancel-button');
|
||||
fireEvent.press(cancelButton);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockAlert).toHaveBeenCalledWith(
|
||||
'Discard Changes?',
|
||||
'You have unsaved changes. Are you sure you want to go back?',
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ text: 'Keep Editing' }),
|
||||
expect.objectContaining({ text: 'Discard', style: 'destructive' }),
|
||||
])
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 11. EDIT PROFILE SAVE FLOW
|
||||
// ----------------------------------------------------------
|
||||
describe('11. EditProfileScreen Save Flow', () => {
|
||||
it('Save button is disabled when no changes', async () => {
|
||||
const { getByTestId } = renderEditProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
const saveButton = getByTestId('edit-profile-save-button');
|
||||
expect(saveButton).toBeTruthy();
|
||||
// Save button should have disabled styling when no changes
|
||||
});
|
||||
});
|
||||
|
||||
it('enables Save button when changes are made', async () => {
|
||||
const { getByTestId } = renderEditProfileScreen();
|
||||
|
||||
await waitFor(async () => {
|
||||
// Make a change
|
||||
const nameInput = getByTestId('edit-profile-name-input');
|
||||
fireEvent.changeText(nameInput, 'New Name Here');
|
||||
|
||||
// Save button should now be enabled
|
||||
const saveButton = getByTestId('edit-profile-save-button');
|
||||
expect(saveButton).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 12. EDGE CASES
|
||||
// ----------------------------------------------------------
|
||||
describe('12. Edge Cases', () => {
|
||||
it('handles user without profile data gracefully', async () => {
|
||||
// Override mock to return null profile
|
||||
jest.doMock('../../lib/supabase', () => ({
|
||||
supabase: {
|
||||
from: () => ({
|
||||
select: jest.fn().mockReturnThis(),
|
||||
eq: jest.fn().mockReturnThis(),
|
||||
single: jest.fn().mockResolvedValue({
|
||||
data: null,
|
||||
error: null,
|
||||
}),
|
||||
}),
|
||||
},
|
||||
}));
|
||||
|
||||
const { getByTestId } = renderProfileScreen();
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('profile-screen')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('displays fallback for missing user email', async () => {
|
||||
const { getByTestId } = renderProfileScreen({
|
||||
auth: { user: null },
|
||||
});
|
||||
|
||||
// Should handle gracefully
|
||||
await waitFor(() => {
|
||||
// Loading state or screen should render
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,563 @@
|
||||
/**
|
||||
* SettingsButton E2E Tests
|
||||
*
|
||||
* Tests the Settings button in DashboardScreen header and all features
|
||||
* within the SettingsScreen. These tests simulate real user interactions.
|
||||
*
|
||||
* Test Coverage:
|
||||
* - Settings screen rendering
|
||||
* - Dark Mode toggle
|
||||
* - Font Size selection
|
||||
* - Push Notifications toggle
|
||||
* - Email Updates toggle
|
||||
* - Network Node selection
|
||||
* - Biometric Security toggle
|
||||
* - Auto-Lock Timer selection
|
||||
* - Profile editing
|
||||
* - Sign Out flow
|
||||
* - Support links
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render, fireEvent, waitFor, act } from '@testing-library/react-native';
|
||||
import { Alert, Linking } from 'react-native';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
|
||||
// Mock contexts
|
||||
jest.mock('../../contexts/ThemeContext', () => require('../../__mocks__/contexts/ThemeContext'));
|
||||
jest.mock('../../contexts/BiometricAuthContext', () => require('../../__mocks__/contexts/BiometricAuthContext'));
|
||||
jest.mock('../../contexts/AuthContext', () => require('../../__mocks__/contexts/AuthContext'));
|
||||
jest.mock('../../contexts/PezkuwiContext', () => ({
|
||||
usePezkuwi: () => ({
|
||||
endpoint: 'wss://rpc.pezkuwichain.io:9944',
|
||||
setEndpoint: jest.fn(),
|
||||
api: null,
|
||||
isApiReady: false,
|
||||
selectedAccount: null,
|
||||
}),
|
||||
}));
|
||||
|
||||
// Mock Alert
|
||||
const mockAlert = jest.spyOn(Alert, 'alert');
|
||||
|
||||
// Mock Linking
|
||||
const mockLinkingOpenURL = jest.spyOn(Linking, 'openURL').mockImplementation(() => Promise.resolve(true));
|
||||
|
||||
// Mock Supabase
|
||||
jest.mock('../../lib/supabase', () => ({
|
||||
supabase: {
|
||||
from: jest.fn(() => ({
|
||||
select: jest.fn().mockReturnThis(),
|
||||
update: jest.fn().mockReturnThis(),
|
||||
eq: jest.fn().mockReturnThis(),
|
||||
maybeSingle: jest.fn().mockResolvedValue({
|
||||
data: {
|
||||
id: 'test-user-id',
|
||||
full_name: 'Test User',
|
||||
notifications_push: true,
|
||||
notifications_email: true,
|
||||
},
|
||||
error: null,
|
||||
}),
|
||||
})),
|
||||
},
|
||||
}));
|
||||
|
||||
import SettingsScreen from '../../screens/SettingsScreen';
|
||||
import { MockThemeProvider, mockThemeContext } from '../../__mocks__/contexts/ThemeContext';
|
||||
import { MockBiometricAuthProvider, mockBiometricContext } from '../../__mocks__/contexts/BiometricAuthContext';
|
||||
import { MockAuthProvider, mockAuthContext } from '../../__mocks__/contexts/AuthContext';
|
||||
|
||||
// ============================================================
|
||||
// TEST HELPERS
|
||||
// ============================================================
|
||||
|
||||
const renderSettingsScreen = (overrides: {
|
||||
theme?: Partial<typeof mockThemeContext>;
|
||||
biometric?: Partial<typeof mockBiometricContext>;
|
||||
auth?: Partial<typeof mockAuthContext>;
|
||||
} = {}) => {
|
||||
return render(
|
||||
<MockAuthProvider value={overrides.auth}>
|
||||
<MockBiometricAuthProvider value={overrides.biometric}>
|
||||
<MockThemeProvider value={overrides.theme}>
|
||||
<SettingsScreen />
|
||||
</MockThemeProvider>
|
||||
</MockBiometricAuthProvider>
|
||||
</MockAuthProvider>
|
||||
);
|
||||
};
|
||||
|
||||
// ============================================================
|
||||
// TESTS
|
||||
// ============================================================
|
||||
|
||||
describe('SettingsButton E2E Tests', () => {
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks();
|
||||
await AsyncStorage.clear();
|
||||
mockAlert.mockClear();
|
||||
mockLinkingOpenURL.mockClear();
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 1. RENDERING TESTS
|
||||
// ----------------------------------------------------------
|
||||
describe('1. Screen Rendering', () => {
|
||||
it('renders Settings screen with all sections', () => {
|
||||
const { getByText, getByTestId } = renderSettingsScreen();
|
||||
|
||||
// Main container
|
||||
expect(getByTestId('settings-screen')).toBeTruthy();
|
||||
|
||||
// Section headers
|
||||
expect(getByText('ACCOUNT')).toBeTruthy();
|
||||
expect(getByText('APP SETTINGS')).toBeTruthy();
|
||||
expect(getByText('NETWORK & SECURITY')).toBeTruthy();
|
||||
expect(getByText('SUPPORT')).toBeTruthy();
|
||||
|
||||
// Header
|
||||
expect(getByText('Settings')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('renders all setting items', () => {
|
||||
const { getByText } = renderSettingsScreen();
|
||||
|
||||
// Account section
|
||||
expect(getByText('Edit Profile')).toBeTruthy();
|
||||
expect(getByText('Wallet Management')).toBeTruthy();
|
||||
|
||||
// App Settings section
|
||||
expect(getByText('Dark Mode')).toBeTruthy();
|
||||
expect(getByText('Font Size')).toBeTruthy();
|
||||
expect(getByText('Push Notifications')).toBeTruthy();
|
||||
expect(getByText('Email Updates')).toBeTruthy();
|
||||
|
||||
// Network & Security section
|
||||
expect(getByText('Network Node')).toBeTruthy();
|
||||
expect(getByText('Biometric Security')).toBeTruthy();
|
||||
expect(getByText('Auto-Lock Timer')).toBeTruthy();
|
||||
|
||||
// Support section
|
||||
expect(getByText('Terms of Service')).toBeTruthy();
|
||||
expect(getByText('Privacy Policy')).toBeTruthy();
|
||||
expect(getByText('Help Center')).toBeTruthy();
|
||||
|
||||
// Logout
|
||||
expect(getByText('Sign Out')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('displays version info in footer', () => {
|
||||
const { getByText } = renderSettingsScreen();
|
||||
|
||||
expect(getByText('Pezkuwi Super App v1.0.0')).toBeTruthy();
|
||||
expect(getByText('© 2026 Digital Kurdistan')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 2. DARK MODE TESTS
|
||||
// ----------------------------------------------------------
|
||||
describe('2. Dark Mode Toggle', () => {
|
||||
it('shows correct subtitle when dark mode is OFF', () => {
|
||||
const { getByText } = renderSettingsScreen({
|
||||
theme: { isDarkMode: false },
|
||||
});
|
||||
|
||||
expect(getByText('Light theme enabled')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('shows correct subtitle when dark mode is ON', () => {
|
||||
const { getByText } = renderSettingsScreen({
|
||||
theme: { isDarkMode: true },
|
||||
});
|
||||
|
||||
expect(getByText('Dark theme enabled')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('calls toggleDarkMode when switch is toggled', async () => {
|
||||
const mockToggle = jest.fn();
|
||||
const { getByTestId } = renderSettingsScreen({
|
||||
theme: { isDarkMode: false, toggleDarkMode: mockToggle },
|
||||
});
|
||||
|
||||
const darkModeSwitch = getByTestId('dark-mode-switch');
|
||||
fireEvent(darkModeSwitch, 'valueChange', true);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockToggle).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 3. FONT SIZE TESTS
|
||||
// ----------------------------------------------------------
|
||||
describe('3. Font Size Selection', () => {
|
||||
it('shows current font size in subtitle', () => {
|
||||
const { getByText } = renderSettingsScreen({
|
||||
theme: { fontSize: 'medium' },
|
||||
});
|
||||
|
||||
expect(getByText('Medium')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('opens font size modal when button is pressed', async () => {
|
||||
const { getByTestId, getByText } = renderSettingsScreen();
|
||||
|
||||
const fontSizeButton = getByTestId('font-size-button');
|
||||
fireEvent.press(fontSizeButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByText('Select Font Size')).toBeTruthy();
|
||||
expect(getByText('Small')).toBeTruthy();
|
||||
expect(getByText('Large')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls setFontSize when Small option is selected', async () => {
|
||||
const mockSetFontSize = jest.fn();
|
||||
const { getByTestId } = renderSettingsScreen({
|
||||
theme: { fontSize: 'medium', setFontSize: mockSetFontSize },
|
||||
});
|
||||
|
||||
// Open modal
|
||||
fireEvent.press(getByTestId('font-size-button'));
|
||||
|
||||
// Select Small
|
||||
await waitFor(() => {
|
||||
const smallOption = getByTestId('font-size-option-small');
|
||||
fireEvent.press(smallOption);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockSetFontSize).toHaveBeenCalledWith('small');
|
||||
});
|
||||
});
|
||||
|
||||
it('calls setFontSize when Large option is selected', async () => {
|
||||
const mockSetFontSize = jest.fn();
|
||||
const { getByTestId } = renderSettingsScreen({
|
||||
theme: { fontSize: 'medium', setFontSize: mockSetFontSize },
|
||||
});
|
||||
|
||||
// Open modal
|
||||
fireEvent.press(getByTestId('font-size-button'));
|
||||
|
||||
// Select Large
|
||||
await waitFor(() => {
|
||||
const largeOption = getByTestId('font-size-option-large');
|
||||
fireEvent.press(largeOption);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockSetFontSize).toHaveBeenCalledWith('large');
|
||||
});
|
||||
});
|
||||
|
||||
it('closes modal when Cancel is pressed', async () => {
|
||||
const { getByTestId, queryByText } = renderSettingsScreen();
|
||||
|
||||
// Open modal
|
||||
fireEvent.press(getByTestId('font-size-button'));
|
||||
|
||||
// Cancel
|
||||
await waitFor(() => {
|
||||
const cancelButton = getByTestId('font-size-modal-cancel');
|
||||
fireEvent.press(cancelButton);
|
||||
});
|
||||
|
||||
// Modal should close (title should not be visible)
|
||||
await waitFor(() => {
|
||||
// After closing, modal content should not be rendered
|
||||
// This is a basic check - in reality modal visibility is controlled by state
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 4. AUTO-LOCK TIMER TESTS
|
||||
// ----------------------------------------------------------
|
||||
describe('4. Auto-Lock Timer Selection', () => {
|
||||
it('shows current auto-lock time in subtitle', () => {
|
||||
const { getByText } = renderSettingsScreen({
|
||||
biometric: { autoLockTimer: 5 },
|
||||
});
|
||||
|
||||
expect(getByText('5 minutes')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('opens auto-lock modal when button is pressed', async () => {
|
||||
const { getByTestId, getByText } = renderSettingsScreen();
|
||||
|
||||
const autoLockButton = getByTestId('auto-lock-button');
|
||||
fireEvent.press(autoLockButton);
|
||||
|
||||
await waitFor(() => {
|
||||
// Check for modal-specific content
|
||||
expect(getByText('Lock app after inactivity')).toBeTruthy();
|
||||
expect(getByText('1 minute')).toBeTruthy();
|
||||
expect(getByText('15 minutes')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls setAutoLockTimer when option is selected', async () => {
|
||||
const mockSetAutoLock = jest.fn();
|
||||
const { getByTestId } = renderSettingsScreen({
|
||||
biometric: { autoLockTimer: 5, setAutoLockTimer: mockSetAutoLock },
|
||||
});
|
||||
|
||||
// Open modal
|
||||
fireEvent.press(getByTestId('auto-lock-button'));
|
||||
|
||||
// Select 15 minutes
|
||||
await waitFor(() => {
|
||||
const option = getByTestId('auto-lock-option-15');
|
||||
fireEvent.press(option);
|
||||
});
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockSetAutoLock).toHaveBeenCalledWith(15);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 5. BIOMETRIC SECURITY TESTS
|
||||
// ----------------------------------------------------------
|
||||
describe('5. Biometric Security Toggle', () => {
|
||||
it('shows "FaceID / Fingerprint" when biometric is disabled', () => {
|
||||
const { getByText } = renderSettingsScreen({
|
||||
biometric: { isBiometricEnabled: false },
|
||||
});
|
||||
|
||||
expect(getByText('FaceID / Fingerprint')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('shows biometric type when enabled', () => {
|
||||
const { getByText } = renderSettingsScreen({
|
||||
biometric: { isBiometricEnabled: true, biometricType: 'fingerprint' },
|
||||
});
|
||||
|
||||
expect(getByText('Enabled (fingerprint)')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('calls enableBiometric when toggled ON', async () => {
|
||||
const mockEnable = jest.fn().mockResolvedValue(true);
|
||||
const { getByTestId } = renderSettingsScreen({
|
||||
biometric: { isBiometricEnabled: false, enableBiometric: mockEnable },
|
||||
});
|
||||
|
||||
const biometricSwitch = getByTestId('biometric-security-switch');
|
||||
fireEvent(biometricSwitch, 'valueChange', true);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockEnable).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls disableBiometric when toggled OFF', async () => {
|
||||
const mockDisable = jest.fn();
|
||||
const { getByTestId } = renderSettingsScreen({
|
||||
biometric: { isBiometricEnabled: true, disableBiometric: mockDisable },
|
||||
});
|
||||
|
||||
const biometricSwitch = getByTestId('biometric-security-switch');
|
||||
fireEvent(biometricSwitch, 'valueChange', false);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockDisable).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 6. NETWORK NODE TESTS
|
||||
// ----------------------------------------------------------
|
||||
describe('6. Network Node Selection', () => {
|
||||
it('shows Mainnet in subtitle for production endpoint', () => {
|
||||
const { getByText } = renderSettingsScreen();
|
||||
|
||||
expect(getByText('Mainnet')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('opens network modal when button is pressed', async () => {
|
||||
const { getByTestId, getByText } = renderSettingsScreen();
|
||||
|
||||
const networkButton = getByTestId('network-node-button');
|
||||
fireEvent.press(networkButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(getByText('Select Network Node')).toBeTruthy();
|
||||
expect(getByText('Pezkuwi Mainnet')).toBeTruthy();
|
||||
expect(getByText('Pezkuwi Testnet')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 7. SIGN OUT TESTS
|
||||
// ----------------------------------------------------------
|
||||
describe('7. Sign Out Flow', () => {
|
||||
it('shows confirmation alert when Sign Out is pressed', async () => {
|
||||
const { getByTestId } = renderSettingsScreen();
|
||||
|
||||
const signOutButton = getByTestId('sign-out-button');
|
||||
fireEvent.press(signOutButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockAlert).toHaveBeenCalledWith(
|
||||
'Sign Out',
|
||||
'Are you sure you want to sign out?',
|
||||
expect.arrayContaining([
|
||||
expect.objectContaining({ text: 'Cancel' }),
|
||||
expect.objectContaining({ text: 'Sign Out', style: 'destructive' }),
|
||||
])
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('calls signOut when confirmed', async () => {
|
||||
const mockSignOut = jest.fn();
|
||||
const { getByTestId } = renderSettingsScreen({
|
||||
auth: { signOut: mockSignOut },
|
||||
});
|
||||
|
||||
const signOutButton = getByTestId('sign-out-button');
|
||||
fireEvent.press(signOutButton);
|
||||
|
||||
await waitFor(() => {
|
||||
// Get the alert call arguments
|
||||
const alertCall = mockAlert.mock.calls[0];
|
||||
const buttons = alertCall[2];
|
||||
const signOutAction = buttons.find((b: any) => b.text === 'Sign Out');
|
||||
|
||||
// Simulate pressing Sign Out
|
||||
if (signOutAction?.onPress) {
|
||||
signOutAction.onPress();
|
||||
}
|
||||
|
||||
expect(mockSignOut).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 8. SUPPORT LINKS TESTS
|
||||
// ----------------------------------------------------------
|
||||
describe('8. Support Links', () => {
|
||||
it('shows Terms of Service alert when pressed', async () => {
|
||||
const { getByTestId } = renderSettingsScreen();
|
||||
|
||||
const tosButton = getByTestId('terms-of-service-button');
|
||||
fireEvent.press(tosButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockAlert).toHaveBeenCalledWith(
|
||||
'Terms',
|
||||
'Terms of service content...'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('shows Privacy Policy alert when pressed', async () => {
|
||||
const { getByTestId } = renderSettingsScreen();
|
||||
|
||||
const privacyButton = getByTestId('privacy-policy-button');
|
||||
fireEvent.press(privacyButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockAlert).toHaveBeenCalledWith(
|
||||
'Privacy',
|
||||
'Privacy policy content...'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('opens email client when Help Center is pressed', async () => {
|
||||
const { getByTestId } = renderSettingsScreen();
|
||||
|
||||
const helpButton = getByTestId('help-center-button');
|
||||
fireEvent.press(helpButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockLinkingOpenURL).toHaveBeenCalledWith(
|
||||
'mailto:support@pezkuwichain.io'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 9. PROFILE EDIT TESTS
|
||||
// ----------------------------------------------------------
|
||||
describe('9. Profile Editing', () => {
|
||||
it('opens profile edit modal when Edit Profile is pressed', async () => {
|
||||
const { getByTestId, getByText } = renderSettingsScreen();
|
||||
|
||||
const editProfileButton = getByTestId('edit-profile-button');
|
||||
fireEvent.press(editProfileButton);
|
||||
|
||||
await waitFor(() => {
|
||||
// Check for modal-specific content (Full Name and Bio labels)
|
||||
expect(getByText('Full Name')).toBeTruthy();
|
||||
expect(getByText('Bio')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 10. WALLET MANAGEMENT TESTS
|
||||
// ----------------------------------------------------------
|
||||
describe('10. Wallet Management', () => {
|
||||
it('shows Coming Soon alert when Wallet Management is pressed', async () => {
|
||||
const { getByTestId } = renderSettingsScreen();
|
||||
|
||||
const walletButton = getByTestId('wallet-management-button');
|
||||
fireEvent.press(walletButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockAlert).toHaveBeenCalledWith(
|
||||
'Coming Soon',
|
||||
'Wallet management screen'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// 11. EDGE CASES
|
||||
// ----------------------------------------------------------
|
||||
describe('11. Edge Cases', () => {
|
||||
it('handles rapid toggle clicks gracefully', async () => {
|
||||
const mockToggle = jest.fn();
|
||||
const { getByTestId } = renderSettingsScreen({
|
||||
theme: { isDarkMode: false, toggleDarkMode: mockToggle },
|
||||
});
|
||||
|
||||
const darkModeSwitch = getByTestId('dark-mode-switch');
|
||||
|
||||
// Rapid clicks
|
||||
fireEvent(darkModeSwitch, 'valueChange', true);
|
||||
fireEvent(darkModeSwitch, 'valueChange', false);
|
||||
fireEvent(darkModeSwitch, 'valueChange', true);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockToggle).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
});
|
||||
|
||||
it('displays correctly with all toggles enabled', () => {
|
||||
const { getByTestId } = renderSettingsScreen({
|
||||
theme: { isDarkMode: true },
|
||||
biometric: { isBiometricEnabled: true, biometricType: 'facial' },
|
||||
});
|
||||
|
||||
// All toggles should be visible
|
||||
expect(getByTestId('dark-mode-switch')).toBeTruthy();
|
||||
expect(getByTestId('biometric-security-switch')).toBeTruthy();
|
||||
expect(getByTestId('push-notifications-switch')).toBeTruthy();
|
||||
expect(getByTestId('email-updates-switch')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,179 @@
|
||||
/**
|
||||
* WalletButton E2E Tests
|
||||
*
|
||||
* Tests the Wallet button flow including:
|
||||
* - WalletSetupScreen choice screen
|
||||
* - Basic navigation
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render, fireEvent, waitFor } from '@testing-library/react-native';
|
||||
import { Alert } from 'react-native';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
|
||||
// Mock contexts
|
||||
jest.mock('../../contexts/ThemeContext', () => require('../../__mocks__/contexts/ThemeContext'));
|
||||
jest.mock('../../contexts/AuthContext', () => require('../../__mocks__/contexts/AuthContext'));
|
||||
|
||||
jest.mock('../../contexts/PezkuwiContext', () => ({
|
||||
usePezkuwi: () => ({
|
||||
api: null,
|
||||
isApiReady: false,
|
||||
accounts: [],
|
||||
selectedAccount: null,
|
||||
connectWallet: jest.fn().mockResolvedValue(undefined),
|
||||
disconnectWallet: jest.fn(),
|
||||
createWallet: jest.fn().mockResolvedValue({
|
||||
address: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',
|
||||
mnemonic: 'test test test test test test test test test test test junk',
|
||||
}),
|
||||
importWallet: jest.fn().mockResolvedValue({
|
||||
address: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY',
|
||||
}),
|
||||
getKeyPair: jest.fn(),
|
||||
currentNetwork: 'mainnet',
|
||||
switchNetwork: jest.fn(),
|
||||
error: null,
|
||||
}),
|
||||
NetworkType: { MAINNET: 'mainnet' },
|
||||
NETWORKS: { mainnet: { displayName: 'Mainnet', endpoint: 'wss://mainnet.example.com' } },
|
||||
}));
|
||||
|
||||
// Mock @pezkuwi/util-crypto
|
||||
jest.mock('@pezkuwi/util-crypto', () => ({
|
||||
mnemonicGenerate: () => 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about',
|
||||
mnemonicValidate: () => true,
|
||||
cryptoWaitReady: jest.fn().mockResolvedValue(true),
|
||||
}));
|
||||
|
||||
// Mock navigation
|
||||
const mockGoBack = jest.fn();
|
||||
const mockReplace = jest.fn();
|
||||
jest.mock('@react-navigation/native', () => ({
|
||||
...jest.requireActual('@react-navigation/native'),
|
||||
useNavigation: () => ({
|
||||
navigate: jest.fn(),
|
||||
goBack: mockGoBack,
|
||||
replace: mockReplace,
|
||||
setOptions: jest.fn(),
|
||||
}),
|
||||
}));
|
||||
|
||||
// Mock Alert
|
||||
jest.spyOn(Alert, 'alert');
|
||||
|
||||
import WalletSetupScreen from '../../screens/WalletSetupScreen';
|
||||
import { MockThemeProvider } from '../../__mocks__/contexts/ThemeContext';
|
||||
import { MockAuthProvider } from '../../__mocks__/contexts/AuthContext';
|
||||
|
||||
const renderSetup = () => render(
|
||||
<MockAuthProvider>
|
||||
<MockThemeProvider>
|
||||
<WalletSetupScreen />
|
||||
</MockThemeProvider>
|
||||
</MockAuthProvider>
|
||||
);
|
||||
|
||||
describe('WalletSetupScreen', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('renders choice screen', async () => {
|
||||
const { getByTestId, getByText } = renderSetup();
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('wallet-setup-screen')).toBeTruthy();
|
||||
expect(getByText('Set Up Your Wallet')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('shows create button', async () => {
|
||||
const { getByTestId, getByText } = renderSetup();
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('wallet-setup-create-button')).toBeTruthy();
|
||||
expect(getByText('Create New Wallet')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('shows import button', async () => {
|
||||
const { getByTestId, getByText } = renderSetup();
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('wallet-setup-import-button')).toBeTruthy();
|
||||
expect(getByText('Import Existing Wallet')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('close button calls goBack', async () => {
|
||||
const { getByTestId } = renderSetup();
|
||||
await waitFor(() => {
|
||||
fireEvent.press(getByTestId('wallet-setup-close'));
|
||||
});
|
||||
expect(mockGoBack).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('create button shows seed phrase screen', async () => {
|
||||
const { getByTestId, getByText } = renderSetup();
|
||||
await waitFor(() => {
|
||||
fireEvent.press(getByTestId('wallet-setup-create-button'));
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(getByText('Your Recovery Phrase')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('import button shows import screen', async () => {
|
||||
const { getByTestId, getByText } = renderSetup();
|
||||
await waitFor(() => {
|
||||
fireEvent.press(getByTestId('wallet-setup-import-button'));
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(getByText('Import Wallet')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('seed phrase screen has mnemonic grid', async () => {
|
||||
const { getByTestId } = renderSetup();
|
||||
await waitFor(() => {
|
||||
fireEvent.press(getByTestId('wallet-setup-create-button'));
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('mnemonic-grid')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('import screen has input field', async () => {
|
||||
const { getByTestId } = renderSetup();
|
||||
await waitFor(() => {
|
||||
fireEvent.press(getByTestId('wallet-setup-import-button'));
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('wallet-import-input')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('back from seed phrase goes to choice', async () => {
|
||||
const { getByTestId } = renderSetup();
|
||||
await waitFor(() => {
|
||||
fireEvent.press(getByTestId('wallet-setup-create-button'));
|
||||
});
|
||||
await waitFor(() => {
|
||||
fireEvent.press(getByTestId('wallet-setup-back'));
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('wallet-setup-choice')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
it('back from import goes to choice', async () => {
|
||||
const { getByTestId } = renderSetup();
|
||||
await waitFor(() => {
|
||||
fireEvent.press(getByTestId('wallet-setup-import-button'));
|
||||
});
|
||||
await waitFor(() => {
|
||||
fireEvent.press(getByTestId('wallet-setup-back'));
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(getByTestId('wallet-setup-choice')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,222 +0,0 @@
|
||||
import React from 'react';
|
||||
import { render, fireEvent, waitFor } from '@testing-library/react-native';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
|
||||
// Mock contexts before importing SettingsScreen
|
||||
jest.mock('../../contexts/ThemeContext', () => require('../../__mocks__/contexts/ThemeContext'));
|
||||
jest.mock('../../contexts/BiometricAuthContext', () => require('../../__mocks__/contexts/BiometricAuthContext'));
|
||||
jest.mock('../../contexts/AuthContext', () => require('../../__mocks__/contexts/AuthContext'));
|
||||
|
||||
// Mock Alert
|
||||
jest.mock('react-native/Libraries/Alert/Alert', () => ({
|
||||
alert: jest.fn(),
|
||||
}));
|
||||
|
||||
import SettingsScreen from '../../screens/SettingsScreen';
|
||||
import { MockThemeProvider } from '../../__mocks__/contexts/ThemeContext';
|
||||
import { MockBiometricAuthProvider } from '../../__mocks__/contexts/BiometricAuthContext';
|
||||
import { MockAuthProvider } from '../../__mocks__/contexts/AuthContext';
|
||||
|
||||
// Helper to render SettingsScreen with all required providers
|
||||
const renderSettingsScreen = (themeValue = {}, biometricValue = {}, authValue = {}) => {
|
||||
return render(
|
||||
<MockAuthProvider value={authValue}>
|
||||
<MockBiometricAuthProvider value={biometricValue}>
|
||||
<MockThemeProvider value={themeValue}>
|
||||
<SettingsScreen />
|
||||
</MockThemeProvider>
|
||||
</MockBiometricAuthProvider>
|
||||
</MockAuthProvider>
|
||||
);
|
||||
};
|
||||
|
||||
describe('SettingsScreen - Dark Mode Feature', () => {
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks();
|
||||
// Clear AsyncStorage before each test
|
||||
await AsyncStorage.clear();
|
||||
});
|
||||
|
||||
describe('Rendering', () => {
|
||||
it('should render Dark Mode section with toggle', () => {
|
||||
const { getByText } = renderSettingsScreen();
|
||||
|
||||
expect(getByText('APPEARANCE')).toBeTruthy();
|
||||
expect(getByText('darkMode')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should show current dark mode state', () => {
|
||||
const { getByText } = renderSettingsScreen({ isDarkMode: false });
|
||||
|
||||
// Should show subtitle when dark mode is off
|
||||
expect(getByText(/settingsScreen.subtitles.lightThemeEnabled/i)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should show "Enabled" when dark mode is on', () => {
|
||||
const { getByText } = renderSettingsScreen({ isDarkMode: true });
|
||||
|
||||
// Should show subtitle when dark mode is on
|
||||
expect(getByText(/settingsScreen.subtitles.darkThemeEnabled/i)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Toggle Functionality', () => {
|
||||
it('should toggle dark mode when switch is pressed', async () => {
|
||||
const mockToggleDarkMode = jest.fn().mockResolvedValue(undefined);
|
||||
const { getByTestId } = renderSettingsScreen({
|
||||
isDarkMode: false,
|
||||
toggleDarkMode: mockToggleDarkMode,
|
||||
});
|
||||
|
||||
// Find the toggle switch
|
||||
const darkModeSwitch = getByTestId('dark-mode-switch');
|
||||
|
||||
// Toggle the switch
|
||||
fireEvent(darkModeSwitch, 'valueChange', true);
|
||||
|
||||
// Verify toggleDarkMode was called
|
||||
await waitFor(() => {
|
||||
expect(mockToggleDarkMode).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
it('should toggle from enabled to disabled', async () => {
|
||||
const mockToggleDarkMode = jest.fn().mockResolvedValue(undefined);
|
||||
const { getByTestId } = renderSettingsScreen({
|
||||
isDarkMode: true,
|
||||
toggleDarkMode: mockToggleDarkMode,
|
||||
});
|
||||
|
||||
const darkModeSwitch = getByTestId('dark-mode-switch');
|
||||
|
||||
// Toggle off
|
||||
fireEvent(darkModeSwitch, 'valueChange', false);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockToggleDarkMode).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Persistence', () => {
|
||||
it('should save dark mode preference to AsyncStorage', async () => {
|
||||
const mockToggleDarkMode = jest.fn(async () => {
|
||||
await AsyncStorage.setItem('@pezkuwi/theme', 'dark');
|
||||
});
|
||||
|
||||
const { getByTestId } = renderSettingsScreen({
|
||||
isDarkMode: false,
|
||||
toggleDarkMode: mockToggleDarkMode,
|
||||
});
|
||||
|
||||
const darkModeSwitch = getByTestId('dark-mode-switch');
|
||||
fireEvent(darkModeSwitch, 'valueChange', true);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(AsyncStorage.setItem).toHaveBeenCalledWith('@pezkuwi/theme', 'dark');
|
||||
});
|
||||
});
|
||||
|
||||
it('should load dark mode preference on mount', async () => {
|
||||
// Pre-set dark mode in AsyncStorage
|
||||
await AsyncStorage.setItem('@pezkuwi/theme', 'dark');
|
||||
|
||||
const { getByText } = renderSettingsScreen({ isDarkMode: true });
|
||||
|
||||
// Verify dark mode is enabled - check for dark theme subtitle
|
||||
expect(getByText(/settingsScreen.subtitles.darkThemeEnabled/i)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Theme Application', () => {
|
||||
it('should apply dark theme colors when enabled', () => {
|
||||
const darkColors = {
|
||||
background: '#121212',
|
||||
surface: '#1E1E1E',
|
||||
text: '#FFFFFF',
|
||||
textSecondary: '#B0B0B0',
|
||||
border: '#333333',
|
||||
};
|
||||
|
||||
const { getByTestId } = renderSettingsScreen({
|
||||
isDarkMode: true,
|
||||
colors: darkColors,
|
||||
});
|
||||
|
||||
const container = getByTestId('settings-screen');
|
||||
|
||||
// Verify dark background is applied
|
||||
expect(container.props.style).toEqual(
|
||||
expect.objectContaining({
|
||||
backgroundColor: darkColors.background,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should apply light theme colors when disabled', () => {
|
||||
const lightColors = {
|
||||
background: '#F5F5F5',
|
||||
surface: '#FFFFFF',
|
||||
text: '#000000',
|
||||
textSecondary: '#666666',
|
||||
border: '#E0E0E0',
|
||||
};
|
||||
|
||||
const { getByTestId } = renderSettingsScreen({
|
||||
isDarkMode: false,
|
||||
colors: lightColors,
|
||||
});
|
||||
|
||||
const container = getByTestId('settings-screen');
|
||||
|
||||
// Verify light background is applied
|
||||
expect(container.props.style).toEqual(
|
||||
expect.objectContaining({
|
||||
backgroundColor: lightColors.background,
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Edge Cases', () => {
|
||||
it('should handle rapid toggle clicks', async () => {
|
||||
const mockToggleDarkMode = jest.fn().mockResolvedValue(undefined);
|
||||
const { getByTestId } = renderSettingsScreen({
|
||||
isDarkMode: false,
|
||||
toggleDarkMode: mockToggleDarkMode,
|
||||
});
|
||||
|
||||
const darkModeSwitch = getByTestId('dark-mode-switch');
|
||||
|
||||
// Rapid clicks
|
||||
fireEvent(darkModeSwitch, 'valueChange', true);
|
||||
fireEvent(darkModeSwitch, 'valueChange', false);
|
||||
fireEvent(darkModeSwitch, 'valueChange', true);
|
||||
|
||||
await waitFor(() => {
|
||||
// Should handle all toggle attempts
|
||||
expect(mockToggleDarkMode).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should call toggleDarkMode multiple times without issues', async () => {
|
||||
const mockToggleDarkMode = jest.fn().mockResolvedValue(undefined);
|
||||
const { getByTestId } = renderSettingsScreen({
|
||||
isDarkMode: false,
|
||||
toggleDarkMode: mockToggleDarkMode,
|
||||
});
|
||||
|
||||
const darkModeSwitch = getByTestId('dark-mode-switch');
|
||||
|
||||
// Toggle multiple times
|
||||
fireEvent(darkModeSwitch, 'valueChange', true);
|
||||
fireEvent(darkModeSwitch, 'valueChange', false);
|
||||
fireEvent(darkModeSwitch, 'valueChange', true);
|
||||
|
||||
await waitFor(() => {
|
||||
// Should handle all calls
|
||||
expect(mockToggleDarkMode).toHaveBeenCalledTimes(3);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,240 +0,0 @@
|
||||
import React from 'react';
|
||||
import { render, fireEvent, waitFor } from '@testing-library/react-native';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
|
||||
// Mock contexts before importing SettingsScreen
|
||||
jest.mock('../../contexts/ThemeContext', () => require('../../__mocks__/contexts/ThemeContext'));
|
||||
jest.mock('../../contexts/BiometricAuthContext', () => require('../../__mocks__/contexts/BiometricAuthContext'));
|
||||
jest.mock('../../contexts/AuthContext', () => require('../../__mocks__/contexts/AuthContext'));
|
||||
|
||||
// Mock Alert
|
||||
jest.mock('react-native/Libraries/Alert/Alert', () => ({
|
||||
alert: jest.fn(),
|
||||
}));
|
||||
|
||||
import SettingsScreen from '../../screens/SettingsScreen';
|
||||
import FontSizeModal from '../../components/FontSizeModal';
|
||||
import { MockThemeProvider } from '../../__mocks__/contexts/ThemeContext';
|
||||
import { MockBiometricAuthProvider } from '../../__mocks__/contexts/BiometricAuthContext';
|
||||
import { MockAuthProvider } from '../../__mocks__/contexts/AuthContext';
|
||||
|
||||
// Helper to render SettingsScreen with all required providers
|
||||
const renderSettingsScreen = (themeValue = {}, biometricValue = {}, authValue = {}) => {
|
||||
return render(
|
||||
<MockAuthProvider value={authValue}>
|
||||
<MockBiometricAuthProvider value={biometricValue}>
|
||||
<MockThemeProvider value={themeValue}>
|
||||
<SettingsScreen />
|
||||
</MockThemeProvider>
|
||||
</MockBiometricAuthProvider>
|
||||
</MockAuthProvider>
|
||||
);
|
||||
};
|
||||
|
||||
// Helper to render FontSizeModal
|
||||
const renderFontSizeModal = (overrides: any = {}) => {
|
||||
const mockSetFontSize = overrides.setFontSize || jest.fn().mockResolvedValue(undefined);
|
||||
const mockOnClose = overrides.onClose || jest.fn();
|
||||
|
||||
const themeValue = {
|
||||
fontSize: overrides.fontSize || ('medium' as 'small' | 'medium' | 'large'),
|
||||
setFontSize: mockSetFontSize,
|
||||
};
|
||||
|
||||
const props = {
|
||||
visible: overrides.visible !== undefined ? overrides.visible : true,
|
||||
onClose: mockOnClose,
|
||||
};
|
||||
|
||||
return {
|
||||
...render(
|
||||
<MockThemeProvider value={themeValue}>
|
||||
<FontSizeModal {...props} />
|
||||
</MockThemeProvider>
|
||||
),
|
||||
mockSetFontSize,
|
||||
mockOnClose,
|
||||
};
|
||||
};
|
||||
|
||||
describe('SettingsScreen - Font Size Feature', () => {
|
||||
beforeEach(async () => {
|
||||
jest.clearAllMocks();
|
||||
await AsyncStorage.clear();
|
||||
});
|
||||
|
||||
describe('Rendering', () => {
|
||||
it('should render Font Size button', () => {
|
||||
const { getByText } = renderSettingsScreen();
|
||||
|
||||
expect(getByText('Font Size')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should show current font size in subtitle', () => {
|
||||
const { getByText } = renderSettingsScreen({ fontSize: 'medium' });
|
||||
|
||||
expect(getByText('Current: Medium')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should show Small font size in subtitle', () => {
|
||||
const { getByText } = renderSettingsScreen({ fontSize: 'small' });
|
||||
|
||||
expect(getByText('Current: Small')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should show Large font size in subtitle', () => {
|
||||
const { getByText } = renderSettingsScreen({ fontSize: 'large' });
|
||||
|
||||
expect(getByText('Current: Large')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Modal Interaction', () => {
|
||||
it('should open font size modal when button is pressed', async () => {
|
||||
const { getByText, getByTestId } = renderSettingsScreen();
|
||||
|
||||
const fontSizeButton = getByText('Font Size').parent?.parent;
|
||||
expect(fontSizeButton).toBeTruthy();
|
||||
|
||||
fireEvent.press(fontSizeButton!);
|
||||
|
||||
// Modal should open (we'll test modal rendering separately)
|
||||
await waitFor(() => {
|
||||
// Just verify the button was pressable
|
||||
expect(fontSizeButton).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Font Scale Application', () => {
|
||||
it('should display small font scale', () => {
|
||||
const { getByText } = renderSettingsScreen({
|
||||
fontSize: 'small',
|
||||
fontScale: 0.875,
|
||||
});
|
||||
|
||||
// Verify font size is displayed
|
||||
expect(getByText('Current: Small')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display medium font scale', () => {
|
||||
const { getByText } = renderSettingsScreen({
|
||||
fontSize: 'medium',
|
||||
fontScale: 1.0,
|
||||
});
|
||||
|
||||
expect(getByText('Current: Medium')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should display large font scale', () => {
|
||||
const { getByText } = renderSettingsScreen({
|
||||
fontSize: 'large',
|
||||
fontScale: 1.125,
|
||||
});
|
||||
|
||||
expect(getByText('Current: Large')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Persistence', () => {
|
||||
it('should save font size to AsyncStorage', async () => {
|
||||
const mockSetFontSize = jest.fn(async (size) => {
|
||||
await AsyncStorage.setItem('@pezkuwi/font_size', size);
|
||||
});
|
||||
|
||||
const { getByText } = renderSettingsScreen({
|
||||
fontSize: 'medium',
|
||||
setFontSize: mockSetFontSize,
|
||||
});
|
||||
|
||||
// Simulate selecting a new size
|
||||
await mockSetFontSize('large');
|
||||
|
||||
await waitFor(() => {
|
||||
expect(AsyncStorage.setItem).toHaveBeenCalledWith('@pezkuwi/font_size', 'large');
|
||||
});
|
||||
});
|
||||
|
||||
it('should load saved font size on mount', async () => {
|
||||
await AsyncStorage.setItem('@pezkuwi/font_size', 'large');
|
||||
|
||||
const { getByText } = renderSettingsScreen({ fontSize: 'large' });
|
||||
|
||||
expect(getByText('Current: Large')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('FontSizeModal Component', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
describe('Rendering', () => {
|
||||
it('should render modal when visible', () => {
|
||||
const { getByText } = renderFontSizeModal({ fontSize: 'medium', visible: true });
|
||||
|
||||
expect(getByText('Font Size')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should render all three size options', () => {
|
||||
const { getByText } = renderFontSizeModal();
|
||||
|
||||
expect(getByText('Small')).toBeTruthy();
|
||||
expect(getByText(/Medium.*Default/i)).toBeTruthy();
|
||||
expect(getByText('Large')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should show checkmark on current size', () => {
|
||||
const { getByTestId, getByText } = renderFontSizeModal({ fontSize: 'medium' });
|
||||
|
||||
const mediumOption = getByTestId('font-size-medium');
|
||||
expect(mediumOption).toBeTruthy();
|
||||
// Checkmark should be visible for medium
|
||||
expect(getByText('✓')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Size Selection', () => {
|
||||
it('should call setFontSize when Small is pressed', async () => {
|
||||
const { getByTestId, mockSetFontSize, mockOnClose } = renderFontSizeModal({
|
||||
fontSize: 'medium',
|
||||
});
|
||||
|
||||
const smallButton = getByTestId('font-size-small');
|
||||
fireEvent.press(smallButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockSetFontSize).toHaveBeenCalledWith('small');
|
||||
expect(mockOnClose).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('should call setFontSize when Large is pressed', async () => {
|
||||
const { getByTestId, mockSetFontSize, mockOnClose } = renderFontSizeModal({
|
||||
fontSize: 'medium',
|
||||
});
|
||||
|
||||
const largeButton = getByTestId('font-size-large');
|
||||
fireEvent.press(largeButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockSetFontSize).toHaveBeenCalledWith('large');
|
||||
expect(mockOnClose).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Modal Close', () => {
|
||||
it('should call onClose when close button is pressed', async () => {
|
||||
const { getByTestId, mockOnClose } = renderFontSizeModal();
|
||||
|
||||
const closeButton = getByTestId('font-size-modal-close');
|
||||
fireEvent.press(closeButton);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(mockOnClose).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -4,7 +4,6 @@ import { render, RenderOptions } from '@testing-library/react-native';
|
||||
// Mock all contexts with simple implementations
|
||||
const MockAuthProvider = ({ children }: { children: React.ReactNode }) => <>{children}</>;
|
||||
const MockPezkuwiProvider = ({ children }: { children: React.ReactNode }) => <>{children}</>;
|
||||
const MockLanguageProvider = ({ children }: { children: React.ReactNode }) => <>{children}</>;
|
||||
const MockBiometricAuthProvider = ({ children }: { children: React.ReactNode }) => <>{children}</>;
|
||||
|
||||
// Wrapper component with all providers
|
||||
@@ -12,11 +11,9 @@ const AllTheProviders = ({ children }: { children: React.ReactNode }) => {
|
||||
return (
|
||||
<MockAuthProvider>
|
||||
<MockPezkuwiProvider>
|
||||
<MockLanguageProvider>
|
||||
<MockBiometricAuthProvider>
|
||||
{children}
|
||||
</MockBiometricAuthProvider>
|
||||
</MockLanguageProvider>
|
||||
<MockBiometricAuthProvider>
|
||||
{children}
|
||||
</MockBiometricAuthProvider>
|
||||
</MockPezkuwiProvider>
|
||||
</MockAuthProvider>
|
||||
);
|
||||
|
||||
@@ -16,6 +16,16 @@ import { KurdistanColors } from '../theme/colors';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import { supabase } from '../lib/supabase';
|
||||
|
||||
// Cross-platform alert helper
|
||||
const showAlert = (title: string, message: string, buttons?: Array<{text: string; onPress?: () => void}>) => {
|
||||
if (Platform.OS === 'web') {
|
||||
window.alert(`${title}\n\n${message}`);
|
||||
if (buttons?.[0]?.onPress) buttons[0].onPress();
|
||||
} else {
|
||||
showAlert(title, message, buttons);
|
||||
}
|
||||
};
|
||||
|
||||
// Avatar pool - Kurdish/Middle Eastern themed avatars
|
||||
const AVATAR_POOL = [
|
||||
{ id: 'avatar1', emoji: '👨🏻', label: 'Man 1' },
|
||||
@@ -74,7 +84,7 @@ const AvatarPickerModal: React.FC<AvatarPickerModalProps> = ({
|
||||
if (Platform.OS !== 'web') {
|
||||
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
|
||||
if (status !== 'granted') {
|
||||
Alert.alert(
|
||||
showAlert(
|
||||
'Permission Required',
|
||||
'Sorry, we need camera roll permissions to upload your photo!'
|
||||
);
|
||||
@@ -111,63 +121,88 @@ const AvatarPickerModal: React.FC<AvatarPickerModalProps> = ({
|
||||
if (__DEV__) console.log('[AvatarPicker] Upload successful:', uploadedUrl);
|
||||
setUploadedImageUri(uploadedUrl);
|
||||
setSelectedAvatar(null); // Clear emoji selection
|
||||
Alert.alert('Success', 'Photo uploaded successfully!');
|
||||
showAlert('Success', 'Photo uploaded successfully!');
|
||||
} else {
|
||||
if (__DEV__) console.error('[AvatarPicker] Upload failed: no URL returned');
|
||||
Alert.alert('Upload Failed', 'Could not upload your photo. Please check your internet connection and try again.');
|
||||
showAlert('Upload Failed', 'Could not upload your photo. Please check your internet connection and try again.');
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
setIsUploading(false);
|
||||
if (__DEV__) console.error('[AvatarPicker] Error picking image:', error);
|
||||
Alert.alert('Error', 'Failed to pick image. Please try again.');
|
||||
showAlert('Error', 'Failed to pick image. Please try again.');
|
||||
}
|
||||
};
|
||||
|
||||
const uploadImageToSupabase = async (imageUri: string): Promise<string | null> => {
|
||||
if (!user) {
|
||||
if (__DEV__) console.error('[AvatarPicker] No user found');
|
||||
console.error('[AvatarPicker] No user found');
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
if (__DEV__) console.log('[AvatarPicker] Fetching image blob...');
|
||||
// Convert image URI to blob for web, or use file for native
|
||||
console.log('[AvatarPicker] Starting upload for URI:', imageUri.substring(0, 50) + '...');
|
||||
|
||||
// Convert image URI to blob
|
||||
const response = await fetch(imageUri);
|
||||
const blob = await response.blob();
|
||||
if (__DEV__) console.log('[AvatarPicker] Blob size:', blob.size, 'bytes');
|
||||
console.log('[AvatarPicker] Blob created - size:', blob.size, 'bytes, type:', blob.type);
|
||||
|
||||
// Generate unique filename
|
||||
const fileExt = imageUri.split('.').pop()?.toLowerCase() || 'jpg';
|
||||
const fileName = `${user.id}-${Date.now()}.${fileExt}`;
|
||||
const filePath = `avatars/${fileName}`;
|
||||
if (__DEV__) console.log('[AvatarPicker] Uploading to:', filePath);
|
||||
|
||||
// Upload to Supabase Storage
|
||||
const { data: uploadData, error: uploadError } = await supabase.storage
|
||||
.from('profiles')
|
||||
.upload(filePath, blob, {
|
||||
contentType: `image/${fileExt}`,
|
||||
upsert: false,
|
||||
});
|
||||
|
||||
if (uploadError) {
|
||||
if (__DEV__) console.error('[AvatarPicker] Upload error:', uploadError);
|
||||
if (blob.size === 0) {
|
||||
console.error('[AvatarPicker] Blob is empty!');
|
||||
return null;
|
||||
}
|
||||
|
||||
if (__DEV__) console.log('[AvatarPicker] Upload successful:', uploadData);
|
||||
// Get file extension from blob type or URI
|
||||
let fileExt = 'jpg';
|
||||
if (blob.type) {
|
||||
// Extract extension from MIME type (e.g., 'image/jpeg' -> 'jpeg')
|
||||
const mimeExt = blob.type.split('/')[1];
|
||||
if (mimeExt && mimeExt !== 'octet-stream') {
|
||||
fileExt = mimeExt === 'jpeg' ? 'jpg' : mimeExt;
|
||||
}
|
||||
} else if (!imageUri.startsWith('blob:') && !imageUri.startsWith('data:')) {
|
||||
// Try to get extension from URI for non-blob URIs
|
||||
const uriExt = imageUri.split('.').pop()?.toLowerCase();
|
||||
if (uriExt && ['jpg', 'jpeg', 'png', 'gif', 'webp'].includes(uriExt)) {
|
||||
fileExt = uriExt;
|
||||
}
|
||||
}
|
||||
|
||||
const fileName = `${user.id}-${Date.now()}.${fileExt}`;
|
||||
const filePath = `avatars/${fileName}`;
|
||||
const contentType = blob.type || `image/${fileExt}`;
|
||||
|
||||
console.log('[AvatarPicker] Uploading to path:', filePath, 'contentType:', contentType);
|
||||
|
||||
// Upload to Supabase Storage
|
||||
const { data: uploadData, error: uploadError } = await supabase.storage
|
||||
.from('avatars')
|
||||
.upload(filePath, blob, {
|
||||
contentType: contentType,
|
||||
upsert: true, // Allow overwriting if file exists
|
||||
});
|
||||
|
||||
if (uploadError) {
|
||||
console.error('[AvatarPicker] Supabase upload error:', uploadError.message, uploadError);
|
||||
// Show more specific error to user
|
||||
showAlert('Upload Error', `Storage error: ${uploadError.message}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
console.log('[AvatarPicker] Upload successful:', uploadData);
|
||||
|
||||
// Get public URL
|
||||
const { data } = supabase.storage
|
||||
.from('profiles')
|
||||
.from('avatars')
|
||||
.getPublicUrl(filePath);
|
||||
|
||||
if (__DEV__) console.log('[AvatarPicker] Public URL:', data.publicUrl);
|
||||
console.log('[AvatarPicker] Public URL:', data.publicUrl);
|
||||
|
||||
return data.publicUrl;
|
||||
} catch (error) {
|
||||
if (__DEV__) console.error('[AvatarPicker] Error uploading to Supabase:', error);
|
||||
} catch (error: any) {
|
||||
console.error('[AvatarPicker] Error uploading to Supabase:', error?.message || error);
|
||||
showAlert('Upload Error', `Failed to upload: ${error?.message || 'Unknown error'}`);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
@@ -176,7 +211,7 @@ const AvatarPickerModal: React.FC<AvatarPickerModalProps> = ({
|
||||
const avatarToSave = uploadedImageUri || selectedAvatar;
|
||||
|
||||
if (!avatarToSave || !user) {
|
||||
Alert.alert('Error', 'Please select an avatar or upload a photo');
|
||||
showAlert('Error', 'Please select an avatar or upload a photo');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -199,7 +234,7 @@ const AvatarPickerModal: React.FC<AvatarPickerModalProps> = ({
|
||||
|
||||
if (__DEV__) console.log('[AvatarPicker] Avatar saved successfully:', data);
|
||||
|
||||
Alert.alert('Success', 'Avatar updated successfully!');
|
||||
showAlert('Success', 'Avatar updated successfully!');
|
||||
|
||||
if (onAvatarSelected) {
|
||||
onAvatarSelected(avatarToSave);
|
||||
@@ -208,7 +243,7 @@ const AvatarPickerModal: React.FC<AvatarPickerModalProps> = ({
|
||||
onClose();
|
||||
} catch (error) {
|
||||
if (__DEV__) console.error('[AvatarPicker] Error updating avatar:', error);
|
||||
Alert.alert('Error', 'Failed to update avatar. Please try again.');
|
||||
showAlert('Error', 'Failed to update avatar. Please try again.');
|
||||
} finally {
|
||||
setIsSaving(false);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,224 @@
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { View, Animated, Easing, StyleSheet } from 'react-native';
|
||||
import Svg, { Circle, Line, Defs, RadialGradient, Stop } from 'react-native-svg';
|
||||
|
||||
interface KurdistanSunProps {
|
||||
size?: number;
|
||||
}
|
||||
|
||||
const AnimatedView = Animated.View;
|
||||
|
||||
export const KurdistanSun: React.FC<KurdistanSunProps> = ({ size = 200 }) => {
|
||||
// Animation values
|
||||
const greenHaloRotation = useRef(new Animated.Value(0)).current;
|
||||
const redHaloRotation = useRef(new Animated.Value(0)).current;
|
||||
const yellowHaloRotation = useRef(new Animated.Value(0)).current;
|
||||
const raysPulse = useRef(new Animated.Value(1)).current;
|
||||
const glowPulse = useRef(new Animated.Value(0.6)).current;
|
||||
|
||||
useEffect(() => {
|
||||
// Green halo rotation (3s, clockwise)
|
||||
Animated.loop(
|
||||
Animated.timing(greenHaloRotation, {
|
||||
toValue: 1,
|
||||
duration: 3000,
|
||||
easing: Easing.linear,
|
||||
useNativeDriver: true,
|
||||
})
|
||||
).start();
|
||||
|
||||
// Red halo rotation (2.5s, counter-clockwise)
|
||||
Animated.loop(
|
||||
Animated.timing(redHaloRotation, {
|
||||
toValue: -1,
|
||||
duration: 2500,
|
||||
easing: Easing.linear,
|
||||
useNativeDriver: true,
|
||||
})
|
||||
).start();
|
||||
|
||||
// Yellow halo rotation (2s, clockwise)
|
||||
Animated.loop(
|
||||
Animated.timing(yellowHaloRotation, {
|
||||
toValue: 1,
|
||||
duration: 2000,
|
||||
easing: Easing.linear,
|
||||
useNativeDriver: true,
|
||||
})
|
||||
).start();
|
||||
|
||||
// Rays pulse animation
|
||||
Animated.loop(
|
||||
Animated.sequence([
|
||||
Animated.timing(raysPulse, {
|
||||
toValue: 0.7,
|
||||
duration: 1000,
|
||||
easing: Easing.inOut(Easing.ease),
|
||||
useNativeDriver: true,
|
||||
}),
|
||||
Animated.timing(raysPulse, {
|
||||
toValue: 1,
|
||||
duration: 1000,
|
||||
easing: Easing.inOut(Easing.ease),
|
||||
useNativeDriver: true,
|
||||
}),
|
||||
])
|
||||
).start();
|
||||
|
||||
// Glow pulse animation
|
||||
Animated.loop(
|
||||
Animated.sequence([
|
||||
Animated.timing(glowPulse, {
|
||||
toValue: 0.3,
|
||||
duration: 1000,
|
||||
easing: Easing.inOut(Easing.ease),
|
||||
useNativeDriver: true,
|
||||
}),
|
||||
Animated.timing(glowPulse, {
|
||||
toValue: 0.6,
|
||||
duration: 1000,
|
||||
easing: Easing.inOut(Easing.ease),
|
||||
useNativeDriver: true,
|
||||
}),
|
||||
])
|
||||
).start();
|
||||
}, []);
|
||||
|
||||
const greenSpin = greenHaloRotation.interpolate({
|
||||
inputRange: [0, 1],
|
||||
outputRange: ['0deg', '360deg'],
|
||||
});
|
||||
|
||||
const redSpin = redHaloRotation.interpolate({
|
||||
inputRange: [-1, 0],
|
||||
outputRange: ['-360deg', '0deg'],
|
||||
});
|
||||
|
||||
const yellowSpin = yellowHaloRotation.interpolate({
|
||||
inputRange: [0, 1],
|
||||
outputRange: ['0deg', '360deg'],
|
||||
});
|
||||
|
||||
const haloSize = size * 0.9;
|
||||
const borderWidth = size * 0.02;
|
||||
|
||||
// Generate 21 rays for Kurdistan flag
|
||||
const rays = Array.from({ length: 21 }).map((_, i) => {
|
||||
const angle = (i * 360) / 21;
|
||||
return (
|
||||
<Line
|
||||
key={i}
|
||||
x1="100"
|
||||
y1="100"
|
||||
x2="100"
|
||||
y2="20"
|
||||
stroke="rgba(255, 255, 255, 0.9)"
|
||||
strokeWidth="3"
|
||||
strokeLinecap="round"
|
||||
transform={`rotate(${angle} 100 100)`}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
<View style={[styles.container, { width: size, height: size }]}>
|
||||
{/* Rotating colored halos */}
|
||||
<View style={styles.halosContainer}>
|
||||
{/* Green halo (outermost) */}
|
||||
<AnimatedView
|
||||
style={[
|
||||
styles.halo,
|
||||
{
|
||||
width: haloSize,
|
||||
height: haloSize,
|
||||
borderWidth: borderWidth,
|
||||
borderTopColor: '#00FF00',
|
||||
borderBottomColor: '#00FF00',
|
||||
borderLeftColor: 'transparent',
|
||||
borderRightColor: 'transparent',
|
||||
transform: [{ rotate: greenSpin }],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
{/* Red halo (middle) */}
|
||||
<AnimatedView
|
||||
style={[
|
||||
styles.halo,
|
||||
{
|
||||
width: haloSize * 0.8,
|
||||
height: haloSize * 0.8,
|
||||
borderWidth: borderWidth,
|
||||
borderTopColor: 'transparent',
|
||||
borderBottomColor: 'transparent',
|
||||
borderLeftColor: '#FF0000',
|
||||
borderRightColor: '#FF0000',
|
||||
transform: [{ rotate: redSpin }],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
{/* Yellow halo (inner) */}
|
||||
<AnimatedView
|
||||
style={[
|
||||
styles.halo,
|
||||
{
|
||||
width: haloSize * 0.6,
|
||||
height: haloSize * 0.6,
|
||||
borderWidth: borderWidth,
|
||||
borderTopColor: '#FFD700',
|
||||
borderBottomColor: '#FFD700',
|
||||
borderLeftColor: 'transparent',
|
||||
borderRightColor: 'transparent',
|
||||
transform: [{ rotate: yellowSpin }],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</View>
|
||||
|
||||
{/* Kurdistan Sun SVG with 21 rays */}
|
||||
<AnimatedView style={[styles.svgContainer, { opacity: raysPulse }]}>
|
||||
<Svg width={size} height={size} viewBox="0 0 200 200">
|
||||
<Defs>
|
||||
<RadialGradient id="sunGradient" cx="50%" cy="50%" r="50%">
|
||||
<Stop offset="0%" stopColor="rgba(255, 255, 255, 0.8)" />
|
||||
<Stop offset="100%" stopColor="rgba(255, 255, 255, 0.2)" />
|
||||
</RadialGradient>
|
||||
</Defs>
|
||||
|
||||
{/* Sun rays (21 rays for Kurdistan flag) */}
|
||||
{rays}
|
||||
|
||||
{/* Central white circle */}
|
||||
<Circle cx="100" cy="100" r="35" fill="white" />
|
||||
|
||||
{/* Inner glow */}
|
||||
<Circle cx="100" cy="100" r="35" fill="url(#sunGradient)" />
|
||||
</Svg>
|
||||
</AnimatedView>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
position: 'relative',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
halosContainer: {
|
||||
position: 'absolute',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
halo: {
|
||||
position: 'absolute',
|
||||
borderRadius: 1000,
|
||||
},
|
||||
svgContainer: {
|
||||
position: 'relative',
|
||||
zIndex: 1,
|
||||
},
|
||||
});
|
||||
|
||||
export default KurdistanSun;
|
||||
@@ -0,0 +1,2 @@
|
||||
export { default as HezTokenLogo } from './HezTokenLogo';
|
||||
export { default as PezTokenLogo } from './PezTokenLogo';
|
||||
@@ -1,64 +0,0 @@
|
||||
import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
|
||||
import { I18nManager } from 'react-native';
|
||||
import { isRTL, languages } from '../i18n';
|
||||
import i18n from '../i18n';
|
||||
|
||||
// Language is set at build time via environment variable
|
||||
const BUILD_LANGUAGE = process.env.EXPO_PUBLIC_DEFAULT_LANGUAGE || 'en';
|
||||
|
||||
interface Language {
|
||||
code: string;
|
||||
name: string;
|
||||
nativeName: string;
|
||||
rtl: boolean;
|
||||
}
|
||||
|
||||
interface LanguageContextType {
|
||||
currentLanguage: string;
|
||||
isRTL: boolean;
|
||||
hasSelectedLanguage: boolean;
|
||||
availableLanguages: Language[];
|
||||
}
|
||||
|
||||
const LanguageContext = createContext<LanguageContextType | undefined>(undefined);
|
||||
|
||||
export const LanguageProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
|
||||
// Language is fixed at build time - no runtime switching
|
||||
const [currentLanguage] = useState(BUILD_LANGUAGE);
|
||||
const [currentIsRTL] = useState(isRTL(BUILD_LANGUAGE));
|
||||
|
||||
useEffect(() => {
|
||||
// Initialize i18n with build-time language
|
||||
i18n.changeLanguage(BUILD_LANGUAGE);
|
||||
|
||||
// Set RTL if needed
|
||||
const isRTLLanguage = ['ar', 'ckb', 'fa'].includes(BUILD_LANGUAGE);
|
||||
I18nManager.allowRTL(isRTLLanguage);
|
||||
I18nManager.forceRTL(isRTLLanguage);
|
||||
|
||||
if (__DEV__) {
|
||||
console.log(`[LanguageContext] Build language: ${BUILD_LANGUAGE}, RTL: ${isRTLLanguage}`);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<LanguageContext.Provider
|
||||
value={{
|
||||
currentLanguage,
|
||||
isRTL: currentIsRTL,
|
||||
hasSelectedLanguage: true, // Always true - language pre-selected at build time
|
||||
availableLanguages: languages,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</LanguageContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const useLanguage = (): LanguageContextType => {
|
||||
const context = useContext(LanguageContext);
|
||||
if (!context) {
|
||||
throw new Error('useLanguage must be used within LanguageProvider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
import React, { createContext, useContext, useEffect, useState, ReactNode } from 'react';
|
||||
import { Platform } from 'react-native';
|
||||
import { Keyring } from '@pezkuwi/keyring';
|
||||
import { KeyringPair } from '@pezkuwi/keyring/types';
|
||||
import { ApiPromise, WsProvider } from '@pezkuwi/api';
|
||||
@@ -7,6 +8,34 @@ import * as SecureStore from 'expo-secure-store';
|
||||
import { cryptoWaitReady, mnemonicGenerate } from '@pezkuwi/util-crypto';
|
||||
import { ENV } from '../config/environment';
|
||||
|
||||
// Secure storage helper - uses SecureStore on native, AsyncStorage on web (with warning)
|
||||
const secureStorage = {
|
||||
setItem: async (key: string, value: string): Promise<void> => {
|
||||
if (Platform.OS === 'web') {
|
||||
// WARNING: AsyncStorage is NOT secure for storing seeds on web
|
||||
// In production, consider using Web Crypto API or server-side storage
|
||||
if (__DEV__) console.warn('[SecureStorage] Using AsyncStorage on web - NOT SECURE for production');
|
||||
await AsyncStorage.setItem(key, value);
|
||||
} else {
|
||||
await SecureStore.setItemAsync(key, value);
|
||||
}
|
||||
},
|
||||
getItem: async (key: string): Promise<string | null> => {
|
||||
if (Platform.OS === 'web') {
|
||||
return await AsyncStorage.getItem(key);
|
||||
} else {
|
||||
return await SecureStore.getItemAsync(key);
|
||||
}
|
||||
},
|
||||
removeItem: async (key: string): Promise<void> => {
|
||||
if (Platform.OS === 'web') {
|
||||
await AsyncStorage.removeItem(key);
|
||||
} else {
|
||||
await SecureStore.deleteItemAsync(key);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
interface Account {
|
||||
address: string;
|
||||
name: string;
|
||||
@@ -15,14 +44,14 @@ interface Account {
|
||||
};
|
||||
}
|
||||
|
||||
export type NetworkType = 'pezkuwi' | 'dicle' | 'zagros' | 'bizinikiwi';
|
||||
export type NetworkType = 'pezkuwi' | 'dicle' | 'zagros' | 'bizinikiwi' | 'zombienet';
|
||||
|
||||
export interface NetworkConfig {
|
||||
name: string;
|
||||
displayName: string;
|
||||
rpcEndpoint: string;
|
||||
ss58Format: number;
|
||||
type: 'mainnet' | 'testnet' | 'canary';
|
||||
type: 'mainnet' | 'testnet' | 'canary' | 'dev';
|
||||
}
|
||||
|
||||
export const NETWORKS: Record<NetworkType, NetworkConfig> = {
|
||||
@@ -54,6 +83,13 @@ export const NETWORKS: Record<NetworkType, NetworkConfig> = {
|
||||
ss58Format: 42,
|
||||
type: 'testnet',
|
||||
},
|
||||
zombienet: {
|
||||
name: 'zombienet',
|
||||
displayName: 'Zombienet Dev (Alice/Bob)',
|
||||
rpcEndpoint: 'wss://zombienet-rpc.pezkuwichain.io',
|
||||
ss58Format: 42,
|
||||
type: 'dev',
|
||||
},
|
||||
};
|
||||
|
||||
interface PezkuwiContextType {
|
||||
@@ -73,6 +109,7 @@ interface PezkuwiContextType {
|
||||
disconnectWallet: () => void;
|
||||
createWallet: (name: string, mnemonic?: string) => Promise<{ address: string; mnemonic: string }>;
|
||||
importWallet: (name: string, mnemonic: string) => Promise<{ address: string }>;
|
||||
deleteWallet: (address: string) => Promise<void>;
|
||||
getKeyPair: (address: string) => Promise<KeyringPair | null>;
|
||||
signMessage: (address: string, message: string) => Promise<string | null>;
|
||||
error: string | null;
|
||||
@@ -131,7 +168,14 @@ export const PezkuwiProvider: React.FC<PezkuwiProviderProps> = ({ children }) =>
|
||||
const provider = new WsProvider(networkConfig.rpcEndpoint);
|
||||
console.log('📡 [Pezkuwi] WsProvider created, creating API...');
|
||||
const newApi = await ApiPromise.create({ provider });
|
||||
console.log('✅ [Pezkuwi] API created successfully');
|
||||
|
||||
// Set SS58 format for address encoding/decoding
|
||||
newApi.registry.setChainProperties(
|
||||
newApi.registry.createType('ChainProperties', {
|
||||
ss58Format: networkConfig.ss58Format,
|
||||
})
|
||||
);
|
||||
console.log(`✅ [Pezkuwi] API created with SS58 format: ${networkConfig.ss58Format}`);
|
||||
|
||||
if (isSubscribed) {
|
||||
setApi(newApi);
|
||||
@@ -256,9 +300,9 @@ export const PezkuwiProvider: React.FC<PezkuwiProviderProps> = ({ children }) =>
|
||||
setAccounts(updatedAccounts);
|
||||
await AsyncStorage.setItem(WALLET_STORAGE_KEY, JSON.stringify(updatedAccounts));
|
||||
|
||||
// SECURITY: Store encrypted seed in SecureStore (hardware-backed storage)
|
||||
// SECURITY: Store encrypted seed in secure storage (hardware-backed on native)
|
||||
const seedKey = `pezkuwi_seed_${pair.address}`;
|
||||
await SecureStore.setItemAsync(seedKey, mnemonicPhrase);
|
||||
await secureStorage.setItem(seedKey, mnemonicPhrase);
|
||||
|
||||
if (__DEV__) console.log('[Pezkuwi] Wallet created:', pair.address);
|
||||
|
||||
@@ -266,24 +310,33 @@ export const PezkuwiProvider: React.FC<PezkuwiProviderProps> = ({ children }) =>
|
||||
address: pair.address,
|
||||
mnemonic: mnemonicPhrase,
|
||||
};
|
||||
} catch (err) {
|
||||
if (__DEV__) console.error('[Pezkuwi] Failed to create wallet:', err);
|
||||
throw new Error('Failed to create wallet');
|
||||
} catch (err: any) {
|
||||
if (__DEV__) {
|
||||
console.error('[Pezkuwi] Failed to create wallet:', err);
|
||||
console.error('[Pezkuwi] Error message:', err?.message);
|
||||
console.error('[Pezkuwi] Error stack:', err?.stack);
|
||||
}
|
||||
throw new Error(err?.message || 'Failed to create wallet');
|
||||
}
|
||||
};
|
||||
|
||||
// Import existing wallet from mnemonic
|
||||
// Import existing wallet from mnemonic or dev URI (like //Alice)
|
||||
const importWallet = async (
|
||||
name: string,
|
||||
mnemonic: string
|
||||
seedOrUri: string
|
||||
): Promise<{ address: string }> => {
|
||||
if (!keyring) {
|
||||
throw new Error('Keyring not initialized');
|
||||
}
|
||||
|
||||
try {
|
||||
// Create account from mnemonic
|
||||
const pair = keyring.addFromMnemonic(mnemonic.trim(), { name });
|
||||
const trimmedInput = seedOrUri.trim();
|
||||
const isDevUri = trimmedInput.startsWith('//');
|
||||
|
||||
// Create account from URI or mnemonic
|
||||
const pair = isDevUri
|
||||
? keyring.addFromUri(trimmedInput, { name })
|
||||
: keyring.addFromMnemonic(trimmedInput, { name });
|
||||
|
||||
// Check if account already exists
|
||||
if (accounts.some(a => a.address === pair.address)) {
|
||||
@@ -301,16 +354,49 @@ export const PezkuwiProvider: React.FC<PezkuwiProviderProps> = ({ children }) =>
|
||||
setAccounts(updatedAccounts);
|
||||
await AsyncStorage.setItem(WALLET_STORAGE_KEY, JSON.stringify(updatedAccounts));
|
||||
|
||||
// Store seed securely
|
||||
// Store seed/URI securely
|
||||
const seedKey = `pezkuwi_seed_${pair.address}`;
|
||||
await SecureStore.setItemAsync(seedKey, mnemonic.trim());
|
||||
await secureStorage.setItem(seedKey, trimmedInput);
|
||||
|
||||
if (__DEV__) console.log('[Pezkuwi] Wallet imported:', pair.address);
|
||||
if (__DEV__) console.log('[Pezkuwi] Wallet imported:', pair.address, isDevUri ? '(dev URI)' : '(mnemonic)');
|
||||
|
||||
return { address: pair.address };
|
||||
} catch (err) {
|
||||
if (__DEV__) console.error('[Pezkuwi] Failed to import wallet:', err);
|
||||
throw err;
|
||||
} catch (err: any) {
|
||||
if (__DEV__) {
|
||||
console.error('[Pezkuwi] Failed to import wallet:', err);
|
||||
console.error('[Pezkuwi] Error message:', err?.message);
|
||||
}
|
||||
throw new Error(err?.message || 'Failed to import wallet');
|
||||
}
|
||||
};
|
||||
|
||||
// Delete a wallet
|
||||
const deleteWallet = async (address: string): Promise<void> => {
|
||||
try {
|
||||
// Remove from accounts list
|
||||
const updatedAccounts = accounts.filter(a => a.address !== address);
|
||||
setAccounts(updatedAccounts);
|
||||
await AsyncStorage.setItem(WALLET_STORAGE_KEY, JSON.stringify(updatedAccounts));
|
||||
|
||||
// Remove seed from secure storage
|
||||
const seedKey = `pezkuwi_seed_${address}`;
|
||||
await secureStorage.removeItem(seedKey);
|
||||
|
||||
// If deleted account was selected, select another one
|
||||
if (selectedAccount?.address === address) {
|
||||
if (updatedAccounts.length > 0) {
|
||||
setSelectedAccount(updatedAccounts[0]);
|
||||
await AsyncStorage.setItem(SELECTED_ACCOUNT_KEY, updatedAccounts[0].address);
|
||||
} else {
|
||||
setSelectedAccount(null);
|
||||
await AsyncStorage.removeItem(SELECTED_ACCOUNT_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
if (__DEV__) console.log('[Pezkuwi] Wallet deleted:', address);
|
||||
} catch (err: any) {
|
||||
if (__DEV__) console.error('[Pezkuwi] Failed to delete wallet:', err);
|
||||
throw new Error(err?.message || 'Failed to delete wallet');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -321,17 +407,21 @@ export const PezkuwiProvider: React.FC<PezkuwiProviderProps> = ({ children }) =>
|
||||
}
|
||||
|
||||
try {
|
||||
// SECURITY: Load seed from SecureStore (encrypted storage)
|
||||
// SECURITY: Load seed/URI from secure storage (encrypted on native)
|
||||
const seedKey = `pezkuwi_seed_${address}`;
|
||||
const mnemonic = await SecureStore.getItemAsync(seedKey);
|
||||
const seedOrUri = await secureStorage.getItem(seedKey);
|
||||
|
||||
if (!mnemonic) {
|
||||
if (!seedOrUri) {
|
||||
if (__DEV__) console.error('[Pezkuwi] No seed found for address:', address);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Recreate keypair from mnemonic
|
||||
const pair = keyring.addFromMnemonic(mnemonic);
|
||||
// Recreate keypair from URI or mnemonic
|
||||
const isDevUri = seedOrUri.startsWith('//');
|
||||
const pair = isDevUri
|
||||
? keyring.addFromUri(seedOrUri)
|
||||
: keyring.addFromMnemonic(seedOrUri);
|
||||
|
||||
return pair;
|
||||
} catch (err) {
|
||||
if (__DEV__) console.error('[Pezkuwi] Failed to get keypair:', err);
|
||||
@@ -431,6 +521,7 @@ export const PezkuwiProvider: React.FC<PezkuwiProviderProps> = ({ children }) =>
|
||||
disconnectWallet,
|
||||
createWallet,
|
||||
importWallet,
|
||||
deleteWallet,
|
||||
getKeyPair,
|
||||
signMessage,
|
||||
error,
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
import React from 'react';
|
||||
import { renderHook, act } from '@testing-library/react-native';
|
||||
import { LanguageProvider, useLanguage } from '../LanguageContext';
|
||||
|
||||
// Mock the i18n module relative to src/
|
||||
jest.mock('../../i18n', () => ({
|
||||
saveLanguage: jest.fn(() => Promise.resolve()),
|
||||
getCurrentLanguage: jest.fn(() => 'en'),
|
||||
isRTL: jest.fn((code?: string) => {
|
||||
const testCode = code || 'en';
|
||||
return ['ckb', 'ar', 'fa'].includes(testCode);
|
||||
}),
|
||||
LANGUAGE_KEY: '@language',
|
||||
languages: [
|
||||
{ code: 'en', name: 'English', nativeName: 'English', rtl: false },
|
||||
{ code: 'tr', name: 'Turkish', nativeName: 'Türkçe', rtl: false },
|
||||
{ code: 'kmr', name: 'Kurdish Kurmanji', nativeName: 'Kurmancî', rtl: false },
|
||||
{ code: 'ckb', name: 'Kurdish Sorani', nativeName: 'سۆرانی', rtl: true },
|
||||
{ code: 'ar', name: 'Arabic', nativeName: 'العربية', rtl: true },
|
||||
{ code: 'fa', name: 'Persian', nativeName: 'فارسی', rtl: true },
|
||||
],
|
||||
}));
|
||||
|
||||
// Wrapper for provider
|
||||
const wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
<LanguageProvider>{children}</LanguageProvider>
|
||||
);
|
||||
|
||||
describe('LanguageContext', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should provide language context', () => {
|
||||
const { result } = renderHook(() => useLanguage(), { wrapper });
|
||||
|
||||
expect(result.current).toBeDefined();
|
||||
expect(result.current.currentLanguage).toBe('en');
|
||||
});
|
||||
|
||||
it('should change language', async () => {
|
||||
const { result } = renderHook(() => useLanguage(), { wrapper });
|
||||
|
||||
await act(async () => {
|
||||
await result.current.changeLanguage('kmr');
|
||||
});
|
||||
|
||||
expect(result.current.currentLanguage).toBe('kmr');
|
||||
});
|
||||
|
||||
it('should provide available languages', () => {
|
||||
const { result } = renderHook(() => useLanguage(), { wrapper });
|
||||
|
||||
expect(result.current.availableLanguages).toBeDefined();
|
||||
expect(Array.isArray(result.current.availableLanguages)).toBe(true);
|
||||
expect(result.current.availableLanguages.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should handle RTL languages', async () => {
|
||||
const { result } = renderHook(() => useLanguage(), { wrapper });
|
||||
|
||||
await act(async () => {
|
||||
await result.current.changeLanguage('ar');
|
||||
});
|
||||
|
||||
expect(result.current.isRTL).toBe(true);
|
||||
});
|
||||
|
||||
it('should handle LTR languages', async () => {
|
||||
const { result } = renderHook(() => useLanguage(), { wrapper });
|
||||
|
||||
expect(result.current.isRTL).toBe(false);
|
||||
});
|
||||
|
||||
it('should throw error when used outside provider', () => {
|
||||
const spy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
||||
expect(() => {
|
||||
renderHook(() => useLanguage());
|
||||
}).toThrow('useLanguage must be used within LanguageProvider');
|
||||
|
||||
spy.mockRestore();
|
||||
});
|
||||
|
||||
it('should handle language change errors gracefully', async () => {
|
||||
const { result } = renderHook(() => useLanguage(), { wrapper });
|
||||
|
||||
// changeLanguage should not throw but handle errors internally
|
||||
await act(async () => {
|
||||
await result.current.changeLanguage('en');
|
||||
});
|
||||
|
||||
expect(result.current.currentLanguage).toBeDefined();
|
||||
});
|
||||
|
||||
it('should persist language selection', async () => {
|
||||
const { result } = renderHook(() => useLanguage(), { wrapper });
|
||||
|
||||
await act(async () => {
|
||||
await result.current.changeLanguage('tr');
|
||||
});
|
||||
|
||||
expect(result.current.currentLanguage).toBe('tr');
|
||||
});
|
||||
});
|
||||
@@ -1,22 +0,0 @@
|
||||
import i18n from '../index';
|
||||
|
||||
describe('i18n Configuration', () => {
|
||||
it('should be initialized', () => {
|
||||
expect(i18n).toBeDefined();
|
||||
});
|
||||
|
||||
it('should have language property', () => {
|
||||
expect(i18n.language).toBeDefined();
|
||||
});
|
||||
|
||||
it('should have translation function', () => {
|
||||
expect(i18n.t).toBeDefined();
|
||||
expect(typeof i18n.t).toBe('function');
|
||||
});
|
||||
|
||||
it('should support changeLanguage', async () => {
|
||||
expect(i18n.changeLanguage).toBeDefined();
|
||||
await i18n.changeLanguage('en');
|
||||
expect(i18n.language).toBe('en');
|
||||
});
|
||||
});
|
||||
@@ -1,55 +0,0 @@
|
||||
import i18n from 'i18next';
|
||||
import { initReactI18next } from 'react-i18next';
|
||||
|
||||
// Import shared translations and language configurations
|
||||
import {
|
||||
comprehensiveTranslations as translations,
|
||||
LANGUAGES,
|
||||
DEFAULT_LANGUAGE,
|
||||
isRTL as checkIsRTL,
|
||||
} from '../../../shared/i18n';
|
||||
|
||||
// Language is set at build time via environment variable
|
||||
const BUILD_LANGUAGE = (process.env.EXPO_PUBLIC_DEFAULT_LANGUAGE || DEFAULT_LANGUAGE) as string;
|
||||
|
||||
// Available languages (re-export for compatibility)
|
||||
export const languages = LANGUAGES;
|
||||
|
||||
// Initialize i18n with build-time language only
|
||||
const initializeI18n = () => {
|
||||
if (__DEV__) {
|
||||
console.log(`[i18n] Initializing with build language: ${BUILD_LANGUAGE}`);
|
||||
}
|
||||
|
||||
i18n
|
||||
.use(initReactI18next)
|
||||
.init({
|
||||
resources: {
|
||||
// Only load the build-time language (reduces APK size)
|
||||
[BUILD_LANGUAGE]: { translation: translations[BUILD_LANGUAGE as keyof typeof translations] },
|
||||
},
|
||||
lng: BUILD_LANGUAGE,
|
||||
fallbackLng: BUILD_LANGUAGE,
|
||||
compatibilityJSON: 'v3',
|
||||
interpolation: {
|
||||
escapeValue: false,
|
||||
},
|
||||
});
|
||||
|
||||
return BUILD_LANGUAGE;
|
||||
};
|
||||
|
||||
// Get current language (always returns BUILD_LANGUAGE)
|
||||
export const getCurrentLanguage = () => BUILD_LANGUAGE;
|
||||
|
||||
// Check if language is RTL
|
||||
export const isRTL = (languageCode?: string) => {
|
||||
const code = languageCode || BUILD_LANGUAGE;
|
||||
return checkIsRTL(code);
|
||||
};
|
||||
|
||||
// Initialize i18n automatically
|
||||
initializeI18n();
|
||||
|
||||
export { initializeI18n, BUILD_LANGUAGE };
|
||||
export default i18n;
|
||||
@@ -1,228 +0,0 @@
|
||||
{
|
||||
"welcome": {
|
||||
"title": "مرحباً بك في بيزكوي",
|
||||
"subtitle": "بوابتك للحوكمة اللامركزية",
|
||||
"selectLanguage": "اختر لغتك",
|
||||
"continue": "متابعة"
|
||||
},
|
||||
"auth": {
|
||||
"signIn": "تسجيل الدخول",
|
||||
"signUp": "إنشاء حساب",
|
||||
"email": "البريد الإلكتروني",
|
||||
"password": "كلمة المرور",
|
||||
"confirmPassword": "تأكيد كلمة المرور",
|
||||
"forgotPassword": "نسيت كلمة المرور؟",
|
||||
"noAccount": "ليس لديك حساب؟",
|
||||
"haveAccount": "هل لديك حساب بالفعل؟",
|
||||
"createAccount": "إنشاء حساب",
|
||||
"welcomeBack": "مرحباً بعودتك!",
|
||||
"getStarted": "ابدأ الآن",
|
||||
"username": "اسم المستخدم",
|
||||
"emailRequired": "البريد الإلكتروني مطلوب",
|
||||
"passwordRequired": "كلمة المرور مطلوبة",
|
||||
"usernameRequired": "اسم المستخدم مطلوب",
|
||||
"signInSuccess": "تم تسجيل الدخول بنجاح!",
|
||||
"signUpSuccess": "تم إنشاء الحساب بنجاح!",
|
||||
"invalidCredentials": "بريد إلكتروني أو كلمة مرور غير صحيحة",
|
||||
"passwordsMustMatch": "يجب أن تتطابق كلمات المرور"
|
||||
},
|
||||
"dashboard": {
|
||||
"title": "لوحة التحكم",
|
||||
"wallet": "المحفظة",
|
||||
"staking": "التخزين",
|
||||
"governance": "الحوكمة",
|
||||
"dex": "البورصة",
|
||||
"history": "السجل",
|
||||
"settings": "الإعدادات",
|
||||
"balance": "الرصيد",
|
||||
"totalStaked": "إجمالي المخزن",
|
||||
"rewards": "المكافآت",
|
||||
"activeProposals": "المقترحات النشطة"
|
||||
},
|
||||
"wallet": {
|
||||
"title": "المحفظة",
|
||||
"connect": "ربط المحفظة",
|
||||
"disconnect": "فصل الاتصال",
|
||||
"address": "العنوان",
|
||||
"balance": "الرصيد",
|
||||
"send": "إرسال",
|
||||
"receive": "استقبال",
|
||||
"transaction": "المعاملة",
|
||||
"history": "السجل"
|
||||
},
|
||||
"governance": {
|
||||
"title": "الحوكمة",
|
||||
"vote": "تصويت",
|
||||
"voteFor": "تصويت نعم",
|
||||
"voteAgainst": "تصويت لا",
|
||||
"submitVote": "إرسال التصويت",
|
||||
"votingSuccess": "تم تسجيل تصويتك!",
|
||||
"selectCandidate": "اختر مرشحاً",
|
||||
"multipleSelect": "يمكنك اختيار عدة مرشحين",
|
||||
"singleSelect": "اختر مرشحاً واحداً",
|
||||
"proposals": "المقترحات",
|
||||
"elections": "الانتخابات",
|
||||
"parliament": "البرلمان",
|
||||
"activeElections": "الانتخابات النشطة",
|
||||
"totalVotes": "إجمالي الأصوات",
|
||||
"blocksLeft": "الكتل المتبقية",
|
||||
"leading": "الرائد"
|
||||
},
|
||||
"citizenship": {
|
||||
"title": "المواطنة",
|
||||
"applyForCitizenship": "التقدم للحصول على الجنسية",
|
||||
"newCitizen": "مواطن جديد",
|
||||
"existingCitizen": "مواطن حالي",
|
||||
"fullName": "الاسم الكامل",
|
||||
"fatherName": "اسم الأب",
|
||||
"motherName": "اسم الأم",
|
||||
"tribe": "القبيلة",
|
||||
"region": "المنطقة",
|
||||
"profession": "المهنة",
|
||||
"referralCode": "رمز الإحالة",
|
||||
"submitApplication": "إرسال الطلب",
|
||||
"applicationSuccess": "تم إرسال طلبك بنجاح!",
|
||||
"applicationPending": "طلبك قيد المراجعة",
|
||||
"citizenshipBenefits": "مزايا المواطنة",
|
||||
"votingRights": "حق التصويت في الحوكمة",
|
||||
"exclusiveAccess": "الوصول إلى الخدمات الحصرية",
|
||||
"referralRewards": "برنامج مكافآت الإحالة",
|
||||
"communityRecognition": "الاعتراف المجتمعي"
|
||||
},
|
||||
"p2p": {
|
||||
"title": "تداول P2P",
|
||||
"trade": "تداول",
|
||||
"createOffer": "إنشاء عرض",
|
||||
"buyToken": "شراء",
|
||||
"sellToken": "بيع",
|
||||
"amount": "الكمية",
|
||||
"price": "السعر",
|
||||
"total": "الإجمالي",
|
||||
"initiateTrade": "بدء التداول",
|
||||
"comingSoon": "قريباً",
|
||||
"tradingWith": "التداول مع",
|
||||
"available": "متاح",
|
||||
"minOrder": "الحد الأدنى للطلب",
|
||||
"maxOrder": "الحد الأقصى للطلب",
|
||||
"youWillPay": "ستدفع",
|
||||
"myOffers": "عروضي",
|
||||
"noOffers": "لا توجد عروض",
|
||||
"postAd": "نشر إعلان"
|
||||
},
|
||||
"forum": {
|
||||
"title": "المنتدى",
|
||||
"categories": "الفئات",
|
||||
"threads": "المواضيع",
|
||||
"replies": "الردود",
|
||||
"views": "المشاهدات",
|
||||
"lastActivity": "آخر نشاط",
|
||||
"createThread": "إنشاء موضوع",
|
||||
"generalDiscussion": "مناقشة عامة",
|
||||
"noThreads": "لا توجد مواضيع",
|
||||
"pinned": "مثبت",
|
||||
"locked": "مقفل"
|
||||
},
|
||||
"referral": {
|
||||
"title": "برنامج الإحالة",
|
||||
"myReferralCode": "رمز الإحالة الخاص بي",
|
||||
"totalReferrals": "إجمالي الإحالات",
|
||||
"activeReferrals": "الإحالات النشطة",
|
||||
"totalEarned": "إجمالي الأرباح",
|
||||
"pendingRewards": "المكافآت المعلقة",
|
||||
"shareCode": "مشاركة الرمز",
|
||||
"copyCode": "نسخ الرمز",
|
||||
"connectWallet": "ربط المحفظة",
|
||||
"inviteFriends": "دعوة الأصدقاء",
|
||||
"earnRewards": "احصل على المكافآت",
|
||||
"codeCopied": "تم نسخ الرمز!"
|
||||
},
|
||||
"settings": {
|
||||
"title": "الإعدادات",
|
||||
"sections": {
|
||||
"appearance": "المظهر",
|
||||
"language": "اللغة",
|
||||
"security": "الأمان",
|
||||
"notifications": "الإشعارات",
|
||||
"about": "حول"
|
||||
},
|
||||
"appearance": {
|
||||
"darkMode": "الوضع الداكن",
|
||||
"darkModeSubtitle": "التبديل بين السمة الفاتحة والداكنة",
|
||||
"fontSize": "حجم الخط",
|
||||
"fontSizeSubtitle": "الحالي: {{size}}",
|
||||
"fontSizePrompt": "اختر حجم الخط المفضل لديك",
|
||||
"small": "صغير",
|
||||
"medium": "متوسط",
|
||||
"large": "كبير"
|
||||
},
|
||||
"language": {
|
||||
"title": "اللغة",
|
||||
"changePrompt": "التبديل إلى {{language}}؟",
|
||||
"changeSuccess": "تم تحديث اللغة بنجاح!"
|
||||
},
|
||||
"security": {
|
||||
"biometric": "المصادقة البيومترية",
|
||||
"biometricSubtitle": "استخدم بصمة الإصبع أو التعرف على الوجه",
|
||||
"biometricPrompt": "هل تريد تفعيل المصادقة البيومترية؟",
|
||||
"biometricEnabled": "تم تفعيل المصادقة البيومترية",
|
||||
"twoFactor": "المصادقة الثنائية",
|
||||
"twoFactorSubtitle": "أضف طبقة أمان إضافية",
|
||||
"twoFactorPrompt": "المصادقة الثنائية تضيف طبقة أمان إضافية.",
|
||||
"twoFactorSetup": "إعداد",
|
||||
"changePassword": "تغيير كلمة المرور",
|
||||
"changePasswordSubtitle": "تحديث كلمة مرور حسابك"
|
||||
},
|
||||
"notifications": {
|
||||
"push": "الإشعارات الفورية",
|
||||
"pushSubtitle": "تلقي التنبيهات والتحديثات",
|
||||
"email": "إشعارات البريد الإلكتروني",
|
||||
"emailSubtitle": "إدارة تفضيلات البريد الإلكتروني"
|
||||
},
|
||||
"about": {
|
||||
"pezkuwi": "حول بيزكوي",
|
||||
"pezkuwiSubtitle": "تعرف أكثر على كردستان الرقمية",
|
||||
"pezkuwiMessage": "بيزكوي هو منصة بلوكتشين لامركزية لكردستان الرقمية.\n\nالإصدار: 1.0.0\n\nصُنع بـ ❤️",
|
||||
"terms": "شروط الخدمة",
|
||||
"privacy": "سياسة الخصوصية",
|
||||
"contact": "اتصل بالدعم",
|
||||
"contactSubtitle": "احصل على مساعدة من فريقنا",
|
||||
"contactEmail": "البريد الإلكتروني: support@pezkuwichain.io"
|
||||
},
|
||||
"version": {
|
||||
"app": "بيزكوي موبايل",
|
||||
"number": "الإصدار 1.0.0",
|
||||
"copyright": "© 2026 كردستان الرقمية"
|
||||
},
|
||||
"alerts": {
|
||||
"comingSoon": "قريباً",
|
||||
"darkModeMessage": "الوضع الداكن سيكون متاحاً قريباً",
|
||||
"twoFactorMessage": "إعداد المصادقة الثنائية سيكون متاحاً قريباً",
|
||||
"passwordMessage": "تغيير كلمة المرور سيكون متاحاً قريباً",
|
||||
"emailMessage": "إعدادات البريد الإلكتروني ستكون متاحة قريباً",
|
||||
"termsMessage": "شروط الخدمة ستكون متاحة قريباً",
|
||||
"privacyMessage": "سياسة الخصوصية ستكون متاحة قريباً"
|
||||
},
|
||||
"common": {
|
||||
"enable": "تفعيل",
|
||||
"cancel": "إلغاء",
|
||||
"confirm": "تأكيد",
|
||||
"success": "نجح",
|
||||
"error": "خطأ"
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
"cancel": "إلغاء",
|
||||
"confirm": "تأكيد",
|
||||
"save": "حفظ",
|
||||
"loading": "جاري التحميل...",
|
||||
"error": "خطأ",
|
||||
"success": "نجاح",
|
||||
"retry": "إعادة المحاولة",
|
||||
"close": "إغلاق",
|
||||
"back": "رجوع",
|
||||
"next": "التالي",
|
||||
"submit": "إرسال",
|
||||
"required": "مطلوب",
|
||||
"optional": "اختياري"
|
||||
}
|
||||
}
|
||||
@@ -1,228 +0,0 @@
|
||||
{
|
||||
"welcome": {
|
||||
"title": "بەخێربێیت بۆ پێزکووی",
|
||||
"subtitle": "دەرگای تۆ بۆ بەڕێوەبردنی نامەرکەزی",
|
||||
"selectLanguage": "زمانەکەت هەڵبژێرە",
|
||||
"continue": "بەردەوام بە"
|
||||
},
|
||||
"auth": {
|
||||
"signIn": "چوونەژوورەوە",
|
||||
"signUp": "تۆمارکردن",
|
||||
"email": "ئیمەیڵ",
|
||||
"password": "وشەی نهێنی",
|
||||
"username": "ناوی بەکارهێنەر",
|
||||
"confirmPassword": "پشتڕاستکردنەوەی وشەی نهێنی",
|
||||
"forgotPassword": "وشەی نهێنیت لەبیرکردووە؟",
|
||||
"noAccount": "هەژمارت نییە؟",
|
||||
"haveAccount": "هەژمارت هەیە؟",
|
||||
"createAccount": "دروستکردنی هەژمار",
|
||||
"welcomeBack": "بەخێربێیتەوە!",
|
||||
"getStarted": "دەست پێبکە",
|
||||
"emailRequired": "ئیمەیڵ پێویستە",
|
||||
"passwordRequired": "وشەی نهێنی پێویستە",
|
||||
"usernameRequired": "ناوی بەکارهێنەر پێویستە",
|
||||
"signInSuccess": "بەسەرکەوتووی چوویتە ژوورەوە!",
|
||||
"signUpSuccess": "هەژمار بەسەرکەوتووی دروستکرا!",
|
||||
"invalidCredentials": "ئیمەیڵ یان وشەی نهێنی هەڵەیە",
|
||||
"passwordsMustMatch": "وشەی نهێنییەکان دەبێت وەک یەک بن"
|
||||
},
|
||||
"dashboard": {
|
||||
"title": "سەرەتا",
|
||||
"wallet": "جزدان",
|
||||
"staking": "ستەیکینگ",
|
||||
"governance": "بەڕێوەبردن",
|
||||
"dex": "ئاڵوگۆڕ",
|
||||
"history": "مێژوو",
|
||||
"settings": "ڕێکخستنەکان",
|
||||
"balance": "باڵانس",
|
||||
"totalStaked": "کۆی گشتی",
|
||||
"rewards": "خەڵات",
|
||||
"activeProposals": "پێشنیارە چالاکەکان"
|
||||
},
|
||||
"governance": {
|
||||
"title": "بەڕێوەبردن",
|
||||
"vote": "دەنگدان",
|
||||
"voteFor": "دەنگی بەڵێ",
|
||||
"voteAgainst": "دەنگی نەخێر",
|
||||
"submitVote": "ناردنی دەنگ",
|
||||
"votingSuccess": "دەنگەکەت تۆمارکرا!",
|
||||
"selectCandidate": "کاندیدێک هەڵبژێرە",
|
||||
"multipleSelect": "دەتوانیت چەند کاندیدێک هەڵبژێریت",
|
||||
"singleSelect": "تەنها کاندیدێک هەڵبژێرە",
|
||||
"proposals": "پێشنیارەکان",
|
||||
"elections": "هەڵبژاردنەکان",
|
||||
"parliament": "پەرلەمان",
|
||||
"activeElections": "هەڵبژاردنە چالاکەکان",
|
||||
"totalVotes": "کۆی دەنگەکان",
|
||||
"blocksLeft": "بلۆکی ماوە",
|
||||
"leading": "پێشەنگ"
|
||||
},
|
||||
"citizenship": {
|
||||
"title": "هاووڵاتیێتی",
|
||||
"applyForCitizenship": "داوای هاووڵاتیێتی بکە",
|
||||
"newCitizen": "هاووڵاتی نوێ",
|
||||
"existingCitizen": "هاووڵاتی هەیە",
|
||||
"fullName": "ناوی تەواو",
|
||||
"fatherName": "ناوی باوک",
|
||||
"motherName": "ناوی دایک",
|
||||
"tribe": "عەشیرە",
|
||||
"region": "هەرێم",
|
||||
"profession": "پیشە",
|
||||
"referralCode": "کۆدی ئاماژەپێدان",
|
||||
"submitApplication": "ناردنی داواکاری",
|
||||
"applicationSuccess": "داواکاریەکەت بەسەرکەوتووی نێردرا!",
|
||||
"applicationPending": "داواکاریەکەت لە ژێر پێداچوونەوەدایە",
|
||||
"citizenshipBenefits": "سوودەکانی هاووڵاتیێتی",
|
||||
"votingRights": "مافی دەنگدان لە بەڕێوەبردندا",
|
||||
"exclusiveAccess": "دەستگەیشتن بە خزمەتگوزارییە تایبەتەکان",
|
||||
"referralRewards": "بەرنامەی خەڵاتی ئاماژەپێدان",
|
||||
"communityRecognition": "ناسینەوەی کۆمەڵگە"
|
||||
},
|
||||
"p2p": {
|
||||
"title": "بازرگانیی P2P",
|
||||
"trade": "بازرگانی",
|
||||
"createOffer": "دروستکردنی پێشنیار",
|
||||
"buyToken": "کڕین",
|
||||
"sellToken": "فرۆشتن",
|
||||
"amount": "بڕ",
|
||||
"price": "نرخ",
|
||||
"total": "کۆ",
|
||||
"initiateTrade": "دەستپێکردنی بازرگانی",
|
||||
"comingSoon": "بەم زووانە",
|
||||
"tradingWith": "بازرگانی لەگەڵ",
|
||||
"available": "بەردەستە",
|
||||
"minOrder": "کەمترین داواکاری",
|
||||
"maxOrder": "زۆرترین داواکاری",
|
||||
"youWillPay": "تۆ دەدەیت",
|
||||
"myOffers": "پێشنیارەکانم",
|
||||
"noOffers": "هیچ پێشنیارێک نییە",
|
||||
"postAd": "ڕیکلام بکە"
|
||||
},
|
||||
"forum": {
|
||||
"title": "فۆرەم",
|
||||
"categories": "هاوپۆلەکان",
|
||||
"threads": "بابەتەکان",
|
||||
"replies": "وەڵامەکان",
|
||||
"views": "بینینەکان",
|
||||
"lastActivity": "دوا چالاکی",
|
||||
"createThread": "دروستکردنی بابەت",
|
||||
"generalDiscussion": "گفتوگۆی گشتی",
|
||||
"noThreads": "هیچ بابەتێک نییە",
|
||||
"pinned": "جێگیرکراو",
|
||||
"locked": "داخراو"
|
||||
},
|
||||
"referral": {
|
||||
"title": "بەرنامەی ئاماژەپێدان",
|
||||
"myReferralCode": "کۆدی ئاماژەپێدانی من",
|
||||
"totalReferrals": "کۆی ئاماژەپێدانەکان",
|
||||
"activeReferrals": "ئاماژەپێدانە چالاکەکان",
|
||||
"totalEarned": "کۆی قازانج",
|
||||
"pendingRewards": "خەڵاتە چاوەڕوانکراوەکان",
|
||||
"shareCode": "هاوبەشکردنی کۆد",
|
||||
"copyCode": "کۆپیکردنی کۆد",
|
||||
"connectWallet": "گرێدانی جزدان",
|
||||
"inviteFriends": "بانگهێشتکردنی هاوڕێیان",
|
||||
"earnRewards": "خەڵات بەدەستبهێنە",
|
||||
"codeCopied": "کۆدەکە کۆپیکرا!"
|
||||
},
|
||||
"wallet": {
|
||||
"title": "جزدان",
|
||||
"connect": "گرێدانی جزدان",
|
||||
"disconnect": "پچڕاندنی گرێدان",
|
||||
"address": "ناونیشان",
|
||||
"balance": "باڵانس",
|
||||
"send": "ناردن",
|
||||
"receive": "وەرگرتن",
|
||||
"transaction": "مامەڵە",
|
||||
"history": "مێژوو"
|
||||
},
|
||||
"settings": {
|
||||
"title": "ڕێکخستنەکان",
|
||||
"sections": {
|
||||
"appearance": "دەرکەوتن",
|
||||
"language": "زمان",
|
||||
"security": "ئاسایش",
|
||||
"notifications": "ئاگادارییەکان",
|
||||
"about": "دەربارە"
|
||||
},
|
||||
"appearance": {
|
||||
"darkMode": "دۆخی تاریک",
|
||||
"darkModeSubtitle": "لە نێوان دۆخی ڕووناک و تاریک بگۆڕە",
|
||||
"fontSize": "قەبارەی فۆنت",
|
||||
"fontSizeSubtitle": "ئێستا: {{size}}",
|
||||
"fontSizePrompt": "قەبارەی فۆنتی دڵخوازت هەڵبژێرە",
|
||||
"small": "بچووک",
|
||||
"medium": "مامناوەند",
|
||||
"large": "گەورە"
|
||||
},
|
||||
"language": {
|
||||
"title": "زمان",
|
||||
"changePrompt": "بگۆڕدرێت بۆ {{language}}؟",
|
||||
"changeSuccess": "زمان بە سەرکەوتوویی نوێکرایەوە!"
|
||||
},
|
||||
"security": {
|
||||
"biometric": "ناسینەوەی بایۆمێتریک",
|
||||
"biometricSubtitle": "پەنجە نوێن یان ناسینەوەی ڕوخسار بەکاربهێنە",
|
||||
"biometricPrompt": "دەتەوێت ناسینەوەی بایۆمێتریک چالاک بکەیت؟",
|
||||
"biometricEnabled": "ناسینەوەی بایۆمێتریک چالاککرا",
|
||||
"twoFactor": "ناسینەوەی دوو-هەنگاوی",
|
||||
"twoFactorSubtitle": "چینێکی ئاسایشی زیادە زیاد بکە",
|
||||
"twoFactorPrompt": "ناسینەوەی دوو-هەنگاوی چینێکی ئاسایشی زیادە زیاد دەکات.",
|
||||
"twoFactorSetup": "ڕێکبخە",
|
||||
"changePassword": "وشەی نهێنی بگۆڕە",
|
||||
"changePasswordSubtitle": "وشەی نهێنی هەژمارەکەت نوێ بکەرەوە"
|
||||
},
|
||||
"notifications": {
|
||||
"push": "ئاگادارییە خێراکان",
|
||||
"pushSubtitle": "ئاگاداری و نوێکارییەکان وەربگرە",
|
||||
"email": "ئاگادارییەکانی ئیمەیل",
|
||||
"emailSubtitle": "هەڵبژاردنەکانی ئیمەیل بەڕێوەببە"
|
||||
},
|
||||
"about": {
|
||||
"pezkuwi": "دەربارەی پێزکووی",
|
||||
"pezkuwiSubtitle": "زیاتر دەربارەی کوردستانی دیجیتاڵ بزانە",
|
||||
"pezkuwiMessage": "پێزکووی پلاتفۆرمێکی بلۆکچەینی ناناوەندییە بۆ کوردستانی دیجیتاڵ.\n\nوەشان: 1.0.0\n\nبە ❤️ دروستکرا",
|
||||
"terms": "مەرجەکانی خزمەتگوزاری",
|
||||
"privacy": "سیاسەتی تایبەتمەندی",
|
||||
"contact": "پەیوەندی پشتگیری",
|
||||
"contactSubtitle": "یارمەتی لە تیمەکەمان وەربگرە",
|
||||
"contactEmail": "ئیمەیل: support@pezkuwichain.io"
|
||||
},
|
||||
"version": {
|
||||
"app": "پێزکووی مۆبایل",
|
||||
"number": "وەشان 1.0.0",
|
||||
"copyright": "© 2026 کوردستانی دیجیتاڵ"
|
||||
},
|
||||
"alerts": {
|
||||
"comingSoon": "بەم زووانە",
|
||||
"darkModeMessage": "دۆخی تاریک لە نوێکردنەوەی داهاتوودا بەردەست دەبێت",
|
||||
"twoFactorMessage": "ڕێکخستنی 2FA بەم زووانە بەردەست دەبێت",
|
||||
"passwordMessage": "گۆڕینی وشەی نهێنی بەم زووانە بەردەست دەبێت",
|
||||
"emailMessage": "ڕێکخستنەکانی ئیمەیل بەم زووانە بەردەست دەبن",
|
||||
"termsMessage": "مەرجەکانی خزمەتگوزاری بەم زووانە بەردەست دەبن",
|
||||
"privacyMessage": "سیاسەتی تایبەتمەندی بەم زووانە بەردەست دەبێت"
|
||||
},
|
||||
"common": {
|
||||
"enable": "چالاککردن",
|
||||
"cancel": "هەڵوەشاندنەوە",
|
||||
"confirm": "پشتڕاستکردنەوە",
|
||||
"success": "سەرکەوتوو",
|
||||
"error": "هەڵە"
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
"cancel": "هەڵوەشاندنەوە",
|
||||
"confirm": "پشتڕاستکردنەوە",
|
||||
"save": "پاشەکەوتکردن",
|
||||
"loading": "بارکردن...",
|
||||
"error": "هەڵە",
|
||||
"success": "سەرکەوتوو",
|
||||
"retry": "هەوڵ بدەرەوە",
|
||||
"close": "داخستن",
|
||||
"back": "گەڕانەوە",
|
||||
"next": "دواتر",
|
||||
"submit": "ناردن",
|
||||
"required": "پێویستە",
|
||||
"optional": "ئیختیاری"
|
||||
}
|
||||
}
|
||||
@@ -1,228 +0,0 @@
|
||||
{
|
||||
"welcome": {
|
||||
"title": "Welcome to Pezkuwi",
|
||||
"subtitle": "Your gateway to decentralized governance",
|
||||
"selectLanguage": "Select Your Language",
|
||||
"continue": "Continue"
|
||||
},
|
||||
"auth": {
|
||||
"signIn": "Sign In",
|
||||
"signUp": "Sign Up",
|
||||
"email": "Email",
|
||||
"password": "Password",
|
||||
"username": "Username",
|
||||
"confirmPassword": "Confirm Password",
|
||||
"forgotPassword": "Forgot Password?",
|
||||
"noAccount": "Don't have an account?",
|
||||
"haveAccount": "Already have an account?",
|
||||
"createAccount": "Create Account",
|
||||
"welcomeBack": "Welcome Back!",
|
||||
"getStarted": "Get Started",
|
||||
"emailRequired": "Email is required",
|
||||
"passwordRequired": "Password is required",
|
||||
"usernameRequired": "Username is required",
|
||||
"signInSuccess": "Signed in successfully!",
|
||||
"signUpSuccess": "Account created successfully!",
|
||||
"invalidCredentials": "Invalid email or password",
|
||||
"passwordsMustMatch": "Passwords must match"
|
||||
},
|
||||
"dashboard": {
|
||||
"title": "Dashboard",
|
||||
"wallet": "Wallet",
|
||||
"staking": "Staking",
|
||||
"governance": "Governance",
|
||||
"dex": "Exchange",
|
||||
"history": "History",
|
||||
"settings": "Settings",
|
||||
"balance": "Balance",
|
||||
"totalStaked": "Total Staked",
|
||||
"rewards": "Rewards",
|
||||
"activeProposals": "Active Proposals"
|
||||
},
|
||||
"governance": {
|
||||
"title": "Governance",
|
||||
"vote": "Vote",
|
||||
"voteFor": "Vote FOR",
|
||||
"voteAgainst": "Vote AGAINST",
|
||||
"submitVote": "Submit Vote",
|
||||
"votingSuccess": "Your vote has been recorded!",
|
||||
"selectCandidate": "Select Candidate",
|
||||
"multipleSelect": "You can select multiple candidates",
|
||||
"singleSelect": "Select one candidate",
|
||||
"proposals": "Proposals",
|
||||
"elections": "Elections",
|
||||
"parliament": "Parliament",
|
||||
"activeElections": "Active Elections",
|
||||
"totalVotes": "Total Votes",
|
||||
"blocksLeft": "Blocks Left",
|
||||
"leading": "Leading"
|
||||
},
|
||||
"citizenship": {
|
||||
"title": "Citizenship",
|
||||
"applyForCitizenship": "Apply for Citizenship",
|
||||
"newCitizen": "New Citizen",
|
||||
"existingCitizen": "Existing Citizen",
|
||||
"fullName": "Full Name",
|
||||
"fatherName": "Father's Name",
|
||||
"motherName": "Mother's Name",
|
||||
"tribe": "Tribe",
|
||||
"region": "Region",
|
||||
"profession": "Profession",
|
||||
"referralCode": "Referral Code",
|
||||
"submitApplication": "Submit Application",
|
||||
"applicationSuccess": "Application submitted successfully!",
|
||||
"applicationPending": "Your application is pending review",
|
||||
"citizenshipBenefits": "Citizenship Benefits",
|
||||
"votingRights": "Voting rights in governance",
|
||||
"exclusiveAccess": "Access to exclusive services",
|
||||
"referralRewards": "Referral rewards program",
|
||||
"communityRecognition": "Community recognition"
|
||||
},
|
||||
"p2p": {
|
||||
"title": "P2P Trading",
|
||||
"trade": "Trade",
|
||||
"createOffer": "Create Offer",
|
||||
"buyToken": "Buy",
|
||||
"sellToken": "Sell",
|
||||
"amount": "Amount",
|
||||
"price": "Price",
|
||||
"total": "Total",
|
||||
"initiateTrade": "Initiate Trade",
|
||||
"comingSoon": "Coming Soon",
|
||||
"tradingWith": "Trading with",
|
||||
"available": "Available",
|
||||
"minOrder": "Min Order",
|
||||
"maxOrder": "Max Order",
|
||||
"youWillPay": "You will pay",
|
||||
"myOffers": "My Offers",
|
||||
"noOffers": "No offers available",
|
||||
"postAd": "Post Ad"
|
||||
},
|
||||
"forum": {
|
||||
"title": "Forum",
|
||||
"categories": "Categories",
|
||||
"threads": "Threads",
|
||||
"replies": "Replies",
|
||||
"views": "Views",
|
||||
"lastActivity": "Last Activity",
|
||||
"createThread": "Create Thread",
|
||||
"generalDiscussion": "General Discussion",
|
||||
"noThreads": "No threads available",
|
||||
"pinned": "Pinned",
|
||||
"locked": "Locked"
|
||||
},
|
||||
"referral": {
|
||||
"title": "Referral Program",
|
||||
"myReferralCode": "My Referral Code",
|
||||
"totalReferrals": "Total Referrals",
|
||||
"activeReferrals": "Active Referrals",
|
||||
"totalEarned": "Total Earned",
|
||||
"pendingRewards": "Pending Rewards",
|
||||
"shareCode": "Share Code",
|
||||
"copyCode": "Copy Code",
|
||||
"connectWallet": "Connect Wallet",
|
||||
"inviteFriends": "Invite Friends",
|
||||
"earnRewards": "Earn Rewards",
|
||||
"codeCopied": "Code copied to clipboard!"
|
||||
},
|
||||
"wallet": {
|
||||
"title": "Wallet",
|
||||
"connect": "Connect Wallet",
|
||||
"disconnect": "Disconnect",
|
||||
"address": "Address",
|
||||
"balance": "Balance",
|
||||
"send": "Send",
|
||||
"receive": "Receive",
|
||||
"transaction": "Transaction",
|
||||
"history": "History"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Settings",
|
||||
"sections": {
|
||||
"appearance": "APPEARANCE",
|
||||
"language": "LANGUAGE",
|
||||
"security": "SECURITY",
|
||||
"notifications": "NOTIFICATIONS",
|
||||
"about": "ABOUT"
|
||||
},
|
||||
"appearance": {
|
||||
"darkMode": "Dark Mode",
|
||||
"darkModeSubtitle": "Switch between light and dark theme",
|
||||
"fontSize": "Font Size",
|
||||
"fontSizeSubtitle": "Current: {{size}}",
|
||||
"fontSizePrompt": "Choose your preferred font size",
|
||||
"small": "Small",
|
||||
"medium": "Medium",
|
||||
"large": "Large"
|
||||
},
|
||||
"language": {
|
||||
"title": "Language",
|
||||
"changePrompt": "Switch to {{language}}?",
|
||||
"changeSuccess": "Language updated successfully!"
|
||||
},
|
||||
"security": {
|
||||
"biometric": "Biometric Authentication",
|
||||
"biometricSubtitle": "Use fingerprint or face recognition",
|
||||
"biometricPrompt": "Do you want to enable biometric authentication (fingerprint/face recognition)?",
|
||||
"biometricEnabled": "Biometric authentication enabled",
|
||||
"twoFactor": "Two-Factor Authentication",
|
||||
"twoFactorSubtitle": "Add an extra layer of security",
|
||||
"twoFactorPrompt": "Two-factor authentication adds an extra layer of security. You will need to set up an authenticator app.",
|
||||
"twoFactorSetup": "Set Up",
|
||||
"changePassword": "Change Password",
|
||||
"changePasswordSubtitle": "Update your account password"
|
||||
},
|
||||
"notifications": {
|
||||
"push": "Push Notifications",
|
||||
"pushSubtitle": "Receive alerts and updates",
|
||||
"email": "Email Notifications",
|
||||
"emailSubtitle": "Manage email preferences"
|
||||
},
|
||||
"about": {
|
||||
"pezkuwi": "About Pezkuwi",
|
||||
"pezkuwiSubtitle": "Learn more about Digital Kurdistan",
|
||||
"pezkuwiMessage": "Pezkuwi is a decentralized blockchain platform for Digital Kurdistan, enabling citizens to participate in governance, economy, and social life.\n\nVersion: 1.0.0\n\nBuilt with ❤️ by the Digital Kurdistan team",
|
||||
"terms": "Terms of Service",
|
||||
"privacy": "Privacy Policy",
|
||||
"contact": "Contact Support",
|
||||
"contactSubtitle": "Get help from our team",
|
||||
"contactEmail": "Email: support@pezkuwichain.io"
|
||||
},
|
||||
"version": {
|
||||
"app": "Pezkuwi Mobile",
|
||||
"number": "Version 1.0.0",
|
||||
"copyright": "© 2026 Digital Kurdistan"
|
||||
},
|
||||
"alerts": {
|
||||
"comingSoon": "Coming Soon",
|
||||
"darkModeMessage": "Dark mode will be available in the next update",
|
||||
"twoFactorMessage": "2FA setup will be available soon",
|
||||
"passwordMessage": "Password change will be available soon",
|
||||
"emailMessage": "Email settings will be available soon",
|
||||
"termsMessage": "Terms of Service will be available soon",
|
||||
"privacyMessage": "Privacy Policy will be available soon"
|
||||
},
|
||||
"common": {
|
||||
"enable": "Enable",
|
||||
"cancel": "Cancel",
|
||||
"confirm": "Confirm",
|
||||
"success": "Success",
|
||||
"error": "Error"
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
"cancel": "Cancel",
|
||||
"confirm": "Confirm",
|
||||
"save": "Save",
|
||||
"loading": "Loading...",
|
||||
"error": "Error",
|
||||
"success": "Success",
|
||||
"retry": "Retry",
|
||||
"close": "Close",
|
||||
"back": "Back",
|
||||
"next": "Next",
|
||||
"submit": "Submit",
|
||||
"required": "Required",
|
||||
"optional": "Optional"
|
||||
}
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
{
|
||||
"welcome": {
|
||||
"title": "به پێزکووی خوش آمدید",
|
||||
"subtitle": "دروازه شما به حکمرانی غیرمتمرکز",
|
||||
"selectLanguage": "زبان خود را انتخاب کنید",
|
||||
"continue": "ادامه"
|
||||
},
|
||||
"auth": {
|
||||
"signIn": "ورود",
|
||||
"signUp": "ثبت نام",
|
||||
"email": "ایمیل",
|
||||
"password": "رمز عبور",
|
||||
"confirmPassword": "تأیید رمز عبور",
|
||||
"forgotPassword": "رمز عبور را فراموش کردهاید؟",
|
||||
"noAccount": "حساب کاربری ندارید؟",
|
||||
"haveAccount": "قبلاً حساب کاربری دارید؟",
|
||||
"createAccount": "ایجاد حساب",
|
||||
"welcomeBack": "خوش آمدید!",
|
||||
"getStarted": "شروع کنید",
|
||||
"username": "نام کاربری",
|
||||
"emailRequired": "ایمیل الزامی است",
|
||||
"passwordRequired": "رمز عبور الزامی است",
|
||||
"usernameRequired": "نام کاربری الزامی است",
|
||||
"signInSuccess": "با موفقیت وارد شدید!",
|
||||
"signUpSuccess": "حساب با موفقیت ایجاد شد!",
|
||||
"invalidCredentials": "ایمیل یا رمز عبور نامعتبر",
|
||||
"passwordsMustMatch": "رمزهای عبور باید یکسان باشند"
|
||||
},
|
||||
"dashboard": {
|
||||
"title": "داشبورد",
|
||||
"wallet": "کیف پول",
|
||||
"staking": "سپردهگذاری",
|
||||
"governance": "حکمرانی",
|
||||
"dex": "صرافی",
|
||||
"history": "تاریخچه",
|
||||
"settings": "تنظیمات",
|
||||
"balance": "موجودی",
|
||||
"totalStaked": "کل سپرده",
|
||||
"rewards": "پاداشها",
|
||||
"activeProposals": "پیشنهادات فعال"
|
||||
},
|
||||
"wallet": {
|
||||
"title": "کیف پول",
|
||||
"connect": "اتصال کیف پول",
|
||||
"disconnect": "قطع اتصال",
|
||||
"address": "آدرس",
|
||||
"balance": "موجودی",
|
||||
"send": "ارسال",
|
||||
"receive": "دریافت",
|
||||
"transaction": "تراکنش",
|
||||
"history": "تاریخچه"
|
||||
},
|
||||
"governance": {
|
||||
"title": "حکمرانی",
|
||||
"vote": "رأی دادن",
|
||||
"voteFor": "رأی موافق",
|
||||
"voteAgainst": "رأی مخالف",
|
||||
"submitVote": "ثبت رأی",
|
||||
"votingSuccess": "رأی شما ثبت شد!",
|
||||
"selectCandidate": "انتخاب کاندیدا",
|
||||
"multipleSelect": "میتوانید چند کاندیدا انتخاب کنید",
|
||||
"singleSelect": "یک کاندیدا انتخاب کنید",
|
||||
"proposals": "پیشنهادها",
|
||||
"elections": "انتخابات",
|
||||
"parliament": "پارلمان",
|
||||
"activeElections": "انتخابات فعال",
|
||||
"totalVotes": "مجموع آرا",
|
||||
"blocksLeft": "بلوکهای باقیمانده",
|
||||
"leading": "پیشرو"
|
||||
},
|
||||
"citizenship": {
|
||||
"title": "تابعیت",
|
||||
"applyForCitizenship": "درخواست تابعیت",
|
||||
"newCitizen": "شهروند جدید",
|
||||
"existingCitizen": "شهروند موجود",
|
||||
"fullName": "نام کامل",
|
||||
"fatherName": "نام پدر",
|
||||
"motherName": "نام مادر",
|
||||
"tribe": "قبیله",
|
||||
"region": "منطقه",
|
||||
"profession": "شغل",
|
||||
"referralCode": "کد معرف",
|
||||
"submitApplication": "ارسال درخواست",
|
||||
"applicationSuccess": "درخواست شما با موفقیت ارسال شد!",
|
||||
"applicationPending": "درخواست شما در حال بررسی است",
|
||||
"citizenshipBenefits": "مزایای تابعیت",
|
||||
"votingRights": "حق رأی در حکمرانی",
|
||||
"exclusiveAccess": "دسترسی به خدمات انحصاری",
|
||||
"referralRewards": "برنامه پاداش معرفی",
|
||||
"communityRecognition": "شناخت اجتماعی"
|
||||
},
|
||||
"p2p": {
|
||||
"title": "تجارت P2P",
|
||||
"trade": "معامله",
|
||||
"createOffer": "ایجاد پیشنهاد",
|
||||
"buyToken": "خرید",
|
||||
"sellToken": "فروش",
|
||||
"amount": "مقدار",
|
||||
"price": "قیمت",
|
||||
"total": "مجموع",
|
||||
"initiateTrade": "شروع معامله",
|
||||
"comingSoon": "به زودی",
|
||||
"tradingWith": "معامله با",
|
||||
"available": "موجود",
|
||||
"minOrder": "حداقل سفارش",
|
||||
"maxOrder": "حداکثر سفارش",
|
||||
"youWillPay": "شما پرداخت خواهید کرد",
|
||||
"myOffers": "پیشنهادهای من",
|
||||
"noOffers": "پیشنهادی موجود نیست",
|
||||
"postAd": "ثبت آگهی"
|
||||
},
|
||||
"forum": {
|
||||
"title": "انجمن",
|
||||
"categories": "دستهبندیها",
|
||||
"threads": "موضوعات",
|
||||
"replies": "پاسخها",
|
||||
"views": "بازدیدها",
|
||||
"lastActivity": "آخرین فعالیت",
|
||||
"createThread": "ایجاد موضوع",
|
||||
"generalDiscussion": "بحث عمومی",
|
||||
"noThreads": "موضوعی موجود نیست",
|
||||
"pinned": "پین شده",
|
||||
"locked": "قفل شده"
|
||||
},
|
||||
"referral": {
|
||||
"title": "برنامه معرفی",
|
||||
"myReferralCode": "کد معرف من",
|
||||
"totalReferrals": "مجموع معرفیها",
|
||||
"activeReferrals": "معرفیهای فعال",
|
||||
"totalEarned": "مجموع درآمد",
|
||||
"pendingRewards": "پاداشهای در انتظار",
|
||||
"shareCode": "اشتراکگذاری کد",
|
||||
"copyCode": "کپی کد",
|
||||
"connectWallet": "اتصال کیف پول",
|
||||
"inviteFriends": "دعوت از دوستان",
|
||||
"earnRewards": "کسب پاداش",
|
||||
"codeCopied": "کد کپی شد!"
|
||||
},
|
||||
"settings": {
|
||||
"title": "تنظیمات",
|
||||
"language": "زبان",
|
||||
"theme": "تم",
|
||||
"notifications": "اعلانها",
|
||||
"security": "امنیت",
|
||||
"about": "درباره",
|
||||
"logout": "خروج"
|
||||
},
|
||||
"common": {
|
||||
"cancel": "لغو",
|
||||
"confirm": "تأیید",
|
||||
"save": "ذخیره",
|
||||
"loading": "در حال بارگذاری...",
|
||||
"error": "خطا",
|
||||
"success": "موفق",
|
||||
"retry": "تلاش مجدد",
|
||||
"close": "بستن",
|
||||
"back": "بازگشت",
|
||||
"next": "بعدی",
|
||||
"submit": "ارسال",
|
||||
"required": "الزامی",
|
||||
"optional": "اختیاری"
|
||||
}
|
||||
}
|
||||
@@ -1,228 +0,0 @@
|
||||
{
|
||||
"welcome": {
|
||||
"title": "Bi xêr hatî Pezkuwî",
|
||||
"subtitle": "Deriyê te yê bo rêveberiya desentralîze",
|
||||
"selectLanguage": "Zimanê Xwe Hilbijêre",
|
||||
"continue": "Bidomîne"
|
||||
},
|
||||
"auth": {
|
||||
"signIn": "Têkeve",
|
||||
"signUp": "Tomar bibe",
|
||||
"email": "E-posta",
|
||||
"password": "Şîfre",
|
||||
"username": "Navê Bikarhêner",
|
||||
"confirmPassword": "Şîfreyê Bipejirîne",
|
||||
"forgotPassword": "Şîfreyê te ji bîr kiriye?",
|
||||
"noAccount": "Hesabê te tune ye?",
|
||||
"haveAccount": "Jixwe hesabê te heye?",
|
||||
"createAccount": "Hesab Biafirîne",
|
||||
"welcomeBack": "Dîsa bi xêr hatî!",
|
||||
"getStarted": "Dest pê bike",
|
||||
"emailRequired": "E-posta hewce ye",
|
||||
"passwordRequired": "Şîfre hewce ye",
|
||||
"usernameRequired": "Navê bikarhêner hewce ye",
|
||||
"signInSuccess": "Bi serfirazî têkeve!",
|
||||
"signUpSuccess": "Hesab bi serfirazî hate afirandin!",
|
||||
"invalidCredentials": "E-posta an şîfreya nederbasdar",
|
||||
"passwordsMustMatch": "Şîfre divê hevdu bigire"
|
||||
},
|
||||
"dashboard": {
|
||||
"title": "Serûpel",
|
||||
"wallet": "Berîk",
|
||||
"staking": "Staking",
|
||||
"governance": "Rêvebir",
|
||||
"dex": "Guherîn",
|
||||
"history": "Dîrok",
|
||||
"settings": "Mîheng",
|
||||
"balance": "Bilanço",
|
||||
"totalStaked": "Hemû Stake",
|
||||
"rewards": "Xelat",
|
||||
"activeProposals": "Pêşniyarên Çalak"
|
||||
},
|
||||
"governance": {
|
||||
"title": "Rêvebir",
|
||||
"vote": "Deng bide",
|
||||
"voteFor": "Dengê ERÊ",
|
||||
"voteAgainst": "Dengê NA",
|
||||
"submitVote": "Dengê Xwe Bişîne",
|
||||
"votingSuccess": "Dengê we hate tomarkirin!",
|
||||
"selectCandidate": "Namzed Hilbijêre",
|
||||
"multipleSelect": "Hûn dikarin çend namzedan hilbijêrin",
|
||||
"singleSelect": "Yek namzed hilbijêre",
|
||||
"proposals": "Pêşniyar",
|
||||
"elections": "Hilbijartin",
|
||||
"parliament": "Parlamenter",
|
||||
"activeElections": "Hilbijartinên Çalak",
|
||||
"totalVotes": "Giştî Deng",
|
||||
"blocksLeft": "Blokên Mayî",
|
||||
"leading": "Pêşeng"
|
||||
},
|
||||
"citizenship": {
|
||||
"title": "Hemwelatî",
|
||||
"applyForCitizenship": "Ji bo Hemwelatî Serlêdan Bike",
|
||||
"newCitizen": "Hemwelatîyê Nû",
|
||||
"existingCitizen": "Hemwelatîya Heyî",
|
||||
"fullName": "Nav û Paşnav",
|
||||
"fatherName": "Navê Bav",
|
||||
"motherName": "Navê Dê",
|
||||
"tribe": "Eşîret",
|
||||
"region": "Herêm",
|
||||
"profession": "Pîşe",
|
||||
"referralCode": "Koda Referansê",
|
||||
"submitApplication": "Serldanê Bişîne",
|
||||
"applicationSuccess": "Serlêdan bi serfirazî hate şandin!",
|
||||
"applicationPending": "Serlêdana we di bin lêkolînê de ye",
|
||||
"citizenshipBenefits": "Faydeyên Hemwelatî",
|
||||
"votingRights": "Mafê dengdanê di rêvebiriyê de",
|
||||
"exclusiveAccess": "Gihîştina karûbarên taybet",
|
||||
"referralRewards": "Bernameya xelatên referansê",
|
||||
"communityRecognition": "Naskirina civakê"
|
||||
},
|
||||
"p2p": {
|
||||
"title": "Bazirganiya P2P",
|
||||
"trade": "Bazirganî",
|
||||
"createOffer": "Pêşniyar Biafirîne",
|
||||
"buyToken": "Bikire",
|
||||
"sellToken": "Bifiroşe",
|
||||
"amount": "Mîqdar",
|
||||
"price": "Biha",
|
||||
"total": "Giştî",
|
||||
"initiateTrade": "Bazirganiyê Destpêbike",
|
||||
"comingSoon": "Pir nêzîk",
|
||||
"tradingWith": "Bi re bazirganî",
|
||||
"available": "Heyî",
|
||||
"minOrder": "Daxwaza Kêm",
|
||||
"maxOrder": "Daxwaza Zêde",
|
||||
"youWillPay": "Hûn dê bidin",
|
||||
"myOffers": "Pêşniyarên Min",
|
||||
"noOffers": "Pêşniyar tunene",
|
||||
"postAd": "Agahî Bide"
|
||||
},
|
||||
"forum": {
|
||||
"title": "Forum",
|
||||
"categories": "Kategoriyan",
|
||||
"threads": "Mijar",
|
||||
"replies": "Bersiv",
|
||||
"views": "Nêrîn",
|
||||
"lastActivity": "Çalakiya Dawî",
|
||||
"createThread": "Mijar Biafirîne",
|
||||
"generalDiscussion": "Gotûbêja Giştî",
|
||||
"noThreads": "Mijar tunene",
|
||||
"pinned": "Girêdayî",
|
||||
"locked": "Girtî"
|
||||
},
|
||||
"referral": {
|
||||
"title": "Bernameya Referansê",
|
||||
"myReferralCode": "Koda Referansa Min",
|
||||
"totalReferrals": "Giştî Referans",
|
||||
"activeReferrals": "Referansên Çalak",
|
||||
"totalEarned": "Giştî Qezenc",
|
||||
"pendingRewards": "Xelatên Li Benda",
|
||||
"shareCode": "Kodê Parve Bike",
|
||||
"copyCode": "Kodê Kopî Bike",
|
||||
"connectWallet": "Berîkê Girêbide",
|
||||
"inviteFriends": "Hevalên Xwe Vexwîne",
|
||||
"earnRewards": "Xelat Qezenc Bike",
|
||||
"codeCopied": "Kod hate kopîkirin!"
|
||||
},
|
||||
"wallet": {
|
||||
"title": "Berîk",
|
||||
"connect": "Berîkê Girêde",
|
||||
"disconnect": "Girêdanê Rake",
|
||||
"address": "Navnîşan",
|
||||
"balance": "Bilanço",
|
||||
"send": "Bişîne",
|
||||
"receive": "Bistîne",
|
||||
"transaction": "Ragihandin",
|
||||
"history": "Dîrok"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Mîhengên",
|
||||
"sections": {
|
||||
"appearance": "XUYANÎ",
|
||||
"language": "ZIMAN",
|
||||
"security": "EWLEHÎ",
|
||||
"notifications": "AGAHDARÎ",
|
||||
"about": "DER BARÊ"
|
||||
},
|
||||
"appearance": {
|
||||
"darkMode": "Moda Tarî",
|
||||
"darkModeSubtitle": "Di navbera moda ronî û tarî de biguherîne",
|
||||
"fontSize": "Mezinahiya Nivîsê",
|
||||
"fontSizeSubtitle": "Niha: {{size}}",
|
||||
"fontSizePrompt": "Mezinahiya nivîsê ya xwe hilbijêre",
|
||||
"small": "Piçûk",
|
||||
"medium": "Nav",
|
||||
"large": "Mezin"
|
||||
},
|
||||
"language": {
|
||||
"title": "Ziman",
|
||||
"changePrompt": "Biguherîne bo {{language}}?",
|
||||
"changeSuccess": "Ziman bi serkeftî hate nûkirin!"
|
||||
},
|
||||
"security": {
|
||||
"biometric": "Naskirina Bîyometrîk",
|
||||
"biometricSubtitle": "Şopa tilî yan naskirina rû bikar bîne",
|
||||
"biometricPrompt": "Hûn dixwazin naskirina bîyometrîk çalak bikin?",
|
||||
"biometricEnabled": "Naskirina bîyometrîk çalak kirin",
|
||||
"twoFactor": "Naskirina Du-Pîlan",
|
||||
"twoFactorSubtitle": "Qateka ewlehiyê zêde bikin",
|
||||
"twoFactorPrompt": "Naskirina du-pîlan qateka ewlehiyê zêde dike.",
|
||||
"twoFactorSetup": "Saz Bike",
|
||||
"changePassword": "Şîfreyê Biguherîne",
|
||||
"changePasswordSubtitle": "Şîfreya hesabê xwe nû bike"
|
||||
},
|
||||
"notifications": {
|
||||
"push": "Agahdariyên Zû",
|
||||
"pushSubtitle": "Hişyarî û nûvekirinên werbigire",
|
||||
"email": "Agahdariyên E-nameyê",
|
||||
"emailSubtitle": "Vebijarkên e-nameyê birêve bibin"
|
||||
},
|
||||
"about": {
|
||||
"pezkuwi": "Der barê Pezkuwi",
|
||||
"pezkuwiSubtitle": "Zêdetir der barê Kurdistana Dîjîtal bizanin",
|
||||
"pezkuwiMessage": "Pezkuwi platformek blockchain-ê ya bê-navend e ji bo Kurdistana Dîjîtal.\n\nGuherto: 1.0.0\n\nBi ❤️ hatiye çêkirin",
|
||||
"terms": "Mercên Karûbarê",
|
||||
"privacy": "Siyaseta Nepenîtiyê",
|
||||
"contact": "Têkiliya Piştgiriyê",
|
||||
"contactSubtitle": "Ji tîma me alîkarî bistînin",
|
||||
"contactEmail": "E-name: support@pezkuwichain.io"
|
||||
},
|
||||
"version": {
|
||||
"app": "Pezkuwi Mobîl",
|
||||
"number": "Guherto 1.0.0",
|
||||
"copyright": "© 2026 Kurdistana Dîjîtal"
|
||||
},
|
||||
"alerts": {
|
||||
"comingSoon": "Zû tê",
|
||||
"darkModeMessage": "Moda tarî di nûvekirina pêş de berdest dibe",
|
||||
"twoFactorMessage": "Sazkirina 2FA zû berdest dibe",
|
||||
"passwordMessage": "Guherandina şîfreyê zû berdest dibe",
|
||||
"emailMessage": "Mîhengên e-nameyê zû berdest dibin",
|
||||
"termsMessage": "Mercên karûbarê zû berdest dibin",
|
||||
"privacyMessage": "Siyaseta nepenîtiyê zû berdest dibe"
|
||||
},
|
||||
"common": {
|
||||
"enable": "Çalak Bike",
|
||||
"cancel": "Betal Bike",
|
||||
"confirm": "Pejirandin",
|
||||
"success": "Serkeft",
|
||||
"error": "Çewtî"
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
"cancel": "Betal bike",
|
||||
"confirm": "Bipejirîne",
|
||||
"save": "Tomar bike",
|
||||
"loading": "Tê barkirin...",
|
||||
"error": "Çewtî",
|
||||
"success": "Serkeftin",
|
||||
"retry": "Dîsa biceribîne",
|
||||
"close": "Bigire",
|
||||
"back": "Paş",
|
||||
"next": "Pêş",
|
||||
"submit": "Bişîne",
|
||||
"required": "Hewce ye",
|
||||
"optional": "Bijarte"
|
||||
}
|
||||
}
|
||||
@@ -1,228 +0,0 @@
|
||||
{
|
||||
"welcome": {
|
||||
"title": "Pezkuwi'ye Hoş Geldiniz",
|
||||
"subtitle": "Merkezi olmayan yönetim kapınız",
|
||||
"selectLanguage": "Dilinizi Seçin",
|
||||
"continue": "Devam Et"
|
||||
},
|
||||
"auth": {
|
||||
"signIn": "Giriş Yap",
|
||||
"signUp": "Kayıt Ol",
|
||||
"email": "E-posta",
|
||||
"password": "Şifre",
|
||||
"username": "Kullanıcı Adı",
|
||||
"confirmPassword": "Şifreyi Onayla",
|
||||
"forgotPassword": "Şifremi Unuttum",
|
||||
"noAccount": "Hesabınız yok mu?",
|
||||
"haveAccount": "Zaten hesabınız var mı?",
|
||||
"createAccount": "Hesap Oluştur",
|
||||
"welcomeBack": "Tekrar Hoş Geldiniz!",
|
||||
"getStarted": "Başlayın",
|
||||
"emailRequired": "E-posta gereklidir",
|
||||
"passwordRequired": "Şifre gereklidir",
|
||||
"usernameRequired": "Kullanıcı adı gereklidir",
|
||||
"signInSuccess": "Başarıyla giriş yapıldı!",
|
||||
"signUpSuccess": "Hesap başarıyla oluşturuldu!",
|
||||
"invalidCredentials": "Geçersiz e-posta veya şifre",
|
||||
"passwordsMustMatch": "Şifreler eşleşmelidir"
|
||||
},
|
||||
"dashboard": {
|
||||
"title": "Ana Sayfa",
|
||||
"wallet": "Cüzdan",
|
||||
"staking": "Stake Etme",
|
||||
"governance": "Yönetişim",
|
||||
"dex": "Borsa",
|
||||
"history": "Geçmiş",
|
||||
"settings": "Ayarlar",
|
||||
"balance": "Bakiye",
|
||||
"totalStaked": "Toplam Stake",
|
||||
"rewards": "Ödüller",
|
||||
"activeProposals": "Aktif Teklifler"
|
||||
},
|
||||
"governance": {
|
||||
"title": "Yönetişim",
|
||||
"vote": "Oy Ver",
|
||||
"voteFor": "EVET Oyu",
|
||||
"voteAgainst": "HAYIR Oyu",
|
||||
"submitVote": "Oyu Gönder",
|
||||
"votingSuccess": "Oyunuz kaydedildi!",
|
||||
"selectCandidate": "Aday Seç",
|
||||
"multipleSelect": "Birden fazla aday seçebilirsiniz",
|
||||
"singleSelect": "Bir aday seçin",
|
||||
"proposals": "Teklifler",
|
||||
"elections": "Seçimler",
|
||||
"parliament": "Meclis",
|
||||
"activeElections": "Aktif Seçimler",
|
||||
"totalVotes": "Toplam Oylar",
|
||||
"blocksLeft": "Kalan Bloklar",
|
||||
"leading": "Önde Giden"
|
||||
},
|
||||
"citizenship": {
|
||||
"title": "Vatandaşlık",
|
||||
"applyForCitizenship": "Vatandaşlığa Başvur",
|
||||
"newCitizen": "Yeni Vatandaş",
|
||||
"existingCitizen": "Mevcut Vatandaş",
|
||||
"fullName": "Ad Soyad",
|
||||
"fatherName": "Baba Adı",
|
||||
"motherName": "Anne Adı",
|
||||
"tribe": "Aşiret",
|
||||
"region": "Bölge",
|
||||
"profession": "Meslek",
|
||||
"referralCode": "Referans Kodu",
|
||||
"submitApplication": "Başvuruyu Gönder",
|
||||
"applicationSuccess": "Başvuru başarıyla gönderildi!",
|
||||
"applicationPending": "Başvurunuz inceleniyor",
|
||||
"citizenshipBenefits": "Vatandaşlık Avantajları",
|
||||
"votingRights": "Yönetişimde oy hakkı",
|
||||
"exclusiveAccess": "Özel hizmetlere erişim",
|
||||
"referralRewards": "Referans ödül programı",
|
||||
"communityRecognition": "Topluluk tanınması"
|
||||
},
|
||||
"p2p": {
|
||||
"title": "P2P Ticaret",
|
||||
"trade": "Ticaret",
|
||||
"createOffer": "Teklif Oluştur",
|
||||
"buyToken": "Al",
|
||||
"sellToken": "Sat",
|
||||
"amount": "Miktar",
|
||||
"price": "Fiyat",
|
||||
"total": "Toplam",
|
||||
"initiateTrade": "Ticareti Başlat",
|
||||
"comingSoon": "Yakında",
|
||||
"tradingWith": "İle ticaret",
|
||||
"available": "Mevcut",
|
||||
"minOrder": "Min Sipariş",
|
||||
"maxOrder": "Max Sipariş",
|
||||
"youWillPay": "Ödeyeceğiniz",
|
||||
"myOffers": "Tekliflerim",
|
||||
"noOffers": "Teklif bulunmuyor",
|
||||
"postAd": "İlan Ver"
|
||||
},
|
||||
"forum": {
|
||||
"title": "Forum",
|
||||
"categories": "Kategoriler",
|
||||
"threads": "Konular",
|
||||
"replies": "Cevaplar",
|
||||
"views": "Görüntüleme",
|
||||
"lastActivity": "Son Aktivite",
|
||||
"createThread": "Konu Oluştur",
|
||||
"generalDiscussion": "Genel Tartışma",
|
||||
"noThreads": "Konu bulunmuyor",
|
||||
"pinned": "Sabitlenmiş",
|
||||
"locked": "Kilitli"
|
||||
},
|
||||
"referral": {
|
||||
"title": "Referans Programı",
|
||||
"myReferralCode": "Referans Kodum",
|
||||
"totalReferrals": "Toplam Referanslar",
|
||||
"activeReferrals": "Aktif Referanslar",
|
||||
"totalEarned": "Toplam Kazanç",
|
||||
"pendingRewards": "Bekleyen Ödüller",
|
||||
"shareCode": "Kodu Paylaş",
|
||||
"copyCode": "Kodu Kopyala",
|
||||
"connectWallet": "Cüzdan Bağla",
|
||||
"inviteFriends": "Arkadaşlarını Davet Et",
|
||||
"earnRewards": "Ödül Kazan",
|
||||
"codeCopied": "Kod panoya kopyalandı!"
|
||||
},
|
||||
"wallet": {
|
||||
"title": "Cüzdan",
|
||||
"connect": "Cüzdan Bağla",
|
||||
"disconnect": "Bağlantıyı Kes",
|
||||
"address": "Adres",
|
||||
"balance": "Bakiye",
|
||||
"send": "Gönder",
|
||||
"receive": "Al",
|
||||
"transaction": "İşlem",
|
||||
"history": "Geçmiş"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Ayarlar",
|
||||
"sections": {
|
||||
"appearance": "GÖRÜNÜM",
|
||||
"language": "DİL",
|
||||
"security": "GÜVENLİK",
|
||||
"notifications": "BİLDİRİMLER",
|
||||
"about": "HAKKINDA"
|
||||
},
|
||||
"appearance": {
|
||||
"darkMode": "Karanlık Mod",
|
||||
"darkModeSubtitle": "Açık ve karanlık tema arasında geçiş yapın",
|
||||
"fontSize": "Yazı Boyutu",
|
||||
"fontSizeSubtitle": "Şu anki: {{size}}",
|
||||
"fontSizePrompt": "Tercih ettiğiniz yazı boyutunu seçin",
|
||||
"small": "Küçük",
|
||||
"medium": "Orta",
|
||||
"large": "Büyük"
|
||||
},
|
||||
"language": {
|
||||
"title": "Dil",
|
||||
"changePrompt": "{{language}} diline geçilsin mi?",
|
||||
"changeSuccess": "Dil başarıyla güncellendi!"
|
||||
},
|
||||
"security": {
|
||||
"biometric": "Biyometrik Kimlik Doğrulama",
|
||||
"biometricSubtitle": "Parmak izi veya yüz tanıma kullanın",
|
||||
"biometricPrompt": "Biyometrik kimlik doğrulamayı (parmak izi/yüz tanıma) etkinleştirmek istiyor musunuz?",
|
||||
"biometricEnabled": "Biyometrik kimlik doğrulama etkinleştirildi",
|
||||
"twoFactor": "İki Faktörlü Kimlik Doğrulama",
|
||||
"twoFactorSubtitle": "Ekstra bir güvenlik katmanı ekleyin",
|
||||
"twoFactorPrompt": "İki faktörlü kimlik doğrulama ekstra bir güvenlik katmanı ekler. Bir kimlik doğrulayıcı uygulama kurmanız gerekecek.",
|
||||
"twoFactorSetup": "Kur",
|
||||
"changePassword": "Şifre Değiştir",
|
||||
"changePasswordSubtitle": "Hesap şifrenizi güncelleyin"
|
||||
},
|
||||
"notifications": {
|
||||
"push": "Anlık Bildirimler",
|
||||
"pushSubtitle": "Uyarılar ve güncellemeler alın",
|
||||
"email": "E-posta Bildirimleri",
|
||||
"emailSubtitle": "E-posta tercihlerini yönetin"
|
||||
},
|
||||
"about": {
|
||||
"pezkuwi": "Pezkuwi Hakkında",
|
||||
"pezkuwiSubtitle": "Dijital Kürdistan hakkında daha fazla bilgi edinin",
|
||||
"pezkuwiMessage": "Pezkuwi, vatandaşların yönetişim, ekonomi ve sosyal yaşama katılımını sağlayan Dijital Kürdistan için merkezi olmayan bir blockchain platformudur.\n\nVersiyon: 1.0.0\n\nDijital Kürdistan ekibi tarafından ❤️ ile yapıldı",
|
||||
"terms": "Hizmet Şartları",
|
||||
"privacy": "Gizlilik Politikası",
|
||||
"contact": "Destek İletişim",
|
||||
"contactSubtitle": "Ekibimizden yardım alın",
|
||||
"contactEmail": "E-posta: support@pezkuwichain.io"
|
||||
},
|
||||
"version": {
|
||||
"app": "Pezkuwi Mobil",
|
||||
"number": "Versiyon 1.0.0",
|
||||
"copyright": "© 2026 Dijital Kürdistan"
|
||||
},
|
||||
"alerts": {
|
||||
"comingSoon": "Yakında",
|
||||
"darkModeMessage": "Karanlık mod bir sonraki güncellemede kullanılabilir olacak",
|
||||
"twoFactorMessage": "2FA kurulumu yakında kullanılabilir olacak",
|
||||
"passwordMessage": "Şifre değiştirme yakında kullanılabilir olacak",
|
||||
"emailMessage": "E-posta ayarları yakında kullanılabilir olacak",
|
||||
"termsMessage": "Hizmet Şartları yakında kullanılabilir olacak",
|
||||
"privacyMessage": "Gizlilik Politikası yakında kullanılabilir olacak"
|
||||
},
|
||||
"common": {
|
||||
"enable": "Etkinleştir",
|
||||
"cancel": "İptal",
|
||||
"confirm": "Onayla",
|
||||
"success": "Başarılı",
|
||||
"error": "Hata"
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
"cancel": "İptal",
|
||||
"confirm": "Onayla",
|
||||
"save": "Kaydet",
|
||||
"loading": "Yükleniyor...",
|
||||
"error": "Hata",
|
||||
"success": "Başarılı",
|
||||
"retry": "Tekrar Dene",
|
||||
"close": "Kapat",
|
||||
"back": "Geri",
|
||||
"next": "İleri",
|
||||
"submit": "Gönder",
|
||||
"required": "Gerekli",
|
||||
"optional": "İsteğe Bağlı"
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,10 @@ import SettingsScreen from '../screens/SettingsScreen';
|
||||
import BeCitizenChoiceScreen from '../screens/BeCitizenChoiceScreen';
|
||||
import BeCitizenApplyScreen from '../screens/BeCitizenApplyScreen';
|
||||
import BeCitizenClaimScreen from '../screens/BeCitizenClaimScreen';
|
||||
import EditProfileScreen from '../screens/EditProfileScreen';
|
||||
import WalletScreen from '../screens/WalletScreen';
|
||||
import WalletSetupScreen from '../screens/WalletSetupScreen';
|
||||
import SwapScreen from '../screens/SwapScreen';
|
||||
|
||||
export type RootStackParamList = {
|
||||
Welcome: undefined;
|
||||
@@ -22,6 +26,10 @@ export type RootStackParamList = {
|
||||
Auth: undefined;
|
||||
MainApp: undefined;
|
||||
Settings: undefined;
|
||||
EditProfile: undefined;
|
||||
Wallet: undefined;
|
||||
WalletSetup: undefined;
|
||||
Swap: undefined;
|
||||
BeCitizenChoice: undefined;
|
||||
BeCitizenApply: undefined;
|
||||
BeCitizenClaim: undefined;
|
||||
@@ -119,6 +127,34 @@ const AppNavigator: React.FC = () => {
|
||||
headerBackTitle: 'Back',
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="EditProfile"
|
||||
component={EditProfileScreen}
|
||||
options={{
|
||||
headerShown: false,
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="Wallet"
|
||||
component={WalletScreen}
|
||||
options={{
|
||||
headerShown: false,
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="WalletSetup"
|
||||
component={WalletSetupScreen}
|
||||
options={{
|
||||
headerShown: false,
|
||||
}}
|
||||
/>
|
||||
<Stack.Screen
|
||||
name="Swap"
|
||||
component={SwapScreen}
|
||||
options={{
|
||||
headerShown: false,
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Stack.Navigator>
|
||||
|
||||
@@ -14,12 +14,10 @@ import {
|
||||
Image,
|
||||
} from 'react-native';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import { KurdistanColors } from '../theme/colors';
|
||||
|
||||
const AuthScreen: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
const { signIn, signUp } = useAuth();
|
||||
|
||||
// Tab state
|
||||
@@ -47,7 +45,7 @@ const AuthScreen: React.FC = () => {
|
||||
setError('');
|
||||
|
||||
if (!loginEmail || !loginPassword) {
|
||||
setError(t('auth.fillAllFields', 'Please fill in all fields'));
|
||||
setError('Please fill in all fields');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -58,13 +56,13 @@ const AuthScreen: React.FC = () => {
|
||||
|
||||
if (signInError) {
|
||||
if (signInError.message?.includes('Invalid login credentials')) {
|
||||
setError(t('auth.invalidCredentials', 'Email or password is incorrect'));
|
||||
setError('Email or password is incorrect');
|
||||
} else {
|
||||
setError(signInError.message || t('auth.loginFailed', 'Login failed'));
|
||||
setError(signInError.message || 'Login failed');
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
setError(t('auth.loginFailed', 'Login failed. Please try again.'));
|
||||
setError('Login failed. Please try again.');
|
||||
if (__DEV__) console.error('Sign in error:', err);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
@@ -75,17 +73,17 @@ const AuthScreen: React.FC = () => {
|
||||
setError('');
|
||||
|
||||
if (!signupName || !signupEmail || !signupPassword || !signupConfirmPassword) {
|
||||
setError(t('auth.fillAllFields', 'Please fill in all required fields'));
|
||||
setError('Please fill in all required fields');
|
||||
return;
|
||||
}
|
||||
|
||||
if (signupPassword !== signupConfirmPassword) {
|
||||
setError(t('auth.passwordsDoNotMatch', 'Passwords do not match'));
|
||||
setError('Passwords do not match');
|
||||
return;
|
||||
}
|
||||
|
||||
if (signupPassword.length < 8) {
|
||||
setError(t('auth.passwordTooShort', 'Password must be at least 8 characters'));
|
||||
setError('Password must be at least 8 characters');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -100,10 +98,10 @@ const AuthScreen: React.FC = () => {
|
||||
);
|
||||
|
||||
if (signUpError) {
|
||||
setError(signUpError.message || t('auth.signupFailed', 'Sign up failed'));
|
||||
setError(signUpError.message || 'Sign up failed');
|
||||
}
|
||||
} catch (err) {
|
||||
setError(t('auth.signupFailed', 'Sign up failed. Please try again.'));
|
||||
setError('Sign up failed. Please try again.');
|
||||
if (__DEV__) console.error('Sign up error:', err);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
@@ -144,7 +142,7 @@ const AuthScreen: React.FC = () => {
|
||||
</View>
|
||||
<Text style={styles.brandTitle}>PezkuwiChain</Text>
|
||||
<Text style={styles.subtitle}>
|
||||
{t('login.subtitle', 'Access your governance account')}
|
||||
Access your governance account
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
@@ -158,7 +156,7 @@ const AuthScreen: React.FC = () => {
|
||||
}}
|
||||
>
|
||||
<Text style={[styles.tabText, activeTab === 'signin' && styles.tabTextActive]}>
|
||||
{t('login.signin', 'Sign In')}
|
||||
Sign In
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
@@ -169,7 +167,7 @@ const AuthScreen: React.FC = () => {
|
||||
}}
|
||||
>
|
||||
<Text style={[styles.tabText, activeTab === 'signup' && styles.tabTextActive]}>
|
||||
{t('login.signup', 'Sign Up')}
|
||||
Sign Up
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
@@ -178,7 +176,7 @@ const AuthScreen: React.FC = () => {
|
||||
{activeTab === 'signin' && (
|
||||
<View style={styles.form}>
|
||||
<View style={styles.inputGroup}>
|
||||
<Text style={styles.label}>{t('login.email', 'Email')}</Text>
|
||||
<Text style={styles.label}>Email</Text>
|
||||
<View style={styles.inputContainer}>
|
||||
<Text style={styles.inputIcon}>✉️</Text>
|
||||
<TextInput
|
||||
@@ -195,7 +193,7 @@ const AuthScreen: React.FC = () => {
|
||||
</View>
|
||||
|
||||
<View style={styles.inputGroup}>
|
||||
<Text style={styles.label}>{t('login.password', 'Password')}</Text>
|
||||
<Text style={styles.label}>Password</Text>
|
||||
<View style={styles.inputContainer}>
|
||||
<Text style={styles.inputIcon}>🔒</Text>
|
||||
<TextInput
|
||||
@@ -225,12 +223,12 @@ const AuthScreen: React.FC = () => {
|
||||
{rememberMe && <Text style={styles.checkmark}>✓</Text>}
|
||||
</View>
|
||||
<Text style={styles.checkboxLabel}>
|
||||
{t('login.rememberMe', 'Remember me')}
|
||||
Remember me
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity>
|
||||
<Text style={styles.linkText}>
|
||||
{t('login.forgotPassword', 'Forgot password?')}
|
||||
Forgot password?
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
@@ -251,7 +249,7 @@ const AuthScreen: React.FC = () => {
|
||||
<ActivityIndicator color="#FFFFFF" />
|
||||
) : (
|
||||
<Text style={styles.primaryButtonText}>
|
||||
{t('login.signin', 'Sign In')}
|
||||
Sign In
|
||||
</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
@@ -262,7 +260,7 @@ const AuthScreen: React.FC = () => {
|
||||
{activeTab === 'signup' && (
|
||||
<View style={styles.form}>
|
||||
<View style={styles.inputGroup}>
|
||||
<Text style={styles.label}>{t('login.fullName', 'Full Name')}</Text>
|
||||
<Text style={styles.label}>Full Name</Text>
|
||||
<View style={styles.inputContainer}>
|
||||
<Text style={styles.inputIcon}>👤</Text>
|
||||
<TextInput
|
||||
@@ -277,7 +275,7 @@ const AuthScreen: React.FC = () => {
|
||||
</View>
|
||||
|
||||
<View style={styles.inputGroup}>
|
||||
<Text style={styles.label}>{t('login.email', 'Email')}</Text>
|
||||
<Text style={styles.label}>Email</Text>
|
||||
<View style={styles.inputContainer}>
|
||||
<Text style={styles.inputIcon}>✉️</Text>
|
||||
<TextInput
|
||||
@@ -294,7 +292,7 @@ const AuthScreen: React.FC = () => {
|
||||
</View>
|
||||
|
||||
<View style={styles.inputGroup}>
|
||||
<Text style={styles.label}>{t('login.password', 'Password')}</Text>
|
||||
<Text style={styles.label}>Password</Text>
|
||||
<View style={styles.inputContainer}>
|
||||
<Text style={styles.inputIcon}>🔒</Text>
|
||||
<TextInput
|
||||
@@ -316,7 +314,7 @@ const AuthScreen: React.FC = () => {
|
||||
</View>
|
||||
|
||||
<View style={styles.inputGroup}>
|
||||
<Text style={styles.label}>{t('login.confirmPassword', 'Confirm Password')}</Text>
|
||||
<Text style={styles.label}>Confirm Password</Text>
|
||||
<View style={styles.inputContainer}>
|
||||
<Text style={styles.inputIcon}>🔒</Text>
|
||||
<TextInput
|
||||
@@ -333,16 +331,16 @@ const AuthScreen: React.FC = () => {
|
||||
|
||||
<View style={styles.inputGroup}>
|
||||
<Text style={styles.label}>
|
||||
{t('login.referralCode', 'Referral Code')}{' '}
|
||||
Referral Code{' '}
|
||||
<Text style={styles.optionalText}>
|
||||
({t('login.optional', 'Optional')})
|
||||
(Optional)
|
||||
</Text>
|
||||
</Text>
|
||||
<View style={styles.inputContainer}>
|
||||
<Text style={styles.inputIcon}>👥</Text>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
placeholder={t('login.enterReferralCode', 'Referral code (optional)')}
|
||||
placeholder="Referral code (optional)"
|
||||
placeholderTextColor="#9CA3AF"
|
||||
value={signupReferralCode}
|
||||
onChangeText={setSignupReferralCode}
|
||||
@@ -350,7 +348,7 @@ const AuthScreen: React.FC = () => {
|
||||
/>
|
||||
</View>
|
||||
<Text style={styles.hintText}>
|
||||
{t('login.referralDescription', 'If someone referred you, enter their code here')}
|
||||
If someone referred you, enter their code here
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
@@ -370,7 +368,7 @@ const AuthScreen: React.FC = () => {
|
||||
<ActivityIndicator color="#FFFFFF" />
|
||||
) : (
|
||||
<Text style={styles.primaryButtonText}>
|
||||
{t('login.createAccount', 'Create Account')}
|
||||
Create Account
|
||||
</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
@@ -380,15 +378,15 @@ const AuthScreen: React.FC = () => {
|
||||
{/* Footer */}
|
||||
<View style={styles.footer}>
|
||||
<Text style={styles.footerText}>
|
||||
{t('login.terms', 'By continuing, you agree to our')}{' '}
|
||||
By continuing, you agree to our{' '}
|
||||
</Text>
|
||||
<View style={styles.footerLinks}>
|
||||
<Text style={styles.footerLink}>
|
||||
{t('login.termsOfService', 'Terms of Service')}
|
||||
Terms of Service
|
||||
</Text>
|
||||
<Text style={styles.footerText}> {t('login.and', 'and')} </Text>
|
||||
<Text style={styles.footerText}> and </Text>
|
||||
<Text style={styles.footerLink}>
|
||||
{t('login.privacyPolicy', 'Privacy Policy')}
|
||||
Privacy Policy
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
ActivityIndicator,
|
||||
Modal,
|
||||
} from 'react-native';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { usePezkuwi } from '../contexts/PezkuwiContext';
|
||||
import {
|
||||
@@ -97,7 +96,6 @@ const CustomPicker: React.FC<{
|
||||
};
|
||||
|
||||
const BeCitizenApplyScreen: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
const navigation = useNavigation();
|
||||
const { api, selectedAccount } = usePezkuwi();
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
StatusBar,
|
||||
} from 'react-native';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { KurdistanColors } from '../theme/colors';
|
||||
import type { NavigationProp } from '@react-navigation/native';
|
||||
@@ -21,7 +20,6 @@ type RootStackParamList = {
|
||||
};
|
||||
|
||||
const BeCitizenChoiceScreen: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
const navigation = useNavigation<NavigationProp<RootStackParamList>>();
|
||||
|
||||
return (
|
||||
|
||||
@@ -10,14 +10,12 @@ import {
|
||||
Alert,
|
||||
ActivityIndicator,
|
||||
} from 'react-native';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { usePezkuwi } from '../contexts/PezkuwiContext';
|
||||
import { getCitizenshipStatus } from '@pezkuwi/lib/citizenship-workflow';
|
||||
import { KurdistanColors } from '../theme/colors';
|
||||
|
||||
const BeCitizenClaimScreen: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
const navigation = useNavigation();
|
||||
const { api, selectedAccount } = usePezkuwi();
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
@@ -12,7 +12,6 @@ import {
|
||||
ActivityIndicator,
|
||||
} from 'react-native';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { usePezkuwi } from '../contexts/PezkuwiContext';
|
||||
import {
|
||||
submitKycApplication,
|
||||
@@ -22,7 +21,6 @@ import {
|
||||
import { KurdistanColors } from '../theme/colors';
|
||||
|
||||
const BeCitizenScreen: React.FC = () => {
|
||||
const { t: _t } = useTranslation();
|
||||
const { api, selectedAccount } = usePezkuwi();
|
||||
const [_isExistingCitizen, _setIsExistingCitizen] = useState(false);
|
||||
const [currentStep, setCurrentStep] = useState<'choice' | 'new' | 'existing'>('choice');
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
ActivityIndicator,
|
||||
} from 'react-native';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import type { NavigationProp } from '@react-navigation/native';
|
||||
import type { BottomTabParamList } from '../navigation/BottomTabNavigator';
|
||||
@@ -82,7 +81,6 @@ const getEmojiFromAvatarId = (avatarId: string): string => {
|
||||
interface DashboardScreenProps {}
|
||||
|
||||
const DashboardScreen: React.FC<DashboardScreenProps> = () => {
|
||||
const { t } = useTranslation();
|
||||
const navigation = useNavigation<NavigationProp<BottomTabParamList & RootStackParamList>>();
|
||||
const { user } = useAuth();
|
||||
const { api, isApiReady, selectedAccount } = usePezkuwi();
|
||||
@@ -171,8 +169,8 @@ const DashboardScreen: React.FC<DashboardScreenProps> = () => {
|
||||
|
||||
const showComingSoon = (featureName: string) => {
|
||||
Alert.alert(
|
||||
t('settingsScreen.comingSoon'),
|
||||
`${featureName} ${t('settingsScreen.comingSoonMessage')}`,
|
||||
'Coming Soon',
|
||||
`${featureName} will be available soon!`,
|
||||
[{ text: 'OK' }]
|
||||
);
|
||||
};
|
||||
@@ -431,21 +429,8 @@ const DashboardScreen: React.FC<DashboardScreenProps> = () => {
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={styles.appsGrid}>
|
||||
{/* Wallet Visitors - Everyone can use */}
|
||||
{renderAppIcon('Wallet Visitors', '👁️', () => showComingSoon('Wallet Visitors'), true)}
|
||||
|
||||
{/* Wallet Welati - Only Citizens can use */}
|
||||
{renderAppIcon('Wallet Welati', '🏛️', () => {
|
||||
if (tikis.includes('Citizen') || tikis.includes('Welati')) {
|
||||
showComingSoon('Wallet Welati');
|
||||
} else {
|
||||
Alert.alert(
|
||||
'Citizens Only',
|
||||
'Wallet Welati is only available to Pezkuwi citizens. Please apply for citizenship first.',
|
||||
[{ text: 'OK' }]
|
||||
);
|
||||
}
|
||||
}, true, !tikis.includes('Citizen') && !tikis.includes('Welati'))}
|
||||
{/* Wallet - Navigate to WalletScreen */}
|
||||
{renderAppIcon('Wallet', '👛', () => navigation.navigate('Wallet'), true)}
|
||||
|
||||
{renderAppIcon('Bank', qaBank, () => showComingSoon('Bank'), false, true)}
|
||||
{renderAppIcon('Exchange', qaExchange, () => showComingSoon('Swap'), false)}
|
||||
|
||||
@@ -0,0 +1,450 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
StyleSheet,
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
TextInput,
|
||||
ActivityIndicator,
|
||||
Alert,
|
||||
Platform,
|
||||
KeyboardAvoidingView,
|
||||
} from 'react-native';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import { useTheme } from '../contexts/ThemeContext';
|
||||
import { KurdistanColors } from '../theme/colors';
|
||||
import { supabase } from '../lib/supabase';
|
||||
import AvatarPickerModal from '../components/AvatarPickerModal';
|
||||
|
||||
// Cross-platform alert helper
|
||||
const showAlert = (title: string, message: string, buttons?: Array<{text: string; onPress?: () => void; style?: string}>) => {
|
||||
if (Platform.OS === 'web') {
|
||||
if (buttons && buttons.length > 1) {
|
||||
const result = window.confirm(`${title}\n\n${message}`);
|
||||
if (result && buttons[1]?.onPress) {
|
||||
buttons[1].onPress();
|
||||
} else if (!result && buttons[0]?.onPress) {
|
||||
buttons[0].onPress();
|
||||
}
|
||||
} else {
|
||||
window.alert(`${title}\n\n${message}`);
|
||||
if (buttons?.[0]?.onPress) buttons[0].onPress();
|
||||
}
|
||||
} else {
|
||||
Alert.alert(title, message, buttons as any);
|
||||
}
|
||||
};
|
||||
|
||||
// Avatar pool matching AvatarPickerModal
|
||||
const AVATAR_POOL = [
|
||||
{ id: 'avatar1', emoji: '👨🏻' },
|
||||
{ id: 'avatar2', emoji: '👨🏼' },
|
||||
{ id: 'avatar3', emoji: '👨🏽' },
|
||||
{ id: 'avatar4', emoji: '👨🏾' },
|
||||
{ id: 'avatar5', emoji: '👩🏻' },
|
||||
{ id: 'avatar6', emoji: '👩🏼' },
|
||||
{ id: 'avatar7', emoji: '👩🏽' },
|
||||
{ id: 'avatar8', emoji: '👩🏾' },
|
||||
{ id: 'avatar9', emoji: '🧔🏻' },
|
||||
{ id: 'avatar10', emoji: '🧔🏼' },
|
||||
{ id: 'avatar11', emoji: '🧔🏽' },
|
||||
{ id: 'avatar12', emoji: '🧔🏾' },
|
||||
{ id: 'avatar13', emoji: '👳🏻♂️' },
|
||||
{ id: 'avatar14', emoji: '👳🏼♂️' },
|
||||
{ id: 'avatar15', emoji: '👳🏽♂️' },
|
||||
{ id: 'avatar16', emoji: '🧕🏻' },
|
||||
{ id: 'avatar17', emoji: '🧕🏼' },
|
||||
{ id: 'avatar18', emoji: '🧕🏽' },
|
||||
{ id: 'avatar19', emoji: '👴🏻' },
|
||||
{ id: 'avatar20', emoji: '👴🏼' },
|
||||
{ id: 'avatar21', emoji: '👵🏻' },
|
||||
{ id: 'avatar22', emoji: '👵🏼' },
|
||||
{ id: 'avatar23', emoji: '👦🏻' },
|
||||
{ id: 'avatar24', emoji: '👦🏼' },
|
||||
{ id: 'avatar25', emoji: '👧🏻' },
|
||||
{ id: 'avatar26', emoji: '👧🏼' },
|
||||
];
|
||||
|
||||
const getEmojiFromAvatarId = (avatarId: string): string => {
|
||||
const avatar = AVATAR_POOL.find(a => a.id === avatarId);
|
||||
return avatar ? avatar.emoji : '👤';
|
||||
};
|
||||
|
||||
const EditProfileScreen: React.FC = () => {
|
||||
const navigation = useNavigation();
|
||||
const { user } = useAuth();
|
||||
const { isDarkMode, colors, fontScale } = useTheme();
|
||||
|
||||
const [fullName, setFullName] = useState('');
|
||||
const [avatarUrl, setAvatarUrl] = useState<string | null>(null);
|
||||
const [originalName, setOriginalName] = useState('');
|
||||
const [originalAvatar, setOriginalAvatar] = useState<string | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [saving, setSaving] = useState(false);
|
||||
const [avatarModalVisible, setAvatarModalVisible] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
fetchProfile();
|
||||
}, []);
|
||||
|
||||
const fetchProfile = async () => {
|
||||
if (!user) {
|
||||
setLoading(false);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const { data, error } = await supabase
|
||||
.from('profiles')
|
||||
.select('full_name, avatar_url')
|
||||
.eq('id', user.id)
|
||||
.single();
|
||||
|
||||
if (error) throw error;
|
||||
|
||||
setFullName(data?.full_name || '');
|
||||
setAvatarUrl(data?.avatar_url || null);
|
||||
setOriginalName(data?.full_name || '');
|
||||
setOriginalAvatar(data?.avatar_url || null);
|
||||
} catch (error) {
|
||||
if (__DEV__) console.error('Error fetching profile:', error);
|
||||
showAlert('Error', 'Failed to load profile data');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
const hasChanges = () => {
|
||||
return fullName !== originalName || avatarUrl !== originalAvatar;
|
||||
};
|
||||
|
||||
const handleSave = async () => {
|
||||
if (!user) return;
|
||||
|
||||
if (!hasChanges()) {
|
||||
navigation.goBack();
|
||||
return;
|
||||
}
|
||||
|
||||
setSaving(true);
|
||||
try {
|
||||
const updates: { full_name?: string | null; avatar_url?: string | null } = {};
|
||||
|
||||
if (fullName !== originalName) {
|
||||
updates.full_name = fullName.trim() || null;
|
||||
}
|
||||
if (avatarUrl !== originalAvatar) {
|
||||
updates.avatar_url = avatarUrl;
|
||||
}
|
||||
|
||||
const { error } = await supabase
|
||||
.from('profiles')
|
||||
.update(updates)
|
||||
.eq('id', user.id);
|
||||
|
||||
if (error) throw error;
|
||||
|
||||
showAlert('Success', 'Profile updated successfully', [
|
||||
{ text: 'OK', onPress: () => navigation.goBack() }
|
||||
]);
|
||||
} catch (error) {
|
||||
if (__DEV__) console.error('Error saving profile:', error);
|
||||
showAlert('Error', 'Failed to save profile. Please try again.');
|
||||
} finally {
|
||||
setSaving(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
if (hasChanges()) {
|
||||
showAlert(
|
||||
'Discard Changes?',
|
||||
'You have unsaved changes. Are you sure you want to go back?',
|
||||
[
|
||||
{ text: 'Keep Editing', style: 'cancel' },
|
||||
{ text: 'Discard', style: 'destructive', onPress: () => navigation.goBack() }
|
||||
]
|
||||
);
|
||||
} else {
|
||||
navigation.goBack();
|
||||
}
|
||||
};
|
||||
|
||||
const handleAvatarSelected = (newAvatarUrl: string) => {
|
||||
setAvatarUrl(newAvatarUrl);
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<SafeAreaView style={[styles.container, { backgroundColor: colors.background }]} testID="edit-profile-loading">
|
||||
<View style={styles.loadingContainer}>
|
||||
<ActivityIndicator size="large" color={KurdistanColors.kesk} />
|
||||
<Text style={[styles.loadingText, { color: colors.textSecondary, fontSize: 14 * fontScale }]}>
|
||||
Loading profile...
|
||||
</Text>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView style={[styles.container, { backgroundColor: colors.background }]} testID="edit-profile-screen">
|
||||
<KeyboardAvoidingView
|
||||
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
|
||||
style={styles.keyboardAvoid}
|
||||
>
|
||||
{/* Header */}
|
||||
<View style={[styles.header, { borderBottomColor: colors.border }]} testID="edit-profile-header">
|
||||
<TouchableOpacity onPress={handleCancel} testID="edit-profile-cancel-button">
|
||||
<Text style={[styles.headerButton, { color: colors.textSecondary, fontSize: 16 * fontScale }]}>
|
||||
Cancel
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<Text style={[styles.headerTitle, { color: colors.text, fontSize: 18 * fontScale }]}>
|
||||
Edit Profile
|
||||
</Text>
|
||||
<TouchableOpacity
|
||||
onPress={handleSave}
|
||||
disabled={saving || !hasChanges()}
|
||||
testID="edit-profile-save-button"
|
||||
>
|
||||
{saving ? (
|
||||
<ActivityIndicator size="small" color={KurdistanColors.kesk} />
|
||||
) : (
|
||||
<Text style={[
|
||||
styles.headerButton,
|
||||
styles.saveButton,
|
||||
{ fontSize: 16 * fontScale },
|
||||
!hasChanges() && styles.saveButtonDisabled
|
||||
]}>
|
||||
Save
|
||||
</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<ScrollView
|
||||
style={styles.content}
|
||||
contentContainerStyle={styles.contentContainer}
|
||||
showsVerticalScrollIndicator={false}
|
||||
testID="edit-profile-scroll"
|
||||
>
|
||||
{/* Avatar Section */}
|
||||
<View style={styles.avatarSection} testID="edit-profile-avatar-section">
|
||||
<TouchableOpacity
|
||||
onPress={() => setAvatarModalVisible(true)}
|
||||
style={styles.avatarButton}
|
||||
testID="edit-profile-avatar-button"
|
||||
>
|
||||
<View style={[styles.avatarCircle, { backgroundColor: colors.surface }]}>
|
||||
{avatarUrl ? (
|
||||
<Text style={styles.avatarEmoji}>{getEmojiFromAvatarId(avatarUrl)}</Text>
|
||||
) : (
|
||||
<Text style={[styles.avatarInitial, { color: colors.textSecondary }]}>
|
||||
{fullName?.charAt(0)?.toUpperCase() || user?.email?.charAt(0)?.toUpperCase() || '?'}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
<View style={styles.editAvatarBadge}>
|
||||
<Text style={styles.editAvatarIcon}>📷</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<Text style={[styles.changePhotoText, { color: KurdistanColors.kesk, fontSize: 14 * fontScale }]}>
|
||||
Change Avatar
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{/* Form Section */}
|
||||
<View style={styles.formSection}>
|
||||
{/* Display Name */}
|
||||
<View style={styles.inputGroup} testID="edit-profile-name-group">
|
||||
<Text style={[styles.inputLabel, { color: colors.textSecondary, fontSize: 14 * fontScale }]}>
|
||||
Display Name
|
||||
</Text>
|
||||
<TextInput
|
||||
style={[styles.textInput, {
|
||||
backgroundColor: colors.surface,
|
||||
color: colors.text,
|
||||
borderColor: colors.border,
|
||||
fontSize: 16 * fontScale
|
||||
}]}
|
||||
value={fullName}
|
||||
onChangeText={setFullName}
|
||||
placeholder="Enter your display name"
|
||||
placeholderTextColor={colors.textSecondary}
|
||||
autoCapitalize="words"
|
||||
autoCorrect={false}
|
||||
testID="edit-profile-name-input"
|
||||
/>
|
||||
<Text style={[styles.inputHint, { color: colors.textSecondary, fontSize: 12 * fontScale }]}>
|
||||
This is how other users will see you
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
{/* Email (Read-only) */}
|
||||
<View style={styles.inputGroup} testID="edit-profile-email-group">
|
||||
<Text style={[styles.inputLabel, { color: colors.textSecondary, fontSize: 14 * fontScale }]}>
|
||||
Email
|
||||
</Text>
|
||||
<View style={[styles.readOnlyField, { backgroundColor: colors.background, borderColor: colors.border }]}>
|
||||
<Text style={[styles.readOnlyText, { color: colors.textSecondary, fontSize: 16 * fontScale }]}>
|
||||
{user?.email || 'N/A'}
|
||||
</Text>
|
||||
<Text style={styles.lockIcon}>🔒</Text>
|
||||
</View>
|
||||
<Text style={[styles.inputHint, { color: colors.textSecondary, fontSize: 12 * fontScale }]}>
|
||||
Email cannot be changed
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</KeyboardAvoidingView>
|
||||
|
||||
{/* Avatar Picker Modal */}
|
||||
<AvatarPickerModal
|
||||
visible={avatarModalVisible}
|
||||
onClose={() => setAvatarModalVisible(false)}
|
||||
currentAvatar={avatarUrl || undefined}
|
||||
onAvatarSelected={handleAvatarSelected}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
},
|
||||
keyboardAvoid: {
|
||||
flex: 1,
|
||||
},
|
||||
loadingContainer: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
gap: 12,
|
||||
},
|
||||
loadingText: {
|
||||
fontSize: 14,
|
||||
},
|
||||
header: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 12,
|
||||
borderBottomWidth: 1,
|
||||
},
|
||||
headerButton: {
|
||||
fontSize: 16,
|
||||
fontWeight: '500',
|
||||
},
|
||||
headerTitle: {
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
},
|
||||
saveButton: {
|
||||
color: KurdistanColors.kesk,
|
||||
fontWeight: '600',
|
||||
},
|
||||
saveButtonDisabled: {
|
||||
opacity: 0.4,
|
||||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
},
|
||||
contentContainer: {
|
||||
padding: 24,
|
||||
},
|
||||
avatarSection: {
|
||||
alignItems: 'center',
|
||||
marginBottom: 32,
|
||||
},
|
||||
avatarButton: {
|
||||
position: 'relative',
|
||||
},
|
||||
avatarCircle: {
|
||||
width: 120,
|
||||
height: 120,
|
||||
borderRadius: 60,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowOpacity: 0.1,
|
||||
shadowRadius: 8,
|
||||
elevation: 4,
|
||||
},
|
||||
avatarEmoji: {
|
||||
fontSize: 70,
|
||||
},
|
||||
avatarInitial: {
|
||||
fontSize: 48,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
editAvatarBadge: {
|
||||
position: 'absolute',
|
||||
bottom: 4,
|
||||
right: 4,
|
||||
backgroundColor: '#FFFFFF',
|
||||
width: 36,
|
||||
height: 36,
|
||||
borderRadius: 18,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
shadowColor: '#000',
|
||||
shadowOffset: { width: 0, height: 2 },
|
||||
shadowOpacity: 0.2,
|
||||
shadowRadius: 4,
|
||||
elevation: 4,
|
||||
},
|
||||
editAvatarIcon: {
|
||||
fontSize: 18,
|
||||
},
|
||||
changePhotoText: {
|
||||
marginTop: 12,
|
||||
fontWeight: '500',
|
||||
},
|
||||
formSection: {
|
||||
gap: 24,
|
||||
},
|
||||
inputGroup: {
|
||||
gap: 8,
|
||||
},
|
||||
inputLabel: {
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
marginLeft: 4,
|
||||
},
|
||||
textInput: {
|
||||
borderWidth: 1,
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
fontSize: 16,
|
||||
},
|
||||
inputHint: {
|
||||
fontSize: 12,
|
||||
marginLeft: 4,
|
||||
},
|
||||
readOnlyField: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
borderWidth: 1,
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
},
|
||||
readOnlyText: {
|
||||
fontSize: 16,
|
||||
flex: 1,
|
||||
},
|
||||
lockIcon: {
|
||||
fontSize: 16,
|
||||
marginLeft: 8,
|
||||
},
|
||||
});
|
||||
|
||||
export default EditProfileScreen;
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
@@ -10,15 +10,33 @@ import {
|
||||
Image,
|
||||
ActivityIndicator,
|
||||
Alert,
|
||||
Platform,
|
||||
} from 'react-native';
|
||||
import { useFocusEffect } from '@react-navigation/native';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import { useTheme } from '../contexts/ThemeContext';
|
||||
import { KurdistanColors } from '../theme/colors';
|
||||
import { supabase } from '../lib/supabase';
|
||||
import AvatarPickerModal from '../components/AvatarPickerModal';
|
||||
|
||||
// Cross-platform alert helper
|
||||
const showAlert = (title: string, message: string, buttons?: Array<{text: string; onPress?: () => void; style?: string}>) => {
|
||||
if (Platform.OS === 'web') {
|
||||
if (buttons && buttons.length > 1) {
|
||||
const result = window.confirm(`${title}\n\n${message}`);
|
||||
if (result && buttons[1]?.onPress) {
|
||||
buttons[1].onPress();
|
||||
}
|
||||
} else {
|
||||
window.alert(`${title}\n\n${message}`);
|
||||
}
|
||||
} else {
|
||||
Alert.alert(title, message, buttons as any);
|
||||
}
|
||||
};
|
||||
|
||||
// Avatar pool matching AvatarPickerModal
|
||||
const AVATAR_POOL = [
|
||||
{ id: 'avatar1', emoji: '👨🏻' },
|
||||
@@ -65,16 +83,19 @@ interface ProfileData {
|
||||
}
|
||||
|
||||
const ProfileScreen: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
const navigation = useNavigation();
|
||||
const navigation = useNavigation<any>();
|
||||
const { user, signOut } = useAuth();
|
||||
const { isDarkMode, colors, fontScale } = useTheme();
|
||||
const [profileData, setProfileData] = useState<ProfileData | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [avatarModalVisible, setAvatarModalVisible] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
fetchProfileData();
|
||||
}, [user]);
|
||||
// Refresh profile data when screen is focused (e.g., after EditProfile)
|
||||
useFocusEffect(
|
||||
useCallback(() => {
|
||||
fetchProfileData();
|
||||
}, [user])
|
||||
);
|
||||
|
||||
const fetchProfileData = async () => {
|
||||
if (!user) {
|
||||
@@ -100,7 +121,7 @@ const ProfileScreen: React.FC = () => {
|
||||
};
|
||||
|
||||
const handleLogout = () => {
|
||||
Alert.alert(
|
||||
showAlert(
|
||||
'Logout',
|
||||
'Are you sure you want to logout?',
|
||||
[
|
||||
@@ -120,12 +141,22 @@ const ProfileScreen: React.FC = () => {
|
||||
setProfileData(prev => prev ? { ...prev, avatar_url: avatarUrl } : null);
|
||||
};
|
||||
|
||||
const ProfileCard = ({ icon, title, value, onPress }: { icon: string; title: string; value: string; onPress?: () => void }) => (
|
||||
<TouchableOpacity style={styles.profileCard} onPress={onPress} disabled={!onPress} activeOpacity={onPress ? 0.7 : 1}>
|
||||
const handleEditProfile = () => {
|
||||
navigation.navigate('EditProfile');
|
||||
};
|
||||
|
||||
const ProfileCard = ({ icon, title, value, onPress, testID }: { icon: string; title: string; value: string; onPress?: () => void; testID?: string }) => (
|
||||
<TouchableOpacity
|
||||
style={[styles.profileCard, { backgroundColor: colors.surface }]}
|
||||
onPress={onPress}
|
||||
disabled={!onPress}
|
||||
activeOpacity={onPress ? 0.7 : 1}
|
||||
testID={testID}
|
||||
>
|
||||
<Text style={styles.cardIcon}>{icon}</Text>
|
||||
<View style={styles.cardContent}>
|
||||
<Text style={styles.cardTitle}>{title}</Text>
|
||||
<Text style={styles.cardValue} numberOfLines={1}>{value}</Text>
|
||||
<Text style={[styles.cardTitle, { fontSize: 12 * fontScale }]}>{title}</Text>
|
||||
<Text style={[styles.cardValue, { color: colors.text, fontSize: 16 * fontScale }]} numberOfLines={1}>{value}</Text>
|
||||
</View>
|
||||
{onPress && <Text style={styles.cardArrow}>→</Text>}
|
||||
</TouchableOpacity>
|
||||
@@ -133,41 +164,42 @@ const ProfileScreen: React.FC = () => {
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<SafeAreaView style={[styles.container, { backgroundColor: colors.background }]} testID="profile-loading-container">
|
||||
<View style={styles.loadingContainer}>
|
||||
<ActivityIndicator size="large" color={KurdistanColors.kesk} />
|
||||
<ActivityIndicator size="large" color={KurdistanColors.kesk} testID="profile-loading-indicator" />
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<StatusBar barStyle="light-content" />
|
||||
<SafeAreaView style={[styles.container, { backgroundColor: colors.background }]} testID="profile-screen">
|
||||
<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
|
||||
|
||||
<ScrollView showsVerticalScrollIndicator={false}>
|
||||
<ScrollView showsVerticalScrollIndicator={false} testID="profile-scroll-view">
|
||||
{/* Header with Gradient */}
|
||||
<LinearGradient
|
||||
colors={[KurdistanColors.kesk, '#008f43']}
|
||||
style={styles.header}
|
||||
testID="profile-header-gradient"
|
||||
>
|
||||
<View style={styles.avatarContainer}>
|
||||
<TouchableOpacity onPress={() => setAvatarModalVisible(true)} style={styles.avatarWrapper}>
|
||||
<TouchableOpacity onPress={() => setAvatarModalVisible(true)} style={styles.avatarWrapper} testID="profile-avatar-button">
|
||||
{profileData?.avatar_url ? (
|
||||
// Check if avatar_url is a URL (starts with http) or an emoji ID
|
||||
profileData.avatar_url.startsWith('http') ? (
|
||||
<Image source={{ uri: profileData.avatar_url }} style={styles.avatar} />
|
||||
<Image source={{ uri: profileData.avatar_url }} style={styles.avatar} testID="profile-avatar-image" />
|
||||
) : (
|
||||
// It's an emoji ID, render as emoji text
|
||||
<View style={styles.avatarPlaceholder}>
|
||||
<Text style={styles.avatarEmojiLarge}>
|
||||
<View style={styles.avatarPlaceholder} testID="profile-avatar-emoji-container">
|
||||
<Text style={styles.avatarEmojiLarge} testID="profile-avatar-emoji">
|
||||
{getEmojiFromAvatarId(profileData.avatar_url)}
|
||||
</Text>
|
||||
</View>
|
||||
)
|
||||
) : (
|
||||
<View style={styles.avatarPlaceholder}>
|
||||
<Text style={styles.avatarText}>
|
||||
<View style={styles.avatarPlaceholder} testID="profile-avatar-placeholder">
|
||||
<Text style={styles.avatarText} testID="profile-avatar-initial">
|
||||
{profileData?.full_name?.charAt(0)?.toUpperCase() || user?.email?.charAt(0)?.toUpperCase() || '?'}
|
||||
</Text>
|
||||
</View>
|
||||
@@ -176,25 +208,27 @@ const ProfileScreen: React.FC = () => {
|
||||
<Text style={styles.editAvatarIcon}>📷</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
<Text style={styles.name}>
|
||||
<Text style={[styles.name, { fontSize: 24 * fontScale }]} testID="profile-name">
|
||||
{profileData?.full_name || user?.email?.split('@')[0] || 'User'}
|
||||
</Text>
|
||||
<Text style={styles.email}>{user?.email}</Text>
|
||||
<Text style={[styles.email, { fontSize: 14 * fontScale }]} testID="profile-email">{user?.email}</Text>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
|
||||
{/* Profile Info Cards */}
|
||||
<View style={styles.cardsContainer}>
|
||||
<View style={styles.cardsContainer} testID="profile-cards-container">
|
||||
<ProfileCard
|
||||
icon="📧"
|
||||
title="Email"
|
||||
value={user?.email || 'N/A'}
|
||||
testID="profile-card-email"
|
||||
/>
|
||||
|
||||
<ProfileCard
|
||||
icon="📅"
|
||||
title="Member Since"
|
||||
value={profileData?.created_at ? new Date(profileData.created_at).toLocaleDateString() : 'N/A'}
|
||||
testID="profile-card-member-since"
|
||||
/>
|
||||
|
||||
<ProfileCard
|
||||
@@ -202,6 +236,7 @@ const ProfileScreen: React.FC = () => {
|
||||
title="Referrals"
|
||||
value={`${profileData?.referral_count || 0} people`}
|
||||
onPress={() => (navigation as any).navigate('Referral')}
|
||||
testID="profile-card-referrals"
|
||||
/>
|
||||
|
||||
{profileData?.referral_code && (
|
||||
@@ -209,6 +244,7 @@ const ProfileScreen: React.FC = () => {
|
||||
icon="🎁"
|
||||
title="Your Referral Code"
|
||||
value={profileData.referral_code}
|
||||
testID="profile-card-referral-code"
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -217,31 +253,34 @@ const ProfileScreen: React.FC = () => {
|
||||
icon="👛"
|
||||
title="Wallet Address"
|
||||
value={`${profileData.wallet_address.slice(0, 10)}...${profileData.wallet_address.slice(-8)}`}
|
||||
testID="profile-card-wallet"
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
|
||||
{/* Action Buttons */}
|
||||
<View style={styles.actionsContainer}>
|
||||
<View style={styles.actionsContainer} testID="profile-actions-container">
|
||||
<TouchableOpacity
|
||||
style={styles.actionButton}
|
||||
onPress={() => Alert.alert('Coming Soon', 'Edit profile feature will be available soon')}
|
||||
style={[styles.actionButton, { backgroundColor: colors.surface }]}
|
||||
onPress={handleEditProfile}
|
||||
testID="profile-edit-button"
|
||||
>
|
||||
<Text style={styles.actionIcon}>✏️</Text>
|
||||
<Text style={styles.actionText}>Edit Profile</Text>
|
||||
<Text style={[styles.actionText, { color: colors.text, fontSize: 16 * fontScale }]}>Edit Profile</Text>
|
||||
<Text style={styles.actionArrow}>→</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity
|
||||
style={styles.actionButton}
|
||||
onPress={() => Alert.alert(
|
||||
style={[styles.actionButton, { backgroundColor: colors.surface }]}
|
||||
onPress={() => showAlert(
|
||||
'About Pezkuwi',
|
||||
'Pezkuwi is a decentralized blockchain platform for Digital Kurdistan.\n\nVersion: 1.0.0\n\n© 2026 Digital Kurdistan',
|
||||
[{ text: 'OK' }]
|
||||
)}
|
||||
testID="profile-about-button"
|
||||
>
|
||||
<Text style={styles.actionIcon}>ℹ️</Text>
|
||||
<Text style={styles.actionText}>About Pezkuwi</Text>
|
||||
<Text style={[styles.actionText, { color: colors.text, fontSize: 16 * fontScale }]}>About Pezkuwi</Text>
|
||||
<Text style={styles.actionArrow}>→</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
@@ -251,15 +290,16 @@ const ProfileScreen: React.FC = () => {
|
||||
style={styles.logoutButton}
|
||||
onPress={handleLogout}
|
||||
activeOpacity={0.8}
|
||||
testID="profile-logout-button"
|
||||
>
|
||||
<Text style={styles.logoutButtonText}>Logout</Text>
|
||||
<Text style={[styles.logoutButtonText, { fontSize: 16 * fontScale }]}>Logout</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={styles.footer}>
|
||||
<Text style={styles.footerText}>
|
||||
<View style={styles.footer} testID="profile-footer">
|
||||
<Text style={[styles.footerText, { color: colors.textSecondary, fontSize: 12 * fontScale }]}>
|
||||
Pezkuwi Blockchain • {new Date().getFullYear()}
|
||||
</Text>
|
||||
<Text style={styles.footerVersion}>Version 1.0.0</Text>
|
||||
<Text style={[styles.footerVersion, { fontSize: 10 * fontScale }]}>Version 1.0.0</Text>
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ import {
|
||||
ActivityIndicator,
|
||||
} from 'react-native';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { usePezkuwi } from '../contexts/PezkuwiContext';
|
||||
import { KurdistanColors } from '../theme/colors';
|
||||
import {
|
||||
@@ -41,7 +40,6 @@ interface Referral {
|
||||
}
|
||||
|
||||
const ReferralScreen: React.FC = () => {
|
||||
const { t: _t } = useTranslation();
|
||||
const { selectedAccount, api, connectWallet, isApiReady } = usePezkuwi();
|
||||
const isConnected = !!selectedAccount;
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
ActivityIndicator,
|
||||
} from 'react-native';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import { KurdistanColors } from '../theme/colors';
|
||||
|
||||
@@ -24,7 +23,6 @@ interface SignInScreenProps {
|
||||
}
|
||||
|
||||
const SignInScreen: React.FC<SignInScreenProps> = ({ onSignIn, onNavigateToSignUp }) => {
|
||||
const { t } = useTranslation();
|
||||
const { signIn } = useAuth();
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
@@ -78,17 +76,17 @@ const SignInScreen: React.FC<SignInScreenProps> = ({ onSignIn, onNavigateToSignU
|
||||
<View style={styles.logoContainer}>
|
||||
<Text style={styles.logoText}>PZK</Text>
|
||||
</View>
|
||||
<Text style={styles.title}>{t('auth.welcomeBack')}</Text>
|
||||
<Text style={styles.subtitle}>{t('auth.signIn')}</Text>
|
||||
<Text style={styles.title}>Welcome Back!</Text>
|
||||
<Text style={styles.subtitle}>Sign In</Text>
|
||||
</View>
|
||||
|
||||
{/* Form */}
|
||||
<View style={styles.form}>
|
||||
<View style={styles.inputGroup}>
|
||||
<Text style={styles.label}>{t('auth.email')}</Text>
|
||||
<Text style={styles.label}>Email</Text>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
placeholder={t('auth.email')}
|
||||
placeholder="Email"
|
||||
value={email}
|
||||
onChangeText={setEmail}
|
||||
keyboardType="email-address"
|
||||
@@ -98,10 +96,10 @@ const SignInScreen: React.FC<SignInScreenProps> = ({ onSignIn, onNavigateToSignU
|
||||
</View>
|
||||
|
||||
<View style={styles.inputGroup}>
|
||||
<Text style={styles.label}>{t('auth.password')}</Text>
|
||||
<Text style={styles.label}>Password</Text>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
placeholder={t('auth.password')}
|
||||
placeholder="Password"
|
||||
value={password}
|
||||
onChangeText={setPassword}
|
||||
secureTextEntry
|
||||
@@ -111,7 +109,7 @@ const SignInScreen: React.FC<SignInScreenProps> = ({ onSignIn, onNavigateToSignU
|
||||
|
||||
<TouchableOpacity style={styles.forgotPassword}>
|
||||
<Text style={styles.forgotPasswordText}>
|
||||
{t('auth.forgotPassword')}
|
||||
Forgot Password?
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
@@ -124,7 +122,7 @@ const SignInScreen: React.FC<SignInScreenProps> = ({ onSignIn, onNavigateToSignU
|
||||
{isLoading ? (
|
||||
<ActivityIndicator color={KurdistanColors.spi} />
|
||||
) : (
|
||||
<Text style={styles.signInButtonText}>{t('auth.signIn')}</Text>
|
||||
<Text style={styles.signInButtonText}>Sign In</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
|
||||
@@ -139,8 +137,8 @@ const SignInScreen: React.FC<SignInScreenProps> = ({ onSignIn, onNavigateToSignU
|
||||
onPress={onNavigateToSignUp}
|
||||
>
|
||||
<Text style={styles.signUpPromptText}>
|
||||
{t('auth.noAccount')}{' '}
|
||||
<Text style={styles.signUpLink}>{t('auth.signUp')}</Text>
|
||||
Don't have an account?{' '}
|
||||
<Text style={styles.signUpLink}>Sign Up</Text>
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
ActivityIndicator,
|
||||
} from 'react-native';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useAuth } from '../contexts/AuthContext';
|
||||
import { KurdistanColors } from '../theme/colors';
|
||||
|
||||
@@ -24,7 +23,6 @@ interface SignUpScreenProps {
|
||||
}
|
||||
|
||||
const SignUpScreen: React.FC<SignUpScreenProps> = ({ onSignUp, onNavigateToSignIn }) => {
|
||||
const { t } = useTranslation();
|
||||
const { signUp } = useAuth();
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
@@ -85,17 +83,17 @@ const SignUpScreen: React.FC<SignUpScreenProps> = ({ onSignUp, onNavigateToSignI
|
||||
<View style={styles.logoContainer}>
|
||||
<Text style={styles.logoText}>PZK</Text>
|
||||
</View>
|
||||
<Text style={styles.title}>{t('auth.getStarted')}</Text>
|
||||
<Text style={styles.subtitle}>{t('auth.createAccount')}</Text>
|
||||
<Text style={styles.title}>Get Started</Text>
|
||||
<Text style={styles.subtitle}>Create Account</Text>
|
||||
</View>
|
||||
|
||||
{/* Form */}
|
||||
<View style={styles.form}>
|
||||
<View style={styles.inputGroup}>
|
||||
<Text style={styles.label}>{t('auth.email')}</Text>
|
||||
<Text style={styles.label}>Email</Text>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
placeholder={t('auth.email')}
|
||||
placeholder="Email"
|
||||
value={email}
|
||||
onChangeText={setEmail}
|
||||
keyboardType="email-address"
|
||||
@@ -105,10 +103,10 @@ const SignUpScreen: React.FC<SignUpScreenProps> = ({ onSignUp, onNavigateToSignI
|
||||
</View>
|
||||
|
||||
<View style={styles.inputGroup}>
|
||||
<Text style={styles.label}>{t('auth.username')}</Text>
|
||||
<Text style={styles.label}>Username</Text>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
placeholder={t('auth.username')}
|
||||
placeholder="Username"
|
||||
value={username}
|
||||
onChangeText={setUsername}
|
||||
autoCapitalize="none"
|
||||
@@ -117,10 +115,10 @@ const SignUpScreen: React.FC<SignUpScreenProps> = ({ onSignUp, onNavigateToSignI
|
||||
</View>
|
||||
|
||||
<View style={styles.inputGroup}>
|
||||
<Text style={styles.label}>{t('auth.password')}</Text>
|
||||
<Text style={styles.label}>Password</Text>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
placeholder={t('auth.password')}
|
||||
placeholder="Password"
|
||||
value={password}
|
||||
onChangeText={setPassword}
|
||||
secureTextEntry
|
||||
@@ -129,10 +127,10 @@ const SignUpScreen: React.FC<SignUpScreenProps> = ({ onSignUp, onNavigateToSignI
|
||||
</View>
|
||||
|
||||
<View style={styles.inputGroup}>
|
||||
<Text style={styles.label}>{t('auth.confirmPassword')}</Text>
|
||||
<Text style={styles.label}>Confirm Password</Text>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
placeholder={t('auth.confirmPassword')}
|
||||
placeholder="Confirm Password"
|
||||
value={confirmPassword}
|
||||
onChangeText={setConfirmPassword}
|
||||
secureTextEntry
|
||||
@@ -149,7 +147,7 @@ const SignUpScreen: React.FC<SignUpScreenProps> = ({ onSignUp, onNavigateToSignI
|
||||
{isLoading ? (
|
||||
<ActivityIndicator color={KurdistanColors.spi} />
|
||||
) : (
|
||||
<Text style={styles.signUpButtonText}>{t('auth.signUp')}</Text>
|
||||
<Text style={styles.signUpButtonText}>Sign Up</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
|
||||
@@ -164,8 +162,8 @@ const SignUpScreen: React.FC<SignUpScreenProps> = ({ onSignUp, onNavigateToSignI
|
||||
onPress={onNavigateToSignIn}
|
||||
>
|
||||
<Text style={styles.signInPromptText}>
|
||||
{t('auth.haveAccount')}{' '}
|
||||
<Text style={styles.signInLink}>{t('auth.signIn')}</Text>
|
||||
Already have an account?{' '}
|
||||
<Text style={styles.signInLink}>Sign In</Text>
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
@@ -42,7 +42,7 @@ const SCORE_WEIGHTS = {
|
||||
};
|
||||
|
||||
export default function StakingScreen() {
|
||||
const { api, selectedAccount, isApiReady } = usePezkuwi();
|
||||
const { api, selectedAccount, isApiReady, getKeyPair } = usePezkuwi();
|
||||
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [refreshing, setRefreshing] = useState(false);
|
||||
@@ -137,17 +137,20 @@ export default function StakingScreen() {
|
||||
setProcessing(true);
|
||||
if (!api || !selectedAccount) return;
|
||||
|
||||
// Get keypair for signing
|
||||
const keyPair = await getKeyPair(selectedAccount.address);
|
||||
if (!keyPair) {
|
||||
Alert.alert('Error', 'Could not retrieve wallet keypair for signing');
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert amount to planck
|
||||
const amountPlanck = BigInt(Math.floor(parseFloat(stakeAmount) * 1e12));
|
||||
|
||||
// Bond tokens (or bond_extra if already bonding)
|
||||
// For simplicity, using bond_extra if already bonded, otherwise bond
|
||||
// But UI should handle controller/stash logic. Assuming simple setup.
|
||||
// This part is simplified.
|
||||
|
||||
const tx = api.tx.staking.bondExtra(amountPlanck);
|
||||
|
||||
await tx.signAndSend(selectedAccount.address, ({ status }) => {
|
||||
|
||||
await tx.signAndSend(keyPair, ({ status }) => {
|
||||
if (status.isInBlock) {
|
||||
Alert.alert('Success', `Successfully staked ${stakeAmount} HEZ!`);
|
||||
setStakeSheetVisible(false);
|
||||
@@ -173,10 +176,17 @@ export default function StakingScreen() {
|
||||
setProcessing(true);
|
||||
if (!api || !selectedAccount) return;
|
||||
|
||||
// Get keypair for signing
|
||||
const keyPair = await getKeyPair(selectedAccount.address);
|
||||
if (!keyPair) {
|
||||
Alert.alert('Error', 'Could not retrieve wallet keypair for signing');
|
||||
return;
|
||||
}
|
||||
|
||||
const amountPlanck = BigInt(Math.floor(parseFloat(unstakeAmount) * 1e12));
|
||||
|
||||
const tx = api.tx.staking.unbond(amountPlanck);
|
||||
await tx.signAndSend(selectedAccount.address, ({ status }) => {
|
||||
await tx.signAndSend(keyPair, ({ status }) => {
|
||||
if (status.isInBlock) {
|
||||
Alert.alert(
|
||||
'Success',
|
||||
@@ -200,10 +210,17 @@ export default function StakingScreen() {
|
||||
setProcessing(true);
|
||||
if (!api || !selectedAccount) return;
|
||||
|
||||
// Get keypair for signing
|
||||
const keyPair = await getKeyPair(selectedAccount.address);
|
||||
if (!keyPair) {
|
||||
Alert.alert('Error', 'Could not retrieve wallet keypair for signing');
|
||||
return;
|
||||
}
|
||||
|
||||
// Withdraw all available unbonded funds
|
||||
// num_slashing_spans is usually 0 for simple stakers
|
||||
const tx = api.tx.staking.withdrawUnbonded(0);
|
||||
await tx.signAndSend(selectedAccount.address, ({ status }) => {
|
||||
await tx.signAndSend(keyPair, ({ status }) => {
|
||||
if (status.isInBlock) {
|
||||
Alert.alert('Success', 'Successfully withdrawn unbonded tokens!');
|
||||
fetchStakingData();
|
||||
@@ -226,8 +243,16 @@ export default function StakingScreen() {
|
||||
|
||||
setProcessing(true);
|
||||
try {
|
||||
// Get keypair for signing
|
||||
const keyPair = await getKeyPair(selectedAccount.address);
|
||||
if (!keyPair) {
|
||||
Alert.alert('Error', 'Could not retrieve wallet keypair for signing');
|
||||
setProcessing(false);
|
||||
return;
|
||||
}
|
||||
|
||||
const tx = api.tx.staking.nominate(validators);
|
||||
await tx.signAndSend(selectedAccount.address, ({ status }) => {
|
||||
await tx.signAndSend(keyPair, ({ status }) => {
|
||||
if (status.isInBlock) {
|
||||
Alert.alert('Success', 'Nomination transaction sent!');
|
||||
setValidatorSheetVisible(false);
|
||||
|
||||
@@ -13,8 +13,10 @@ import {
|
||||
Platform,
|
||||
Image,
|
||||
} from 'react-native';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { KurdistanColors } from '../theme/colors';
|
||||
import { usePezkuwi } from '../contexts/PezkuwiContext';
|
||||
import { KurdistanSun } from '../components/KurdistanSun';
|
||||
|
||||
// Token Images
|
||||
const hezLogo = require('../../../shared/images/hez_logo.png');
|
||||
@@ -30,14 +32,15 @@ interface TokenInfo {
|
||||
}
|
||||
|
||||
const TOKENS: TokenInfo[] = [
|
||||
{ symbol: 'HEZ', name: 'Hemuwelet', assetId: 0, decimals: 12, logo: hezLogo },
|
||||
{ symbol: 'PEZ', name: 'Pezkunel', assetId: 1, decimals: 12, logo: pezLogo },
|
||||
{ symbol: 'HEZ', name: 'Welati Coin', assetId: 0, decimals: 12, logo: hezLogo },
|
||||
{ symbol: 'PEZ', name: 'Pezkuwichain Token', assetId: 1, decimals: 12, logo: pezLogo },
|
||||
{ symbol: 'USDT', name: 'Tether USD', assetId: 1000, decimals: 6, logo: usdtLogo },
|
||||
];
|
||||
|
||||
type TransactionStatus = 'idle' | 'signing' | 'submitting' | 'success' | 'error';
|
||||
|
||||
const SwapScreen: React.FC = () => {
|
||||
const navigation = useNavigation<any>();
|
||||
const { api, isApiReady, selectedAccount, getKeyPair } = usePezkuwi();
|
||||
|
||||
const [fromToken, setFromToken] = useState<TokenInfo>(TOKENS[0]);
|
||||
@@ -49,6 +52,17 @@ const SwapScreen: React.FC = () => {
|
||||
const [fromBalance, setFromBalance] = useState('0');
|
||||
const [toBalance, setToBalance] = useState('0');
|
||||
|
||||
// Pool reserves for AMM calculation
|
||||
const [poolReserves, setPoolReserves] = useState<{
|
||||
reserve0: number;
|
||||
reserve1: number;
|
||||
asset0: number;
|
||||
asset1: number;
|
||||
} | null>(null);
|
||||
const [exchangeRate, setExchangeRate] = useState(0);
|
||||
const [isLoadingRate, setIsLoadingRate] = useState(false);
|
||||
const [isDexAvailable, setIsDexAvailable] = useState(false);
|
||||
|
||||
const [txStatus, setTxStatus] = useState<TransactionStatus>('idle');
|
||||
const [errorMessage, setErrorMessage] = useState('');
|
||||
|
||||
@@ -93,18 +107,184 @@ const SwapScreen: React.FC = () => {
|
||||
fetchBalances();
|
||||
}, [api, isApiReady, selectedAccount, fromToken, toToken]);
|
||||
|
||||
// Calculate output amount (simple 1:1 for now - should use pool reserves)
|
||||
// Check if AssetConversion pallet is available
|
||||
useEffect(() => {
|
||||
if (api && isApiReady) {
|
||||
const hasAssetConversion = api.tx.assetConversion !== undefined;
|
||||
setIsDexAvailable(hasAssetConversion);
|
||||
if (__DEV__ && !hasAssetConversion) {
|
||||
console.warn('AssetConversion pallet not available in runtime');
|
||||
}
|
||||
}
|
||||
}, [api, isApiReady]);
|
||||
|
||||
// Fetch exchange rate from AssetConversion pool
|
||||
useEffect(() => {
|
||||
const fetchExchangeRate = async () => {
|
||||
if (!api || !isApiReady || !isDexAvailable) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoadingRate(true);
|
||||
try {
|
||||
// Map user-selected tokens to actual pool assets
|
||||
// HEZ → wHEZ (Asset 0) behind the scenes
|
||||
const getPoolAssetId = (token: TokenInfo) => {
|
||||
if (token.symbol === 'HEZ') return 0; // wHEZ
|
||||
return token.assetId;
|
||||
};
|
||||
|
||||
const fromAssetId = getPoolAssetId(fromToken);
|
||||
const toAssetId = getPoolAssetId(toToken);
|
||||
|
||||
// Pool ID must be sorted (smaller asset ID first)
|
||||
const [asset1, asset2] = fromAssetId < toAssetId
|
||||
? [fromAssetId, toAssetId]
|
||||
: [toAssetId, fromAssetId];
|
||||
|
||||
// Create pool asset tuple [asset1, asset2] - must be sorted!
|
||||
const poolAssets = [
|
||||
{ NativeOrAsset: { Asset: asset1 } },
|
||||
{ NativeOrAsset: { Asset: asset2 } }
|
||||
];
|
||||
|
||||
// Query pool from AssetConversion pallet
|
||||
const poolInfo = await api.query.assetConversion.pools(poolAssets);
|
||||
|
||||
if (poolInfo && !poolInfo.isEmpty) {
|
||||
try {
|
||||
// Derive pool account using AccountIdConverter
|
||||
// blake2_256(&Encode::encode(&(PalletId, PoolId))[..])
|
||||
const { stringToU8a } = await import('@pezkuwi/util');
|
||||
const { blake2AsU8a } = await import('@pezkuwi/util-crypto');
|
||||
|
||||
// PalletId for AssetConversion: "py/ascon" (8 bytes)
|
||||
const PALLET_ID = stringToU8a('py/ascon');
|
||||
|
||||
// Create PoolId tuple (u32, u32)
|
||||
const poolId = api.createType('(u32, u32)', [asset1, asset2]);
|
||||
|
||||
// Create (PalletId, PoolId) tuple: ([u8; 8], (u32, u32))
|
||||
const palletIdType = api.createType('[u8; 8]', PALLET_ID);
|
||||
const fullTuple = api.createType('([u8; 8], (u32, u32))', [palletIdType, poolId]);
|
||||
|
||||
// Hash the SCALE-encoded tuple
|
||||
const accountHash = blake2AsU8a(fullTuple.toU8a(), 256);
|
||||
const poolAccountId = api.createType('AccountId32', accountHash);
|
||||
|
||||
// Query pool account's asset balances
|
||||
const reserve0Query = await api.query.assets.account(asset1, poolAccountId);
|
||||
const reserve1Query = await api.query.assets.account(asset2, poolAccountId);
|
||||
|
||||
const reserve0Data = reserve0Query.toJSON() as { balance?: string } | null;
|
||||
const reserve1Data = reserve1Query.toJSON() as { balance?: string } | null;
|
||||
|
||||
if (reserve0Data?.balance && reserve1Data?.balance) {
|
||||
// Parse hex string balances to BigInt, then to number
|
||||
const balance0Hex = reserve0Data.balance.toString();
|
||||
const balance1Hex = reserve1Data.balance.toString();
|
||||
|
||||
// Use correct decimals for each asset
|
||||
const decimals0 = asset1 === 1000 ? 6 : 12;
|
||||
const decimals1 = asset2 === 1000 ? 6 : 12;
|
||||
|
||||
const reserve0 = Number(BigInt(balance0Hex)) / (10 ** decimals0);
|
||||
const reserve1 = Number(BigInt(balance1Hex)) / (10 ** decimals1);
|
||||
|
||||
if (__DEV__) {
|
||||
console.log('Pool reserves found:', { reserve0, reserve1, asset1, asset2 });
|
||||
}
|
||||
|
||||
// Store pool reserves for AMM calculation
|
||||
setPoolReserves({
|
||||
reserve0,
|
||||
reserve1,
|
||||
asset0: asset1,
|
||||
asset1: asset2
|
||||
});
|
||||
|
||||
// Calculate simple exchange rate for display
|
||||
const rate = fromAssetId === asset1
|
||||
? reserve1 / reserve0 // from asset1 to asset2
|
||||
: reserve0 / reserve1; // from asset2 to asset1
|
||||
|
||||
setExchangeRate(rate);
|
||||
} else {
|
||||
if (__DEV__) console.warn('Pool has no reserves');
|
||||
setExchangeRate(0);
|
||||
setPoolReserves(null);
|
||||
}
|
||||
} catch (err) {
|
||||
if (__DEV__) console.error('Error deriving pool account:', err);
|
||||
setExchangeRate(0);
|
||||
setPoolReserves(null);
|
||||
}
|
||||
} else {
|
||||
if (__DEV__) console.warn('No liquidity pool found for this pair');
|
||||
setExchangeRate(0);
|
||||
setPoolReserves(null);
|
||||
}
|
||||
} catch (error) {
|
||||
if (__DEV__) console.error('Failed to fetch exchange rate:', error);
|
||||
setExchangeRate(0);
|
||||
setPoolReserves(null);
|
||||
} finally {
|
||||
setIsLoadingRate(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchExchangeRate();
|
||||
}, [api, isApiReady, isDexAvailable, fromToken, toToken]);
|
||||
|
||||
// Calculate output amount using Uniswap V2 AMM formula
|
||||
useEffect(() => {
|
||||
if (!fromAmount || parseFloat(fromAmount) <= 0) {
|
||||
setToAmount('');
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Implement proper AMM calculation using pool reserves
|
||||
// For now, simple 1:1 conversion (placeholder)
|
||||
const calculatedAmount = (parseFloat(fromAmount) * 0.97).toFixed(6); // 3% fee simulation
|
||||
setToAmount(calculatedAmount);
|
||||
}, [fromAmount, fromToken, toToken]);
|
||||
// If no pool reserves available, cannot calculate
|
||||
if (!poolReserves) {
|
||||
setToAmount('');
|
||||
return;
|
||||
}
|
||||
|
||||
const amountIn = parseFloat(fromAmount);
|
||||
const { reserve0, reserve1, asset0 } = poolReserves;
|
||||
|
||||
// Determine which reserve is input and which is output
|
||||
const getPoolAssetId = (token: TokenInfo) => {
|
||||
if (token.symbol === 'HEZ') return 0; // wHEZ
|
||||
return token.assetId;
|
||||
};
|
||||
const fromAssetId = getPoolAssetId(fromToken);
|
||||
const isAsset0ToAsset1 = fromAssetId === asset0;
|
||||
|
||||
const reserveIn = isAsset0ToAsset1 ? reserve0 : reserve1;
|
||||
const reserveOut = isAsset0ToAsset1 ? reserve1 : reserve0;
|
||||
|
||||
// Uniswap V2 AMM formula (matches Substrate runtime exactly)
|
||||
// Runtime: amount_in_with_fee = amount_in * (1000 - LPFee) = amount_in * 970
|
||||
// LPFee = 30 (3% fee)
|
||||
// Formula: amountOut = (amountIn * 970 * reserveOut) / (reserveIn * 1000 + amountIn * 970)
|
||||
const LP_FEE = 30; // 3% fee
|
||||
const amountInWithFee = amountIn * (1000 - LP_FEE);
|
||||
const numerator = amountInWithFee * reserveOut;
|
||||
const denominator = reserveIn * 1000 + amountInWithFee;
|
||||
const amountOut = numerator / denominator;
|
||||
|
||||
if (__DEV__) {
|
||||
console.log('AMM calculation:', {
|
||||
amountIn,
|
||||
reserveIn,
|
||||
reserveOut,
|
||||
amountOut,
|
||||
lpFee: `${LP_FEE / 10}%`
|
||||
});
|
||||
}
|
||||
|
||||
setToAmount(amountOut.toFixed(6));
|
||||
}, [fromAmount, fromToken, toToken, poolReserves]);
|
||||
|
||||
// Calculate formatted balances
|
||||
const fromBalanceFormatted = useMemo(() => {
|
||||
@@ -161,6 +341,11 @@ const SwapScreen: React.FC = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!exchangeRate || exchangeRate === 0) {
|
||||
Alert.alert('Error', 'No liquidity pool available for this pair');
|
||||
return;
|
||||
}
|
||||
|
||||
setTxStatus('signing');
|
||||
setShowConfirm(false);
|
||||
setErrorMessage('');
|
||||
@@ -276,21 +461,22 @@ const SwapScreen: React.FC = () => {
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
{/* Transaction Loading Overlay */}
|
||||
{/* Kurdistan Sun Loading Overlay */}
|
||||
{(txStatus === 'signing' || txStatus === 'submitting') && (
|
||||
<View style={styles.loadingOverlay}>
|
||||
<View style={styles.loadingCard}>
|
||||
<ActivityIndicator size="large" color={KurdistanColors.kesk} />
|
||||
<Text style={styles.loadingText}>
|
||||
{txStatus === 'signing' ? 'Waiting for signature...' : 'Processing swap...'}
|
||||
</Text>
|
||||
</View>
|
||||
<KurdistanSun size={250} />
|
||||
<Text style={styles.loadingText}>
|
||||
{txStatus === 'signing' ? 'Waiting for signature...' : 'Processing your swap...'}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
|
||||
<ScrollView style={styles.scrollContent} contentContainerStyle={styles.scrollContentContainer}>
|
||||
{/* Header */}
|
||||
<View style={styles.header}>
|
||||
<TouchableOpacity onPress={() => navigation.goBack()} style={styles.backButton}>
|
||||
<Text style={styles.backButtonText}>←</Text>
|
||||
</TouchableOpacity>
|
||||
<Text style={styles.headerTitle}>Swap Tokens</Text>
|
||||
<TouchableOpacity onPress={() => setShowSettings(true)} style={styles.settingsButton}>
|
||||
<Text style={styles.settingsIcon}>⚙️</Text>
|
||||
@@ -369,7 +555,13 @@ const SwapScreen: React.FC = () => {
|
||||
<View style={styles.detailsCard}>
|
||||
<View style={styles.detailRow}>
|
||||
<Text style={styles.detailLabel}>ℹ️ Exchange Rate</Text>
|
||||
<Text style={styles.detailValue}>1 {fromToken.symbol} ≈ 1 {toToken.symbol}</Text>
|
||||
<Text style={styles.detailValue}>
|
||||
{isLoadingRate
|
||||
? 'Loading...'
|
||||
: exchangeRate > 0
|
||||
? `1 ${fromToken.symbol} ≈ ${exchangeRate.toFixed(4)} ${toToken.symbol}`
|
||||
: 'No pool available'}
|
||||
</Text>
|
||||
</View>
|
||||
<View style={styles.detailRow}>
|
||||
<Text style={styles.detailLabel}>Slippage Tolerance</Text>
|
||||
@@ -389,14 +581,16 @@ const SwapScreen: React.FC = () => {
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.swapButton,
|
||||
(!fromAmount || hasInsufficientBalance || txStatus !== 'idle') && styles.swapButtonDisabled
|
||||
(!fromAmount || hasInsufficientBalance || txStatus !== 'idle' || exchangeRate === 0) && styles.swapButtonDisabled
|
||||
]}
|
||||
onPress={() => setShowConfirm(true)}
|
||||
disabled={!fromAmount || hasInsufficientBalance || txStatus !== 'idle'}
|
||||
disabled={!fromAmount || hasInsufficientBalance || txStatus !== 'idle' || exchangeRate === 0}
|
||||
>
|
||||
<Text style={styles.swapButtonText}>
|
||||
{hasInsufficientBalance
|
||||
? `Insufficient ${fromToken.symbol} Balance`
|
||||
: exchangeRate === 0
|
||||
? 'No Pool Available'
|
||||
: 'Swap Tokens'}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
@@ -468,6 +662,10 @@ const SwapScreen: React.FC = () => {
|
||||
<Text style={styles.confirmValue}>{toAmount} {toToken.symbol}</Text>
|
||||
</View>
|
||||
<View style={[styles.confirmRow, styles.confirmRowBorder]}>
|
||||
<Text style={styles.confirmLabelSmall}>Exchange Rate</Text>
|
||||
<Text style={styles.confirmValueSmall}>1 {fromToken.symbol} = {exchangeRate.toFixed(4)} {toToken.symbol}</Text>
|
||||
</View>
|
||||
<View style={styles.confirmRow}>
|
||||
<Text style={styles.confirmLabelSmall}>Slippage</Text>
|
||||
<Text style={styles.confirmValueSmall}>{slippage}%</Text>
|
||||
</View>
|
||||
@@ -519,8 +717,20 @@ const styles = StyleSheet.create({
|
||||
alignItems: 'center',
|
||||
marginBottom: 20,
|
||||
},
|
||||
headerTitle: {
|
||||
backButton: {
|
||||
width: 40,
|
||||
height: 40,
|
||||
borderRadius: 20,
|
||||
backgroundColor: '#F5F5F5',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
backButtonText: {
|
||||
fontSize: 24,
|
||||
color: '#333',
|
||||
},
|
||||
headerTitle: {
|
||||
fontSize: 20,
|
||||
fontWeight: 'bold',
|
||||
color: '#333',
|
||||
},
|
||||
@@ -693,22 +903,16 @@ const styles = StyleSheet.create({
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
backgroundColor: 'rgba(0,0,0,0.7)',
|
||||
backgroundColor: 'rgba(0,0,0,0.85)',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
zIndex: 1000,
|
||||
},
|
||||
loadingCard: {
|
||||
backgroundColor: '#FFFFFF',
|
||||
borderRadius: 20,
|
||||
padding: 32,
|
||||
alignItems: 'center',
|
||||
gap: 16,
|
||||
},
|
||||
loadingText: {
|
||||
fontSize: 16,
|
||||
marginTop: 24,
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
color: '#333',
|
||||
color: '#FFFFFF',
|
||||
},
|
||||
modalOverlay: {
|
||||
flex: 1,
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
Animated,
|
||||
} from 'react-native';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { KurdistanColors } from '../theme/colors';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
|
||||
@@ -20,7 +19,6 @@ interface VerifyHumanScreenProps {
|
||||
}
|
||||
|
||||
const VerifyHumanScreen: React.FC<VerifyHumanScreenProps> = ({ onVerified }) => {
|
||||
const { t } = useTranslation();
|
||||
const [isChecked, setIsChecked] = useState(false);
|
||||
const [scaleValue] = useState(new Animated.Value(1));
|
||||
|
||||
@@ -71,9 +69,9 @@ const VerifyHumanScreen: React.FC<VerifyHumanScreenProps> = ({ onVerified }) =>
|
||||
</View>
|
||||
|
||||
{/* Title */}
|
||||
<Text style={styles.title}>{t('verify.title', 'Security Verification')}</Text>
|
||||
<Text style={styles.title}>Security Verification</Text>
|
||||
<Text style={styles.subtitle}>
|
||||
{t('verify.subtitle', 'Please confirm you are human to continue')}
|
||||
Please confirm you are human to continue
|
||||
</Text>
|
||||
|
||||
{/* Verification Box */}
|
||||
@@ -86,13 +84,13 @@ const VerifyHumanScreen: React.FC<VerifyHumanScreenProps> = ({ onVerified }) =>
|
||||
{isChecked && <Text style={styles.checkmark}>✓</Text>}
|
||||
</View>
|
||||
<Text style={styles.verificationText}>
|
||||
{t('verify.checkbox', "I'm not a robot")}
|
||||
I'm not a robot
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
{/* Info Text */}
|
||||
<Text style={styles.infoText}>
|
||||
{t('verify.info', 'This helps protect the Pezkuwi network from automated attacks')}
|
||||
This helps protect the Pezkuwi network from automated attacks
|
||||
</Text>
|
||||
|
||||
{/* Continue Button */}
|
||||
@@ -109,7 +107,7 @@ const VerifyHumanScreen: React.FC<VerifyHumanScreenProps> = ({ onVerified }) =>
|
||||
!isChecked && styles.continueButtonTextDisabled,
|
||||
]}
|
||||
>
|
||||
{t('verify.continue', 'Continue')}
|
||||
Continue
|
||||
</Text>
|
||||
</Animated.View>
|
||||
</TouchableOpacity>
|
||||
@@ -117,7 +115,7 @@ const VerifyHumanScreen: React.FC<VerifyHumanScreenProps> = ({ onVerified }) =>
|
||||
{/* Footer */}
|
||||
<View style={styles.footer}>
|
||||
<Text style={styles.footerText}>
|
||||
🔒 {t('verify.secure', 'Secure & Private')}
|
||||
Secure & Private
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -18,12 +18,44 @@ import {
|
||||
Share,
|
||||
} from 'react-native';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import QRCode from 'react-native-qrcode-svg';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import * as SecureStore from 'expo-secure-store';
|
||||
import { KurdistanColors } from '../theme/colors';
|
||||
import { usePezkuwi, NetworkType, NETWORKS } from '../contexts/PezkuwiContext';
|
||||
import { AddTokenModal } from '../components/wallet/AddTokenModal';
|
||||
import { HezTokenLogo, PezTokenLogo } from '../components/icons';
|
||||
|
||||
// Secure storage helper - same as in PezkuwiContext
|
||||
const secureStorage = {
|
||||
getItem: async (key: string): Promise<string | null> => {
|
||||
if (Platform.OS === 'web') {
|
||||
return await AsyncStorage.getItem(key);
|
||||
} else {
|
||||
return await SecureStore.getItemAsync(key);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// Cross-platform alert helper
|
||||
const showAlert = (title: string, message: string, buttons?: Array<{text: string; onPress?: () => void; style?: string}>) => {
|
||||
if (Platform.OS === 'web') {
|
||||
if (buttons && buttons.length > 1) {
|
||||
const result = window.confirm(`${title}\n\n${message}`);
|
||||
if (result && buttons[1]?.onPress) {
|
||||
buttons[1].onPress();
|
||||
} else if (!result && buttons[0]?.onPress) {
|
||||
buttons[0].onPress();
|
||||
}
|
||||
} else {
|
||||
window.alert(`${title}\n\n${message}`);
|
||||
if (buttons?.[0]?.onPress) buttons[0].onPress();
|
||||
}
|
||||
} else {
|
||||
showAlert(title, message, buttons as any);
|
||||
}
|
||||
};
|
||||
|
||||
// Token Images - From shared/images
|
||||
const hezLogo = require('../../../shared/images/hez_logo.png');
|
||||
@@ -59,16 +91,17 @@ interface Transaction {
|
||||
}
|
||||
|
||||
const WalletScreen: React.FC = () => {
|
||||
const { t } = useTranslation();
|
||||
const navigation = useNavigation<any>();
|
||||
const {
|
||||
api,
|
||||
isApiReady,
|
||||
accounts,
|
||||
selectedAccount,
|
||||
setSelectedAccount,
|
||||
connectWallet,
|
||||
disconnectWallet,
|
||||
createWallet,
|
||||
deleteWallet,
|
||||
getKeyPair,
|
||||
currentNetwork,
|
||||
switchNetwork,
|
||||
@@ -82,6 +115,7 @@ const WalletScreen: React.FC = () => {
|
||||
const [importWalletModalVisible, setImportWalletModalVisible] = useState(false);
|
||||
const [backupModalVisible, setBackupModalVisible] = useState(false);
|
||||
const [networkSelectorVisible, setNetworkSelectorVisible] = useState(false);
|
||||
const [walletSelectorVisible, setWalletSelectorVisible] = useState(false);
|
||||
const [addTokenModalVisible, setAddTokenModalVisible] = useState(false);
|
||||
const [recipientAddress, setRecipientAddress] = useState('');
|
||||
const [sendAmount, setSendAmount] = useState('');
|
||||
@@ -225,7 +259,7 @@ const WalletScreen: React.FC = () => {
|
||||
|
||||
const handleConfirmSend = async () => {
|
||||
if (!recipientAddress || !sendAmount || !selectedToken || !selectedAccount || !api) {
|
||||
Alert.alert('Error', 'Please enter recipient address and amount');
|
||||
showAlert('Error', 'Please enter recipient address and amount');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -251,13 +285,13 @@ const WalletScreen: React.FC = () => {
|
||||
if (status.isFinalized) {
|
||||
setSendModalVisible(false);
|
||||
setIsSending(false);
|
||||
Alert.alert('Success', 'Transaction Sent!');
|
||||
showAlert('Success', 'Transaction Sent!');
|
||||
fetchData();
|
||||
}
|
||||
});
|
||||
} catch (e: any) {
|
||||
setIsSending(false);
|
||||
Alert.alert('Error', e.message);
|
||||
showAlert('Error', e.message);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -272,21 +306,21 @@ const WalletScreen: React.FC = () => {
|
||||
const { address, mnemonic } = await createWallet(walletName);
|
||||
setUserMnemonic(mnemonic); // Save for backup
|
||||
setCreateWalletModalVisible(false);
|
||||
Alert.alert('Wallet Created', `Save this mnemonic:\n${mnemonic}`, [{ text: 'OK', onPress: () => connectWallet() }]);
|
||||
} catch (e) { Alert.alert('Error', 'Failed'); }
|
||||
showAlert('Wallet Created', `Save this mnemonic:\n${mnemonic}`, [{ text: 'OK', onPress: () => connectWallet() }]);
|
||||
} catch (e) { showAlert('Error', 'Failed'); }
|
||||
};
|
||||
|
||||
// Copy Address Handler
|
||||
const handleCopyAddress = () => {
|
||||
if (!selectedAccount) return;
|
||||
Clipboard.setString(selectedAccount.address);
|
||||
Alert.alert('Copied!', 'Address copied to clipboard');
|
||||
showAlert('Copied!', 'Address copied to clipboard');
|
||||
};
|
||||
|
||||
// Import Wallet Handler
|
||||
const handleImportWallet = async () => {
|
||||
if (!importMnemonic.trim()) {
|
||||
Alert.alert('Error', 'Please enter a valid mnemonic');
|
||||
showAlert('Error', 'Please enter a valid mnemonic');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
@@ -297,23 +331,36 @@ const WalletScreen: React.FC = () => {
|
||||
const pair = keyring.addFromMnemonic(importMnemonic.trim());
|
||||
|
||||
// Store in AsyncStorage (via context method ideally)
|
||||
Alert.alert('Success', `Wallet imported: ${pair.address.slice(0,8)}...`);
|
||||
showAlert('Success', `Wallet imported: ${pair.address.slice(0,8)}...`);
|
||||
setImportWalletModalVisible(false);
|
||||
setImportMnemonic('');
|
||||
connectWallet();
|
||||
} catch (e: any) {
|
||||
Alert.alert('Error', e.message || 'Invalid mnemonic');
|
||||
showAlert('Error', e.message || 'Invalid mnemonic');
|
||||
}
|
||||
};
|
||||
|
||||
// Backup Mnemonic Handler
|
||||
const handleBackupMnemonic = async () => {
|
||||
// Retrieve mnemonic from secure storage
|
||||
// For demo, we show the saved one or prompt user
|
||||
if (userMnemonic) {
|
||||
setBackupModalVisible(true);
|
||||
} else {
|
||||
Alert.alert('No Backup', 'Mnemonic not available. Create a new wallet or import existing one.');
|
||||
if (!selectedAccount) {
|
||||
showAlert('No Wallet', 'Please create or import a wallet first.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Retrieve mnemonic from secure storage
|
||||
const seedKey = `pezkuwi_seed_${selectedAccount.address}`;
|
||||
const storedMnemonic = await secureStorage.getItem(seedKey);
|
||||
|
||||
if (storedMnemonic) {
|
||||
setUserMnemonic(storedMnemonic);
|
||||
setBackupModalVisible(true);
|
||||
} else {
|
||||
showAlert('No Backup', 'Mnemonic not found in secure storage. It may have been imported from another device.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error retrieving mnemonic:', error);
|
||||
showAlert('Error', 'Failed to retrieve mnemonic from secure storage.');
|
||||
}
|
||||
};
|
||||
|
||||
@@ -334,156 +381,110 @@ const WalletScreen: React.FC = () => {
|
||||
try {
|
||||
await switchNetwork(network);
|
||||
setNetworkSelectorVisible(false);
|
||||
Alert.alert('Success', `Switched to ${NETWORKS[network].displayName}`);
|
||||
showAlert('Success', `Switched to ${NETWORKS[network].displayName}`);
|
||||
} catch (e: any) {
|
||||
Alert.alert('Error', e.message || 'Failed to switch network');
|
||||
showAlert('Error', e.message || 'Failed to switch network');
|
||||
}
|
||||
};
|
||||
|
||||
if (!selectedAccount) {
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<LinearGradient
|
||||
colors={['#00693E', '#008f43', '#00A651']}
|
||||
style={styles.welcomeGradient}
|
||||
>
|
||||
<View style={styles.welcomeContent}>
|
||||
<Text style={styles.welcomeEmoji}>🔐</Text>
|
||||
<Text style={styles.welcomeTitle}>Welcome to</Text>
|
||||
<Text style={styles.welcomeBrand}>Pezkuwichain Wallet</Text>
|
||||
<Text style={styles.welcomeSubtitle}>
|
||||
Secure, Fast & Decentralized
|
||||
</Text>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
// Redirect to WalletSetupScreen if no wallet exists
|
||||
useEffect(() => {
|
||||
if (!selectedAccount && accounts.length === 0) {
|
||||
navigation.replace('WalletSetup');
|
||||
}
|
||||
}, [selectedAccount, accounts, navigation]);
|
||||
|
||||
<View style={styles.buttonContainer}>
|
||||
<TouchableOpacity
|
||||
style={styles.primaryWalletButton}
|
||||
onPress={handleConnectWallet}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
<LinearGradient
|
||||
colors={[KurdistanColors.kesk, '#00A651']}
|
||||
style={styles.buttonGradient}
|
||||
start={{x: 0, y: 0}}
|
||||
end={{x: 1, y: 0}}
|
||||
>
|
||||
<View style={styles.buttonIcon}>
|
||||
<Text style={styles.buttonIconText}>➕</Text>
|
||||
</View>
|
||||
<View style={styles.buttonTextContainer}>
|
||||
<Text style={styles.primaryButtonText}>Create New Wallet</Text>
|
||||
<Text style={styles.primaryButtonSubtext}>
|
||||
Get started in seconds
|
||||
</Text>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity
|
||||
style={styles.secondaryWalletButton}
|
||||
onPress={() => setImportWalletModalVisible(true)}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
<View style={styles.secondaryButtonContent}>
|
||||
<View style={[styles.buttonIcon, {backgroundColor: 'rgba(0,105,62,0.1)'}]}>
|
||||
<Text style={[styles.buttonIconText, {color: KurdistanColors.kesk}]}>📥</Text>
|
||||
</View>
|
||||
<View style={styles.buttonTextContainer}>
|
||||
<Text style={styles.secondaryButtonText}>Import Existing Wallet</Text>
|
||||
<Text style={styles.secondaryButtonSubtext}>
|
||||
Use your seed phrase
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={styles.securityNotice}>
|
||||
<Text style={styles.securityIcon}>🛡️</Text>
|
||||
<Text style={styles.securityText}>
|
||||
Your keys are encrypted and stored locally on your device
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Create Wallet Modal */}
|
||||
<Modal visible={createWalletModalVisible} transparent animationType="slide" onRequestClose={() => setCreateWalletModalVisible(false)}>
|
||||
<View style={styles.modalOverlay}>
|
||||
<View style={styles.modalCard}>
|
||||
<Text style={styles.modalHeader}>Create New Wallet</Text>
|
||||
<TextInput style={styles.inputField} placeholder="Wallet Name" value={walletName} onChangeText={setWalletName} />
|
||||
<View style={styles.modalActions}>
|
||||
<TouchableOpacity style={styles.btnCancel} onPress={() => setCreateWalletModalVisible(false)}><Text>Cancel</Text></TouchableOpacity>
|
||||
<TouchableOpacity style={styles.btnConfirm} onPress={handleCreateWallet}><Text style={{color:'white'}}>Create</Text></TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</Modal>
|
||||
|
||||
{/* Import Wallet Modal */}
|
||||
<Modal visible={importWalletModalVisible} transparent animationType="slide" onRequestClose={() => setImportWalletModalVisible(false)}>
|
||||
<View style={styles.modalOverlay}>
|
||||
<View style={styles.modalCard}>
|
||||
<Text style={styles.modalHeader}>Import Wallet</Text>
|
||||
<Text style={{color: '#666', fontSize: 12, marginBottom: 12}}>Enter your 12 or 24 word mnemonic phrase</Text>
|
||||
<TextInput
|
||||
style={[styles.inputField, {height: 100, textAlignVertical: 'top'}]}
|
||||
placeholder="word1 word2 word3..."
|
||||
multiline
|
||||
value={importMnemonic}
|
||||
onChangeText={setImportMnemonic}
|
||||
/>
|
||||
<View style={styles.modalActions}>
|
||||
<TouchableOpacity style={styles.btnCancel} onPress={() => setImportWalletModalVisible(false)}><Text>Cancel</Text></TouchableOpacity>
|
||||
<TouchableOpacity style={styles.btnConfirm} onPress={handleImportWallet}><Text style={{color:'white'}}>Import</Text></TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</Modal>
|
||||
</SafeAreaView>
|
||||
);
|
||||
// Show loading while checking wallet state or redirecting
|
||||
if (!selectedAccount && accounts.length === 0) {
|
||||
return (
|
||||
<SafeAreaView style={styles.container} testID="wallet-redirecting">
|
||||
<View style={styles.loadingContainer}>
|
||||
<ActivityIndicator size="large" color={KurdistanColors.kesk} />
|
||||
<Text style={styles.loadingText}>Loading wallet...</Text>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<SafeAreaView style={styles.container} testID="wallet-screen">
|
||||
<StatusBar barStyle="dark-content" />
|
||||
|
||||
{/* Top Header with Back Button */}
|
||||
<View style={styles.topHeader} testID="wallet-top-header">
|
||||
<TouchableOpacity onPress={() => navigation.goBack()} style={styles.backButton} testID="wallet-back-button">
|
||||
<Text style={styles.backButtonText}>← Back</Text>
|
||||
</TouchableOpacity>
|
||||
<Text style={styles.topHeaderTitle}>Wallet</Text>
|
||||
<TouchableOpacity onPress={() => setNetworkSelectorVisible(true)} testID="wallet-network-button">
|
||||
<Text style={styles.networkBadge}>🌐 {NETWORKS[currentNetwork].displayName}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<ScrollView
|
||||
style={styles.scrollContent}
|
||||
refreshControl={<RefreshControl refreshing={isLoadingBalances} onRefresh={fetchData} />}
|
||||
showsVerticalScrollIndicator={false}
|
||||
testID="wallet-scroll-view"
|
||||
>
|
||||
{/* Header */}
|
||||
<View style={styles.headerContainer}>
|
||||
<Text style={styles.walletTitle}>pezkuwi wallet</Text>
|
||||
<TouchableOpacity onPress={() => setNetworkSelectorVisible(true)}>
|
||||
<Text style={styles.networkBadge}>🌐 {NETWORKS[currentNetwork].displayName}</Text>
|
||||
{/* Wallet Selector Row */}
|
||||
<View style={styles.walletSelectorRow}>
|
||||
<TouchableOpacity
|
||||
style={styles.walletSelector}
|
||||
onPress={() => setWalletSelectorVisible(true)}
|
||||
testID="wallet-selector-button"
|
||||
>
|
||||
<View style={styles.walletSelectorInfo}>
|
||||
<Text style={styles.walletSelectorName}>{selectedAccount?.name || 'Wallet'}</Text>
|
||||
<Text style={styles.walletSelectorAddress} numberOfLines={1}>
|
||||
{selectedAccount?.address ? `${selectedAccount.address.slice(0, 8)}...${selectedAccount.address.slice(-6)}` : ''}
|
||||
</Text>
|
||||
</View>
|
||||
<Text style={styles.walletSelectorArrow}>▼</Text>
|
||||
</TouchableOpacity>
|
||||
<View style={styles.walletHeaderButtons}>
|
||||
<TouchableOpacity
|
||||
style={styles.addWalletButton}
|
||||
onPress={() => navigation.navigate('WalletSetup')}
|
||||
testID="add-wallet-button"
|
||||
>
|
||||
<Text style={styles.addWalletIcon}>+</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={styles.scanButton}
|
||||
onPress={() => showAlert('Scan', 'QR Scanner coming soon')}
|
||||
testID="wallet-scan-button"
|
||||
>
|
||||
<Text style={styles.scanIcon}>⊡</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Main Token Cards - HEZ and PEZ side by side */}
|
||||
<View style={styles.mainTokensRow}>
|
||||
{/* HEZ Card */}
|
||||
<TouchableOpacity style={styles.mainTokenCard} onPress={() => handleTokenPress(tokens[0])}>
|
||||
<Image source={hezLogo} style={styles.mainTokenLogo} resizeMode="contain" />
|
||||
<View style={styles.mainTokenLogoContainer}>
|
||||
<HezTokenLogo size={56} />
|
||||
</View>
|
||||
<Text style={styles.mainTokenSymbol}>HEZ</Text>
|
||||
<Text style={styles.mainTokenBalance}>{balances.HEZ}</Text>
|
||||
<Text style={styles.mainTokenSubtitle}>Hemuwelet Token</Text>
|
||||
<Text style={styles.mainTokenSubtitle}>Welati Coin</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
{/* PEZ Card */}
|
||||
<TouchableOpacity style={styles.mainTokenCard} onPress={() => handleTokenPress(tokens[1])}>
|
||||
<Image source={pezLogo} style={styles.mainTokenLogo} resizeMode="contain" />
|
||||
<View style={styles.mainTokenLogoContainer}>
|
||||
<PezTokenLogo size={56} />
|
||||
</View>
|
||||
<Text style={styles.mainTokenSymbol}>PEZ</Text>
|
||||
<Text style={styles.mainTokenBalance}>{balances.PEZ}</Text>
|
||||
<Text style={styles.mainTokenSubtitle}>Pezkunel Token</Text>
|
||||
<Text style={styles.mainTokenSubtitle}>Pezkuwichain Token</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Action Buttons Grid - 2x4 */}
|
||||
{/* Action Buttons Grid - 1x4 */}
|
||||
<View style={styles.actionsGrid}>
|
||||
{/* Row 1 */}
|
||||
<TouchableOpacity style={[styles.actionButton, {backgroundColor: '#22C55E'}]} onPress={handleSend}>
|
||||
<Text style={styles.actionIcon}>↑</Text>
|
||||
<Text style={styles.actionLabel}>Send</Text>
|
||||
@@ -494,36 +495,15 @@ const WalletScreen: React.FC = () => {
|
||||
<Text style={styles.actionLabel}>Receive</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity style={[styles.actionButton, {backgroundColor: '#A855F7'}]} onPress={() => Alert.alert('Scan', 'QR Scanner coming soon')}>
|
||||
<Text style={styles.actionIcon}>⊡</Text>
|
||||
<Text style={styles.actionLabel}>Scan</Text>
|
||||
<TouchableOpacity style={[styles.actionButton, {backgroundColor: '#6B7280'}]} onPress={() => navigation.navigate('Swap')}>
|
||||
<Text style={styles.actionIcon}>🔄</Text>
|
||||
<Text style={styles.actionLabel}>Swap</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity style={[styles.actionButton, {backgroundColor: '#6B7280'}]} onPress={() => Alert.alert('P2P', 'Navigate to P2P Platform')}>
|
||||
<Text style={styles.actionIcon}>👥</Text>
|
||||
<Text style={styles.actionLabel}>P2P</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
{/* Row 2 */}
|
||||
<TouchableOpacity style={[styles.actionButton, {backgroundColor: '#EF4444'}]} onPress={() => Alert.alert('Vote', 'Navigate to Governance')}>
|
||||
<Text style={styles.actionIcon}>🗳️</Text>
|
||||
<Text style={styles.actionLabel}>Vote</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity style={[styles.actionButton, {backgroundColor: '#F59E0B'}]} onPress={() => Alert.alert('Dapps', 'Navigate to Apps')}>
|
||||
<Text style={styles.actionIcon}>⊞</Text>
|
||||
<Text style={styles.actionLabel}>Dapps</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity style={[styles.actionButton, {backgroundColor: '#10B981'}]} onPress={() => Alert.alert('Staking', 'Navigate to Staking')}>
|
||||
<TouchableOpacity style={[styles.actionButton, {backgroundColor: '#10B981'}]} onPress={() => showAlert('Staking', 'Navigate to Staking')}>
|
||||
<Text style={styles.actionIcon}>🥩</Text>
|
||||
<Text style={styles.actionLabel}>Staking</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity style={[styles.actionButton, {backgroundColor: '#8B5CF6'}]} onPress={() => setNetworkSelectorVisible(true)}>
|
||||
<Text style={styles.actionIcon}>🔗</Text>
|
||||
<Text style={styles.actionLabel}>Connect</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Tokens List */}
|
||||
@@ -630,7 +610,7 @@ const WalletScreen: React.FC = () => {
|
||||
<View style={styles.modalActions}>
|
||||
<TouchableOpacity style={styles.btnCancel} onPress={() => {
|
||||
Clipboard.setString(userMnemonic);
|
||||
Alert.alert('Copied', 'Mnemonic copied to clipboard');
|
||||
showAlert('Copied', 'Mnemonic copied to clipboard');
|
||||
}}>
|
||||
<Text>📋 Copy</Text>
|
||||
</TouchableOpacity>
|
||||
@@ -642,6 +622,103 @@ const WalletScreen: React.FC = () => {
|
||||
</View>
|
||||
</Modal>
|
||||
|
||||
{/* Wallet Selector Modal */}
|
||||
<Modal visible={walletSelectorVisible} transparent animationType="slide" onRequestClose={() => setWalletSelectorVisible(false)}>
|
||||
<View style={styles.modalOverlay}>
|
||||
<View style={styles.modalCard}>
|
||||
<Text style={styles.modalHeader}>👛 My Wallets</Text>
|
||||
<Text style={{color: '#666', fontSize: 12, marginBottom: 16, textAlign: 'center'}}>
|
||||
Select a wallet or create a new one
|
||||
</Text>
|
||||
|
||||
{/* Wallet List */}
|
||||
{accounts.map((account) => {
|
||||
const isSelected = account.address === selectedAccount?.address;
|
||||
return (
|
||||
<View key={account.address} style={styles.walletOptionRow}>
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.walletOption,
|
||||
isSelected && styles.walletOptionSelected,
|
||||
{flex: 1, marginBottom: 0}
|
||||
]}
|
||||
onPress={() => {
|
||||
setSelectedAccount(account);
|
||||
setWalletSelectorVisible(false);
|
||||
}}
|
||||
>
|
||||
<View style={styles.walletOptionIcon}>
|
||||
<Text style={{fontSize: 24}}>👛</Text>
|
||||
</View>
|
||||
<View style={{flex: 1}}>
|
||||
<Text style={[styles.walletOptionName, isSelected && {color: KurdistanColors.kesk}]}>
|
||||
{account.name}
|
||||
</Text>
|
||||
<Text style={styles.walletOptionAddress} numberOfLines={1}>
|
||||
{account.address.slice(0, 12)}...{account.address.slice(-8)}
|
||||
</Text>
|
||||
</View>
|
||||
{isSelected && <Text style={{fontSize: 20, color: KurdistanColors.kesk}}>✓</Text>}
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={styles.deleteWalletButton}
|
||||
onPress={async () => {
|
||||
const confirmDelete = Platform.OS === 'web'
|
||||
? window.confirm(`Delete "${account.name}"?\n\nThis action cannot be undone. Make sure you have backed up your recovery phrase.`)
|
||||
: await new Promise<boolean>((resolve) => {
|
||||
Alert.alert(
|
||||
'Delete Wallet',
|
||||
`Are you sure you want to delete "${account.name}"?\n\nThis action cannot be undone. Make sure you have backed up your recovery phrase.`,
|
||||
[
|
||||
{ text: 'Cancel', style: 'cancel', onPress: () => resolve(false) },
|
||||
{ text: 'Delete', style: 'destructive', onPress: () => resolve(true) }
|
||||
]
|
||||
);
|
||||
});
|
||||
|
||||
if (confirmDelete) {
|
||||
try {
|
||||
await deleteWallet(account.address);
|
||||
if (accounts.length <= 1) {
|
||||
setWalletSelectorVisible(false);
|
||||
}
|
||||
} catch (err) {
|
||||
if (Platform.OS === 'web') {
|
||||
window.alert('Failed to delete wallet');
|
||||
} else {
|
||||
Alert.alert('Error', 'Failed to delete wallet');
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Text style={styles.deleteWalletIcon}>🗑️</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
})}
|
||||
|
||||
{/* Add New Wallet Button */}
|
||||
<TouchableOpacity
|
||||
style={styles.addNewWalletOption}
|
||||
onPress={() => {
|
||||
setWalletSelectorVisible(false);
|
||||
navigation.navigate('WalletSetup');
|
||||
}}
|
||||
>
|
||||
<View style={styles.addNewWalletIcon}>
|
||||
<Text style={{fontSize: 24, color: KurdistanColors.kesk}}>+</Text>
|
||||
</View>
|
||||
<Text style={styles.addNewWalletText}>Add New Wallet</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity style={styles.btnConfirm} onPress={() => setWalletSelectorVisible(false)}>
|
||||
<Text style={{color:'white'}}>Close</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
</Modal>
|
||||
|
||||
{/* Network Selector Modal */}
|
||||
<Modal visible={networkSelectorVisible} transparent animationType="slide" onRequestClose={() => setNetworkSelectorVisible(false)}>
|
||||
<View style={styles.modalOverlay}>
|
||||
@@ -700,6 +777,42 @@ const styles = StyleSheet.create({
|
||||
scrollContent: {
|
||||
flex: 1,
|
||||
},
|
||||
loadingContainer: {
|
||||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
loadingText: {
|
||||
marginTop: 16,
|
||||
fontSize: 16,
|
||||
color: '#666',
|
||||
},
|
||||
|
||||
// Top Header with Back Button
|
||||
topHeader: {
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 12,
|
||||
backgroundColor: '#FFFFFF',
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: '#E5E5E5',
|
||||
},
|
||||
backButton: {
|
||||
paddingVertical: 4,
|
||||
paddingRight: 8,
|
||||
},
|
||||
backButtonText: {
|
||||
fontSize: 16,
|
||||
color: KurdistanColors.kesk,
|
||||
fontWeight: '500',
|
||||
},
|
||||
topHeaderTitle: {
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
color: '#333',
|
||||
},
|
||||
|
||||
// Header Styles (New Design)
|
||||
headerContainer: {
|
||||
@@ -725,6 +838,18 @@ const styles = StyleSheet.create({
|
||||
borderRadius: 16,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
scanButton: {
|
||||
width: 40,
|
||||
height: 40,
|
||||
borderRadius: 20,
|
||||
backgroundColor: '#F5F5F5',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
scanIcon: {
|
||||
fontSize: 20,
|
||||
color: '#333',
|
||||
},
|
||||
|
||||
// Main Token Cards (HEZ & PEZ) - New Design
|
||||
mainTokensRow: {
|
||||
@@ -747,6 +872,13 @@ const styles = StyleSheet.create({
|
||||
height: 56,
|
||||
marginBottom: 12,
|
||||
},
|
||||
mainTokenLogoContainer: {
|
||||
width: 56,
|
||||
height: 56,
|
||||
marginBottom: 12,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
mainTokenSymbol: {
|
||||
fontSize: 18,
|
||||
fontWeight: 'bold',
|
||||
@@ -1071,6 +1203,140 @@ const styles = StyleSheet.create({
|
||||
color: '#666',
|
||||
lineHeight: 18,
|
||||
},
|
||||
// Wallet Selector Row
|
||||
walletSelectorRow: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 12,
|
||||
marginBottom: 8,
|
||||
},
|
||||
walletSelector: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
backgroundColor: '#FFFFFF',
|
||||
borderRadius: 12,
|
||||
padding: 12,
|
||||
marginRight: 12,
|
||||
boxShadow: '0px 2px 4px rgba(0, 0, 0, 0.05)',
|
||||
elevation: 2,
|
||||
},
|
||||
walletSelectorInfo: {
|
||||
flex: 1,
|
||||
},
|
||||
walletSelectorName: {
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
color: KurdistanColors.reş,
|
||||
},
|
||||
walletSelectorAddress: {
|
||||
fontSize: 12,
|
||||
color: '#999',
|
||||
marginTop: 2,
|
||||
},
|
||||
walletSelectorArrow: {
|
||||
fontSize: 12,
|
||||
color: '#666',
|
||||
marginLeft: 8,
|
||||
},
|
||||
walletHeaderButtons: {
|
||||
flexDirection: 'row',
|
||||
gap: 8,
|
||||
},
|
||||
addWalletButton: {
|
||||
width: 44,
|
||||
height: 44,
|
||||
borderRadius: 12,
|
||||
backgroundColor: '#FFFFFF',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
boxShadow: '0px 2px 4px rgba(0, 0, 0, 0.05)',
|
||||
elevation: 2,
|
||||
},
|
||||
addWalletIcon: {
|
||||
fontSize: 24,
|
||||
color: KurdistanColors.kesk,
|
||||
fontWeight: '300',
|
||||
},
|
||||
// Wallet Selector Modal
|
||||
walletOption: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
padding: 16,
|
||||
backgroundColor: '#F8F9FA',
|
||||
borderRadius: 12,
|
||||
marginBottom: 8,
|
||||
borderWidth: 2,
|
||||
borderColor: 'transparent',
|
||||
},
|
||||
walletOptionSelected: {
|
||||
borderColor: KurdistanColors.kesk,
|
||||
backgroundColor: 'rgba(0, 143, 67, 0.05)',
|
||||
},
|
||||
walletOptionIcon: {
|
||||
width: 48,
|
||||
height: 48,
|
||||
borderRadius: 24,
|
||||
backgroundColor: '#FFFFFF',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginRight: 12,
|
||||
},
|
||||
walletOptionName: {
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
color: KurdistanColors.reş,
|
||||
},
|
||||
walletOptionAddress: {
|
||||
fontSize: 12,
|
||||
color: '#999',
|
||||
marginTop: 2,
|
||||
},
|
||||
addNewWalletOption: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
padding: 16,
|
||||
backgroundColor: 'rgba(0, 143, 67, 0.05)',
|
||||
borderRadius: 12,
|
||||
marginBottom: 16,
|
||||
borderWidth: 2,
|
||||
borderColor: KurdistanColors.kesk,
|
||||
borderStyle: 'dashed',
|
||||
},
|
||||
addNewWalletIcon: {
|
||||
width: 48,
|
||||
height: 48,
|
||||
borderRadius: 24,
|
||||
backgroundColor: '#FFFFFF',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginRight: 12,
|
||||
},
|
||||
addNewWalletText: {
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
color: KurdistanColors.kesk,
|
||||
},
|
||||
// Delete wallet
|
||||
walletOptionRow: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
marginBottom: 8,
|
||||
gap: 8,
|
||||
},
|
||||
deleteWalletButton: {
|
||||
width: 44,
|
||||
height: 44,
|
||||
borderRadius: 12,
|
||||
backgroundColor: 'rgba(239, 68, 68, 0.1)',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
deleteWalletIcon: {
|
||||
fontSize: 18,
|
||||
},
|
||||
});
|
||||
|
||||
export default WalletScreen;
|
||||
@@ -0,0 +1,820 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
StyleSheet,
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
TextInput,
|
||||
ActivityIndicator,
|
||||
Alert,
|
||||
Platform,
|
||||
} from 'react-native';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { KurdistanColors } from '../theme/colors';
|
||||
import { usePezkuwi } from '../contexts/PezkuwiContext';
|
||||
import { mnemonicGenerate, mnemonicValidate } from '@pezkuwi/util-crypto';
|
||||
|
||||
// Cross-platform alert helper
|
||||
const showAlert = (title: string, message: string, buttons?: Array<{text: string; onPress?: () => void; style?: string}>) => {
|
||||
if (Platform.OS === 'web') {
|
||||
window.alert(`${title}\n\n${message}`);
|
||||
if (buttons?.[0]?.onPress) buttons[0].onPress();
|
||||
} else {
|
||||
Alert.alert(title, message, buttons as any);
|
||||
}
|
||||
};
|
||||
|
||||
type SetupStep = 'choice' | 'create-show' | 'create-verify' | 'import' | 'wallet-name' | 'success';
|
||||
|
||||
const WalletSetupScreen: React.FC = () => {
|
||||
const navigation = useNavigation<any>();
|
||||
const { createWallet, importWallet, connectWallet, isReady } = usePezkuwi();
|
||||
|
||||
const [step, setStep] = useState<SetupStep>('choice');
|
||||
const [mnemonic, setMnemonic] = useState<string[]>([]);
|
||||
const [walletName, setWalletName] = useState('');
|
||||
const [importMnemonic, setImportMnemonic] = useState('');
|
||||
const [verificationIndices, setVerificationIndices] = useState<number[]>([]);
|
||||
const [selectedWords, setSelectedWords] = useState<{[key: number]: string}>({});
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [createdAddress, setCreatedAddress] = useState('');
|
||||
const [isCreateFlow, setIsCreateFlow] = useState(true);
|
||||
|
||||
// Generate mnemonic when entering create flow
|
||||
const handleCreateNew = () => {
|
||||
const generatedMnemonic = mnemonicGenerate(12);
|
||||
setMnemonic(generatedMnemonic.split(' '));
|
||||
setIsCreateFlow(true);
|
||||
setStep('create-show');
|
||||
};
|
||||
|
||||
// Go to import flow
|
||||
const handleImport = () => {
|
||||
setIsCreateFlow(false);
|
||||
setStep('import');
|
||||
};
|
||||
|
||||
// After showing mnemonic, go to verification
|
||||
const handleMnemonicConfirmed = () => {
|
||||
// Select 3 random indices for verification
|
||||
const indices: number[] = [];
|
||||
while (indices.length < 3) {
|
||||
const randomIndex = Math.floor(Math.random() * 12);
|
||||
if (!indices.includes(randomIndex)) {
|
||||
indices.push(randomIndex);
|
||||
}
|
||||
}
|
||||
indices.sort((a, b) => a - b);
|
||||
setVerificationIndices(indices);
|
||||
setSelectedWords({});
|
||||
setStep('create-verify');
|
||||
};
|
||||
|
||||
// Verify selected words
|
||||
const handleVerifyWord = (index: number, word: string) => {
|
||||
setSelectedWords(prev => ({ ...prev, [index]: word }));
|
||||
};
|
||||
|
||||
// Check if verification is complete and correct
|
||||
const isVerificationComplete = () => {
|
||||
return verificationIndices.every(idx => selectedWords[idx] === mnemonic[idx]);
|
||||
};
|
||||
|
||||
// After verification, go to wallet name
|
||||
const handleVerificationComplete = () => {
|
||||
if (!isVerificationComplete()) {
|
||||
showAlert('Incorrect', 'The words you selected do not match. Please try again.');
|
||||
setSelectedWords({});
|
||||
return;
|
||||
}
|
||||
setStep('wallet-name');
|
||||
};
|
||||
|
||||
// Create wallet with name
|
||||
const handleCreateWallet = async () => {
|
||||
if (!walletName.trim()) {
|
||||
showAlert('Error', 'Please enter a wallet name');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isReady) {
|
||||
showAlert('Error', 'Crypto libraries are still loading. Please wait a moment and try again.');
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const { address } = await createWallet(walletName.trim(), mnemonic.join(' '));
|
||||
setCreatedAddress(address);
|
||||
await connectWallet();
|
||||
setStep('success');
|
||||
} catch (error: any) {
|
||||
console.error('[WalletSetup] Create wallet error:', error);
|
||||
showAlert('Error', error.message || 'Failed to create wallet');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Import wallet with mnemonic or dev URI (like //Alice)
|
||||
const handleImportWallet = async () => {
|
||||
const trimmedInput = importMnemonic.trim();
|
||||
|
||||
// Check if it's a dev URI (starts with //)
|
||||
if (trimmedInput.startsWith('//')) {
|
||||
// Dev URI like //Alice, //Bob, etc.
|
||||
setMnemonic([trimmedInput]); // Store as single-element array to indicate URI
|
||||
setStep('wallet-name');
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise treat as mnemonic
|
||||
const words = trimmedInput.toLowerCase().split(/\s+/);
|
||||
|
||||
if (words.length !== 12 && words.length !== 24) {
|
||||
showAlert('Invalid Input', 'Please enter a valid 12 or 24 word recovery phrase, or a dev URI like //Alice');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mnemonicValidate(trimmedInput.toLowerCase())) {
|
||||
showAlert('Invalid Mnemonic', 'The recovery phrase is invalid. Please check and try again.');
|
||||
return;
|
||||
}
|
||||
|
||||
setMnemonic(words);
|
||||
setStep('wallet-name');
|
||||
};
|
||||
|
||||
// After naming imported wallet
|
||||
const handleImportComplete = async () => {
|
||||
if (!walletName.trim()) {
|
||||
showAlert('Error', 'Please enter a wallet name');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isReady) {
|
||||
showAlert('Error', 'Crypto libraries are still loading. Please wait a moment and try again.');
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoading(true);
|
||||
try {
|
||||
const { address } = await importWallet(walletName.trim(), mnemonic.join(' '));
|
||||
setCreatedAddress(address);
|
||||
await connectWallet();
|
||||
setStep('success');
|
||||
} catch (error: any) {
|
||||
console.error('[WalletSetup] Import wallet error:', error);
|
||||
showAlert('Error', error.message || 'Failed to import wallet');
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// Finish setup and go to wallet
|
||||
const handleFinish = () => {
|
||||
navigation.replace('Wallet');
|
||||
};
|
||||
|
||||
// Go back to previous step
|
||||
const handleBack = () => {
|
||||
switch (step) {
|
||||
case 'create-show':
|
||||
case 'import':
|
||||
setStep('choice');
|
||||
break;
|
||||
case 'create-verify':
|
||||
setStep('create-show');
|
||||
break;
|
||||
case 'wallet-name':
|
||||
if (isCreateFlow) {
|
||||
setStep('create-verify');
|
||||
} else {
|
||||
setStep('import');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
navigation.goBack();
|
||||
}
|
||||
};
|
||||
|
||||
// Generate shuffled words for verification options
|
||||
const getShuffledOptions = (correctWord: string): string[] => {
|
||||
const allWords = [...mnemonic];
|
||||
const options = [correctWord];
|
||||
|
||||
while (options.length < 4) {
|
||||
const randomWord = allWords[Math.floor(Math.random() * allWords.length)];
|
||||
if (!options.includes(randomWord)) {
|
||||
options.push(randomWord);
|
||||
}
|
||||
}
|
||||
|
||||
// Shuffle options
|
||||
return options.sort(() => Math.random() - 0.5);
|
||||
};
|
||||
|
||||
// ============================================================
|
||||
// RENDER FUNCTIONS
|
||||
// ============================================================
|
||||
|
||||
const renderChoiceStep = () => (
|
||||
<View style={styles.stepContainer} testID="wallet-setup-choice">
|
||||
<View style={styles.iconContainer}>
|
||||
<Text style={styles.mainIcon}>👛</Text>
|
||||
</View>
|
||||
|
||||
<Text style={styles.title}>Set Up Your Wallet</Text>
|
||||
<Text style={styles.subtitle}>
|
||||
Create a new wallet or import an existing one using your recovery phrase
|
||||
</Text>
|
||||
|
||||
<View style={styles.choiceButtons}>
|
||||
<TouchableOpacity
|
||||
style={styles.choiceButton}
|
||||
onPress={handleCreateNew}
|
||||
testID="wallet-setup-create-button"
|
||||
>
|
||||
<LinearGradient
|
||||
colors={[KurdistanColors.kesk, '#008f43']}
|
||||
style={styles.choiceButtonGradient}
|
||||
>
|
||||
<Text style={styles.choiceButtonIcon}>✨</Text>
|
||||
<Text style={styles.choiceButtonTitle}>Create New Wallet</Text>
|
||||
<Text style={styles.choiceButtonSubtitle}>
|
||||
Generate a new recovery phrase
|
||||
</Text>
|
||||
</LinearGradient>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity
|
||||
style={styles.choiceButton}
|
||||
onPress={handleImport}
|
||||
testID="wallet-setup-import-button"
|
||||
>
|
||||
<View style={styles.choiceButtonOutline}>
|
||||
<Text style={styles.choiceButtonIcon}>📥</Text>
|
||||
<Text style={[styles.choiceButtonTitle, { color: KurdistanColors.reş }]}>
|
||||
Import Existing Wallet
|
||||
</Text>
|
||||
<Text style={[styles.choiceButtonSubtitle, { color: '#666' }]}>
|
||||
Use your 12 or 24 word phrase
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
const renderCreateShowStep = () => (
|
||||
<View style={styles.stepContainer} testID="wallet-setup-show-seed">
|
||||
<Text style={styles.title}>Your Recovery Phrase</Text>
|
||||
<Text style={styles.subtitle}>
|
||||
Write down these 12 words in order and keep them safe. This is the only way to recover your wallet.
|
||||
</Text>
|
||||
|
||||
<View style={styles.warningBox}>
|
||||
<Text style={styles.warningIcon}>⚠️</Text>
|
||||
<Text style={styles.warningText}>
|
||||
Never share your recovery phrase with anyone. Anyone with these words can access your funds.
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.mnemonicGrid} testID="mnemonic-grid">
|
||||
{mnemonic.map((word, index) => (
|
||||
<View key={index} style={styles.wordCard}>
|
||||
<Text style={styles.wordNumber}>{index + 1}</Text>
|
||||
<Text style={styles.wordText}>{word}</Text>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
|
||||
<TouchableOpacity
|
||||
style={styles.primaryButton}
|
||||
onPress={handleMnemonicConfirmed}
|
||||
testID="wallet-setup-continue-button"
|
||||
>
|
||||
<Text style={styles.primaryButtonText}>I've Written It Down</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
|
||||
const renderCreateVerifyStep = () => (
|
||||
<View style={styles.stepContainer} testID="wallet-setup-verify-seed">
|
||||
<Text style={styles.title}>Verify Your Phrase</Text>
|
||||
<Text style={styles.subtitle}>
|
||||
Select the correct words to verify you've saved your recovery phrase
|
||||
</Text>
|
||||
|
||||
<View style={styles.verificationContainer}>
|
||||
{verificationIndices.map((wordIndex) => (
|
||||
<View key={wordIndex} style={styles.verificationItem}>
|
||||
<Text style={styles.verificationLabel}>Word #{wordIndex + 1}</Text>
|
||||
<View style={styles.verificationOptions}>
|
||||
{getShuffledOptions(mnemonic[wordIndex]).map((option, optIdx) => (
|
||||
<TouchableOpacity
|
||||
key={optIdx}
|
||||
style={[
|
||||
styles.verificationOption,
|
||||
selectedWords[wordIndex] === option && styles.verificationOptionSelected,
|
||||
selectedWords[wordIndex] === option &&
|
||||
selectedWords[wordIndex] === mnemonic[wordIndex] && styles.verificationOptionCorrect,
|
||||
]}
|
||||
onPress={() => handleVerifyWord(wordIndex, option)}
|
||||
testID={`verify-option-${wordIndex}-${optIdx}`}
|
||||
>
|
||||
<Text style={[
|
||||
styles.verificationOptionText,
|
||||
selectedWords[wordIndex] === option && styles.verificationOptionTextSelected,
|
||||
]}>
|
||||
{option}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.primaryButton,
|
||||
!Object.keys(selectedWords).length && styles.primaryButtonDisabled
|
||||
]}
|
||||
onPress={handleVerificationComplete}
|
||||
disabled={Object.keys(selectedWords).length !== 3}
|
||||
testID="wallet-setup-verify-button"
|
||||
>
|
||||
<Text style={styles.primaryButtonText}>Verify & Continue</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
|
||||
const renderImportStep = () => (
|
||||
<View style={styles.stepContainer} testID="wallet-setup-import">
|
||||
<Text style={styles.title}>Import Wallet</Text>
|
||||
<Text style={styles.subtitle}>
|
||||
Enter your 12 or 24 word recovery phrase, or a dev URI like //Alice
|
||||
</Text>
|
||||
|
||||
<View style={styles.importInputContainer}>
|
||||
<TextInput
|
||||
style={styles.importInput}
|
||||
placeholder="Enter recovery phrase or //Alice..."
|
||||
placeholderTextColor="#999"
|
||||
multiline
|
||||
numberOfLines={4}
|
||||
value={importMnemonic}
|
||||
onChangeText={setImportMnemonic}
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
testID="wallet-import-input"
|
||||
/>
|
||||
<Text style={styles.importHint}>
|
||||
Mnemonic: separate words with space | Dev URI: //Alice, //Bob, etc.
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.primaryButton,
|
||||
!importMnemonic.trim() && styles.primaryButtonDisabled
|
||||
]}
|
||||
onPress={handleImportWallet}
|
||||
disabled={!importMnemonic.trim()}
|
||||
testID="wallet-import-continue-button"
|
||||
>
|
||||
<Text style={styles.primaryButtonText}>Continue</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
|
||||
const renderWalletNameStep = () => (
|
||||
<View style={styles.stepContainer} testID="wallet-setup-name">
|
||||
<Text style={styles.title}>Name Your Wallet</Text>
|
||||
<Text style={styles.subtitle}>
|
||||
Give your wallet a name to easily identify it
|
||||
</Text>
|
||||
|
||||
<View style={styles.nameInputContainer}>
|
||||
<TextInput
|
||||
style={styles.nameInput}
|
||||
placeholder="e.g., My Main Wallet"
|
||||
placeholderTextColor="#999"
|
||||
value={walletName}
|
||||
onChangeText={setWalletName}
|
||||
autoCapitalize="words"
|
||||
maxLength={30}
|
||||
testID="wallet-name-input"
|
||||
/>
|
||||
</View>
|
||||
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.primaryButton,
|
||||
(!walletName.trim() || isLoading) && styles.primaryButtonDisabled
|
||||
]}
|
||||
onPress={isCreateFlow ? handleCreateWallet : handleImportComplete}
|
||||
disabled={!walletName.trim() || isLoading}
|
||||
testID="wallet-setup-finish-button"
|
||||
>
|
||||
{isLoading ? (
|
||||
<ActivityIndicator color="#FFFFFF" />
|
||||
) : (
|
||||
<Text style={styles.primaryButtonText}>
|
||||
{isCreateFlow ? 'Create Wallet' : 'Import Wallet'}
|
||||
</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
|
||||
const renderSuccessStep = () => (
|
||||
<View style={styles.stepContainer} testID="wallet-setup-success">
|
||||
<View style={styles.successIconContainer}>
|
||||
<Text style={styles.successIcon}>✅</Text>
|
||||
</View>
|
||||
|
||||
<Text style={styles.title}>Wallet Created!</Text>
|
||||
<Text style={styles.subtitle}>
|
||||
Your wallet is ready to use. You can now send and receive tokens.
|
||||
</Text>
|
||||
|
||||
<View style={styles.addressBox}>
|
||||
<Text style={styles.addressLabel}>Your Wallet Address</Text>
|
||||
<Text style={styles.addressText} numberOfLines={1} ellipsizeMode="middle">
|
||||
{createdAddress}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<TouchableOpacity
|
||||
style={styles.primaryButton}
|
||||
onPress={handleFinish}
|
||||
testID="wallet-setup-done-button"
|
||||
>
|
||||
<Text style={styles.primaryButtonText}>Go to Wallet</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
|
||||
const renderStep = () => {
|
||||
switch (step) {
|
||||
case 'choice':
|
||||
return renderChoiceStep();
|
||||
case 'create-show':
|
||||
return renderCreateShowStep();
|
||||
case 'create-verify':
|
||||
return renderCreateVerifyStep();
|
||||
case 'import':
|
||||
return renderImportStep();
|
||||
case 'wallet-name':
|
||||
return renderWalletNameStep();
|
||||
case 'success':
|
||||
return renderSuccessStep();
|
||||
default:
|
||||
return renderChoiceStep();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container} testID="wallet-setup-screen">
|
||||
{/* Header */}
|
||||
{step !== 'choice' && step !== 'success' && (
|
||||
<View style={styles.header}>
|
||||
<TouchableOpacity onPress={handleBack} style={styles.backButton} testID="wallet-setup-back">
|
||||
<Text style={styles.backButtonText}>← Back</Text>
|
||||
</TouchableOpacity>
|
||||
<View style={styles.progressContainer}>
|
||||
{['create-show', 'create-verify', 'wallet-name'].includes(step) && isCreateFlow && (
|
||||
<>
|
||||
<View style={[styles.progressDot, step === 'create-show' && styles.progressDotActive]} />
|
||||
<View style={[styles.progressDot, step === 'create-verify' && styles.progressDotActive]} />
|
||||
<View style={[styles.progressDot, step === 'wallet-name' && styles.progressDotActive]} />
|
||||
</>
|
||||
)}
|
||||
{['import', 'wallet-name'].includes(step) && !isCreateFlow && (
|
||||
<>
|
||||
<View style={[styles.progressDot, step === 'import' && styles.progressDotActive]} />
|
||||
<View style={[styles.progressDot, step === 'wallet-name' && styles.progressDotActive]} />
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
<View style={styles.headerSpacer} />
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* Close button on choice screen */}
|
||||
{step === 'choice' && (
|
||||
<View style={styles.header}>
|
||||
<TouchableOpacity onPress={() => navigation.goBack()} style={styles.closeButton} testID="wallet-setup-close">
|
||||
<Text style={styles.closeButtonText}>✕</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
)}
|
||||
|
||||
<ScrollView
|
||||
style={styles.content}
|
||||
contentContainerStyle={styles.contentContainer}
|
||||
showsVerticalScrollIndicator={false}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
>
|
||||
{renderStep()}
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#FFFFFF',
|
||||
},
|
||||
header: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 12,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: '#F0F0F0',
|
||||
},
|
||||
backButton: {
|
||||
paddingVertical: 4,
|
||||
paddingRight: 16,
|
||||
},
|
||||
backButtonText: {
|
||||
fontSize: 16,
|
||||
color: KurdistanColors.kesk,
|
||||
fontWeight: '500',
|
||||
},
|
||||
closeButton: {
|
||||
width: 32,
|
||||
height: 32,
|
||||
borderRadius: 16,
|
||||
backgroundColor: '#F5F5F5',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
closeButtonText: {
|
||||
fontSize: 18,
|
||||
color: '#666',
|
||||
},
|
||||
progressContainer: {
|
||||
flexDirection: 'row',
|
||||
gap: 8,
|
||||
},
|
||||
progressDot: {
|
||||
width: 8,
|
||||
height: 8,
|
||||
borderRadius: 4,
|
||||
backgroundColor: '#E0E0E0',
|
||||
},
|
||||
progressDotActive: {
|
||||
backgroundColor: KurdistanColors.kesk,
|
||||
},
|
||||
headerSpacer: {
|
||||
width: 60,
|
||||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
},
|
||||
contentContainer: {
|
||||
padding: 24,
|
||||
paddingBottom: 40,
|
||||
},
|
||||
stepContainer: {
|
||||
flex: 1,
|
||||
},
|
||||
iconContainer: {
|
||||
alignItems: 'center',
|
||||
marginBottom: 24,
|
||||
marginTop: 20,
|
||||
},
|
||||
mainIcon: {
|
||||
fontSize: 80,
|
||||
},
|
||||
title: {
|
||||
fontSize: 28,
|
||||
fontWeight: 'bold',
|
||||
color: KurdistanColors.reş,
|
||||
textAlign: 'center',
|
||||
marginBottom: 12,
|
||||
},
|
||||
subtitle: {
|
||||
fontSize: 16,
|
||||
color: '#666',
|
||||
textAlign: 'center',
|
||||
lineHeight: 24,
|
||||
marginBottom: 32,
|
||||
},
|
||||
|
||||
// Choice buttons
|
||||
choiceButtons: {
|
||||
gap: 16,
|
||||
},
|
||||
choiceButton: {
|
||||
borderRadius: 16,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
choiceButtonGradient: {
|
||||
padding: 24,
|
||||
alignItems: 'center',
|
||||
},
|
||||
choiceButtonOutline: {
|
||||
padding: 24,
|
||||
alignItems: 'center',
|
||||
borderWidth: 2,
|
||||
borderColor: '#E0E0E0',
|
||||
borderRadius: 16,
|
||||
},
|
||||
choiceButtonIcon: {
|
||||
fontSize: 40,
|
||||
marginBottom: 12,
|
||||
},
|
||||
choiceButtonTitle: {
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
color: '#FFFFFF',
|
||||
marginBottom: 4,
|
||||
},
|
||||
choiceButtonSubtitle: {
|
||||
fontSize: 14,
|
||||
color: 'rgba(255,255,255,0.8)',
|
||||
},
|
||||
|
||||
// Warning box
|
||||
warningBox: {
|
||||
flexDirection: 'row',
|
||||
backgroundColor: '#FFF3CD',
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
marginBottom: 24,
|
||||
alignItems: 'flex-start',
|
||||
},
|
||||
warningIcon: {
|
||||
fontSize: 20,
|
||||
marginRight: 12,
|
||||
},
|
||||
warningText: {
|
||||
flex: 1,
|
||||
fontSize: 14,
|
||||
color: '#856404',
|
||||
lineHeight: 20,
|
||||
},
|
||||
|
||||
// Mnemonic grid
|
||||
mnemonicGrid: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
justifyContent: 'space-between',
|
||||
marginBottom: 32,
|
||||
},
|
||||
wordCard: {
|
||||
width: '31%',
|
||||
backgroundColor: '#F8F9FA',
|
||||
borderRadius: 12,
|
||||
padding: 12,
|
||||
marginBottom: 12,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
},
|
||||
wordNumber: {
|
||||
fontSize: 12,
|
||||
color: '#999',
|
||||
marginRight: 8,
|
||||
minWidth: 20,
|
||||
},
|
||||
wordText: {
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
color: KurdistanColors.reş,
|
||||
},
|
||||
|
||||
// Verification
|
||||
verificationContainer: {
|
||||
marginBottom: 32,
|
||||
},
|
||||
verificationItem: {
|
||||
marginBottom: 24,
|
||||
},
|
||||
verificationLabel: {
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
color: KurdistanColors.reş,
|
||||
marginBottom: 12,
|
||||
},
|
||||
verificationOptions: {
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
gap: 10,
|
||||
},
|
||||
verificationOption: {
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 10,
|
||||
borderRadius: 20,
|
||||
backgroundColor: '#F5F5F5',
|
||||
borderWidth: 2,
|
||||
borderColor: 'transparent',
|
||||
},
|
||||
verificationOptionSelected: {
|
||||
borderColor: KurdistanColors.kesk,
|
||||
backgroundColor: 'rgba(0, 143, 67, 0.1)',
|
||||
},
|
||||
verificationOptionCorrect: {
|
||||
borderColor: KurdistanColors.kesk,
|
||||
backgroundColor: 'rgba(0, 143, 67, 0.15)',
|
||||
},
|
||||
verificationOptionText: {
|
||||
fontSize: 14,
|
||||
color: '#333',
|
||||
},
|
||||
verificationOptionTextSelected: {
|
||||
color: KurdistanColors.kesk,
|
||||
fontWeight: '600',
|
||||
},
|
||||
|
||||
// Import
|
||||
importInputContainer: {
|
||||
marginBottom: 32,
|
||||
},
|
||||
importInput: {
|
||||
backgroundColor: '#F8F9FA',
|
||||
borderRadius: 16,
|
||||
padding: 16,
|
||||
fontSize: 16,
|
||||
color: KurdistanColors.reş,
|
||||
minHeight: 120,
|
||||
textAlignVertical: 'top',
|
||||
borderWidth: 1,
|
||||
borderColor: '#E0E0E0',
|
||||
},
|
||||
importHint: {
|
||||
fontSize: 12,
|
||||
color: '#999',
|
||||
marginTop: 8,
|
||||
marginLeft: 4,
|
||||
},
|
||||
|
||||
// Wallet name
|
||||
nameInputContainer: {
|
||||
marginBottom: 32,
|
||||
},
|
||||
nameInput: {
|
||||
backgroundColor: '#F8F9FA',
|
||||
borderRadius: 16,
|
||||
padding: 16,
|
||||
fontSize: 18,
|
||||
color: KurdistanColors.reş,
|
||||
borderWidth: 1,
|
||||
borderColor: '#E0E0E0',
|
||||
textAlign: 'center',
|
||||
},
|
||||
|
||||
// Primary button
|
||||
primaryButton: {
|
||||
backgroundColor: KurdistanColors.kesk,
|
||||
borderRadius: 16,
|
||||
padding: 18,
|
||||
alignItems: 'center',
|
||||
},
|
||||
primaryButtonDisabled: {
|
||||
opacity: 0.5,
|
||||
},
|
||||
primaryButtonText: {
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
color: '#FFFFFF',
|
||||
},
|
||||
|
||||
// Success
|
||||
successIconContainer: {
|
||||
alignItems: 'center',
|
||||
marginBottom: 24,
|
||||
marginTop: 40,
|
||||
},
|
||||
successIcon: {
|
||||
fontSize: 80,
|
||||
},
|
||||
addressBox: {
|
||||
backgroundColor: '#F8F9FA',
|
||||
borderRadius: 16,
|
||||
padding: 20,
|
||||
marginBottom: 32,
|
||||
alignItems: 'center',
|
||||
},
|
||||
addressLabel: {
|
||||
fontSize: 12,
|
||||
color: '#999',
|
||||
marginBottom: 8,
|
||||
},
|
||||
addressText: {
|
||||
fontSize: 14,
|
||||
fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
|
||||
color: KurdistanColors.reş,
|
||||
},
|
||||
});
|
||||
|
||||
export default WalletSetupScreen;
|
||||
@@ -10,7 +10,6 @@ import {
|
||||
Image,
|
||||
} from 'react-native';
|
||||
import { LinearGradient } from 'expo-linear-gradient';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import { KurdistanColors } from '../theme/colors';
|
||||
import PrivacyPolicyModal from '../components/PrivacyPolicyModal';
|
||||
@@ -21,7 +20,6 @@ interface WelcomeScreenProps {
|
||||
}
|
||||
|
||||
const WelcomeScreen: React.FC<WelcomeScreenProps> = ({ onContinue }) => {
|
||||
const { t } = useTranslation();
|
||||
const [agreed, setAgreed] = useState(false);
|
||||
const [privacyModalVisible, setPrivacyModalVisible] = useState(false);
|
||||
const [termsModalVisible, setTermsModalVisible] = useState(false);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import { LanguageProvider } from '../../contexts/LanguageContext';
|
||||
import { PezkuwiProvider } from '../contexts/PezkuwiContext';
|
||||
import BeCitizenScreen from '../BeCitizenScreen';
|
||||
|
||||
@@ -10,11 +9,9 @@ jest.mock('@react-navigation/native', () => ({
|
||||
}));
|
||||
|
||||
const BeCitizenScreenWrapper = () => (
|
||||
<LanguageProvider>
|
||||
<PezkuwiProvider>
|
||||
<BeCitizenScreen />
|
||||
</PezkuwiProvider>
|
||||
</LanguageProvider>
|
||||
<PezkuwiProvider>
|
||||
<BeCitizenScreen />
|
||||
</PezkuwiProvider>
|
||||
);
|
||||
|
||||
describe('BeCitizenScreen', () => {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import { LanguageProvider } from '../../contexts/LanguageContext';
|
||||
import { PezkuwiProvider } from '../contexts/PezkuwiContext';
|
||||
import EducationScreen from '../EducationScreen';
|
||||
|
||||
@@ -10,11 +9,9 @@ jest.mock('@react-navigation/native', () => ({
|
||||
}));
|
||||
|
||||
const EducationScreenWrapper = () => (
|
||||
<LanguageProvider>
|
||||
<PezkuwiProvider>
|
||||
<EducationScreen />
|
||||
</PezkuwiProvider>
|
||||
</LanguageProvider>
|
||||
<PezkuwiProvider>
|
||||
<EducationScreen />
|
||||
</PezkuwiProvider>
|
||||
);
|
||||
|
||||
describe('EducationScreen', () => {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import { LanguageProvider } from '../../contexts/LanguageContext';
|
||||
import { AuthProvider } from '../../contexts/AuthContext';
|
||||
import ForumScreen from '../ForumScreen';
|
||||
|
||||
@@ -10,11 +9,9 @@ jest.mock('@react-navigation/native', () => ({
|
||||
}));
|
||||
|
||||
const ForumScreenWrapper = () => (
|
||||
<LanguageProvider>
|
||||
<AuthProvider>
|
||||
<ForumScreen />
|
||||
</AuthProvider>
|
||||
</LanguageProvider>
|
||||
<AuthProvider>
|
||||
<ForumScreen />
|
||||
</AuthProvider>
|
||||
);
|
||||
|
||||
describe('ForumScreen', () => {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import { LanguageProvider } from '../../contexts/LanguageContext';
|
||||
import { PezkuwiProvider } from '../contexts/PezkuwiContext';
|
||||
import GovernanceScreen from '../GovernanceScreen';
|
||||
|
||||
@@ -10,11 +9,9 @@ jest.mock('@react-navigation/native', () => ({
|
||||
}));
|
||||
|
||||
const GovernanceScreenWrapper = () => (
|
||||
<LanguageProvider>
|
||||
<PezkuwiProvider>
|
||||
<GovernanceScreen />
|
||||
</PezkuwiProvider>
|
||||
</LanguageProvider>
|
||||
<PezkuwiProvider>
|
||||
<GovernanceScreen />
|
||||
</PezkuwiProvider>
|
||||
);
|
||||
|
||||
describe('GovernanceScreen', () => {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import { LanguageProvider } from '../../contexts/LanguageContext';
|
||||
import { BiometricAuthProvider } from '../../contexts/BiometricAuthContext';
|
||||
import LockScreen from '../LockScreen';
|
||||
|
||||
@@ -10,11 +9,9 @@ jest.mock('@react-navigation/native', () => ({
|
||||
}));
|
||||
|
||||
const LockScreenWrapper = () => (
|
||||
<LanguageProvider>
|
||||
<BiometricAuthProvider>
|
||||
<LockScreen />
|
||||
</BiometricAuthProvider>
|
||||
</LanguageProvider>
|
||||
<BiometricAuthProvider>
|
||||
<LockScreen />
|
||||
</BiometricAuthProvider>
|
||||
);
|
||||
|
||||
describe('LockScreen', () => {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import { LanguageProvider } from '../../contexts/LanguageContext';
|
||||
import { PezkuwiProvider } from '../contexts/PezkuwiContext';
|
||||
import NFTGalleryScreen from '../NFTGalleryScreen';
|
||||
|
||||
@@ -10,11 +9,9 @@ jest.mock('@react-navigation/native', () => ({
|
||||
}));
|
||||
|
||||
const NFTGalleryScreenWrapper = () => (
|
||||
<LanguageProvider>
|
||||
<PezkuwiProvider>
|
||||
<NFTGalleryScreen />
|
||||
</PezkuwiProvider>
|
||||
</LanguageProvider>
|
||||
<PezkuwiProvider>
|
||||
<NFTGalleryScreen />
|
||||
</PezkuwiProvider>
|
||||
);
|
||||
|
||||
describe('NFTGalleryScreen', () => {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import { LanguageProvider } from '../../contexts/LanguageContext';
|
||||
import { PezkuwiProvider } from '../contexts/PezkuwiContext';
|
||||
import P2PScreen from '../P2PScreen';
|
||||
|
||||
@@ -11,11 +10,9 @@ jest.mock('@react-navigation/native', () => ({
|
||||
|
||||
// Wrapper with required providers
|
||||
const P2PScreenWrapper = () => (
|
||||
<LanguageProvider>
|
||||
<PezkuwiProvider>
|
||||
<P2PScreen />
|
||||
</PezkuwiProvider>
|
||||
</LanguageProvider>
|
||||
<PezkuwiProvider>
|
||||
<P2PScreen />
|
||||
</PezkuwiProvider>
|
||||
);
|
||||
|
||||
describe('P2PScreen', () => {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import { LanguageProvider } from '../../contexts/LanguageContext';
|
||||
import ProfileScreen from '../ProfileScreen';
|
||||
|
||||
jest.mock('@react-navigation/native', () => ({
|
||||
@@ -9,9 +8,7 @@ jest.mock('@react-navigation/native', () => ({
|
||||
}));
|
||||
|
||||
const ProfileScreenWrapper = () => (
|
||||
<LanguageProvider>
|
||||
<ProfileScreen />
|
||||
</LanguageProvider>
|
||||
<ProfileScreen />
|
||||
);
|
||||
|
||||
describe('ProfileScreen', () => {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import { LanguageProvider } from '../../contexts/LanguageContext';
|
||||
import { PezkuwiProvider } from '../contexts/PezkuwiContext';
|
||||
import ReferralScreen from '../ReferralScreen';
|
||||
|
||||
@@ -10,11 +9,9 @@ jest.mock('@react-navigation/native', () => ({
|
||||
}));
|
||||
|
||||
const ReferralScreenWrapper = () => (
|
||||
<LanguageProvider>
|
||||
<PezkuwiProvider>
|
||||
<ReferralScreen />
|
||||
</PezkuwiProvider>
|
||||
</LanguageProvider>
|
||||
<PezkuwiProvider>
|
||||
<ReferralScreen />
|
||||
</PezkuwiProvider>
|
||||
);
|
||||
|
||||
describe('ReferralScreen', () => {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import { LanguageProvider } from '../../contexts/LanguageContext';
|
||||
import { BiometricAuthProvider } from '../../contexts/BiometricAuthContext';
|
||||
import SecurityScreen from '../SecurityScreen';
|
||||
|
||||
@@ -10,11 +9,9 @@ jest.mock('@react-navigation/native', () => ({
|
||||
}));
|
||||
|
||||
const SecurityScreenWrapper = () => (
|
||||
<LanguageProvider>
|
||||
<BiometricAuthProvider>
|
||||
<SecurityScreen />
|
||||
</BiometricAuthProvider>
|
||||
</LanguageProvider>
|
||||
<BiometricAuthProvider>
|
||||
<SecurityScreen />
|
||||
</BiometricAuthProvider>
|
||||
);
|
||||
|
||||
describe('SecurityScreen', () => {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import { AuthProvider } from '../../contexts/AuthContext';
|
||||
import { LanguageProvider } from '../../contexts/LanguageContext';
|
||||
import SignInScreen from '../SignInScreen';
|
||||
|
||||
jest.mock('@react-navigation/native', () => ({
|
||||
@@ -11,11 +10,9 @@ jest.mock('@react-navigation/native', () => ({
|
||||
|
||||
// Wrapper with required providers
|
||||
const SignInScreenWrapper = () => (
|
||||
<LanguageProvider>
|
||||
<AuthProvider>
|
||||
<SignInScreen />
|
||||
</AuthProvider>
|
||||
</LanguageProvider>
|
||||
<AuthProvider>
|
||||
<SignInScreen />
|
||||
</AuthProvider>
|
||||
);
|
||||
|
||||
describe('SignInScreen', () => {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import { AuthProvider } from '../../contexts/AuthContext';
|
||||
import { LanguageProvider } from '../../contexts/LanguageContext';
|
||||
import SignUpScreen from '../SignUpScreen';
|
||||
|
||||
jest.mock('@react-navigation/native', () => ({
|
||||
@@ -11,11 +10,9 @@ jest.mock('@react-navigation/native', () => ({
|
||||
|
||||
// Wrapper with required providers
|
||||
const SignUpScreenWrapper = () => (
|
||||
<LanguageProvider>
|
||||
<AuthProvider>
|
||||
<SignUpScreen />
|
||||
</AuthProvider>
|
||||
</LanguageProvider>
|
||||
<AuthProvider>
|
||||
<SignUpScreen />
|
||||
</AuthProvider>
|
||||
);
|
||||
|
||||
describe('SignUpScreen', () => {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import { LanguageProvider } from '../../contexts/LanguageContext';
|
||||
import { PezkuwiProvider } from '../contexts/PezkuwiContext';
|
||||
import StakingScreen from '../StakingScreen';
|
||||
|
||||
@@ -10,11 +9,9 @@ jest.mock('@react-navigation/native', () => ({
|
||||
}));
|
||||
|
||||
const StakingScreenWrapper = () => (
|
||||
<LanguageProvider>
|
||||
<PezkuwiProvider>
|
||||
<StakingScreen />
|
||||
</PezkuwiProvider>
|
||||
</LanguageProvider>
|
||||
<PezkuwiProvider>
|
||||
<StakingScreen />
|
||||
</PezkuwiProvider>
|
||||
);
|
||||
|
||||
describe('StakingScreen', () => {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import { LanguageProvider } from '../../contexts/LanguageContext';
|
||||
import { PezkuwiProvider } from '../contexts/PezkuwiContext';
|
||||
import SwapScreen from '../SwapScreen';
|
||||
|
||||
@@ -10,11 +9,9 @@ jest.mock('@react-navigation/native', () => ({
|
||||
}));
|
||||
|
||||
const SwapScreenWrapper = () => (
|
||||
<LanguageProvider>
|
||||
<PezkuwiProvider>
|
||||
<SwapScreen />
|
||||
</PezkuwiProvider>
|
||||
</LanguageProvider>
|
||||
<PezkuwiProvider>
|
||||
<SwapScreen />
|
||||
</PezkuwiProvider>
|
||||
);
|
||||
|
||||
describe('SwapScreen', () => {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import { LanguageProvider } from '../../contexts/LanguageContext';
|
||||
import { PezkuwiProvider } from '../contexts/PezkuwiContext';
|
||||
import WalletScreen from '../WalletScreen';
|
||||
|
||||
@@ -10,11 +9,9 @@ jest.mock('@react-navigation/native', () => ({
|
||||
}));
|
||||
|
||||
const WalletScreenWrapper = () => (
|
||||
<LanguageProvider>
|
||||
<PezkuwiProvider>
|
||||
<WalletScreen />
|
||||
</PezkuwiProvider>
|
||||
</LanguageProvider>
|
||||
<PezkuwiProvider>
|
||||
<WalletScreen />
|
||||
</PezkuwiProvider>
|
||||
);
|
||||
|
||||
describe('WalletScreen', () => {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react-native';
|
||||
import { LanguageProvider } from '../../contexts/LanguageContext';
|
||||
import WelcomeScreen from '../WelcomeScreen';
|
||||
|
||||
// Mock navigation
|
||||
@@ -13,9 +12,7 @@ jest.mock('@react-navigation/native', () => ({
|
||||
|
||||
// Wrapper with required providers
|
||||
const WelcomeScreenWrapper = () => (
|
||||
<LanguageProvider>
|
||||
<WelcomeScreen />
|
||||
</LanguageProvider>
|
||||
<WelcomeScreen />
|
||||
);
|
||||
|
||||
describe('WelcomeScreen', () => {
|
||||
|
||||
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="71.000000pt" height="74.000000pt" viewBox="0 0 71.000000 74.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,74.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M335 680 c-4 -6 -3 -16 3 -22 6 -6 12 -6 17 2 4 6 3 16 -3 22 -6 6
|
||||
-12 6 -17 -2z"/>
|
||||
<path d="M180 660 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||
-10 -4 -10 -10z"/>
|
||||
<path d="M490 660 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||
-10 -4 -10 -10z"/>
|
||||
<path d="M221 600 c-16 -9 -6 -30 15 -30 15 0 20 25 6 34 -4 2 -14 1 -21 -4z"/>
|
||||
<path d="M445 601 c-8 -15 3 -31 21 -31 9 0 14 7 12 17 -4 20 -24 28 -33 14z"/>
|
||||
<path d="M327 576 c-8 -20 20 -43 35 -28 14 14 3 42 -16 42 -7 0 -16 -6 -19
|
||||
-14z"/>
|
||||
<path d="M95 540 c-4 -6 -3 -16 3 -22 6 -6 12 -6 17 2 4 6 3 16 -3 22 -6 6
|
||||
-12 6 -17 -2z"/>
|
||||
<path d="M577 544 c-8 -8 1 -24 14 -24 5 0 9 7 9 15 0 15 -12 20 -23 9z"/>
|
||||
<path d="M266 504 c-19 -18 -19 -20 -6 -45 14 -25 56 -25 70 1 23 44 -29 80
|
||||
-64 44z"/>
|
||||
<path d="M371 506 c-7 -8 -11 -25 -9 -38 2 -18 9 -23 32 -23 36 0 56 27 40 53
|
||||
-14 22 -48 27 -63 8z"/>
|
||||
<path d="M173 484 c-8 -22 18 -37 36 -20 7 8 10 19 7 25 -10 16 -36 13 -43 -5z"/>
|
||||
<path d="M480 480 c0 -13 7 -20 20 -20 13 0 20 7 20 20 0 13 -7 20 -20 20 -13
|
||||
0 -20 -7 -20 -20z"/>
|
||||
<path d="M210 410 c-15 -28 4 -60 35 -60 31 0 50 32 35 60 -6 12 -21 20 -35
|
||||
20 -14 0 -29 -8 -35 -20z"/>
|
||||
<path d="M420 415 c-26 -32 13 -81 48 -59 22 14 27 41 12 59 -16 19 -44 19
|
||||
-60 0z"/>
|
||||
<path d="M104 399 c-10 -17 13 -36 27 -22 12 12 4 33 -11 33 -5 0 -12 -5 -16
|
||||
-11z"/>
|
||||
<path d="M560 390 c0 -11 7 -20 15 -20 8 0 15 9 15 20 0 11 -7 20 -15 20 -8 0
|
||||
-15 -9 -15 -20z"/>
|
||||
<path d="M30 390 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||
-10 -4 -10 -10z"/>
|
||||
<path d="M645 390 c3 -5 10 -10 16 -10 5 0 9 5 9 10 0 6 -7 10 -16 10 -8 0
|
||||
-12 -4 -9 -10z"/>
|
||||
<path d="M262 324 c-20 -36 13 -73 51 -58 22 8 31 42 17 59 -17 20 -57 19 -68
|
||||
-1z"/>
|
||||
<path d="M364 326 c-15 -40 21 -80 54 -60 37 24 21 74 -25 74 -13 0 -26 -6
|
||||
-29 -14z"/>
|
||||
<path d="M181 316 c-14 -17 -7 -36 14 -36 22 0 29 20 13 36 -13 13 -16 13 -27
|
||||
0z"/>
|
||||
<path d="M487 324 c-15 -15 -7 -45 11 -42 9 2 17 12 17 22 0 20 -16 31 -28 20z"/>
|
||||
<path d="M95 260 c-4 -6 -3 -16 3 -22 6 -6 12 -6 17 2 4 6 3 16 -3 22 -6 6
|
||||
-12 6 -17 -2z"/>
|
||||
<path d="M580 255 c0 -9 5 -15 11 -13 6 2 11 8 11 13 0 5 -5 11 -11 13 -6 2
|
||||
-11 -4 -11 -13z"/>
|
||||
<path d="M324 225 c-4 -9 -2 -21 4 -27 15 -15 44 -1 40 19 -4 23 -36 29 -44 8z"/>
|
||||
<path d="M216 201 c-7 -11 18 -33 27 -24 4 3 7 12 7 20 0 15 -26 18 -34 4z"/>
|
||||
<path d="M444 199 c-7 -12 15 -31 28 -23 4 3 8 12 8 20 0 17 -26 19 -36 3z"/>
|
||||
<path d="M186 131 c-4 -7 -5 -15 -2 -18 9 -9 19 4 14 18 -4 11 -6 11 -12 0z"/>
|
||||
<path d="M496 131 c-4 -7 -5 -15 -2 -18 9 -9 19 4 14 18 -4 11 -6 11 -12 0z"/>
|
||||
<path d="M336 123 c-11 -11 -6 -23 9 -23 8 0 15 4 15 9 0 13 -16 22 -24 14z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 363 KiB |
@@ -0,0 +1,235 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="466.000000pt" height="617.000000pt" viewBox="0 0 466.000000 617.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,617.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M0 3085 l0 -3085 2330 0 2330 0 0 3085 0 3085 -2330 0 -2330 0 0
|
||||
-3085z m2658 2740 c119 -24 258 -66 332 -98 34 -15 38 -14 85 9 69 35 252 81
|
||||
376 94 88 10 118 10 195 -4 134 -23 244 -75 244 -116 0 -32 -16 -31 -94 6 -49
|
||||
23 -108 41 -167 51 -85 15 -103 15 -210 -1 -256 -35 -513 -158 -768 -366 -139
|
||||
-112 -154 -130 -141 -164 l10 -27 33 28 c19 15 69 59 113 97 170 147 419 288
|
||||
604 343 85 25 110 28 245 28 144 0 152 -1 212 -29 75 -34 87 -46 70 -70 -12
|
||||
-16 -15 -16 -58 2 -62 27 -139 42 -212 42 -63 0 -229 -24 -248 -35 -5 -4 21
|
||||
-27 58 -52 153 -103 306 -242 401 -365 36 -47 41 -60 36 -87 -4 -17 -10 -34
|
||||
-14 -36 -4 -3 -39 35 -78 83 -124 155 -306 313 -458 397 l-51 28 -102 -52
|
||||
c-116 -58 -182 -101 -321 -207 -92 -70 -148 -121 -139 -127 2 -1 29 -10 59
|
||||
-21 30 -10 88 -33 128 -53 l73 -34 51 32 c50 32 50 32 82 15 17 -9 60 -40 96
|
||||
-70 70 -56 72 -62 56 -152 -7 -38 -5 -44 32 -87 22 -25 57 -74 79 -107 85
|
||||
-136 73 -125 133 -128 59 -3 77 -13 91 -51 11 -27 11 -27 -101 -115 -96 -75
|
||||
-94 -75 -121 -3 -56 155 -128 268 -240 379 -128 127 -274 213 -449 264 l-85
|
||||
24 -32 -37 c-17 -21 -28 -41 -25 -44 4 -4 36 -12 72 -19 248 -47 507 -245 624
|
||||
-478 36 -71 86 -214 86 -245 0 -19 13 -32 58 -59 l59 -34 54 37 c37 25 56 33
|
||||
61 25 4 -6 8 -45 8 -86 l0 -75 98 -95 c116 -112 227 -244 267 -317 15 -29 32
|
||||
-53 37 -53 13 0 69 128 106 240 45 137 64 256 64 395 -1 184 -34 326 -126 545
|
||||
-36 84 -38 108 -11 130 32 27 156 -288 190 -484 42 -243 2 -500 -121 -786
|
||||
l-55 -128 29 -63 c118 -254 146 -523 71 -671 -20 -39 -36 -47 -56 -27 -8 8 -6
|
||||
24 9 58 25 58 36 169 26 269 -15 158 -127 421 -255 602 -65 91 -256 300 -274
|
||||
300 -5 0 -9 -16 -9 -34 0 -28 7 -40 36 -63 20 -15 47 -43 60 -63 13 -19 55
|
||||
-73 93 -120 191 -232 299 -503 289 -724 -4 -83 -25 -160 -36 -128 -2 6 -9 12
|
||||
-15 12 -9 0 -12 42 -13 148 0 141 -2 151 -33 237 -40 109 -104 231 -173 328
|
||||
-65 91 -118 157 -128 157 -4 0 -12 -19 -19 -42 -23 -77 -35 -88 -96 -88 -64 0
|
||||
-61 3 -145 -125 -33 -49 -74 -107 -92 -127 l-31 -38 16 -57 c8 -32 12 -63 9
|
||||
-69 -8 -14 -160 -134 -179 -141 -7 -3 -35 9 -63 26 l-49 30 -73 -34 c-40 -19
|
||||
-77 -35 -83 -35 -5 0 -34 20 -63 45 l-54 45 34 14 c113 49 157 71 221 114 143
|
||||
94 276 241 350 388 42 82 85 206 93 266 5 41 3 44 -35 71 l-41 28 0 -24 c0
|
||||
-104 -103 -340 -202 -463 -106 -132 -290 -259 -439 -304 -55 -17 -59 -17 -73
|
||||
-1 -22 24 -20 28 15 36 153 34 346 164 467 314 92 115 182 333 182 442 0 37
|
||||
-5 41 -115 106 -44 25 -81 48 -83 49 -2 1 3 14 10 28 l14 26 88 -51 c48 -27
|
||||
91 -48 93 -45 3 3 2 21 -1 41 -6 31 -15 39 -81 76 -41 22 -75 42 -75 44 0 2 4
|
||||
15 10 30 l10 25 51 -25 c28 -15 53 -24 55 -22 3 2 -7 40 -20 83 -66 207 -230
|
||||
391 -443 498 -66 33 -241 86 -283 86 -10 0 -33 -24 -57 -60 -38 -58 -40 -59
|
||||
-61 -44 -28 19 -27 23 2 67 l24 35 -31 5 c-26 5 -37 0 -57 -23 l-25 -28 -29
|
||||
20 -28 21 -77 -22 c-235 -68 -418 -211 -534 -418 -29 -51 -77 -162 -77 -178 0
|
||||
-2 32 -23 70 -46 70 -42 78 -51 60 -79 -8 -13 -20 -10 -80 22 -62 33 -70 35
|
||||
-70 18 0 -10 -3 -25 -6 -33 -4 -11 14 -26 60 -52 63 -35 64 -37 54 -65 l-10
|
||||
-29 -76 41 c-43 23 -90 50 -107 61 -89 61 -75 59 -136 21 -30 -18 -57 -34 -62
|
||||
-34 -4 0 -5 35 -1 78 l6 77 -81 69 c-138 116 -346 374 -410 509 -13 26 -26 47
|
||||
-30 47 -13 0 -107 -209 -134 -295 -47 -153 -60 -259 -54 -443 8 -233 47 -395
|
||||
146 -593 l48 -97 -18 -33 -17 -34 -56 115 c-62 130 -116 285 -143 410 -22 106
|
||||
-25 406 -5 520 21 113 90 313 148 427 l53 103 -20 57 c-74 211 -77 448 -8 560
|
||||
21 33 22 34 35 14 13 -18 12 -28 -6 -81 -29 -86 -29 -240 0 -357 56 -223 193
|
||||
-457 388 -664 41 -44 78 -79 82 -79 5 0 13 12 18 28 8 25 3 33 -67 107 -183
|
||||
192 -312 413 -361 619 -25 102 -26 244 -4 310 16 45 17 46 31 27 11 -16 13
|
||||
-37 8 -89 -8 -81 8 -197 40 -292 31 -92 33 -95 55 -75 17 15 19 14 30 -19 9
|
||||
-27 8 -39 -2 -55 -11 -19 -9 -29 17 -78 41 -79 161 -236 233 -307 58 -56 60
|
||||
-57 67 -35 11 34 22 39 91 39 l61 0 48 73 c27 39 82 107 123 149 l74 76 -11
|
||||
52 c-6 28 -11 57 -11 64 0 17 183 136 208 136 10 0 38 -14 61 -32 l44 -32 63
|
||||
23 c35 13 88 29 116 37 l53 13 47 -46 c27 -26 48 -52 48 -58 0 -5 -45 -20 -99
|
||||
-33 -296 -69 -577 -305 -692 -581 l-31 -75 28 -23 c31 -24 54 -30 54 -12 0 6
|
||||
15 44 34 84 129 280 383 477 689 535 51 10 60 16 87 55 27 39 28 44 13 50 -10
|
||||
4 -36 30 -59 59 l-41 52 28 17 29 16 47 -55 48 -55 18 22 c17 21 16 23 -40 86
|
||||
-45 52 -55 68 -46 82 13 20 86 26 179 13 l68 -9 101 84 c88 75 275 206 344
|
||||
243 l24 12 -34 15 c-44 19 -184 57 -284 78 -107 23 -390 31 -522 16 -160 -19
|
||||
-322 -61 -485 -128 -33 -14 -39 -14 -67 3 -17 10 -31 21 -31 24 0 17 288 114
|
||||
430 145 200 43 502 43 708 0z m-1179 -194 l33 -18 -95 -52 c-144 -80 -291
|
||||
-196 -421 -332 -115 -121 -116 -122 -126 -95 -5 15 -10 32 -10 38 0 24 287
|
||||
294 372 351 85 57 198 125 208 126 3 0 20 -8 39 -18z m2374 -598 c15 -26 16
|
||||
-35 6 -57 -16 -33 -30 -33 -49 2 -12 20 -14 35 -6 60 11 38 24 37 49 -5z m58
|
||||
-460 c6 -16 13 -41 16 -56 6 -27 4 -28 -28 -25 -28 2 -35 8 -43 36 -7 26 -5
|
||||
36 9 52 24 27 34 25 46 -7z m-3179 -10 c21 -19 22 -25 7 -76 -10 -36 -13 -38
|
||||
-37 -32 -36 9 -35 7 -22 56 20 79 21 80 52 52z m1366 -45 c7 -7 12 -43 12 -90
|
||||
0 -75 -1 -78 -24 -78 -13 0 -29 7 -36 15 -21 25 -76 19 -99 -11 -28 -35 -26
|
||||
-69 4 -99 27 -28 62 -32 91 -10 10 8 29 15 42 15 20 0 22 -5 22 -53 0 -29 -5
|
||||
-58 -12 -65 -17 -17 -319 -17 -336 0 -8 8 -12 64 -12 188 0 124 4 180 12 188
|
||||
8 8 60 12 168 12 108 0 160 -4 168 -12z m733 2 c18 -10 19 -23 19 -188 0 -125
|
||||
-4 -182 -12 -190 -17 -17 -319 -17 -336 0 -7 7 -12 36 -12 65 0 49 2 53 23 53
|
||||
13 0 32 -7 43 -15 28 -21 62 -18 89 10 30 30 32 64 4 99 -23 30 -78 36 -99 11
|
||||
-7 -8 -23 -15 -36 -15 -23 0 -24 2 -24 80 0 65 3 81 18 89 23 14 298 14 323 1z
|
||||
m704 -97 c6 -24 1 -33 -30 -60 -21 -18 -69 -54 -107 -79 -56 -39 -71 -45 -79
|
||||
-33 -19 30 -6 49 81 113 49 37 92 71 95 76 12 19 33 10 40 -17z m419 -15 c3
|
||||
-13 6 -40 6 -60 0 -36 -2 -38 -30 -38 -22 0 -30 5 -30 18 0 9 -3 33 -6 54 -5
|
||||
30 -3 37 12 41 36 9 42 7 48 -15z m-3236 -22 c1 -2 -1 -24 -4 -49 -6 -44 -9
|
||||
-47 -35 -47 -28 0 -29 2 -29 48 0 27 3 52 7 56 6 6 53 0 61 -8z m1707 -6 c0
|
||||
-12 -13 -15 -60 -15 -50 0 -60 3 -63 18 -3 16 3 18 60 15 48 -2 63 -7 63 -18z
|
||||
m-389 -45 c5 -12 25 -15 93 -15 53 0 92 5 99 12 13 13 42 -6 42 -28 0 -18 -37
|
||||
-37 -45 -24 -8 13 -182 13 -190 0 -3 -5 -17 -10 -30 -10 -31 0 -50 32 -35 60
|
||||
13 24 58 27 66 5z m596 -10 c8 -19 8 -28 -2 -40 -14 -17 -56 -20 -65 -5 -4 6
|
||||
-58 10 -131 10 -104 0 -124 2 -124 15 0 13 20 15 124 15 98 0 126 3 136 15 19
|
||||
23 49 18 62 -10z m1334 -156 c-4 -39 -10 -77 -12 -84 -7 -16 -59 -4 -58 13 1
|
||||
7 2 41 3 77 l1 65 36 0 37 0 -7 -71z m-3252 -10 c8 -75 2 -88 -35 -89 -18 0
|
||||
-29 44 -29 118 0 40 2 42 29 42 28 0 29 -1 35 -71z m576 -29 c0 -37 -3 -42
|
||||
-61 -80 -34 -22 -64 -39 -66 -36 -3 2 -6 19 -6 37 -2 28 5 38 53 75 69 54 80
|
||||
55 80 4z m1148 -37 l3 -43 70 0 c55 0 69 -3 69 -15 0 -12 -17 -15 -91 -15
|
||||
l-90 0 3 43 3 42 -117 3 c-97 2 -118 5 -118 18 0 12 20 14 133 12 l132 -3 3
|
||||
-42z m-1011 -29 c20 -225 93 -397 236 -550 85 -91 167 -151 278 -203 l83 -39
|
||||
36 30 c46 40 144 151 183 208 16 25 31 46 33 48 1 2 14 -4 28 -13 l25 -17 -26
|
||||
-41 c-35 -56 -98 -132 -150 -180 -24 -22 -43 -43 -43 -47 0 -5 14 -12 32 -15
|
||||
30 -7 36 -3 76 41 23 27 70 84 104 127 33 42 64 77 69 77 5 0 18 -5 28 -12 18
|
||||
-11 16 -16 -29 -82 -27 -39 -68 -92 -93 -118 -40 -44 -44 -52 -26 -50 4 1 17
|
||||
-10 29 -23 26 -28 26 -28 -50 -25 -51 1 -57 -1 -89 -34 -19 -20 -32 -39 -28
|
||||
-42 3 -4 66 -9 139 -12 l133 -5 54 -48 c49 -44 53 -51 43 -71 -6 -13 -20 -44
|
||||
-31 -70 l-20 -48 -114 0 c-123 0 -136 5 -152 60 -14 49 -34 70 -66 70 -16 0
|
||||
-50 5 -75 11 -44 11 -46 11 -107 -32 -34 -24 -87 -60 -117 -81 -74 -49 -288
|
||||
-162 -336 -178 -21 -7 -43 -15 -47 -18 -19 -10 210 -221 428 -394 122 -96 249
|
||||
-190 362 -266 l63 -43 107 72 c219 148 492 365 685 547 105 99 108 100 138 89
|
||||
16 -6 29 -16 27 -22 -7 -19 -283 -268 -427 -384 -145 -116 -321 -246 -457
|
||||
-336 l-72 -47 -108 73 c-242 163 -536 397 -726 579 l-108 103 -72 -17 c-40
|
||||
-10 -126 -20 -192 -23 -144 -6 -238 11 -335 59 -55 28 -65 37 -67 61 -1 15 2
|
||||
27 6 27 5 0 38 -14 75 -31 97 -45 159 -59 274 -59 220 0 472 84 717 240 116
|
||||
73 165 111 159 121 -2 4 -15 10 -29 13 -20 5 -41 -4 -98 -42 -211 -141 -419
|
||||
-231 -611 -263 -127 -21 -320 4 -376 49 -27 22 -18 57 14 48 12 -3 55 -15 96
|
||||
-26 63 -18 91 -20 170 -15 154 10 149 5 75 91 -113 129 -279 363 -362 510 -39
|
||||
69 -40 72 -24 98 8 14 19 26 23 26 8 0 10 -2 91 -140 84 -145 237 -352 379
|
||||
-515 l35 -39 74 28 c41 16 106 43 145 61 77 35 274 155 274 167 0 22 -44 16
|
||||
-94 -12 l-56 -32 -32 23 c-18 13 -62 46 -97 73 -69 54 -65 40 -45 149 5 29 -1
|
||||
40 -54 104 -55 66 -118 162 -135 206 -5 13 -18 17 -59 17 -76 0 -93 16 -123
|
||||
113 -36 120 -35 125 37 183 117 94 149 116 154 111 3 -3 10 -37 15 -77 20
|
||||
-145 97 -324 192 -448 89 -115 225 -226 365 -296 l52 -27 35 28 c19 16 35 31
|
||||
35 34 0 4 -24 17 -52 29 -82 35 -217 128 -286 198 -147 149 -238 343 -261 552
|
||||
-6 55 -4 70 9 78 23 16 35 9 37 -24z m509 -46 c82 -86 84 -91 84 -194 l0 -94
|
||||
-195 0 -195 0 0 121 0 121 29 27 c49 46 90 61 166 61 70 0 71 0 111 -42z m945
|
||||
22 c77 -40 79 -45 79 -185 l0 -125 -190 0 -190 0 0 94 c0 103 2 108 84 194 40
|
||||
41 41 42 108 42 50 0 80 -6 109 -20z m-523 -37 l3 -43 95 0 c77 0 94 -3 94
|
||||
-15 0 -12 -19 -15 -109 -15 l-110 0 -3 43 -3 42 -152 3 c-128 2 -153 5 -153
|
||||
18 0 12 24 14 168 12 l167 -3 3 -42z m-110 -55 c-3 -9 -35 -14 -101 -16 -82
|
||||
-2 -97 0 -97 13 0 12 17 15 101 15 76 0 100 -3 97 -12z m82 -93 c0 -12 -15
|
||||
-15 -75 -15 -60 0 -75 3 -75 15 0 12 15 15 75 15 60 0 75 -3 75 -15z m1430
|
||||
-516 c12 -27 11 -36 -4 -63 -56 -103 -283 -390 -399 -505 -49 -48 -58 -52 -86
|
||||
-46 -17 4 -31 9 -31 12 0 3 42 51 93 107 133 144 222 255 318 400 46 69 87
|
||||
125 90 126 4 0 12 -14 19 -31z m-1317 -127 c19 -21 13 -32 -16 -32 -21 0 -57
|
||||
26 -57 42 0 16 57 8 73 -10z m156 -144 c25 -23 47 -45 49 -49 2 -4 -11 -10
|
||||
-28 -14 -27 -6 -38 -1 -86 41 -41 34 -52 49 -42 55 28 18 62 8 107 -33z m1908
|
||||
-1582 c34 -29 39 -92 9 -125 -36 -39 -117 -40 -156 -1 -23 23 -27 87 -7 112
|
||||
35 44 111 51 154 14z m-2339 -247 l2 -204 118 113 117 114 50 -6 c28 -3 68 -6
|
||||
89 -6 l40 0 -114 -115 c-104 -105 -112 -117 -98 -133 42 -50 228 -291 228
|
||||
-296 0 -3 -42 -6 -94 -6 l-94 0 -88 110 -88 110 -33 -32 c-32 -31 -33 -35 -33
|
||||
-110 l0 -78 -85 0 -85 0 0 370 0 369 68 3 c37 2 74 3 82 2 13 -1 15 -32 18
|
||||
-205z m-1651 155 c64 -22 117 -65 142 -117 65 -137 12 -289 -122 -348 -42 -18
|
||||
-75 -23 -174 -27 l-123 -4 0 -99 0 -99 -85 0 -85 0 0 355 0 355 200 0 c157 0
|
||||
209 -3 247 -16z m631 -146 c97 -24 182 -141 182 -249 l0 -57 -205 -7 -204 -7
|
||||
15 -30 c37 -71 149 -91 234 -42 l45 25 37 -43 c21 -24 38 -49 38 -55 0 -21
|
||||
-71 -61 -140 -79 -115 -29 -233 0 -311 78 -110 110 -107 308 6 407 83 72 177
|
||||
91 303 59z m711 6 c30 -6 31 -9 31 -55 0 -48 -2 -52 -130 -204 -71 -86 -130
|
||||
-158 -130 -160 0 -3 65 -5 145 -5 l145 0 0 -65 0 -65 -255 0 -255 0 0 54 0 53
|
||||
103 119 c140 163 157 184 157 195 0 5 -57 9 -130 9 l-130 0 0 65 0 65 209 0
|
||||
c115 0 223 -3 240 -6z m981 -154 c0 -206 14 -244 93 -257 44 -7 100 19 118 55
|
||||
10 18 16 80 19 192 l5 165 80 0 80 0 3 -277 2 -278 -80 0 -80 0 0 36 0 36 -34
|
||||
-30 c-75 -65 -218 -65 -292 0 -71 63 -79 90 -82 301 -2 104 -1 195 2 203 4 10
|
||||
25 14 86 14 l80 0 0 -160z m637 148 c5 -7 33 -86 62 -175 28 -90 55 -163 59
|
||||
-163 4 0 31 69 60 153 77 221 60 198 143 195 l72 -3 60 -178 c35 -101 64 -172
|
||||
68 -165 4 7 30 80 58 161 69 201 58 187 141 187 38 0 71 -3 73 -7 3 -5 -39
|
||||
-129 -93 -278 l-98 -270 -83 -3 -84 -3 -55 166 c-30 91 -58 165 -61 165 -4 0
|
||||
-32 -74 -64 -165 l-58 -166 -85 3 -86 3 -13 35 c-6 19 -48 138 -92 263 -45
|
||||
126 -81 235 -81 243 0 19 143 20 157 2z m1043 -268 l0 -280 -85 0 -85 0 0 273
|
||||
c0 151 3 277 7 280 3 4 42 7 85 7 l78 0 0 -280z m-2360 -775 c0 -126 -1 -135
|
||||
-19 -135 -11 0 -21 5 -23 10 -2 7 -14 6 -34 -1 -66 -25 -124 16 -124 88 0 57
|
||||
33 93 85 93 20 0 45 -5 56 -10 18 -10 19 -7 19 40 0 43 3 50 20 50 19 0 20 -7
|
||||
20 -135z m730 0 c0 -128 -1 -135 -20 -135 -19 0 -20 7 -20 135 0 128 1 135 20
|
||||
135 19 0 20 -7 20 -135z m570 121 c0 -9 -12 -16 -27 -18 -20 -2 -29 -9 -31
|
||||
-25 -3 -19 1 -23 22 -23 16 0 26 -6 26 -15 0 -9 -9 -15 -25 -15 -25 0 -25 -1
|
||||
-25 -80 0 -73 -2 -80 -20 -80 -18 0 -20 7 -20 80 0 62 -3 80 -14 80 -8 0 -16
|
||||
7 -20 15 -4 10 1 15 14 15 14 0 20 7 20 22 0 12 7 30 17 40 20 22 83 25 83 4z
|
||||
m-2578 -18 c24 -12 33 -54 19 -84 -6 -13 -29 -44 -52 -69 l-42 -45 57 0 c49 0
|
||||
56 -2 56 -20 0 -19 -7 -20 -95 -20 -114 0 -119 8 -44 71 60 50 89 92 82 120
|
||||
-7 27 -51 36 -84 16 -22 -12 -31 -13 -44 -3 -15 11 -15 13 -2 25 35 28 104 33
|
||||
149 9z m-224 -4 c26 -18 30 -65 7 -84 -14 -12 -13 -15 5 -32 12 -12 20 -31 20
|
||||
-53 0 -49 -35 -65 -140 -65 l-80 0 0 125 0 125 83 0 c59 0 89 -5 105 -16z
|
||||
m512 -4 c23 -23 25 -49 6 -75 -12 -17 -12 -22 5 -44 25 -31 24 -63 -2 -87 -17
|
||||
-15 -40 -20 -110 -22 l-89 -4 0 126 0 126 85 0 c72 0 88 -3 105 -20z m378 8
|
||||
c-3 -7 -23 -14 -46 -16 l-42 -3 0 -110 c0 -102 -1 -109 -20 -109 -18 0 -20 8
|
||||
-22 108 l-3 107 -42 3 c-29 2 -43 8 -43 18 0 11 21 14 111 14 84 0 110 -3 107
|
||||
-12z m1216 -13 c32 -29 35 -82 7 -116 -15 -19 -32 -25 -83 -29 l-63 -5 -3 -38
|
||||
c-3 -29 -7 -37 -23 -37 -18 0 -19 8 -19 125 l0 125 79 0 c69 0 81 -3 105 -25z
|
||||
m476 -10 c0 -20 5 -25 25 -25 16 0 25 -6 25 -15 0 -9 -9 -15 -25 -15 -24 0
|
||||
-25 -3 -25 -54 0 -56 17 -83 45 -72 10 4 15 -1 15 -14 0 -16 -7 -20 -32 -20
|
||||
-51 0 -68 24 -68 92 0 51 -3 61 -20 65 -11 3 -20 12 -20 19 0 8 9 14 20 14 15
|
||||
0 20 7 20 25 0 18 5 25 20 25 15 0 20 -7 20 -25z m-1550 -40 c0 -17 -5 -25
|
||||
-18 -25 -31 0 -42 -22 -42 -87 0 -61 -1 -63 -25 -63 -28 0 -30 15 -19 129 6
|
||||
50 10 61 25 61 11 0 19 -4 19 -9 0 -6 12 -3 28 5 34 18 32 18 32 -11z m697 -8
|
||||
c7 -7 17 -27 22 -45 l10 -32 -80 0 c-43 0 -79 -4 -79 -8 0 -5 6 -17 14 -27 12
|
||||
-17 36 -20 100 -12 29 3 30 -18 1 -31 -51 -23 -122 -5 -145 37 -27 51 10 135
|
||||
63 143 29 5 77 -8 94 -25z m1672 7 c13 -12 18 -11 32 2 24 21 85 20 110 -2 16
|
||||
-14 19 -31 19 -96 0 -71 -2 -78 -20 -78 -17 0 -19 8 -22 72 -3 69 -4 73 -30
|
||||
82 -22 8 -32 6 -48 -9 -16 -15 -20 -30 -20 -82 0 -56 -2 -63 -20 -63 -18 0
|
||||
-20 7 -20 58 0 63 -19 102 -50 102 -36 0 -50 -27 -50 -96 0 -57 -2 -64 -19
|
||||
-64 -18 0 -20 9 -23 95 -3 93 -2 95 20 95 12 0 22 -5 22 -11 0 -8 4 -8 13 -1
|
||||
29 24 79 22 106 -4z m-2179 -4 c16 -16 20 -33 20 -95 0 -68 -2 -75 -20 -75
|
||||
-11 0 -20 5 -20 10 0 7 -6 7 -19 0 -47 -24 -111 2 -111 45 0 33 36 55 87 55
|
||||
30 0 43 4 43 14 0 25 -29 39 -70 33 -22 -3 -43 -1 -46 5 -20 32 104 40 136 8z
|
||||
m1222 3 c14 -13 18 -31 18 -95 0 -71 -2 -78 -20 -78 -11 0 -20 5 -20 10 0 7
|
||||
-6 7 -19 0 -48 -25 -111 0 -111 44 0 38 16 49 74 54 58 5 70 18 41 42 -9 8
|
||||
-30 11 -55 7 -41 -5 -63 8 -39 24 25 15 111 10 131 -8z m552 -14 c36 -43 35
|
||||
-91 -3 -130 -74 -73 -203 0 -171 97 15 45 45 64 101 64 40 0 51 -4 73 -31z
|
||||
m126 19 c0 -9 3 -9 12 0 17 17 58 15 58 -3 0 -8 -7 -15 -15 -15 -34 0 -55 -38
|
||||
-55 -100 0 -53 -2 -60 -19 -60 -18 0 -20 9 -23 91 -2 50 -1 93 1 95 10 9 41 3
|
||||
41 -8z"/>
|
||||
<path d="M2326 5074 l-38 -49 29 -6 c38 -7 44 -4 71 34 27 40 27 47 3 47 -11
|
||||
0 -21 5 -23 12 -2 6 -21 -10 -42 -38z"/>
|
||||
<path d="M1310 4338 c0 -7 -3 -23 -6 -34 -4 -17 2 -26 31 -44 31 -19 39 -20
|
||||
46 -9 18 28 9 54 -26 77 -40 25 -45 27 -45 10z"/>
|
||||
<path d="M3240 4121 c0 -34 6 -44 37 -70 21 -17 41 -31 45 -31 5 0 8 18 8 40
|
||||
0 35 -4 42 -45 70 l-45 31 0 -40z"/>
|
||||
<path d="M2016 3177 c-39 -33 -39 -34 -15 -40 40 -11 53 -8 87 24 38 34 38 37
|
||||
-4 44 -23 5 -37 -1 -68 -28z"/>
|
||||
<path d="M247 1273 c-4 -3 -7 -57 -7 -120 l0 -113 86 0 c59 0 97 5 120 16 95
|
||||
45 78 185 -25 214 -41 11 -164 14 -174 3z"/>
|
||||
<path d="M983 1120 c-27 -16 -63 -65 -63 -85 0 -3 56 -5 125 -5 81 0 125 4
|
||||
125 10 0 28 -35 73 -65 86 -47 19 -84 18 -122 -6z"/>
|
||||
<path d="M2020 210 c-11 -11 -20 -31 -20 -45 0 -30 32 -65 60 -65 28 0 60 35
|
||||
60 65 0 30 -32 65 -60 65 -11 0 -29 -9 -40 -20z"/>
|
||||
<path d="M512 253 l3 -38 48 1 c57 0 88 24 71 52 -8 12 -27 18 -68 20 l-57 3
|
||||
3 -38z"/>
|
||||
<path d="M512 143 c3 -37 5 -38 44 -41 52 -4 94 12 94 36 0 31 -22 42 -83 42
|
||||
l-58 0 3 -37z"/>
|
||||
<path d="M1022 253 c3 -36 5 -38 38 -39 45 -1 76 10 83 30 10 27 -21 46 -74
|
||||
46 l-50 0 3 -37z"/>
|
||||
<path d="M1022 143 c3 -37 4 -38 49 -41 60 -4 98 23 80 56 -10 19 -20 22 -72
|
||||
22 l-60 0 3 -37z"/>
|
||||
<path d="M2624 276 c-3 -8 -4 -31 -2 -52 3 -38 4 -39 45 -42 32 -2 47 2 62 17
|
||||
26 26 26 46 1 71 -24 24 -98 28 -106 6z"/>
|
||||
<path d="M2270 211 c-15 -30 -14 -31 45 -31 38 0 55 4 55 13 0 39 -81 53 -100
|
||||
18z"/>
|
||||
<path d="M1785 146 c-26 -19 -13 -46 23 -46 32 0 52 16 52 42 0 22 -47 25 -75
|
||||
4z"/>
|
||||
<path d="M3005 146 c-26 -19 -13 -46 23 -46 33 0 57 22 48 45 -7 19 -46 20
|
||||
-71 1z"/>
|
||||
<path d="M3536 211 c-46 -51 13 -133 69 -97 33 22 41 60 21 91 -20 31 -65 34
|
||||
-90 6z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="116.000000pt" height="128.000000pt" viewBox="0 0 116.000000 128.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,128.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 521 B |
|
After Width: | Height: | Size: 131 KiB |
@@ -0,0 +1,128 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="288.000000pt" height="382.000000pt" viewBox="0 0 288.000000 382.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,382.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M0 1910 l0 -1910 1440 0 1440 0 0 1910 0 1910 -1440 0 -1440 0 0
|
||||
-1910z m1643 1655 c47 -8 118 -27 158 -41 70 -25 74 -26 104 -10 89 47 276 69
|
||||
367 42 55 -16 119 -58 107 -70 -3 -4 -33 6 -65 21 -51 24 -71 28 -149 28 -56
|
||||
-1 -112 -8 -150 -19 -142 -43 -303 -136 -444 -260 -48 -41 -80 -62 -90 -58
|
||||
-22 8 108 125 232 209 70 47 95 69 85 74 -8 4 -48 18 -89 29 -115 33 -333 39
|
||||
-462 11 -54 -11 -112 -27 -130 -34 -83 -36 -88 -37 -109 -26 -11 6 -16 15 -12
|
||||
19 22 21 207 78 304 93 64 10 266 6 343 -8z m640 -89 c37 -18 56 -56 20 -41
|
||||
-10 5 -44 15 -77 23 -48 13 -67 13 -102 4 -25 -7 -57 -12 -72 -12 -16 0 -32
|
||||
-3 -35 -6 -3 -4 25 -29 64 -56 76 -53 215 -189 224 -219 4 -10 2 -26 -3 -35
|
||||
-7 -13 -15 -7 -46 34 -48 66 -131 141 -224 204 l-75 51 -56 -28 c-81 -39 -207
|
||||
-125 -280 -190 -47 -42 -66 -54 -75 -45 -24 24 227 216 360 275 144 65 292 81
|
||||
377 41z m-1832 -63 c-38 -137 21 -329 158 -511 85 -112 245 -252 349 -306 32
|
||||
-17 44 -46 18 -46 -7 0 -30 11 -50 25 -20 14 -39 25 -42 25 -3 0 -43 30 -88
|
||||
68 -127 105 -253 248 -303 347 l-21 39 -26 -51 c-57 -113 -79 -200 -83 -333
|
||||
-6 -148 8 -228 63 -357 43 -105 51 -133 35 -133 -14 0 -59 94 -98 207 -26 73
|
||||
-28 88 -27 248 0 159 2 175 27 248 15 43 42 107 60 143 l33 66 -20 56 c-28 78
|
||||
-30 245 -3 286 24 36 31 28 18 -21z m513 41 c9 -3 16 -9 16 -14 0 -4 -38 -30
|
||||
-85 -59 -50 -30 -127 -92 -184 -147 -78 -75 -100 -91 -105 -78 -13 35 136 179
|
||||
270 261 38 23 70 42 71 42 1 1 8 -2 17 -5z m-454 -123 c0 -41 8 -96 21 -135
|
||||
17 -56 23 -66 38 -61 22 7 36 -21 20 -41 -7 -9 -7 -19 2 -36 34 -66 100 -149
|
||||
171 -217 44 -43 85 -88 91 -101 7 -14 27 -29 47 -35 60 -19 90 -38 90 -57 0
|
||||
-10 -2 -18 -5 -18 -18 0 -166 111 -237 179 -185 175 -293 401 -264 555 11 59
|
||||
26 41 26 -33z m1215 -331 c143 -88 268 -169 279 -179 13 -14 17 -27 12 -45
|
||||
l-6 -26 -558 2 -557 3 0 33 c0 31 6 36 270 202 149 93 277 169 285 170 8 0
|
||||
132 -72 275 -160z m635 74 c0 -32 -28 -31 -36 0 -3 14 -3 30 1 36 11 17 35 -8
|
||||
35 -36z m101 -214 c61 -184 50 -362 -38 -568 l-35 -83 26 -58 c58 -130 73
|
||||
-304 31 -368 -23 -34 -30 -18 -16 34 41 147 -44 381 -208 568 -53 60 -158 151
|
||||
-233 202 -38 24 -68 51 -68 59 0 22 12 17 96 -38 108 -72 281 -244 319 -317 8
|
||||
-17 19 -31 24 -31 13 0 77 176 90 244 22 118 7 277 -35 373 -44 102 -54 136
|
||||
-42 151 10 11 16 6 35 -30 12 -24 37 -86 54 -138z m-66 -52 c6 -24 4 -28 -13
|
||||
-28 -25 0 -35 25 -21 52 13 23 25 15 34 -24z m-1861 -26 c-4 -13 -14 -22 -25
|
||||
-22 -22 0 -23 8 -9 46 9 24 13 26 25 13 9 -8 12 -23 9 -37z m1884 -80 c3 -27
|
||||
0 -32 -17 -32 -17 0 -21 6 -21 36 0 28 3 35 18 32 11 -2 18 -14 20 -36z
|
||||
m-1900 -9 c-2 -17 -10 -29 -20 -31 -14 -3 -18 3 -18 27 0 25 4 31 21 31 16 0
|
||||
20 -5 17 -27z m1345 8 c4 -1 6 -90 5 -198 l-3 -198 -75 0 -75 0 -3 190 c-1
|
||||
104 -1 194 1 200 4 8 73 11 150 6z m-665 -198 l-3 -198 -75 0 -75 0 -3 198 -2
|
||||
197 80 0 80 0 -2 -197z m220 0 l-3 -198 -54 -3 c-30 -2 -65 -1 -78 3 l-23 5 0
|
||||
195 0 195 80 0 80 0 -2 -197z m223 3 c0 -104 -4 -193 -9 -198 -5 -5 -38 -8
|
||||
-73 -6 l-64 3 -3 198 -2 198 75 -3 76 -3 0 -189z m-991 154 c0 -5 -7 -10 -15
|
||||
-10 -18 0 -20 -26 -2 -34 10 -5 10 -7 0 -12 -20 -9 -15 -24 7 -24 11 0 20 -4
|
||||
20 -8 0 -4 -15 -8 -34 -8 l-34 0 3 44 c3 43 16 62 43 62 6 0 12 -4 12 -10z
|
||||
m1655 -27 c-4 -10 -7 -28 -6 -41 0 -13 -5 -29 -12 -37 -20 -20 -42 4 -43 48
|
||||
-1 36 10 50 19 25 3 -10 10 -8 23 5 10 9 20 17 22 17 2 0 1 -8 -3 -17z m-1791
|
||||
-19 c12 -30 7 -84 -8 -84 -17 0 -26 21 -26 59 0 41 22 57 34 25z m1904 -31
|
||||
c-2 -35 -7 -48 -18 -48 -11 0 -16 13 -18 48 -3 42 -1 47 18 47 19 0 21 -5 18
|
||||
-47z m-412 -58 c78 -53 210 -185 263 -263 94 -140 142 -291 127 -397 -11 -69
|
||||
-32 -53 -28 21 4 74 -10 136 -50 222 -68 145 -182 280 -320 380 -50 35 -78 62
|
||||
-78 74 0 21 -3 23 86 -37z m-1207 -265 c6 0 11 5 11 10 0 6 4 10 8 10 15 0 8
|
||||
-74 -7 -86 -27 -21 -49 4 -48 54 0 37 2 42 12 28 7 -9 17 -16 24 -16z m1341
|
||||
10 c0 -5 -9 -10 -19 -10 -28 0 -37 -20 -9 -21 23 -1 23 -1 -2 -9 l-25 -8 25
|
||||
-2 c24 -3 24 -3 2 -7 -26 -5 -20 -23 9 -23 10 0 19 -4 19 -10 0 -17 -46 -11
|
||||
-62 8 -25 28 -26 45 -4 69 20 23 66 32 66 13z m-202 -19 c8 -5 12 -17 10 -27
|
||||
-3 -18 -23 -19 -491 -22 -427 -2 -488 0 -493 13 -4 8 -4 22 0 30 5 13 68 15
|
||||
483 15 263 0 484 -4 491 -9z m-1287 -174 c82 -128 197 -267 220 -267 28 0 161
|
||||
64 240 115 83 54 178 127 178 138 1 4 -84 7 -188 7 -203 0 -216 3 -209 52 l3
|
||||
23 557 3 558 2 6 -26 c13 -51 -4 -54 -293 -54 l-264 0 -92 -81 c-50 -45 -124
|
||||
-103 -162 -129 -61 -41 -210 -125 -255 -143 -11 -4 -2 -18 35 -52 86 -80 216
|
||||
-188 315 -261 150 -111 126 -107 222 -42 110 75 297 224 378 302 42 40 71 61
|
||||
83 59 9 -3 17 -8 17 -13 0 -9 -114 -118 -201 -190 -75 -62 -220 -170 -302
|
||||
-225 l-57 -38 -68 45 c-89 59 -249 185 -341 267 -155 139 -150 135 -177 122
|
||||
-41 -18 -217 -15 -274 5 -53 19 -98 49 -88 59 3 4 39 -5 80 -20 65 -24 83 -26
|
||||
163 -22 138 8 287 64 430 160 75 51 182 136 214 171 l24 26 -30 0 c-19 0 -38
|
||||
-9 -54 -26 -40 -44 -200 -158 -279 -201 -126 -68 -199 -88 -320 -88 -86 0
|
||||
-111 3 -134 18 -41 28 -19 39 41 21 39 -11 69 -13 117 -7 l65 8 -87 112 c-48
|
||||
61 -109 148 -136 192 -42 70 -47 83 -35 97 12 15 14 15 24 -1 5 -9 40 -63 76
|
||||
-118z m1649 8 c0 -47 -243 -345 -281 -345 -10 0 -19 4 -19 9 0 5 30 42 66 82
|
||||
82 91 141 168 183 237 33 53 51 59 51 17z m-360 -94 c0 -5 -7 -11 -15 -15 -21
|
||||
-8 -19 -26 3 -26 15 -1 15 -2 -3 -16 -19 -14 -19 -15 3 -20 34 -9 26 -22 -12
|
||||
-21 -33 1 -34 2 -30 40 2 22 9 46 15 53 13 16 39 19 39 5z m798 -1039 c16 -22
|
||||
15 -42 -5 -64 -21 -24 -58 -23 -83 2 -23 23 -25 40 -7 62 24 31 70 31 95 0z
|
||||
m-1368 -135 l5 -118 65 66 c61 62 67 65 112 65 26 0 48 -3 48 -6 0 -4 -27 -35
|
||||
-60 -71 l-61 -64 64 -82 c89 -114 87 -107 23 -107 l-54 0 -52 65 c-50 62 -53
|
||||
65 -71 49 -11 -10 -19 -33 -21 -63 l-3 -46 -47 -3 -48 -3 0 221 0 221 48 -3
|
||||
47 -3 5 -118z m-969 93 c19 -5 48 -23 64 -40 23 -24 29 -41 33 -87 3 -49 0
|
||||
-64 -20 -93 -32 -47 -68 -63 -158 -69 l-75 -6 0 -55 0 -55 -52 -3 -53 -3 0
|
||||
210 0 211 113 0 c61 0 128 -5 148 -10z m399 -102 c48 -33 72 -70 77 -122 l6
|
||||
-46 -122 0 c-66 0 -121 -4 -121 -8 0 -13 43 -49 66 -56 12 -4 40 1 63 10 41
|
||||
16 43 16 66 -6 20 -18 22 -26 13 -37 -41 -50 -155 -59 -225 -18 -110 65 -104
|
||||
232 9 288 49 25 128 22 168 -5z m408 -9 c2 -21 -14 -47 -72 -118 -42 -50 -76
|
||||
-93 -76 -96 0 -3 36 -5 80 -5 l80 0 0 -40 0 -40 -150 0 -150 0 0 29 c0 22 20
|
||||
52 80 123 l80 93 -78 5 c-71 5 -77 7 -80 28 -8 51 -3 53 145 50 l138 -3 3 -26z
|
||||
m552 -65 c0 -100 7 -127 41 -145 25 -13 74 4 84 29 4 10 10 61 13 115 l5 98
|
||||
46 -3 46 -3 0 -160 0 -160 -47 -3 c-38 -2 -48 0 -48 12 0 20 -9 20 -34 1 -12
|
||||
-9 -42 -15 -72 -15 -42 0 -59 5 -83 26 -40 33 -51 77 -51 202 l0 102 50 0 50
|
||||
0 0 -96z m400 11 c33 -102 39 -119 45 -113 3 3 20 47 39 99 l33 94 43 0 43 0
|
||||
28 -80 c48 -142 41 -140 81 -24 l35 104 38 3 c21 2 41 0 46 -5 4 -4 -18 -78
|
||||
-50 -163 l-57 -155 -48 0 -48 0 -30 85 c-16 47 -33 88 -36 92 -4 4 -22 -35
|
||||
-41 -87 l-33 -95 -48 0 -48 0 -56 158 c-31 86 -56 161 -56 165 0 4 21 7 47 5
|
||||
l47 -3 26 -80z m580 -80 l0 -165 -50 0 -50 0 0 158 c0 87 3 162 7 165 3 4 26
|
||||
7 50 7 l43 0 0 -165z m-940 -419 c0 -41 4 -77 8 -80 5 -3 26 13 47 34 22 22
|
||||
47 40 57 40 25 0 23 -9 -13 -46 l-31 -32 37 -49 c32 -41 34 -48 19 -52 -12 -2
|
||||
-30 11 -51 35 -27 33 -35 37 -50 28 -10 -6 -19 -25 -21 -43 -3 -24 -8 -31 -20
|
||||
-29 -15 3 -17 21 -20 136 -2 127 -2 132 18 132 18 0 20 -6 20 -74z m-618 42
|
||||
c23 -19 29 -50 15 -78 -11 -22 -11 -29 7 -53 16 -22 18 -33 10 -55 -12 -35
|
||||
-57 -51 -146 -51 l-68 -1 0 125 0 125 83 0 c51 0 89 -5 99 -12z m234 -69 c15
|
||||
-17 19 -35 17 -91 -2 -76 -6 -87 -26 -69 -10 8 -22 8 -46 0 -36 -13 -85 2 -96
|
||||
28 -16 42 23 73 91 73 31 0 35 3 32 23 -3 20 -8 22 -55 21 -38 -1 -53 2 -53
|
||||
11 0 18 16 23 71 24 35 1 51 -4 65 -20z m129 11 c4 -7 12 -7 25 0 29 15 81 12
|
||||
102 -7 14 -13 18 -31 18 -95 0 -43 -2 -78 -4 -78 -28 0 -36 16 -36 76 0 59 -2
|
||||
65 -25 76 -19 8 -31 8 -50 0 -23 -11 -25 -17 -25 -77 0 -58 -2 -65 -20 -65
|
||||
-19 0 -20 7 -20 90 0 72 3 90 14 90 8 0 18 -5 21 -10z"/>
|
||||
<path d="M1817 2663 c-11 -11 -8 -313 3 -313 6 0 10 60 10 160 0 88 -1 160 -3
|
||||
160 -2 0 -7 -3 -10 -7z"/>
|
||||
<path d="M1075 2659 c-10 -26 -1 -304 10 -302 14 4 19 293 6 306 -7 7 -12 5
|
||||
-16 -4z"/>
|
||||
<path d="M246 824 c-8 -20 -7 -72 1 -103 5 -21 10 -23 59 -19 89 8 122 61 69
|
||||
113 -19 20 -34 25 -73 25 -36 0 -52 -4 -56 -16z"/>
|
||||
<path d="M665 735 c-39 -38 -32 -45 45 -45 63 0 70 2 70 19 0 24 -36 51 -68
|
||||
51 -12 0 -34 -11 -47 -25z"/>
|
||||
<path d="M1042 233 c3 -36 5 -38 38 -41 37 -2 81 15 87 34 8 24 -28 44 -78 44
|
||||
l-50 0 3 -37z"/>
|
||||
<path d="M1052 161 c-8 -5 -12 -22 -10 -42 3 -29 7 -34 32 -37 83 -10 134 31
|
||||
86 70 -23 19 -85 24 -108 9z"/>
|
||||
<path d="M1322 131 c-21 -13 -10 -46 16 -49 28 -4 52 14 52 39 0 14 -7 19 -27
|
||||
19 -16 0 -34 -4 -41 -9z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 5.0 MiB |
@@ -0,0 +1,273 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="2048.000000pt" height="2048.000000pt" viewBox="0 0 2048.000000 2048.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,2048.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M10078 18595 c-2 -1 -86 -5 -188 -9 -354 -12 -1016 -89 -1260 -147
|
||||
-47 -11 -130 -29 -185 -40 -264 -54 -436 -101 -830 -229 -505 -164 -947 -363
|
||||
-1560 -704 -11 -6 -47 -29 -80 -50 -33 -22 -80 -50 -105 -64 -38 -22 -235
|
||||
-151 -415 -272 -48 -33 -199 -145 -239 -177 -11 -9 -47 -37 -80 -62 -34 -25
|
||||
-63 -48 -66 -51 -3 -3 -32 -27 -65 -52 -55 -43 -109 -88 -160 -136 -11 -10
|
||||
-38 -31 -60 -47 -22 -16 -42 -31 -45 -34 -3 -4 -50 -46 -105 -96 -55 -49 -104
|
||||
-96 -108 -103 -5 -7 -15 -18 -24 -25 -35 -26 -354 -348 -448 -452 -220 -243
|
||||
-424 -492 -566 -690 -35 -49 -74 -103 -86 -120 -121 -168 -413 -628 -413 -649
|
||||
0 -4 -12 -25 -27 -49 -67 -105 -235 -425 -301 -572 -88 -199 -152 -347 -186
|
||||
-433 -88 -222 -132 -344 -151 -412 -7 -25 -29 -97 -50 -160 -82 -259 -107
|
||||
-347 -151 -526 -25 -103 -48 -197 -50 -208 -20 -90 -75 -403 -89 -496 -9 -63
|
||||
-18 -126 -20 -140 -9 -56 -50 -459 -59 -585 -19 -240 -25 -782 -11 -1000 3
|
||||
-55 8 -136 11 -180 15 -246 92 -815 144 -1070 113 -551 317 -1193 536 -1682
|
||||
145 -325 362 -735 529 -1003 82 -130 380 -569 394 -580 4 -3 46 -57 93 -120
|
||||
48 -63 117 -153 153 -200 217 -277 695 -769 985 -1014 14 -11 59 -50 101 -86
|
||||
42 -36 85 -72 95 -80 11 -8 48 -38 84 -67 485 -388 985 -707 1535 -977 433
|
||||
-213 671 -312 1075 -445 309 -103 439 -140 775 -219 227 -54 502 -103 770
|
||||
-137 28 -4 59 -8 70 -10 148 -22 270 -35 550 -55 118 -8 887 -5 955 4 19 2 71
|
||||
7 115 10 104 7 264 24 340 36 33 5 80 12 105 15 420 56 906 156 1181 241 25 8
|
||||
54 16 65 19 10 2 55 15 99 30 44 14 127 41 185 60 150 48 394 138 550 203 377
|
||||
158 777 359 1105 556 33 20 77 46 98 58 96 56 532 352 622 421 370 286 477
|
||||
376 774 652 170 158 510 515 585 613 11 15 36 45 55 68 44 50 68 79 103 126
|
||||
15 20 34 42 41 50 91 93 472 635 630 898 159 266 346 621 449 855 20 44 54
|
||||
122 77 173 165 370 389 1072 466 1457 8 39 25 124 39 190 21 102 34 180 61
|
||||
370 5 35 13 105 19 155 2 19 7 46 10 60 5 25 10 66 21 190 3 36 10 115 15 175
|
||||
20 220 25 346 25 660 0 286 -8 557 -20 625 -2 14 -6 61 -9 105 -6 71 -15 166
|
||||
-32 305 -29 253 -82 570 -125 755 -17 72 -40 171 -51 220 -78 344 -293 991
|
||||
-418 1262 -18 37 -41 91 -52 118 -29 75 -264 547 -317 639 -26 45 -74 127
|
||||
-107 184 -107 187 -123 212 -181 298 -32 47 -74 111 -94 143 -53 85 -140 196
|
||||
-151 193 -5 -1 -7 2 -3 8 5 8 -89 146 -153 225 -4 6 -54 69 -112 140 -57 72
|
||||
-108 135 -114 140 -6 6 -36 39 -66 75 -98 117 -222 253 -360 394 -152 156
|
||||
-262 262 -366 355 -27 25 -74 68 -104 95 -31 28 -76 67 -100 86 -25 19 -85 69
|
||||
-135 110 -102 85 -94 78 -200 163 -241 192 -688 484 -1090 712 -242 137 -882
|
||||
434 -995 461 -3 0 -14 4 -25 9 -270 106 -404 150 -780 260 -27 8 -129 33 -225
|
||||
55 -96 22 -184 43 -195 45 -192 49 -632 118 -915 145 -63 6 -131 13 -150 15
|
||||
-126 15 -362 27 -592 30 -147 2 -268 2 -270 0z m687 -454 c289 -20 640 -65
|
||||
905 -116 69 -13 141 -27 160 -30 221 -38 696 -172 1060 -299 142 -50 142 -50
|
||||
234 -90 32 -14 63 -26 69 -26 5 0 39 -13 74 -30 34 -16 65 -30 68 -30 20 0
|
||||
534 -253 705 -346 47 -26 159 -92 250 -146 91 -54 174 -104 185 -111 11 -7 22
|
||||
-14 25 -17 3 -3 73 -50 155 -105 83 -54 156 -105 163 -112 8 -7 22 -18 32 -23
|
||||
40 -21 344 -258 470 -366 14 -12 57 -48 95 -82 39 -33 96 -81 127 -108 68 -59
|
||||
515 -510 609 -615 55 -61 185 -215 236 -279 266 -332 541 -732 698 -1013 17
|
||||
-30 35 -61 41 -68 6 -8 42 -72 79 -144 37 -71 82 -157 101 -190 42 -77 163
|
||||
-339 221 -480 25 -60 51 -123 58 -140 73 -161 236 -651 305 -915 50 -192 94
|
||||
-403 144 -690 39 -220 40 -229 65 -455 11 -99 23 -220 26 -270 4 -49 8 -106
|
||||
11 -125 2 -19 6 -161 10 -315 6 -245 -4 -600 -21 -790 -13 -137 -36 -363 -40
|
||||
-390 -3 -16 -14 -91 -25 -165 -66 -459 -176 -911 -335 -1385 -184 -551 -473
|
||||
-1154 -788 -1645 -233 -364 -409 -604 -654 -891 -297 -349 -744 -790 -1038
|
||||
-1025 -33 -26 -80 -64 -105 -84 -191 -155 -560 -412 -807 -562 -252 -153 -648
|
||||
-360 -923 -482 -58 -26 -118 -53 -135 -61 -132 -60 -582 -223 -730 -265 -16
|
||||
-5 -77 -22 -135 -40 -364 -107 -791 -195 -1195 -246 -22 -2 -51 -7 -65 -9 -14
|
||||
-2 -54 -7 -90 -10 -36 -3 -76 -8 -90 -10 -14 -2 -77 -7 -140 -11 -63 -4 -164
|
||||
-10 -225 -14 -280 -18 -989 3 -1185 35 -14 2 -50 7 -80 10 -290 31 -831 131
|
||||
-1078 200 -219 62 -398 114 -462 136 -156 52 -447 159 -525 194 -16 7 -64 28
|
||||
-105 45 -41 18 -154 70 -250 115 -96 45 -202 95 -235 110 -33 15 -89 44 -125
|
||||
65 -36 21 -101 57 -145 80 -87 46 -496 291 -517 310 -7 6 -44 31 -83 57 -68
|
||||
44 -185 128 -330 236 -63 46 -274 218 -425 344 -171 143 -599 570 -786 783
|
||||
-209 239 -484 599 -645 845 -333 506 -663 1163 -834 1655 -26 74 -58 166 -71
|
||||
204 -29 81 -140 472 -183 642 -65 260 -154 800 -177 1069 -3 39 -7 80 -9 93
|
||||
-2 12 -7 86 -10 165 -4 78 -8 148 -11 156 -5 17 -5 717 0 751 2 14 7 77 11
|
||||
140 11 195 45 529 65 645 5 28 12 68 15 90 3 22 7 47 10 55 2 8 6 33 10 55 20
|
||||
147 85 448 135 630 17 61 43 157 59 215 64 233 175 543 291 815 28 66 64 152
|
||||
80 190 92 229 338 688 520 975 25 39 56 89 70 110 52 83 187 276 225 325 23
|
||||
27 63 81 90 119 85 119 224 293 385 480 157 183 573 594 730 722 19 16 41 34
|
||||
48 41 7 7 34 29 59 50 26 21 61 51 78 67 16 15 66 56 110 89 44 34 85 65 90
|
||||
69 132 103 165 127 190 143 17 11 32 22 35 25 8 9 178 123 208 140 15 8 29 18
|
||||
30 23 2 4 8 7 12 7 5 0 29 14 52 31 94 66 221 147 322 204 58 33 143 82 189
|
||||
108 108 63 518 265 654 322 59 25 117 50 128 55 113 54 611 230 775 274 30 8
|
||||
96 26 145 40 152 41 289 78 310 82 11 2 54 11 95 19 41 8 86 17 100 20 49 10
|
||||
246 46 280 51 19 3 89 14 155 24 143 22 349 47 460 55 44 4 96 8 115 10 19 2
|
||||
118 7 220 11 102 4 187 8 189 10 7 6 537 -5 686 -15z"/>
|
||||
<path d="M10060 17997 c-3 -2 -86 -7 -185 -10 -272 -10 -399 -21 -700 -63
|
||||
-465 -65 -1007 -188 -1320 -299 -55 -20 -145 -51 -200 -70 -173 -58 -320 -116
|
||||
-472 -186 -24 -10 -45 -19 -48 -19 -8 0 -199 -92 -408 -196 -186 -94 -470
|
||||
-257 -462 -266 3 -3 -1 -5 -7 -5 -33 0 -548 -342 -669 -443 -9 -8 -30 -24 -45
|
||||
-35 -86 -63 -355 -283 -439 -360 -55 -49 -121 -110 -148 -135 -28 -25 -57 -53
|
||||
-66 -64 -9 -10 -22 -24 -30 -30 -21 -17 -289 -285 -346 -347 -83 -90 -134
|
||||
-156 -127 -164 4 -5 2 -5 -5 -1 -14 8 -45 -33 -36 -47 3 -6 2 -7 -4 -4 -19 12
|
||||
-294 -325 -445 -549 -30 -43 -84 -122 -121 -176 -37 -53 -67 -101 -67 -106 0
|
||||
-6 -4 -12 -9 -14 -5 -1 -39 -52 -75 -113 -37 -60 -71 -117 -76 -125 -6 -8 -14
|
||||
-24 -19 -36 -5 -12 -25 -45 -44 -75 -91 -143 -342 -659 -431 -889 -21 -52 -47
|
||||
-117 -58 -145 -122 -294 -299 -906 -367 -1265 -62 -326 -108 -673 -126 -950
|
||||
-4 -52 -9 -111 -11 -130 -9 -74 -12 -722 -4 -850 28 -418 73 -763 154 -1180
|
||||
32 -160 54 -253 131 -535 36 -133 155 -498 166 -509 5 -6 9 -16 9 -23 0 -32
|
||||
199 -507 308 -734 66 -137 176 -343 257 -479 18 -30 51 -86 74 -125 98 -170
|
||||
344 -536 420 -627 6 -7 51 -65 99 -129 96 -127 212 -270 252 -309 14 -14 37
|
||||
-41 51 -60 93 -123 506 -533 734 -729 133 -114 172 -147 260 -217 210 -166
|
||||
626 -464 649 -464 3 0 27 -15 53 -34 47 -33 355 -213 461 -269 28 -16 52 -25
|
||||
52 -20 0 4 4 3 8 -4 9 -14 364 -193 512 -258 165 -72 499 -202 541 -210 9 -2
|
||||
30 -10 46 -18 15 -8 42 -18 58 -22 17 -5 35 -9 40 -11 6 -1 53 -17 105 -34 52
|
||||
-17 136 -42 185 -56 50 -14 97 -27 105 -29 313 -88 951 -208 1225 -230 44 -4
|
||||
91 -8 105 -10 158 -24 861 -37 1115 -21 99 6 343 27 485 42 46 5 258 38 375
|
||||
59 438 79 436 78 762 167 45 12 79 26 76 32 -3 5 -1 6 5 2 30 -18 657 195 868
|
||||
295 22 10 43 19 47 19 15 0 440 206 612 298 202 106 429 242 590 352 241 164
|
||||
345 237 475 337 42 32 226 178 230 183 3 3 41 36 85 74 181 156 409 367 489
|
||||
455 17 18 58 61 91 96 59 61 184 197 225 245 12 14 31 36 43 50 148 172 183
|
||||
216 331 415 53 72 99 135 104 140 4 6 27 39 51 75 25 36 47 67 50 70 20 18
|
||||
226 347 319 510 11 19 36 64 57 100 61 105 259 507 305 615 22 55 64 154 92
|
||||
220 89 213 198 525 249 710 134 494 191 765 244 1155 3 25 10 77 15 115 5 39
|
||||
12 104 15 145 4 41 8 86 10 100 32 227 38 989 10 1245 -2 22 -7 69 -10 105 -3
|
||||
36 -10 103 -15 150 -6 47 -12 108 -15 135 -3 28 -10 77 -15 110 -5 33 -12 80
|
||||
-15 105 -3 25 -11 70 -17 100 -6 30 -12 62 -13 70 -1 8 -5 29 -8 45 -4 17 -9
|
||||
46 -12 65 -5 33 -30 170 -39 215 -30 150 -146 577 -201 740 -22 63 -88 250
|
||||
-129 365 -14 38 -66 166 -96 235 -92 213 -130 294 -222 475 -101 197 -136 262
|
||||
-224 412 -17 29 -47 81 -66 114 -34 60 -227 354 -238 364 -3 3 -30 41 -59 85
|
||||
-127 187 -232 323 -440 565 -35 41 -75 89 -89 105 -144 171 -514 538 -732 725
|
||||
-35 30 -71 62 -79 70 -15 13 -83 70 -135 110 -10 8 -39 32 -64 53 -25 21 -57
|
||||
46 -71 55 -14 9 -37 27 -51 39 -14 13 -28 23 -31 23 -3 0 -22 13 -40 30 -19
|
||||
16 -37 30 -41 30 -4 0 -13 6 -20 13 -18 18 -94 72 -273 192 -349 235 -748 453
|
||||
-1220 665 -104 47 -365 149 -480 188 -66 23 -153 53 -192 67 -70 24 -121 39
|
||||
-443 126 -185 51 -441 104 -690 144 -19 3 -57 10 -85 15 -56 11 -319 45 -410
|
||||
54 -209 20 -922 45 -935 33z m575 -461 c17 -2 82 -7 145 -10 102 -6 154 -11
|
||||
345 -31 74 -8 198 -25 226 -30 13 -3 51 -10 84 -16 168 -30 472 -93 579 -120
|
||||
257 -65 724 -215 853 -274 17 -8 34 -15 38 -15 35 0 595 -263 805 -378 177
|
||||
-97 434 -250 519 -310 417 -291 523 -372 836 -640 186 -159 590 -568 720 -728
|
||||
22 -27 50 -60 63 -74 31 -34 236 -299 297 -384 113 -158 187 -265 227 -330 24
|
||||
-37 55 -87 70 -110 26 -39 46 -73 119 -199 19 -32 39 -66 44 -75 95 -158 295
|
||||
-563 362 -732 14 -36 35 -85 46 -110 11 -25 30 -74 43 -110 12 -36 32 -90 44
|
||||
-120 115 -294 263 -838 315 -1160 3 -19 8 -48 10 -65 3 -16 10 -50 15 -75 5
|
||||
-25 17 -98 25 -162 9 -65 18 -126 20 -137 2 -11 7 -51 10 -88 4 -37 9 -70 10
|
||||
-73 2 -3 6 -61 10 -130 4 -69 9 -134 11 -145 2 -11 7 -153 10 -315 10 -452
|
||||
-18 -894 -82 -1275 -13 -82 -27 -163 -30 -180 -14 -86 -87 -432 -108 -510 -56
|
||||
-213 -143 -495 -216 -695 -83 -229 -88 -241 -132 -338 -15 -34 -28 -64 -28
|
||||
-67 0 -3 -16 -40 -36 -82 -20 -43 -43 -96 -52 -118 -8 -22 -18 -44 -22 -50 -5
|
||||
-5 -41 -75 -82 -155 -226 -438 -544 -931 -788 -1220 -26 -30 -91 -109 -145
|
||||
-175 -196 -239 -592 -642 -781 -796 -44 -35 -88 -72 -99 -82 -43 -40 -333
|
||||
-268 -415 -327 -304 -217 -605 -403 -917 -566 -60 -31 -112 -60 -118 -64 -5
|
||||
-4 -48 -24 -95 -45 -47 -21 -121 -56 -165 -77 -170 -83 -738 -294 -910 -338
|
||||
-16 -5 -100 -28 -186 -53 -86 -25 -194 -53 -240 -62 -46 -9 -133 -27 -194 -40
|
||||
-114 -25 -362 -69 -450 -79 -27 -4 -61 -8 -75 -11 -49 -9 -337 -35 -475 -42
|
||||
-308 -17 -968 -5 -1205 22 -42 5 -113 12 -195 20 -32 4 -62 8 -65 10 -3 2 -29
|
||||
6 -58 10 -228 29 -684 127 -917 197 -55 16 -122 36 -150 44 -63 17 -391 131
|
||||
-510 177 -490 188 -1026 473 -1499 797 -139 95 -529 393 -576 440 -3 3 -23 20
|
||||
-45 39 -107 90 -246 221 -405 380 -184 185 -198 200 -350 376 -52 61 -97 112
|
||||
-100 115 -8 8 -233 292 -261 330 -86 117 -247 355 -331 490 -43 69 -83 132
|
||||
-88 140 -47 67 -324 612 -390 765 -88 204 -100 234 -164 407 -89 239 -182 546
|
||||
-256 848 -28 110 -97 462 -109 556 -7 44 -13 89 -15 100 -5 25 -14 95 -21 169
|
||||
-4 33 -8 69 -10 81 -2 11 -6 65 -10 120 -4 54 -9 102 -11 106 -6 9 -19 401
|
||||
-19 548 0 129 13 482 19 520 3 14 7 68 11 120 3 52 8 104 10 115 2 11 7 49 10
|
||||
85 3 36 8 79 10 95 40 296 60 412 112 655 20 91 37 172 38 180 3 23 49 180
|
||||
117 398 11 34 21 68 22 75 4 21 36 119 66 197 16 41 47 127 70 190 37 101 106
|
||||
259 214 495 18 39 41 89 51 113 10 23 22 42 27 42 4 0 8 9 8 19 0 11 3 21 8
|
||||
23 4 2 23 35 42 73 36 72 141 257 202 355 19 30 45 75 59 100 13 25 27 49 32
|
||||
55 4 5 50 74 103 153 127 192 220 319 324 446 19 24 49 60 65 82 34 44 136
|
||||
167 145 174 3 3 16 18 29 35 12 16 55 64 94 106 40 41 106 113 147 158 41 46
|
||||
97 104 125 129 88 83 115 112 115 123 0 5 4 8 9 4 5 -3 18 6 29 20 11 14 23
|
||||
25 27 25 4 0 37 29 74 64 36 36 84 78 106 94 22 16 51 40 65 53 45 42 154 134
|
||||
192 162 20 15 42 33 50 40 7 7 29 24 48 37 19 13 40 29 46 35 6 5 22 17 34 25
|
||||
13 8 35 24 49 35 14 12 61 45 104 75 43 30 104 73 135 95 32 23 79 54 106 70
|
||||
27 17 60 38 75 47 14 10 37 24 51 32 14 8 49 30 79 50 29 20 56 36 60 36 4 0
|
||||
59 31 122 68 93 56 558 292 574 292 2 0 48 21 102 46 104 48 110 51 408 161
|
||||
429 160 871 273 1370 353 132 21 141 22 365 45 85 8 175 17 200 19 25 3 104 8
|
||||
175 12 72 3 132 8 134 10 5 5 596 -5 636 -10z"/>
|
||||
<path d="M9965 17209 c-104 -4 -244 -12 -310 -18 -66 -6 -149 -14 -185 -17
|
||||
-101 -9 -425 -58 -585 -89 -287 -55 -411 -88 -845 -224 -368 -115 -910 -357
|
||||
-1246 -556 -18 -11 -53 -30 -76 -43 -24 -13 -72 -42 -108 -65 -36 -22 -98 -61
|
||||
-138 -86 -40 -25 -100 -65 -132 -88 -33 -24 -90 -64 -127 -89 -104 -72 -208
|
||||
-150 -317 -239 -54 -44 -110 -89 -125 -100 -33 -24 -241 -211 -291 -260 -19
|
||||
-19 -38 -35 -42 -35 -5 0 -8 -7 -8 -16 0 -8 -3 -13 -8 -11 -11 7 -311 -299
|
||||
-410 -418 -18 -22 -46 -56 -62 -75 -16 -19 -55 -66 -87 -105 -32 -38 -65 -77
|
||||
-74 -85 -35 -34 -315 -412 -359 -485 -13 -22 -50 -80 -82 -128 -32 -48 -58
|
||||
-90 -58 -93 0 -3 -13 -25 -30 -49 -16 -24 -30 -46 -30 -49 0 -4 -18 -37 -41
|
||||
-74 -43 -70 -143 -256 -215 -402 -47 -95 -204 -439 -204 -448 0 -8 -60 -164
|
||||
-71 -185 -13 -24 -78 -221 -119 -357 -17 -58 -40 -130 -50 -160 -27 -79 -75
|
||||
-271 -99 -391 -11 -57 -34 -169 -50 -249 -27 -136 -53 -288 -65 -390 -3 -25
|
||||
-8 -65 -11 -90 -3 -25 -12 -129 -20 -230 -16 -217 -14 -1077 4 -1230 6 -52 13
|
||||
-120 16 -150 3 -30 7 -71 10 -90 3 -19 7 -55 10 -80 8 -63 23 -145 51 -290 14
|
||||
-69 27 -136 30 -150 19 -94 89 -384 108 -448 13 -42 45 -147 70 -232 103 -350
|
||||
252 -715 443 -1088 247 -483 611 -1019 936 -1382 327 -364 509 -541 857 -831
|
||||
221 -184 493 -378 782 -557 200 -124 634 -351 813 -425 33 -14 109 -46 169
|
||||
-71 60 -25 113 -43 118 -40 4 3 8 1 8 -5 0 -5 10 -12 23 -16 12 -3 31 -10 42
|
||||
-15 72 -30 170 -64 305 -105 85 -26 180 -55 211 -66 57 -19 398 -103 454 -112
|
||||
17 -3 71 -14 121 -26 102 -23 418 -77 509 -86 33 -4 70 -8 82 -10 12 -2 57 -7
|
||||
100 -10 43 -4 85 -9 94 -10 52 -10 351 -20 584 -20 579 0 928 35 1410 140 11
|
||||
3 34 7 50 10 377 74 958 259 1320 422 55 25 116 52 135 60 111 48 395 196 560
|
||||
291 52 30 114 65 137 78 23 13 91 55 150 94 255 164 427 288 623 450 36 30 85
|
||||
70 107 88 22 18 56 47 75 65 19 18 60 55 93 82 32 28 81 70 109 95 58 50 229
|
||||
222 295 296 25 27 72 78 105 114 90 97 157 174 226 260 19 24 40 48 45 54 6 6
|
||||
26 31 45 56 19 25 37 47 40 50 3 3 17 21 30 40 13 19 27 37 30 40 5 4 157 217
|
||||
200 280 60 88 187 286 221 343 23 40 58 99 78 132 52 88 250 483 305 610 72
|
||||
168 199 498 234 610 17 55 45 144 62 198 140 450 250 1047 277 1512 16 261 7
|
||||
1098 -12 1158 -2 6 -6 48 -9 92 -8 106 -44 365 -61 440 -7 33 -16 78 -20 100
|
||||
-7 48 -67 327 -94 440 -22 91 -61 226 -86 299 -9 26 -18 58 -21 69 -20 104
|
||||
-173 508 -276 727 -22 47 -48 105 -58 130 -21 52 -134 272 -210 410 -29 52
|
||||
-66 120 -83 150 -63 116 -120 200 -131 193 -5 -3 -6 -2 -3 4 4 5 -18 47 -48
|
||||
93 -30 45 -55 86 -55 90 0 5 -4 10 -8 12 -5 2 -28 32 -52 68 -61 91 -139 198
|
||||
-175 241 -16 20 -41 51 -55 70 -14 18 -54 67 -90 109 -36 42 -81 95 -100 119
|
||||
-103 129 -191 224 -394 426 -211 209 -371 353 -586 524 -91 72 -169 135 -175
|
||||
139 -59 48 -393 272 -404 272 -5 0 -11 3 -13 8 -9 22 -362 229 -568 333 -138
|
||||
70 -207 103 -415 197 -196 89 -741 283 -840 299 -11 2 -31 8 -45 13 -71 27
|
||||
-359 94 -584 135 -43 8 -86 17 -95 19 -29 9 -284 45 -426 60 -328 35 -681 47
|
||||
-1040 35z m690 -489 c94 -5 188 -12 210 -15 22 -2 67 -7 100 -10 33 -3 71 -8
|
||||
85 -10 14 -3 48 -7 75 -10 89 -10 118 -15 205 -31 104 -19 311 -62 365 -75 22
|
||||
-5 49 -11 60 -14 50 -9 191 -47 345 -93 98 -29 365 -119 418 -141 26 -11 103
|
||||
-42 172 -69 142 -57 219 -92 440 -199 144 -71 226 -116 405 -222 39 -23 79
|
||||
-48 90 -54 105 -63 434 -287 505 -344 8 -7 69 -55 135 -108 403 -322 738 -660
|
||||
1087 -1095 141 -176 321 -436 428 -617 38 -65 74 -123 80 -130 5 -7 10 -14 10
|
||||
-16 0 -3 30 -58 67 -123 60 -107 115 -218 242 -488 98 -208 304 -801 337 -970
|
||||
2 -10 10 -42 18 -70 8 -28 17 -62 20 -76 15 -71 47 -217 51 -230 9 -29 64
|
||||
-377 74 -465 45 -397 47 -438 44 -885 -3 -753 -138 -1472 -408 -2184 -98 -260
|
||||
-103 -272 -162 -396 -25 -52 -58 -126 -74 -164 -68 -162 -323 -604 -488 -846
|
||||
-116 -170 -317 -431 -425 -550 -23 -25 -66 -75 -96 -110 -221 -259 -632 -634
|
||||
-946 -863 -49 -36 -100 -74 -114 -85 -243 -184 -755 -479 -1081 -622 -52 -23
|
||||
-116 -52 -144 -65 -27 -13 -93 -39 -145 -60 -52 -20 -108 -42 -125 -50 -93
|
||||
-42 -516 -173 -690 -215 -164 -39 -474 -101 -670 -134 -242 -41 -769 -72
|
||||
-1059 -62 -259 9 -553 32 -721 57 -257 37 -729 136 -925 194 -151 45 -360 113
|
||||
-450 147 -237 89 -262 100 -523 222 -55 25 -101 46 -105 46 -13 0 -360 191
|
||||
-517 285 -237 142 -319 198 -610 420 -609 463 -1168 1098 -1581 1795 -108 182
|
||||
-206 360 -244 445 -18 39 -59 129 -92 200 -85 185 -94 206 -176 425 -75 199
|
||||
-179 535 -224 725 -16 70 -99 478 -104 515 -2 19 -6 49 -9 65 -8 53 -22 164
|
||||
-31 245 -3 30 -7 66 -10 80 -25 156 -25 943 0 1204 20 214 22 226 47 386 11
|
||||
69 22 139 25 155 3 17 7 37 9 45 2 8 6 26 9 40 15 83 70 340 91 425 87 347
|
||||
256 815 393 1090 17 33 49 101 73 150 23 50 75 149 116 222 40 72 73 136 73
|
||||
141 0 6 4 12 8 14 5 2 31 41 58 88 47 82 123 202 144 227 5 7 34 47 63 90 134
|
||||
197 278 386 406 534 36 42 85 98 108 125 87 103 468 481 591 587 282 241 656
|
||||
514 907 661 44 26 94 55 110 65 83 49 345 189 380 203 22 9 87 39 145 66 58
|
||||
28 143 66 190 85 47 20 119 50 160 67 78 33 290 108 325 116 11 2 31 8 45 14
|
||||
25 10 127 42 275 85 359 105 972 203 1360 218 202 8 621 6 770 -3z"/>
|
||||
<path d="M6968 11818 c-19 -24 -54 -72 -79 -108 -24 -36 -46 -67 -49 -70 -3
|
||||
-3 -40 -57 -83 -120 -43 -63 -104 -151 -134 -195 -31 -44 -99 -143 -151 -220
|
||||
-144 -211 -150 -220 -249 -360 -119 -169 -168 -239 -248 -355 -36 -52 -117
|
||||
-169 -180 -260 -62 -91 -153 -221 -200 -290 -47 -69 -133 -190 -190 -270 -57
|
||||
-80 -143 -201 -190 -270 -47 -69 -115 -168 -152 -220 -211 -303 -256 -372
|
||||
-242 -380 7 -5 448 -9 979 -9 l967 0 24 40 c13 22 51 77 84 123 33 46 87 123
|
||||
120 171 33 47 83 117 110 155 28 38 75 105 105 149 30 45 61 89 68 98 7 10 39
|
||||
56 72 103 32 47 63 90 67 95 4 6 21 30 38 55 16 25 33 47 36 50 3 3 47 66 98
|
||||
140 97 143 253 365 274 390 6 9 25 36 42 60 16 25 42 62 59 83 l29 38 -24 42
|
||||
c-22 40 -82 129 -104 154 -5 6 -53 73 -105 148 -52 75 -124 177 -159 228 -36
|
||||
51 -88 126 -116 167 -28 41 -110 156 -181 255 -71 99 -142 201 -159 225 -34
|
||||
52 -125 181 -135 193 -4 4 -22 -11 -42 -35z"/>
|
||||
<path d="M13350 11799 c-19 -28 -44 -63 -56 -77 -12 -15 -55 -76 -96 -137 -41
|
||||
-60 -133 -191 -203 -290 -137 -191 -215 -302 -264 -375 -17 -25 -96 -137 -176
|
||||
-249 -80 -112 -145 -207 -145 -211 0 -4 12 -25 27 -46 15 -21 63 -93 108 -159
|
||||
99 -146 180 -264 254 -369 31 -43 76 -109 101 -145 25 -36 86 -122 135 -191
|
||||
49 -69 120 -172 159 -229 57 -85 324 -468 353 -506 5 -6 21 -28 37 -50 62 -83
|
||||
-49 -75 1043 -75 678 0 973 3 973 11 0 5 -4 7 -10 4 -5 -3 -7 0 -5 8 3 7 -16
|
||||
42 -43 78 -26 35 -73 100 -103 144 -61 87 -348 498 -427 610 -27 39 -111 158
|
||||
-187 265 -145 204 -210 299 -307 440 -31 47 -72 105 -89 130 -18 25 -66 95
|
||||
-107 155 -42 61 -78 112 -81 115 -4 3 -15 19 -25 35 -11 17 -72 104 -136 195
|
||||
-65 91 -165 235 -223 320 -58 85 -111 154 -117 152 -6 -1 -9 2 -6 7 3 4 -8 28
|
||||
-25 52 -16 24 -82 121 -144 214 -115 170 -157 225 -172 225 -4 0 -24 -23 -43
|
||||
-51z"/>
|
||||
<path d="M7585 7681 c-2 -4 -4 -405 -4 -892 l0 -885 217 1 217 0 5 360 5 360
|
||||
380 0 380 0 5 -360 5 -360 70 -1 c39 0 77 3 86 7 9 5 19 6 22 2 3 -3 63 -6
|
||||
132 -7 l125 -1 0 435 c1 1112 0 1334 -10 1340 -9 5 -398 7 -422 2 -4 -1 -9
|
||||
-156 -10 -344 l-3 -343 -25 -2 c-65 -4 -104 -4 -372 -3 -158 0 -291 0 -295 -1
|
||||
-5 -1 -23 -1 -40 0 l-33 1 -2 348 -3 347 -213 1 c-117 1 -214 -1 -217 -5z"/>
|
||||
<path d="M9699 7686 c-2 -3 -4 -404 -3 -892 l2 -888 693 -1 c382 0 700 1 707
|
||||
3 9 3 12 47 12 173 l0 169 -482 2 -483 3 -2 25 c-1 14 -2 99 -3 190 l-2 165
|
||||
24 3 c12 1 196 3 408 5 l385 2 3 162 2 162 -406 1 c-223 0 -409 2 -412 4 -4 2
|
||||
-6 85 -4 185 l3 181 463 0 464 0 4 23 c5 25 0 296 -6 312 -4 10 -1356 21
|
||||
-1367 11z"/>
|
||||
<path d="M11360 7515 l0 -176 460 2 c253 2 463 0 466 -4 8 -7 -64 -96 -233
|
||||
-290 -13 -15 -67 -81 -120 -145 -169 -205 -287 -346 -325 -387 -20 -22 -47
|
||||
-53 -59 -70 -35 -46 -129 -155 -172 -202 l-40 -42 -1 -148 -1 -148 785 0 c432
|
||||
0 792 1 800 3 13 3 15 28 13 169 -2 92 -4 168 -6 169 -2 2 -227 4 -500 4 -320
|
||||
1 -497 4 -497 11 0 8 91 131 110 149 3 3 25 30 50 60 25 30 49 60 55 66 5 6
|
||||
26 30 45 54 19 24 51 62 70 85 43 51 84 101 151 185 28 36 61 76 73 90 11 14
|
||||
39 47 61 75 52 65 55 68 183 222 61 72 116 142 123 155 8 14 13 69 13 146 1
|
||||
101 -2 125 -14 132 -8 4 -347 8 -752 9 l-738 1 0 -175z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 476 KiB |
@@ -0,0 +1,154 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="1795.000000pt" height="415.000000pt" viewBox="0 0 1795.000000 415.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,415.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M110 2115 l0 -1945 8820 0 8820 0 0 1945 0 1945 -8820 0 -8820 0 0
|
||||
-1945z m17590 0 l0 -1895 -8770 0 -8770 0 0 1895 0 1895 8770 0 8770 0 0
|
||||
-1895z"/>
|
||||
<path d="M1870 3831 c-14 -5 -47 -9 -73 -10 -45 -1 -160 -40 -230 -78 -15 -8
|
||||
-39 -20 -52 -27 -28 -15 -95 -85 -95 -100 0 -5 -8 -18 -17 -28 -24 -26 -24
|
||||
-135 0 -171 9 -14 17 -32 17 -39 1 -19 54 -75 79 -83 12 -3 21 -10 21 -15 0
|
||||
-4 19 -17 43 -28 148 -69 151 -70 284 -83 179 -17 319 -2 453 49 52 20 97 39
|
||||
100 43 3 3 24 18 47 33 62 38 123 143 123 211 0 47 -105 205 -136 205 -4 0
|
||||
-15 7 -24 15 -28 25 -192 87 -255 96 -94 14 -257 19 -285 10z"/>
|
||||
<path d="M3810 2125 l0 -1685 95 0 95 0 0 1685 0 1685 -95 0 -95 0 0 -1685z"/>
|
||||
<path d="M17320 2125 l0 -1685 95 0 95 0 0 1685 0 1685 -95 0 -95 0 0 -1685z"/>
|
||||
<path d="M1320 3620 c0 -5 -13 -7 -30 -3 -18 3 -30 1 -30 -5 0 -6 10 -12 23
|
||||
-14 20 -3 22 -9 25 -71 4 -86 22 -79 22 9 0 36 4 64 10 64 15 0 12 17 -5 24
|
||||
-8 3 -15 1 -15 -4z"/>
|
||||
<path d="M1283 3423 c24 -4 27 -8 28 -46 0 -23 5 -51 10 -62 6 -14 8 -2 6 42
|
||||
-1 49 1 63 13 67 8 2 -7 4 -35 3 -27 0 -38 -2 -22 -4z"/>
|
||||
<path d="M989 3399 c-25 -4 -66 -16 -92 -28 -25 -12 -49 -21 -53 -21 -4 0 -22
|
||||
-11 -40 -25 -18 -14 -36 -25 -41 -25 -12 -1 -103 -87 -103 -98 0 -5 -11 -17
|
||||
-25 -26 -14 -9 -25 -23 -25 -30 0 -7 -7 -19 -15 -26 -16 -14 -104 -172 -109
|
||||
-198 -1 -9 -8 -29 -13 -43 -6 -14 -17 -60 -24 -102 -14 -84 -2 -179 27 -221 8
|
||||
-11 14 -27 14 -35 0 -15 60 -75 91 -92 10 -5 54 -9 99 -9 70 0 89 4 148 32 37
|
||||
18 72 37 78 43 6 5 23 19 39 30 37 26 86 76 133 134 20 25 40 48 45 49 4 2 7
|
||||
12 7 22 0 10 5 22 10 25 6 4 29 46 52 93 76 162 75 369 -3 470 -48 62 -124 93
|
||||
-200 81z"/>
|
||||
<path d="M2848 3355 c-53 -11 -97 -48 -132 -111 -47 -84 -42 -293 9 -402 81
|
||||
-170 84 -174 198 -292 37 -39 71 -70 76 -70 4 0 21 -11 37 -25 16 -14 43 -29
|
||||
59 -35 17 -5 48 -16 70 -24 53 -20 138 -20 178 0 37 19 97 73 97 88 0 6 6 23
|
||||
14 38 31 60 40 134 26 221 -7 45 -17 93 -23 107 -6 14 -12 34 -14 44 -2 11
|
||||
-17 41 -33 68 -17 27 -30 52 -30 56 0 12 -82 120 -126 168 -120 129 -282 196
|
||||
-406 169z"/>
|
||||
<path d="M8337 3052 c-10 -10 -17 -25 -17 -34 0 -8 -11 -62 -25 -119 -13 -57
|
||||
-29 -124 -35 -149 -11 -49 -72 -305 -125 -525 -47 -196 -84 -351 -97 -410 -6
|
||||
-27 -14 -63 -19 -79 -21 -67 -23 -66 125 -66 l134 0 37 153 c20 83 43 182 52
|
||||
220 9 37 21 67 27 67 6 0 17 -15 25 -32 17 -41 53 -120 86 -193 14 -31 25 -58
|
||||
25 -61 0 -8 39 -95 55 -124 14 -25 16 -25 160 -28 l147 -3 -7 31 c-6 29 -22
|
||||
67 -92 220 -14 30 -40 89 -58 130 -19 41 -41 89 -49 105 -9 17 -16 35 -16 41
|
||||
0 5 95 104 210 218 127 126 210 215 210 227 0 18 -9 19 -142 19 l-142 0 -188
|
||||
-188 c-104 -103 -190 -186 -193 -184 -2 2 0 14 5 25 5 12 20 74 35 137 14 63
|
||||
30 131 35 150 12 41 52 215 81 349 27 121 27 121 -121 121 -91 0 -109 -3 -123
|
||||
-18z"/>
|
||||
<path d="M13100 3055 c-7 -8 -23 -61 -35 -118 -12 -56 -37 -163 -54 -237 -18
|
||||
-74 -41 -173 -52 -220 -19 -81 -26 -109 -49 -197 -5 -21 -16 -67 -24 -103 -37
|
||||
-163 -78 -338 -86 -370 -5 -19 -12 -59 -16 -87 l-7 -53 131 0 130 0 10 33 c11
|
||||
36 23 82 51 207 52 222 92 384 100 397 4 8 29 37 55 63 87 89 177 100 204 25
|
||||
15 -40 6 -106 -39 -295 -16 -69 -34 -145 -40 -170 -6 -25 -14 -61 -20 -81 -5
|
||||
-20 -14 -61 -19 -90 -6 -30 -13 -62 -16 -72 -5 -16 4 -17 132 -15 l138 3 12
|
||||
45 c25 98 98 416 125 545 21 101 24 210 8 269 -6 21 -28 57 -50 81 -32 35 -52
|
||||
46 -104 60 -101 28 -195 3 -315 -82 -23 -18 -24 -17 -16 2 4 11 25 94 46 185
|
||||
22 91 44 186 50 211 18 77 15 79 -120 79 -93 0 -120 -3 -130 -15z"/>
|
||||
<path d="M11794 3036 c-69 -31 -117 -155 -84 -217 17 -31 64 -49 131 -49 116
|
||||
0 179 63 179 178 0 72 -29 96 -123 99 -46 2 -83 -2 -103 -11z"/>
|
||||
<path d="M15033 3034 c-41 -21 -62 -44 -79 -91 -23 -67 -18 -111 17 -144 28
|
||||
-26 38 -29 101 -29 89 0 139 25 168 85 22 45 26 115 9 147 -24 45 -151 64
|
||||
-216 32z"/>
|
||||
<path d="M5515 2961 c-42 -18 -48 -35 -101 -261 -20 -85 -47 -200 -61 -255
|
||||
-14 -55 -28 -116 -33 -135 -4 -19 -31 -132 -60 -250 -29 -118 -58 -244 -66
|
||||
-280 -8 -36 -16 -75 -19 -87 l-5 -23 139 0 140 0 15 53 c14 47 23 86 57 242 5
|
||||
22 15 63 22 90 l13 50 140 6 c191 8 277 34 389 114 91 64 139 130 183 248 25
|
||||
66 31 229 10 288 -30 87 -92 145 -195 182 -51 18 -87 21 -303 24 -135 1 -254
|
||||
-1 -265 -6z m422 -244 c62 -33 78 -107 46 -208 -22 -69 -82 -130 -148 -152
|
||||
-31 -11 -81 -17 -138 -17 -78 0 -88 2 -83 16 6 17 48 191 72 303 8 35 17 68
|
||||
20 73 11 17 194 5 231 -15z"/>
|
||||
<path d="M6735 2676 c-310 -58 -494 -324 -483 -696 4 -124 24 -175 98 -244 57
|
||||
-53 132 -82 236 -91 135 -12 338 28 390 76 19 18 44 112 44 167 0 32 -38 36
|
||||
-109 13 -34 -11 -100 -28 -147 -37 -80 -16 -89 -16 -138 -1 -29 9 -62 27 -74
|
||||
39 -28 31 -47 105 -38 151 l7 37 124 0 c221 0 344 28 423 96 67 57 93 111 99
|
||||
202 8 118 -23 193 -102 242 -76 47 -219 67 -330 46z m122 -206 c58 -21 71
|
||||
-100 24 -152 l-29 -33 -141 -3 c-163 -4 -164 -4 -110 80 60 93 167 138 256
|
||||
108z"/>
|
||||
<path d="M12495 2684 c-11 -2 -45 -9 -75 -15 -94 -18 -208 -80 -271 -146 -133
|
||||
-140 -208 -349 -196 -546 6 -107 28 -166 83 -227 109 -121 334 -142 538 -50
|
||||
75 33 87 50 109 158 13 64 13 75 0 87 -20 21 -26 20 -125 -26 -182 -84 -304
|
||||
-54 -324 79 -8 49 8 188 25 219 5 10 19 39 30 64 52 113 135 173 242 174 57 0
|
||||
75 -5 143 -40 72 -37 79 -39 103 -25 30 17 51 70 60 151 5 53 4 57 -23 76 -66
|
||||
47 -237 83 -319 67z"/>
|
||||
<path d="M14235 2676 c-206 -36 -264 -84 -265 -218 0 -56 22 -63 108 -34 85
|
||||
29 212 50 251 41 56 -12 76 -65 56 -153 -7 -36 -14 -38 -165 -46 -151 -8 -269
|
||||
-54 -349 -134 -61 -62 -90 -125 -97 -215 -11 -125 25 -198 121 -250 32 -18 56
|
||||
-22 125 -22 96 1 143 17 223 78 26 21 49 37 52 37 2 0 5 -19 7 -42 l3 -43 108
|
||||
-3 c59 -1 107 -1 107 0 0 5 29 159 45 238 8 41 23 111 34 155 11 44 27 116 36
|
||||
160 9 44 21 96 26 116 23 89 -1 208 -52 260 -38 39 -97 65 -179 78 -78 13
|
||||
-104 13 -195 -3z m91 -623 c-13 -73 -28 -103 -68 -137 -53 -46 -98 -66 -145
|
||||
-66 -57 0 -77 25 -71 88 10 101 83 148 232 151 l58 1 -6 -37z"/>
|
||||
<path d="M15800 2679 c-58 -17 -114 -45 -163 -83 -26 -20 -49 -36 -52 -36 -2
|
||||
0 -5 21 -7 48 l-3 47 -96 3 c-109 3 -110 3 -126 -73 -26 -117 -65 -283 -73
|
||||
-315 -10 -39 -34 -144 -75 -325 -14 -66 -30 -133 -35 -150 -5 -16 -12 -51 -15
|
||||
-77 l-7 -48 130 0 129 0 11 43 c21 80 91 382 107 462 9 44 25 98 34 120 31 69
|
||||
135 155 188 155 12 0 35 -11 50 -24 26 -22 28 -30 27 -88 -1 -35 -18 -133 -38
|
||||
-218 -20 -85 -43 -189 -52 -230 -9 -41 -20 -88 -24 -105 -5 -16 -12 -49 -15
|
||||
-72 l-7 -43 134 0 134 0 29 123 c15 67 38 163 50 212 13 50 31 126 40 170 10
|
||||
44 24 105 31 135 30 119 12 241 -45 304 -52 57 -179 89 -261 65z"/>
|
||||
<path d="M7334 2604 c-9 -31 -17 -77 -17 -102 l-2 -47 198 -3 c108 -1 197 -3
|
||||
197 -5 0 -1 -85 -88 -188 -193 -413 -420 -387 -391 -406 -473 -28 -122 -63
|
||||
-111 374 -111 350 0 378 1 385 18 14 34 34 127 35 160 l0 32 -215 0 c-118 0
|
||||
-215 3 -215 6 0 4 105 115 233 248 366 379 350 361 366 438 7 37 10 72 6 77
|
||||
-4 8 -124 11 -370 11 l-364 0 -17 -56z"/>
|
||||
<path d="M9217 2642 c-10 -10 -17 -26 -17 -34 0 -16 -15 -84 -85 -378 -67
|
||||
-282 -73 -325 -54 -413 41 -194 290 -234 486 -79 l52 42 3 -53 3 -52 106 -3
|
||||
c122 -3 105 -20 139 133 12 50 25 106 30 125 14 51 119 484 136 560 8 36 20
|
||||
84 26 108 7 28 7 47 1 53 -6 6 -62 8 -134 7 l-124 -3 -17 -55 c-9 -30 -42
|
||||
-161 -73 -290 -64 -267 -78 -304 -132 -355 -80 -77 -154 -95 -200 -49 -24 24
|
||||
-25 31 -20 87 3 34 20 121 37 192 17 72 42 180 56 240 14 61 29 126 34 146 6
|
||||
20 10 48 10 63 l0 26 -123 0 c-107 0 -126 -2 -140 -18z"/>
|
||||
<path d="M10177 2654 c-9 -9 -8 -342 2 -686 6 -194 11 -271 21 -282 10 -13 37
|
||||
-16 146 -16 l133 0 50 103 c47 98 105 221 149 317 11 25 33 72 49 105 l28 60
|
||||
5 -280 c3 -154 9 -286 13 -292 6 -9 46 -13 141 -13 114 0 135 2 148 18 8 9 87
|
||||
159 175 332 89 173 193 377 232 454 40 76 71 148 69 160 -3 20 -10 21 -117 24
|
||||
-81 2 -118 -1 -129 -10 -8 -7 -29 -44 -47 -83 -18 -38 -44 -95 -58 -125 -14
|
||||
-30 -48 -104 -77 -165 -29 -60 -68 -148 -87 -195 -19 -47 -38 -89 -42 -93 -4
|
||||
-4 -6 140 -3 320 4 286 3 330 -11 341 -10 9 -46 12 -118 10 l-104 -3 -47 -95
|
||||
c-89 -178 -206 -427 -238 -504 -18 -42 -33 -76 -35 -76 -1 0 -2 152 -1 338 l1
|
||||
337 -121 3 c-66 1 -123 -1 -127 -4z"/>
|
||||
<path d="M11678 2643 c-8 -10 -23 -52 -32 -93 -26 -113 -66 -281 -76 -320 -5
|
||||
-19 -21 -84 -35 -145 -14 -60 -36 -155 -50 -210 -13 -55 -27 -116 -30 -135 -4
|
||||
-19 -9 -43 -11 -52 -5 -17 6 -18 130 -18 l134 0 11 33 c6 17 22 84 37 147 14
|
||||
63 39 171 56 240 16 69 33 143 37 165 5 22 16 68 25 103 26 97 64 291 58 297
|
||||
-3 3 -58 5 -122 5 -99 0 -119 -3 -132 -17z"/>
|
||||
<path d="M14925 2640 c-15 -17 -36 -90 -75 -270 -12 -55 -31 -135 -60 -260
|
||||
-25 -105 -33 -141 -49 -215 -5 -27 -17 -81 -25 -120 -25 -114 -35 -105 113
|
||||
-105 l128 0 16 58 c8 31 27 109 42 172 14 63 35 153 46 200 27 116 43 184 74
|
||||
325 15 66 31 133 36 149 5 16 9 42 9 57 l0 29 -118 0 c-106 0 -121 -2 -137
|
||||
-20z"/>
|
||||
<path d="M3185 2022 c-68 -17 -165 -77 -242 -148 -56 -53 -136 -158 -148 -192
|
||||
-3 -12 -10 -22 -15 -22 -4 0 -15 -19 -25 -42 -9 -24 -22 -56 -29 -73 -7 -16
|
||||
-18 -43 -25 -58 -17 -42 -24 -213 -13 -284 11 -64 42 -117 91 -158 58 -47 211
|
||||
-46 291 3 19 12 44 26 55 31 11 5 29 18 39 30 11 11 23 21 27 21 5 0 27 21 51
|
||||
46 24 26 51 55 61 65 9 11 17 23 17 27 0 5 9 18 20 30 25 26 78 120 108 192
|
||||
37 86 47 139 47 240 0 95 -3 111 -28 162 -34 69 -72 107 -123 123 -66 21 -97
|
||||
23 -159 7z"/>
|
||||
<path d="M608 2016 c-69 -13 -114 -51 -152 -128 -23 -47 -26 -63 -26 -167 0
|
||||
-124 8 -160 62 -280 16 -35 36 -70 44 -78 8 -8 14 -19 14 -24 0 -5 25 -42 55
|
||||
-83 89 -120 224 -222 332 -248 60 -15 74 -14 165 8 37 8 82 56 112 117 24 46
|
||||
26 62 26 169 0 113 -3 132 -40 223 -28 71 -82 175 -104 200 -14 17 -26 34 -26
|
||||
40 0 12 -170 175 -195 186 -11 5 -36 19 -55 31 -19 11 -55 25 -80 30 -25 4
|
||||
-52 10 -60 12 -8 2 -41 -1 -72 -8z"/>
|
||||
<path d="M1869 1315 c-141 -18 -286 -79 -366 -154 -28 -26 -69 -97 -77 -133
|
||||
-14 -60 30 -165 90 -218 41 -36 91 -70 104 -70 5 0 10 -4 10 -9 0 -5 13 -12
|
||||
30 -16 16 -3 46 -14 67 -24 61 -29 276 -46 398 -31 98 11 190 34 210 51 5 5
|
||||
18 9 30 9 12 0 42 14 68 30 26 17 50 30 54 30 13 0 79 85 92 119 23 60 24 121
|
||||
4 172 -18 46 -74 119 -91 119 -5 0 -21 10 -36 23 -50 43 -182 88 -301 103
|
||||
-129 16 -158 15 -286 -1z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.9 KiB |
|
After Width: | Height: | Size: 586 KiB |
@@ -0,0 +1,229 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="1920.000000pt" height="544.000000pt" viewBox="0 0 1920.000000 544.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,544.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M0 2720 l0 -2720 9600 0 9600 0 0 2720 0 2720 -9600 0 -9600 0 0
|
||||
-2720z m1543 804 c7 -7 -25 -100 -60 -173 -45 -94 -112 -189 -196 -277 -254
|
||||
-269 -527 -297 -639 -66 -31 65 -33 71 -33 192 0 116 9 177 38 270 20 64 -8
|
||||
60 457 60 234 0 429 -3 433 -6z m2607 -14 c43 -86 55 -155 55 -305 0 -133 -1
|
||||
-143 -28 -197 -34 -70 -101 -131 -162 -148 -48 -13 -159 -9 -192 8 -10 5 -38
|
||||
20 -63 32 -160 82 -322 253 -416 440 -34 67 -73 177 -66 185 3 3 199 4 435 3
|
||||
370 -3 431 -5 437 -18z m-1726 -115 c12 -119 28 -230 35 -238 8 -8 38 56 101
|
||||
216 23 59 44 106 47 104 6 -7 -38 -299 -48 -319 -14 -28 0 -21 29 13 14 18 48
|
||||
49 75 70 27 22 46 39 42 39 -3 0 15 27 40 60 25 33 48 60 50 60 11 0 -27 -69
|
||||
-52 -93 l-28 -29 30 15 c71 36 88 40 152 40 43 -1 79 -7 98 -17 17 -9 35 -16
|
||||
41 -16 6 0 39 -26 72 -57 53 -48 62 -62 62 -90 0 -43 -20 -34 -21 10 -1 18 -3
|
||||
24 -6 15 -5 -19 -28 -24 -38 -8 -3 5 -11 7 -18 5 -14 -5 -41 14 -50 35 -4 12
|
||||
-6 11 -6 -2 -1 -14 -10 -18 -36 -18 -19 0 -44 -5 -54 -12 -17 -10 -23 -8 -41
|
||||
13 -19 21 -20 22 -8 2 11 -20 10 -25 -7 -37 -23 -18 -45 -20 -45 -6 0 6 -5 10
|
||||
-11 10 -8 0 -8 -4 0 -14 10 -11 7 -17 -10 -29 -21 -15 -49 -13 -49 4 0 5 -5 9
|
||||
-10 9 -6 0 -3 -11 5 -24 14 -22 14 -25 0 -40 -21 -20 -14 -21 -83 14 -33 17
|
||||
-66 30 -73 30 -8 0 13 -14 46 -31 76 -38 81 -44 62 -63 -16 -16 -57 -22 -57
|
||||
-8 0 12 -82 41 -125 44 -38 3 -41 1 -60 -37 -23 -45 -51 -75 -72 -75 -35 0
|
||||
-88 64 -135 160 -9 19 -26 105 -38 190 -12 85 -24 166 -27 180 -11 50 14 4 47
|
||||
-85 51 -141 91 -235 100 -235 8 0 17 57 41 254 14 107 22 104 33 -9z m-349
|
||||
-62 c52 -74 54 -81 16 -54 -26 19 -71 85 -71 106 0 17 20 -2 55 -52z m-75 -20
|
||||
c25 -10 51 -23 58 -30 7 -7 18 -13 23 -13 25 0 134 -112 178 -184 47 -77 49
|
||||
-86 19 -86 -13 0 -45 -12 -73 -25 -58 -29 -90 -32 -99 -9 -4 9 -5 18 -4 19 14
|
||||
12 102 45 120 45 13 0 30 5 38 10 30 19 -33 10 -105 -14 -50 -18 -73 -22 -82
|
||||
-14 -22 18 -14 33 32 58 24 13 43 25 41 27 -6 6 -66 -19 -66 -27 0 -5 -9 -12
|
||||
-21 -15 -28 -9 -69 32 -48 47 11 8 10 9 -3 4 -10 -3 -23 0 -30 7 -7 7 -30 23
|
||||
-50 36 -39 23 -43 30 -30 47 4 5 -1 1 -10 -9 -13 -14 -21 -16 -37 -8 -11 6
|
||||
-38 11 -60 11 -23 0 -41 5 -41 10 0 6 -10 2 -22 -9 -14 -14 -25 -17 -33 -11
|
||||
-7 6 -15 2 -23 -11 -11 -17 -16 -18 -28 -9 -11 10 -14 9 -14 -4 0 -9 -4 -16
|
||||
-10 -16 -5 0 -10 11 -10 24 0 15 18 40 54 74 102 97 213 121 336 75z m3981
|
||||
-98 c102 -30 161 -60 225 -118 91 -82 133 -190 134 -338 0 -102 -16 -165 -65
|
||||
-264 -26 -52 -110 -155 -127 -155 -5 0 -24 -11 -41 -24 -44 -33 -133 -74 -176
|
||||
-82 -20 -4 -42 -12 -50 -18 -9 -7 -90 -12 -235 -13 l-221 -3 -7 -32 c-28 -133
|
||||
-41 -198 -45 -228 -3 -19 -9 -39 -13 -45 -4 -5 -11 -31 -14 -57 -5 -36 -15
|
||||
-53 -39 -74 -27 -23 -37 -25 -76 -20 -24 3 -53 13 -63 22 -17 16 -35 78 -29
|
||||
99 2 6 7 33 12 60 4 28 15 86 23 130 9 44 18 96 21 115 4 19 10 44 15 55 5 11
|
||||
11 36 14 55 3 19 12 71 21 115 9 44 18 94 21 110 3 17 9 39 14 50 5 11 11 36
|
||||
15 55 13 75 24 130 50 245 15 66 31 138 35 160 22 103 27 121 39 142 28 53
|
||||
109 70 352 72 113 1 170 -3 210 -14z m3001 -47 c26 -29 29 -39 25 -78 -5 -43
|
||||
-27 -161 -47 -245 -5 -22 -16 -76 -25 -120 -9 -44 -20 -100 -25 -125 -5 -25
|
||||
-20 -101 -35 -169 -14 -68 -24 -125 -22 -127 2 -2 34 22 72 54 38 31 113 91
|
||||
166 132 53 41 138 110 190 152 106 86 134 100 181 91 66 -12 99 -76 68 -133
|
||||
-5 -10 -95 -87 -199 -170 l-190 -152 13 -36 c23 -63 93 -224 130 -297 43 -85
|
||||
47 -134 13 -171 -32 -34 -90 -41 -137 -17 -32 17 -74 79 -93 138 -26 82 -95
|
||||
240 -104 240 -6 0 -49 -30 -95 -66 l-84 -66 -19 -98 c-25 -126 -48 -155 -124
|
||||
-155 -43 0 -56 4 -76 26 -14 15 -25 39 -25 53 0 28 23 166 40 246 6 28 15 73
|
||||
20 100 9 53 36 182 51 250 18 80 30 141 35 175 3 19 9 44 14 55 5 11 11 36 14
|
||||
55 3 19 15 78 26 130 19 82 33 153 57 273 3 15 19 41 35 57 24 25 38 30 75 30
|
||||
39 0 51 -5 75 -32z m5269 2 c32 -33 36 -69 18 -150 -6 -25 -14 -64 -20 -87 -5
|
||||
-24 -13 -62 -19 -85 -9 -43 -26 -129 -53 -268 -8 -41 -14 -76 -12 -77 1 -2 17
|
||||
18 35 45 49 67 112 125 167 151 27 13 56 27 65 32 24 12 158 11 158 -1 0 -5 7
|
||||
-10 17 -10 31 0 103 -51 128 -91 60 -94 66 -198 23 -434 -11 -60 -24 -132 -28
|
||||
-160 -25 -147 -39 -216 -52 -242 -18 -39 -79 -59 -131 -43 -64 19 -80 66 -57
|
||||
180 6 30 17 96 25 145 8 50 20 117 27 150 6 33 12 100 12 148 1 88 1 89 -32
|
||||
118 -27 24 -41 29 -87 29 -65 0 -109 -22 -179 -88 -67 -65 -156 -209 -156
|
||||
-253 0 -11 -4 -27 -9 -37 -5 -9 -17 -62 -26 -117 -9 -55 -21 -110 -26 -123 -5
|
||||
-13 -9 -33 -9 -46 0 -27 -18 -65 -41 -88 -21 -21 -80 -30 -116 -18 -60 21 -70
|
||||
81 -39 230 10 47 22 105 26 130 5 25 12 59 15 75 4 17 17 84 30 150 13 66 26
|
||||
134 30 150 3 17 10 50 15 75 5 25 21 99 35 165 15 66 30 143 35 170 5 28 14
|
||||
73 20 100 6 28 13 64 16 80 14 81 58 125 123 125 36 0 49 -6 72 -30z m-12660
|
||||
-41 c-5 -13 -10 -19 -10 -12 -1 15 10 45 15 40 3 -2 0 -15 -5 -28z m11228 -41
|
||||
c73 -75 14 -210 -100 -225 -43 -6 -109 21 -109 44 0 7 -4 13 -10 13 -5 0 -10
|
||||
24 -10 53 0 40 6 61 24 86 38 51 56 60 117 61 51 0 60 -3 88 -32z m3821 0 c30
|
||||
-31 32 -36 27 -91 -4 -43 -12 -66 -28 -83 -72 -77 -179 -71 -219 12 -24 48
|
||||
-24 61 -5 107 24 57 70 87 136 87 51 0 60 -3 89 -32z m-14062 -62 c18 -3 48
|
||||
-16 68 -30 32 -22 34 -25 19 -40 -20 -20 -26 -20 -19 -1 4 8 1 15 -5 15 -6 0
|
||||
-11 -4 -11 -8 0 -14 -35 -7 -64 11 -14 10 -40 20 -56 24 -17 3 -30 9 -30 12 0
|
||||
16 25 30 44 26 12 -2 36 -6 54 -9z m-665 -13 c42 -23 117 -94 117 -110 0 -7 4
|
||||
-13 8 -13 13 0 32 -63 26 -87 -8 -29 -20 -29 -35 -1 -7 13 -24 32 -37 43 -60
|
||||
47 -59 46 -25 40 54 -11 45 9 -33 70 -41 32 -77 62 -80 67 -9 14 27 9 59 -9z
|
||||
m1047 12 c0 -2 -37 -32 -81 -66 -70 -53 -80 -64 -66 -74 15 -10 14 -13 -1 -26
|
||||
-9 -8 -27 -27 -39 -43 -25 -32 -43 -27 -43 12 0 66 138 200 208 202 12 0 22
|
||||
-2 22 -5z m-668 -57 c-18 -5 -30 -13 -27 -18 4 -6 -6 -10 -22 -9 -25 0 -26 1
|
||||
-8 9 11 5 16 9 10 10 -5 1 6 7 25 14 19 8 39 11 45 8 5 -3 -5 -10 -23 -14z
|
||||
m-462 -49 c27 -6 50 -15 50 -20 0 -5 6 -9 14 -9 7 0 20 -7 27 -17 13 -15 12
|
||||
-15 -6 -5 -37 21 -97 42 -121 42 -20 0 -22 -4 -18 -37 l4 -38 -13 40 c-20 60
|
||||
-18 61 63 44z m-90 -13 c0 -9 -7 -12 -20 -9 -31 8 -34 23 -6 23 16 0 26 -6 26
|
||||
-14z m1280 -7 c0 -21 -1 -21 -26 -4 -16 10 -30 13 -37 7 -7 -5 -28 -12 -47
|
||||
-16 -32 -6 -33 -5 -15 8 24 16 49 23 93 25 26 1 32 -3 32 -20z m84 13 c3 -5
|
||||
-10 -14 -29 -20 -39 -11 -49 3 -12 18 29 11 35 12 41 2z m-690 -63 c-5 -30 -3
|
||||
-43 7 -49 11 -7 10 -10 -4 -16 -14 -5 -12 -9 15 -24 30 -16 33 -22 31 -57 -3
|
||||
-42 -6 -40 50 -34 4 1 7 6 7 12 0 8 -5 8 -15 -1 -8 -7 -15 -9 -15 -6 0 13 33
|
||||
56 42 56 6 0 5 -7 -3 -16 -10 -13 -10 -17 0 -24 11 -6 7 -16 -14 -44 -15 -20
|
||||
-25 -39 -21 -43 3 -3 6 -1 6 5 0 7 4 12 9 12 5 0 9 -21 8 -47 -1 -29 3 -48 11
|
||||
-50 15 -6 16 -49 2 -58 -8 -5 -7 -11 1 -21 9 -11 8 -19 -6 -34 -10 -11 -13
|
||||
-20 -7 -20 6 0 10 -29 11 -72 1 -40 5 -100 11 -133 5 -33 10 -76 10 -96 0 -41
|
||||
-29 -81 -63 -86 -12 -2 -26 -8 -31 -13 -14 -14 -42 -12 -56 4 -15 19 6 66 36
|
||||
81 35 17 54 42 54 70 0 23 -4 26 -27 23 -16 -2 -28 -7 -27 -13 0 -5 -10 -21
|
||||
-23 -35 l-23 -24 -38 37 c-39 38 -56 45 -67 27 -10 -16 18 -70 40 -76 36 -11
|
||||
55 -36 55 -71 0 -29 -3 -33 -25 -33 -35 0 -102 35 -115 60 -8 15 -8 65 -1 173
|
||||
6 84 8 162 5 175 -4 13 -2 22 5 22 7 0 6 8 -4 24 -11 17 -13 30 -6 48 6 15 5
|
||||
31 -2 43 -7 14 -7 20 1 23 7 2 9 9 5 15 -4 7 0 8 12 3 14 -5 15 -3 7 6 -15 19
|
||||
-22 108 -9 128 8 15 14 16 29 7 10 -7 18 -17 18 -24 0 -7 5 -13 10 -13 13 0
|
||||
13 17 -1 26 -6 3 -9 17 -6 30 2 13 0 24 -4 24 -5 0 -9 5 -9 10 0 14 27 12 33
|
||||
-2 5 -15 11 -3 22 47 4 17 10 24 12 17 7 -18 23 -4 23 19 0 11 4 18 9 14 5 -3
|
||||
12 4 16 15 11 34 16 22 9 -21z m456 21 c0 -5 -5 -10 -11 -10 -5 0 -7 5 -4 10
|
||||
3 6 8 10 11 10 2 0 4 -4 4 -10z m-522 -25 c-3 -3 -9 2 -12 12 -6 14 -5 15 5 6
|
||||
7 -7 10 -15 7 -18z m662 5 c0 -11 -4 -20 -9 -20 -5 0 -7 9 -4 20 3 11 7 20 9
|
||||
20 2 0 4 -9 4 -20z m-1210 -55 c0 -5 -5 -3 -10 5 -5 8 -10 20 -10 25 0 6 5 3
|
||||
10 -5 5 -8 10 -19 10 -25z m770 -34 c0 -5 -7 -12 -16 -15 -14 -5 -15 -4 -4 9
|
||||
14 17 20 19 20 6z m-762 -36 c11 -23 10 -25 -11 -21 -12 3 -48 8 -79 11 -70 8
|
||||
-76 23 -10 28 26 2 56 4 68 5 14 1 25 -7 32 -23z m348 -9 c62 -62 82 -148 44
|
||||
-186 -11 -11 -21 -18 -21 -15 -1 3 -2 10 -3 15 -1 14 -77 80 -91 80 -6 0 -16
|
||||
-5 -22 -11 -35 -35 -44 41 -13 109 25 54 57 57 106 8z m554 14 c36 -31 43
|
||||
-161 6 -131 -17 14 -61 -7 -91 -45 -35 -44 -55 -27 -55 45 0 55 3 62 41 105
|
||||
46 51 65 56 99 26z m393 10 c47 0 29 -18 -25 -25 -29 -3 -66 -9 -81 -12 l-29
|
||||
-5 18 27 c15 23 22 26 53 21 20 -3 48 -6 64 -6z m14371 -9 c3 -4 19 -11 35
|
||||
-14 41 -8 102 -65 130 -121 39 -80 36 -236 -9 -451 -18 -83 -28 -136 -44 -220
|
||||
-8 -44 -18 -92 -21 -107 -24 -97 -191 -102 -209 -6 -3 18 1 66 10 107 8 41 22
|
||||
118 31 170 8 53 19 119 25 146 37 193 7 285 -95 285 -66 0 -117 -21 -173 -72
|
||||
-87 -80 -163 -214 -186 -325 -4 -24 -12 -62 -17 -85 -5 -24 -14 -77 -21 -118
|
||||
-7 -41 -16 -83 -21 -92 -5 -10 -9 -24 -9 -32 0 -8 -15 -24 -34 -35 -56 -35
|
||||
-130 -24 -161 23 -17 26 -16 45 15 191 5 28 17 88 25 135 21 116 30 161 50
|
||||
260 9 47 21 105 26 130 27 147 32 161 61 190 42 43 103 42 148 0 32 -30 33
|
||||
-31 26 -98 -4 -37 -9 -78 -12 -92 -3 -15 7 -4 27 30 56 94 173 190 230 190 10
|
||||
0 19 5 19 10 0 12 147 14 154 1z m-10385 -17 c133 -46 212 -164 195 -290 -9
|
||||
-61 -53 -142 -98 -179 -43 -35 -163 -95 -190 -95 -8 0 -17 -4 -20 -9 -3 -5
|
||||
-52 -14 -108 -20 -57 -7 -114 -15 -128 -17 -14 -3 -54 -7 -90 -10 -35 -3 -66
|
||||
-7 -69 -9 -2 -3 5 -26 16 -52 13 -33 33 -57 62 -78 41 -29 48 -30 144 -30 102
|
||||
0 102 0 197 48 104 52 145 58 178 27 56 -52 11 -133 -105 -189 -37 -18 -76
|
||||
-37 -85 -42 -10 -5 -26 -9 -36 -9 -10 0 -23 -5 -30 -12 -8 -8 -53 -12 -134
|
||||
-12 -100 -1 -131 3 -163 18 -22 10 -55 25 -73 34 -18 8 -52 34 -75 57 -37 37
|
||||
-55 66 -100 163 -17 36 -12 230 7 288 23 69 53 131 89 184 34 52 146 160 165
|
||||
160 6 0 12 3 12 8 0 8 56 35 130 62 61 23 248 26 309 4z m6567 -18 c27 -14 63
|
||||
-39 78 -55 25 -26 28 -35 24 -75 -7 -60 -36 -85 -99 -86 -44 0 -99 18 -99 33
|
||||
0 4 -9 7 -19 7 -11 0 -23 5 -26 10 -3 6 -35 10 -70 10 -35 0 -67 -4 -70 -10
|
||||
-3 -5 -15 -10 -26 -10 -32 0 -128 -69 -170 -122 -67 -85 -82 -129 -83 -245 -1
|
||||
-97 0 -103 29 -145 70 -99 177 -112 322 -38 129 65 193 53 193 -35 0 -34 -6
|
||||
-47 -37 -77 -40 -38 -150 -98 -181 -98 -10 0 -23 -5 -29 -11 -17 -17 -210 -17
|
||||
-263 1 -25 8 -47 17 -50 20 -3 3 -21 14 -40 24 -52 29 -99 83 -134 156 -29 62
|
||||
-30 71 -30 192 0 87 3 131 12 140 6 6 12 21 12 32 0 30 58 138 104 195 71 87
|
||||
179 160 301 205 30 11 74 14 170 12 118 -3 135 -6 181 -30z m2089 17 c11 -6
|
||||
33 -17 48 -24 51 -24 124 -101 131 -138 3 -19 2 -39 -3 -45 -4 -6 -11 -31 -14
|
||||
-56 -3 -25 -13 -85 -23 -135 -30 -165 -35 -199 -40 -286 -6 -82 -5 -86 16 -92
|
||||
37 -10 68 13 110 79 22 35 40 67 40 71 0 5 11 21 24 37 l23 30 25 -40 c48 -76
|
||||
53 -102 28 -168 -33 -87 -143 -196 -199 -196 -11 0 -23 -4 -26 -10 -3 -5 -26
|
||||
-10 -50 -10 -24 0 -47 5 -50 10 -3 6 -14 10 -23 10 -28 0 -90 57 -100 93 -6
|
||||
17 -13 49 -17 70 l-6 39 -28 -44 c-75 -117 -215 -187 -348 -174 -34 4 -74 13
|
||||
-90 21 -15 8 -34 15 -41 15 -24 0 -122 108 -143 157 -11 26 -25 90 -31 141 -9
|
||||
79 -8 103 7 170 10 42 21 84 25 92 49 108 72 142 150 221 69 70 101 93 170
|
||||
126 47 23 94 43 105 46 36 10 309 2 330 -10z m-13521 -9 c3 -8 2 -12 -4 -9 -6
|
||||
3 -10 10 -10 16 0 14 7 11 14 -7z m7662 -2 c39 -33 47 -58 34 -115 -6 -29 -15
|
||||
-74 -20 -102 -5 -27 -16 -90 -25 -140 -9 -49 -19 -108 -22 -130 -3 -22 -9 -45
|
||||
-14 -51 -5 -6 -10 -43 -11 -81 -3 -87 14 -117 73 -133 95 -26 247 68 314 193
|
||||
7 12 21 38 31 57 27 47 50 128 79 275 9 44 21 94 26 111 5 17 9 40 9 51 0 12
|
||||
14 35 31 52 74 75 216 7 181 -86 -6 -16 -13 -46 -16 -68 -3 -22 -12 -76 -21
|
||||
-120 -25 -124 -33 -163 -50 -255 -9 -47 -20 -105 -25 -130 -5 -25 -14 -74 -20
|
||||
-110 -22 -136 -49 -173 -126 -173 -41 0 -51 4 -77 33 -27 31 -29 37 -23 89 3
|
||||
31 9 67 13 81 5 19 -4 12 -34 -25 -146 -183 -341 -245 -480 -152 -90 61 -118
|
||||
131 -109 272 5 82 11 122 46 295 13 59 20 99 39 200 20 104 31 134 59 157 34
|
||||
29 107 31 138 5z m1061 -9 c20 -19 33 -41 37 -68 22 -132 27 -166 36 -220 6
|
||||
-33 15 -91 20 -130 10 -74 28 -180 40 -230 6 -29 9 -25 59 70 55 107 98 185
|
||||
135 250 13 22 43 76 67 120 113 210 122 221 200 231 42 6 48 4 81 -28 28 -26
|
||||
37 -44 41 -78 8 -59 28 -245 38 -345 6 -62 20 -178 28 -244 1 -4 101 160 101
|
||||
165 0 2 25 42 55 89 30 46 55 87 55 89 0 3 38 69 85 148 95 160 140 208 192
|
||||
208 62 0 114 -59 98 -111 -9 -27 -123 -218 -153 -254 -4 -5 -11 -17 -15 -25
|
||||
-4 -8 -25 -42 -47 -75 -22 -33 -49 -76 -60 -95 -11 -19 -33 -54 -48 -78 -15
|
||||
-23 -60 -95 -101 -160 -41 -64 -81 -125 -90 -136 -25 -29 -98 -59 -129 -53
|
||||
-94 19 -111 44 -128 185 -7 59 -20 166 -29 237 -9 72 -19 150 -23 175 l-7 45
|
||||
-17 -30 c-17 -33 -109 -201 -185 -340 -136 -247 -128 -237 -208 -262 -48 -15
|
||||
-103 -2 -135 32 -21 22 -51 125 -64 215 -3 25 -15 95 -26 155 -12 61 -25 137
|
||||
-31 170 -5 33 -16 96 -24 140 -9 44 -18 107 -21 140 -6 58 -5 61 27 93 44 43
|
||||
101 45 146 5z m1756 15 c54 -26 56 -64 12 -298 -9 -47 -18 -101 -21 -120 -3
|
||||
-19 -9 -44 -14 -55 -5 -11 -11 -38 -14 -60 -14 -115 -67 -351 -87 -383 -15
|
||||
-23 -66 -52 -94 -52 -30 0 -84 31 -92 53 -9 27 -4 128 7 142 4 6 10 28 13 50
|
||||
3 22 13 78 22 125 9 47 21 108 26 135 18 89 28 139 38 185 11 50 16 77 33 164
|
||||
20 103 92 150 171 114z m3841 -3 c42 -28 48 -60 32 -165 -8 -52 -20 -117 -26
|
||||
-145 -5 -27 -17 -88 -26 -135 -17 -93 -28 -151 -43 -220 -5 -25 -16 -79 -25
|
||||
-120 -22 -109 -26 -123 -51 -147 -41 -40 -108 -39 -158 1 -21 17 -25 83 -9
|
||||
161 6 28 18 86 26 130 30 161 36 191 51 265 9 41 21 100 26 130 10 59 24 126
|
||||
34 175 10 45 61 85 107 85 22 0 49 -7 62 -15z m-8120 -20 c20 -26 20 -74 1
|
||||
-113 -17 -34 -73 -85 -540 -493 -77 -67 -141 -126 -143 -131 -2 -4 106 -8 240
|
||||
-8 134 0 253 -3 264 -6 53 -14 64 -107 19 -154 l-29 -30 -402 0 c-221 0 -410
|
||||
3 -419 6 -26 10 -45 58 -38 97 4 28 22 52 82 109 81 77 388 352 452 404 21 17
|
||||
68 59 105 93 l67 61 -217 0 c-240 0 -265 5 -284 59 -7 20 -7 42 -1 65 19 68
|
||||
10 67 441 64 374 -3 388 -4 402 -23z m-6456 -87 c2 -5 9 -8 16 -8 28 0 47 -37
|
||||
44 -85 l-3 -46 -100 -41 c-55 -22 -121 -48 -147 -59 -27 -10 -48 -17 -48 -16
|
||||
0 2 42 35 93 72 50 38 98 75 105 82 7 7 16 13 20 13 4 0 20 11 36 25 23 20 26
|
||||
26 13 31 -13 5 -249 -20 -276 -29 -3 -1 -8 2 -11 8 -3 5 40 28 95 51 97 40
|
||||
101 41 130 25 17 -9 32 -19 33 -23z m1028 1 c139 -56 130 -66 -43 -45 -71 9
|
||||
-134 16 -141 16 -27 0 -8 -22 64 -71 41 -29 79 -60 85 -71 5 -10 25 -25 44
|
||||
-32 19 -8 45 -24 57 -36 l23 -22 -50 20 c-27 11 -99 41 -160 65 l-110 45 -3
|
||||
43 c-1 24 1 49 5 54 13 16 106 63 129 64 12 0 57 -13 100 -30z m-2028 -13
|
||||
c178 -48 385 -236 495 -451 26 -50 77 -170 77 -180 0 -3 -196 -5 -435 -5
|
||||
l-435 0 -11 28 c-32 81 -42 144 -43 257 -1 154 18 219 85 286 72 73 158 94
|
||||
267 65z m3079 -11 c71 -30 120 -93 149 -191 13 -46 15 -83 11 -173 -3 -64 -9
|
||||
-129 -15 -146 -5 -16 -15 -49 -21 -72 l-12 -43 -440 0 -440 0 6 23 c31 102
|
||||
150 296 243 398 174 190 370 266 519 204z m-1373 -107 c-7 -10 -26 -10 -43 1
|
||||
-24 15 -4 30 23 18 13 -7 22 -15 20 -19z m-516 -1 c3 -13 -4 -17 -31 -17 -44
|
||||
0 -59 27 -19 33 38 5 47 3 50 -16z m59 -49 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13
|
||||
3 -3 4 -12 1 -19z m726 -217 c27 -29 7 -19 -56 29 -33 25 -56 55 -82 106 -19
|
||||
39 -35 74 -35 79 0 4 34 -37 76 -91 42 -54 85 -110 97 -123z m-942 151 c-10
|
||||
-34 -33 -72 -43 -72 -5 0 -8 -6 -8 -13 0 -15 -31 -45 -75 -73 -26 -17 -25 -13
|
||||
15 36 25 30 61 76 79 103 19 26 36 47 37 47 1 0 -1 -13 -5 -28z m426 -404 c32
|
||||
5 59 9 60 8 1 0 -5 -10 -13 -21 -12 -16 -26 -20 -78 -20 -60 0 -121 19 -111
|
||||
35 3 5 23 3 44 -2 27 -7 59 -7 98 0z"/>
|
||||
<path d="M2531 3107 c-13 -21 -12 -21 5 -5 10 10 16 20 13 22 -3 3 -11 -5 -18
|
||||
-17z"/>
|
||||
<path d="M1702 3248 c-7 -7 -11 -21 -11 -32 1 -21 1 -21 6 -1 3 11 10 26 15
|
||||
33 13 15 6 16 -10 0z"/>
|
||||
<path d="M1750 3229 c0 -5 5 -7 10 -4 6 3 10 8 10 11 0 2 -4 4 -10 4 -5 0 -10
|
||||
-5 -10 -11z"/>
|
||||
<path d="M2025 3130 c-3 -6 1 -7 9 -4 18 7 21 14 7 14 -6 0 -13 -4 -16 -10z"/>
|
||||
<path d="M5680 3031 c-75 -6 -75 -6 -87 -41 -7 -19 -12 -47 -12 -63 -1 -15 -5
|
||||
-35 -10 -45 -5 -9 -17 -62 -26 -117 -9 -55 -21 -109 -25 -120 -5 -11 -11 -36
|
||||
-14 -55 -3 -19 -11 -65 -17 -101 -19 -106 -23 -103 149 -96 159 7 209 18 310
|
||||
69 98 49 150 122 171 239 10 52 10 79 0 130 -11 56 -19 70 -64 116 -40 39 -65
|
||||
55 -106 67 -67 18 -171 25 -269 17z"/>
|
||||
<path d="M2381 2784 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
|
||||
<path d="M2262 2655 c6 -14 13 -24 14 -22 6 6 -9 47 -17 47 -5 0 -3 -11 3 -25z"/>
|
||||
<path d="M6825 2533 c-73 -29 -150 -97 -188 -168 -21 -39 -46 -102 -42 -107 6
|
||||
-5 188 10 243 20 96 20 178 57 211 96 19 22 26 98 11 125 -26 49 -152 67 -235
|
||||
34z"/>
|
||||
<path d="M15458 2536 c-184 -50 -332 -318 -273 -497 27 -79 50 -99 126 -108
|
||||
35 -5 71 -5 79 0 8 4 29 13 47 19 46 17 129 106 163 175 43 89 55 122 74 210
|
||||
10 44 22 97 28 117 15 51 6 65 -53 82 -62 19 -126 19 -191 2z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 33 KiB |
@@ -0,0 +1,157 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="211.000000pt" height="192.000000pt" viewBox="0 0 211.000000 192.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,192.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M710 1871 c-321 -70 -565 -301 -652 -617 -30 -112 -31 -315 0 -429
|
||||
77 -288 299 -514 587 -601 76 -23 110 -27 220 -28 126 -1 249 16 261 36 3 5
|
||||
-5 26 -19 46 -14 20 -29 54 -32 74 -4 21 -11 38 -16 38 -5 0 -9 15 -8 33 1 30
|
||||
2 29 18 -18 16 -51 81 -185 81 -170 0 5 11 -6 24 -24 14 -18 35 -40 48 -49 13
|
||||
-9 25 -19 29 -24 3 -4 34 -22 69 -39 60 -29 104 -41 205 -55 50 -7 189 20 233
|
||||
47 18 10 39 19 45 19 7 0 27 13 45 30 18 16 35 30 38 30 7 0 44 39 44 48 0 4
|
||||
14 22 30 41 17 18 30 39 30 46 0 7 12 34 27 61 26 47 27 56 27 194 0 138 -1
|
||||
147 -27 198 -15 30 -27 60 -27 67 0 18 -167 185 -185 185 -7 0 -21 3 -31 7
|
||||
-14 5 -16 3 -11 -11 4 -11 3 -15 -4 -11 -6 4 -8 13 -5 21 6 16 -29 38 -50 30
|
||||
-10 -4 -12 -2 -8 6 5 7 -1 9 -19 4 -14 -3 -29 -2 -32 4 -9 14 -88 12 -104 -2
|
||||
-11 -10 -13 -10 -7 0 9 16 -65 17 -81 1 -8 -8 -17 -8 -29 -1 -15 8 -13 10 12
|
||||
15 85 16 145 17 215 3 41 -9 76 -16 78 -16 9 0 -14 145 -36 220 -81 281 -313
|
||||
506 -598 581 -115 30 -276 34 -385 10z m570 -496 l0 -95 -27 0 c-25 0 -25 1
|
||||
-10 18 29 31 19 34 -18 6 -20 -15 -38 -25 -40 -22 -3 2 13 18 35 34 38 28 49
|
||||
44 31 44 -4 0 -28 -18 -53 -40 -45 -39 -46 -39 -134 -42 l-89 -3 -3 -57 c-3
|
||||
-56 -2 -58 21 -58 39 0 87 -12 82 -20 -2 -4 -27 -5 -55 -2 l-50 5 0 -77 0 -76
|
||||
-94 0 c-108 0 -106 -2 -106 92 l0 60 -77 -6 c-164 -15 -263 -42 -263 -73 0
|
||||
-17 75 -52 112 -53 14 0 28 -4 30 -9 2 -5 68 -15 148 -21 113 -10 183 -10 315
|
||||
0 157 11 175 14 229 42 32 16 55 25 52 19 -5 -7 -1 -8 10 -4 11 4 13 8 6 11
|
||||
-7 2 -12 10 -12 17 0 20 -58 42 -147 56 -82 13 -111 29 -52 29 45 0 169 -30
|
||||
210 -51 66 -33 65 -42 -9 -78 -36 -18 -73 -42 -80 -52 -7 -10 -18 -19 -24 -19
|
||||
-13 0 -77 -73 -95 -107 -6 -12 -18 -35 -26 -50 -8 -15 -22 -50 -30 -78 -11
|
||||
-34 -16 -42 -16 -25 -2 53 48 155 108 222 l24 27 -64 -3 c-35 -2 -83 -4 -106
|
||||
-5 l-43 -1 0 -200 0 -201 -97 3 -98 3 -3 196 -2 196 -85 7 c-88 6 -200 27
|
||||
-249 46 -36 13 -66 49 -63 75 5 44 141 87 320 101 l77 6 0 54 0 53 -147 3
|
||||
-148 3 -3 98 -3 97 406 0 405 0 0 -95z m148 -334 c11 -6 10 -10 -4 -15 -9 -3
|
||||
-19 -4 -22 -1 -3 3 1 5 9 5 11 0 11 2 -1 10 -8 5 -10 10 -5 10 6 0 16 -4 23
|
||||
-9z m189 -7 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m-242 -35
|
||||
c-4 -5 -12 -9 -18 -8 -9 0 -8 2 1 6 6 2 9 10 6 15 -4 7 -2 8 5 4 6 -4 9 -12 6
|
||||
-17z m217 6 c49 5 74 3 95 -8 15 -8 52 -26 81 -41 28 -15 52 -32 52 -38 0 -6
|
||||
-11 -3 -25 6 -13 9 -28 16 -32 16 -13 0 38 -32 55 -34 9 -2 16 -7 15 -12 -2
|
||||
-13 28 -44 38 -39 8 5 59 -55 59 -69 0 -5 6 -22 14 -39 52 -117 49 -248 -9
|
||||
-381 -27 -62 -26 -37 2 44 45 133 32 287 -34 393 -13 20 -26 37 -29 37 -3 0
|
||||
-3 -4 1 -9 3 -6 -1 -25 -10 -43 -8 -18 -13 -25 -11 -16 3 10 1 20 -4 23 -6 4
|
||||
-10 2 -10 -2 0 -5 -10 -13 -22 -18 -13 -6 -31 -26 -40 -45 -34 -70 -130 -170
|
||||
-162 -170 -12 0 -27 -9 -34 -20 -15 -25 -28 -25 -49 0 -10 12 -30 20 -48 20
|
||||
-16 0 -25 4 -19 8 6 4 16 17 23 30 7 12 16 20 20 18 5 -3 23 -1 42 5 80 25 99
|
||||
27 99 13 0 -8 -7 -14 -15 -14 -8 0 -15 -7 -15 -15 0 -35 52 3 70 51 9 22 7 27
|
||||
-10 31 -21 5 -24 21 -14 61 7 25 24 30 24 7 0 -12 3 -12 20 2 14 12 16 19 8
|
||||
24 -7 4 -16 5 -21 2 -5 -3 -6 4 -2 16 4 15 2 21 -8 21 -7 0 -14 6 -14 14 0 8
|
||||
6 12 13 9 8 -3 11 2 7 16 -7 26 -47 53 -69 44 -12 -4 -15 -3 -10 5 4 8 -3 11
|
||||
-24 9 -16 -1 -30 -6 -30 -10 0 -5 -4 -6 -8 -3 -12 7 -36 -39 -29 -56 3 -7 6
|
||||
-4 6 9 1 12 6 25 13 29 8 5 9 0 5 -17 l-6 -24 16 23 c25 36 93 25 93 -16 0 -7
|
||||
-4 -11 -9 -7 -6 3 -7 -6 -2 -22 5 -16 5 -37 0 -48 -4 -11 -8 -16 -8 -11 -1 5
|
||||
-7 3 -15 -3 -12 -10 -14 -9 -12 6 2 10 1 12 -1 6 -3 -7 -9 -13 -14 -13 -5 0
|
||||
-9 -5 -9 -11 0 -5 3 -8 8 -5 9 5 47 -22 40 -29 -3 -3 -17 0 -32 6 -25 12 -31
|
||||
22 -26 44 1 5 -8 1 -20 -10 -19 -17 -20 -21 -6 -31 21 -15 20 -31 -1 -43 -27
|
||||
-14 -35 -14 -43 0 -6 9 -17 3 -40 -22 -22 -23 -29 -27 -21 -11 11 20 9 22 -16
|
||||
23 -15 1 -32 1 -37 0 -5 -1 -6 5 -2 14 3 9 2 13 -4 10 -13 -8 -13 -35 0 -35 6
|
||||
0 15 -12 21 -27 9 -24 7 -31 -15 -50 -14 -12 -26 -29 -26 -38 0 -8 -6 -24 -12
|
||||
-35 -10 -16 -10 -24 -1 -40 9 -13 9 -21 2 -26 -16 -9 -21 1 -24 48 -2 29 3 47
|
||||
14 56 9 7 11 11 4 8 -6 -4 -15 -1 -19 5 -4 7 -3 9 3 6 14 -9 63 34 63 55 0 9
|
||||
-7 19 -16 22 -10 4 -14 16 -12 38 2 27 8 34 29 36 31 4 44 34 27 62 -12 19
|
||||
-29 14 -71 -20 -17 -13 -20 -13 -31 2 -7 10 -24 22 -38 27 -28 11 -42 52 -24
|
||||
75 6 8 31 31 54 50 24 20 41 36 37 36 -6 0 -65 -46 -87 -68 -53 -52 -88 -115
|
||||
-113 -202 -13 -44 -13 -44 -14 -11 -3 91 117 247 235 306 32 16 60 32 62 36 1
|
||||
3 24 2 50 -3 26 -5 77 -6 114 -3z m-35 9 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6
|
||||
11 1 17 -2 13 -5z m-222 -33 c-3 -6 -11 -11 -16 -11 -5 0 -4 6 3 14 14 16 24
|
||||
13 13 -3z m530 -102 c11 -17 -1 -21 -15 -4 -8 9 -8 15 -2 15 6 0 14 -5 17 -11z
|
||||
m-685 -244 c0 -8 5 -15 11 -17 7 -2 6 -8 -4 -16 -12 -10 -14 -8 -14 15 0 15
|
||||
-6 29 -12 31 -6 2 -11 8 -11 14 0 6 6 6 15 -2 8 -7 15 -18 15 -25z m764 19 c4
|
||||
-10 1 -14 -6 -12 -15 5 -23 28 -10 28 5 0 13 -7 16 -16z m-28 -33 c-4 -5 -1
|
||||
-11 6 -13 6 -2 -3 -10 -20 -17 -18 -8 -32 -17 -32 -22 0 -4 -13 0 -30 9 -35
|
||||
20 -34 37 3 37 20 1 24 -2 15 -12 -16 -19 -7 -22 22 -6 15 7 19 13 10 14 -10
|
||||
0 -8 3 5 9 27 11 27 11 21 1z m-789 -78 c-2 -16 -4 -3 -4 27 0 30 2 43 4 28 2
|
||||
-16 2 -40 0 -55z m153 56 c0 -5 -5 -9 -12 -9 -6 0 -19 -6 -27 -14 -14 -13 -19
|
||||
-12 -36 1 -11 9 -13 13 -5 11 21 -7 63 10 55 22 -3 6 1 7 9 4 9 -3 16 -10 16
|
||||
-15z m666 -25 c-4 -9 -9 -15 -11 -12 -3 3 -3 13 1 22 4 9 9 15 11 12 3 -3 3
|
||||
-13 -1 -22z m-650 -17 c4 -4 -2 -7 -14 -7 -12 0 -22 4 -22 9 0 10 26 9 36 -2z
|
||||
m504 2 c23 1 23 0 -7 -15 -26 -13 -33 -23 -34 -48 0 -26 -2 -28 -8 -11 -5 11
|
||||
-7 23 -5 26 2 3 -8 12 -21 19 -31 16 -33 34 -4 25 16 -5 19 -4 14 6 -6 9 -2
|
||||
10 16 5 13 -4 35 -7 49 -7z m-362 -11 c-8 -7 -18 -23 -21 -36 -5 -19 -2 -22
|
||||
15 -16 26 8 68 -14 68 -37 0 -14 7 -16 43 -12 23 4 44 10 45 15 13 32 147 49
|
||||
147 18 0 -10 10 -15 33 -14 17 1 30 -2 27 -6 -3 -5 1 -10 7 -13 7 -3 -6 -2
|
||||
-29 0 -34 5 -42 2 -46 -13 -4 -16 -5 -16 -6 3 -1 15 -6 20 -18 18 -10 -2 -24
|
||||
-4 -32 -4 -9 -1 -12 -11 -9 -36 4 -35 3 -36 -24 -30 -21 5 -28 3 -28 -8 0 -8
|
||||
-8 -21 -17 -28 -15 -11 -16 -11 -5 1 18 21 15 32 -7 21 -10 -6 -22 -7 -26 -3
|
||||
-4 4 -5 -3 -2 -15 3 -13 1 -23 -4 -23 -5 0 -9 13 -9 29 0 29 -27 68 -39 56 -3
|
||||
-4 2 -12 12 -19 21 -16 22 -27 2 -20 -21 8 -19 -13 3 -25 19 -12 12 -14 -12
|
||||
-5 -9 3 -16 14 -16 23 0 9 -5 22 -12 29 -7 7 -8 12 -2 12 5 0 10 11 10 24 1
|
||||
18 -2 22 -17 19 -11 -3 -19 -10 -19 -15 0 -5 -7 -3 -15 6 -20 19 -19 28 1 24
|
||||
10 -2 19 2 21 9 5 14 -23 11 -39 -5 -7 -7 -18 -12 -24 -12 -7 0 -14 -8 -17
|
||||
-17 -2 -11 -7 -4 -11 18 -6 27 -3 45 9 65 17 30 17 30 -1 -38 -5 -23 -5 -23
|
||||
11 -3 9 11 21 32 27 48 5 15 17 27 26 27 14 0 14 -1 0 -12z m408 -10 c4 -7 3
|
||||
-8 -4 -4 -7 4 -12 0 -12 -10 0 -10 -3 -15 -6 -11 -7 6 2 37 10 37 3 0 8 -5 12
|
||||
-12z m-568 -41 c2 -9 -2 -17 -8 -17 -6 0 -8 5 -4 11 3 6 0 16 -7 21 -12 8 -11
|
||||
9 1 5 8 -2 16 -11 18 -20z m-115 -87 c24 -47 21 -72 -3 -32 -11 18 -23 54 -25
|
||||
80 -4 37 -3 41 4 16 4 -17 15 -45 24 -64z m152 40 c-3 -5 -11 -10 -16 -10 -6
|
||||
0 -7 5 -4 10 3 6 11 10 16 10 6 0 7 -4 4 -10z m395 -32 c0 -19 -2 -20 -10 -8
|
||||
-13 19 -13 30 0 30 6 0 10 -10 10 -22z m-397 -61 c-3 -5 -10 -2 -15 8 -9 15
|
||||
-12 15 -35 -7 -25 -22 -25 -22 -14 -1 6 12 16 23 23 26 17 5 48 -15 41 -26z
|
||||
m562 -21 c6 -4 0 -3 -12 3 -12 6 -25 16 -28 21 -3 6 -11 10 -17 10 -6 0 -5 -7
|
||||
3 -16 12 -15 11 -16 -9 -10 -13 5 -22 3 -22 -3 0 -10 14 -15 34 -12 4 1 17 -1
|
||||
28 -5 14 -4 17 -8 8 -14 -6 -4 -11 -10 -11 -14 2 -10 -59 -59 -65 -53 -4 3
|
||||
-17 -6 -30 -21 -20 -23 -25 -25 -34 -12 -9 13 -10 13 -10 0 0 -16 -38 -45 -48
|
||||
-36 -3 3 0 6 6 6 7 0 12 5 12 11 0 6 -8 8 -17 5 -17 -6 -17 -5 0 8 9 7 17 16
|
||||
17 20 0 11 -28 6 -33 -6 -4 -10 -6 -10 -6 -1 -1 6 4 15 9 18 15 9 12 25 -4 19
|
||||
-22 -9 -26 -29 -10 -59 11 -22 11 -25 1 -16 -8 6 -17 8 -20 4 -4 -3 -7 8 -7
|
||||
25 0 25 -4 32 -20 32 -14 0 -20 -7 -21 -22 -1 -16 -3 -18 -6 -7 -3 14 -42 34
|
||||
-49 26 -1 -1 1 -17 3 -34 6 -35 22 -45 24 -15 1 15 2 15 6 0 2 -9 12 -19 21
|
||||
-21 9 -3 1 -4 -18 -3 -28 1 -35 6 -40 26 l-6 25 -7 -24 c-5 -21 -8 -22 -21
|
||||
-11 -9 7 -16 20 -16 29 1 11 5 8 15 -9 8 -14 15 -20 15 -15 0 6 3 21 7 34 5
|
||||
20 3 23 -10 18 -9 -3 -18 -1 -20 6 -7 20 -18 1 -20 -36 -2 -35 -13 -38 -44
|
||||
-14 -7 5 -13 6 -13 3 0 -4 -13 1 -30 10 l-29 18 30 27 c18 16 26 30 20 33 -6
|
||||
4 -24 -6 -40 -23 l-29 -30 -22 24 c-19 20 -21 27 -10 40 10 12 10 15 -1 16 -8
|
||||
0 -5 4 6 8 12 5 25 3 33 -6 21 -20 37 -15 18 6 -10 10 -13 22 -8 25 5 3 15 -6
|
||||
22 -19 7 -14 17 -25 22 -25 5 0 6 5 2 12 -4 7 -3 8 5 4 6 -4 8 -12 5 -18 -5
|
||||
-8 -1 -9 10 -5 9 4 15 3 11 -2 -8 -15 94 -44 155 -45 38 -1 68 6 99 21 24 13
|
||||
47 20 52 17 5 -3 10 0 10 5 1 6 2 15 3 20 0 5 5 13 10 18 5 5 6 3 2 -5 -6 -10
|
||||
-3 -13 11 -10 10 1 29 -8 41 -20 13 -13 27 -20 33 -16 5 3 -5 17 -23 32 l-33
|
||||
25 25 27 25 26 25 -20 c14 -12 30 -25 35 -30z m-624 -11 c11 6 11 5 2 -5 -12
|
||||
-14 -33 -6 -33 13 0 8 3 7 9 -2 5 -8 14 -10 22 -6z m348 -136 c9 -27 9 -30 -4
|
||||
-19 -8 7 -15 21 -15 31 0 28 7 23 19 -12z m221 27 c0 -2 -12 -11 -27 -20 l-28
|
||||
-17 24 20 c23 21 31 25 31 17z m-475 -44 c-3 -3 -11 0 -18 7 -9 10 -8 11 6 5
|
||||
10 -3 15 -9 12 -12z m45 -12 c8 -5 11 -10 5 -10 -5 0 -17 5 -25 10 -8 5 -10
|
||||
10 -5 10 6 0 17 -5 25 -10z m316 -9 c-8 -13 -91 -34 -112 -28 -13 3 -9 5 11 7
|
||||
17 1 46 8 65 15 44 17 42 17 36 6z m-306 -27 c0 -2 -7 -4 -15 -4 -8 0 -15 4
|
||||
-15 10 0 5 7 7 15 4 8 -4 15 -8 15 -10z m57 10 c-3 -3 -12 -4 -19 -1 -8 3 -5
|
||||
6 6 6 11 1 17 -2 13 -5z m300 -16 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4
|
||||
-12 1 -19z m-239 5 c-10 -2 -26 -2 -35 0 -10 3 -2 5 17 5 19 0 27 -2 18 -5z
|
||||
m209 1 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m-179 -59 c-3
|
||||
-3 -9 2 -12 12 -6 14 -5 15 5 6 7 -7 10 -15 7 -18z"/>
|
||||
<path d="M1280 1020 c-9 -6 -10 -10 -3 -10 6 0 15 5 18 10 8 12 4 12 -15 0z"/>
|
||||
<path d="M1405 976 c-65 -32 -55 -32 20 -1 33 13 53 25 45 25 -8 0 -37 -11
|
||||
-65 -24z"/>
|
||||
<path d="M1655 981 c87 -31 91 -32 40 -6 -27 13 -59 25 -70 25 -11 -1 3 -9 30
|
||||
-19z"/>
|
||||
<path d="M1269 813 c-13 -16 -12 -17 4 -4 9 7 17 15 17 17 0 8 -8 3 -21 -13z"/>
|
||||
<path d="M1440 701 c-8 -6 -18 -7 -24 -4 -5 3 -6 1 -2 -5 5 -8 13 -9 25 -2 10
|
||||
5 22 6 26 2 5 -4 5 -1 1 6 -8 14 -7 14 -26 3z"/>
|
||||
<path d="M1620 426 c0 -2 7 -7 16 -10 8 -3 12 -2 9 4 -6 10 -25 14 -25 6z"/>
|
||||
<path d="M1561 397 c-15 -19 -2 -29 15 -12 8 7 14 16 14 19 0 11 -17 6 -29 -7z"/>
|
||||
<path d="M1820 312 c0 -12 19 -26 26 -19 2 2 -2 10 -11 17 -9 8 -15 8 -15 2z"/>
|
||||
<path d="M1290 295 c-11 -14 -11 -18 4 -33 17 -16 18 -16 11 8 -6 22 -6 23 6
|
||||
8 9 -12 19 -15 28 -9 9 6 10 11 2 15 -6 4 -11 4 -11 0 0 -4 -6 0 -13 10 -12
|
||||
16 -14 17 -27 1z"/>
|
||||
<path d="M1732 288 c-7 -7 -18 -13 -25 -13 -7 0 -11 -9 -9 -20 4 -20 3 -20
|
||||
-12 0 -11 15 -15 16 -15 5 0 -23 26 -54 31 -38 4 11 8 10 21 -1 20 -16 22 -8
|
||||
6 21 -7 14 -8 23 0 31 7 7 12 1 17 -18 6 -22 8 -25 16 -12 5 9 15 14 23 11 20
|
||||
-8 19 1 -2 26 -20 23 -34 25 -51 8z"/>
|
||||
<path d="M1388 240 c-9 -16 -13 -32 -8 -35 4 -3 11 3 15 13 7 15 9 14 16 -8 7
|
||||
-19 8 -16 4 15 -3 27 -1 35 5 25 7 -12 12 -12 22 -2 8 8 8 12 1 12 -6 0 -17 2
|
||||
-25 5 -7 3 -20 -8 -30 -25z"/>
|
||||
<path d="M1366 244 c-20 -19 -20 -25 -2 -18 8 3 17 12 20 20 7 18 1 18 -18 -2z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 77 KiB |
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="211.000000pt" height="273.000000pt" viewBox="0 0 211.000000 273.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,273.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M173 2490 c-67 -40 -63 33 -63 -1152 0 -1034 1 -1074 19 -1102 10
|
||||
-15 32 -37 47 -47 28 -18 63 -19 889 -19 835 0 861 1 892 20 67 40 63 -33 63
|
||||
1151 0 1071 0 1072 -21 1106 -41 67 11 63 -936 63 -833 0 -859 -1 -890 -20z
|
||||
m998 -590 c30 -6 92 -28 138 -50 153 -73 255 -204 301 -386 24 -92 25 -145 5
|
||||
-239 -68 -323 -394 -520 -708 -428 -192 56 -350 231 -388 431 -16 84 -6 221
|
||||
21 299 92 264 362 423 631 373z"/>
|
||||
<path d="M1035 1768 c-81 -29 -157 -108 -186 -193 -7 -22 -21 -49 -30 -60 -9
|
||||
-11 -24 -34 -33 -52 -9 -18 -33 -44 -53 -59 -77 -56 -80 -78 -23 -136 22 -23
|
||||
40 -47 40 -53 0 -7 6 -18 14 -24 12 -10 18 -4 32 38 19 51 32 61 86 61 52 0
|
||||
122 -121 135 -234 5 -43 8 -47 19 -31 12 16 14 14 28 -20 9 -21 16 -41 16 -46
|
||||
0 -39 141 48 202 125 50 63 89 145 96 201 l4 42 -46 6 c-25 4 -74 21 -108 38
|
||||
-72 35 -178 101 -178 110 0 3 11 11 24 17 13 6 29 25 35 42 l11 32 -65 -4 -65
|
||||
-4 33 34 c17 18 60 47 95 64 54 27 69 30 120 25 31 -3 66 -9 77 -13 38 -15 -7
|
||||
28 -50 47 -93 43 -212 12 -300 -76 -25 -25 -41 -37 -36 -27 14 27 94 98 132
|
||||
118 20 10 57 18 91 18 32 1 58 4 58 7 0 20 -125 25 -175 7z m-160 -298 c-3 -5
|
||||
-13 -10 -21 -10 -8 0 -14 5 -14 10 0 6 9 10 21 10 11 0 17 -4 14 -10z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 11 KiB |
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="105.000000pt" height="107.000000pt" viewBox="0 0 105.000000 107.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,107.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 521 B |
|
After Width: | Height: | Size: 9.1 KiB |
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="165.000000pt" height="171.000000pt" viewBox="0 0 165.000000 171.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,171.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 521 B |
|
After Width: | Height: | Size: 274 KiB |
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="814.000000pt" height="811.000000pt" viewBox="0 0 814.000000 811.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,811.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M3775 7969 c-361 -29 -748 -111 -1051 -224 -1194 -446 -2091 -1443
|
||||
-2402 -2670 -138 -545 -158 -1074 -60 -1635 176 -1019 786 -1951 1653 -2531
|
||||
611 -408 1294 -624 2040 -646 1052 -31 2070 373 2816 1117 479 478 798 1014
|
||||
985 1655 94 321 154 738 154 1070 0 326 -59 742 -150 1057 -378 1310 -1395
|
||||
2324 -2684 2677 -425 116 -891 163 -1301 130z m635 -2137 c443 -97 831 -360
|
||||
1077 -732 190 -287 293 -626 293 -965 0 -544 -255 -1049 -695 -1375 -296 -220
|
||||
-643 -335 -1010 -333 -469 1 -885 179 -1216 519 -179 185 -292 363 -380 604
|
||||
-351 958 212 2015 1205 2266 148 38 202 43 426 40 162 -3 225 -8 300 -24z"/>
|
||||
<path d="M4052 5449 c-202 -54 -391 -189 -519 -370 -59 -84 -128 -226 -150
|
||||
-313 -14 -54 -23 -71 -44 -82 -37 -19 -75 -66 -89 -111 -33 -102 -88 -171
|
||||
-204 -255 -149 -108 -184 -158 -171 -244 9 -62 46 -104 93 -105 32 -1 34 -2
|
||||
12 -8 -40 -11 -29 -32 35 -65 70 -36 72 -38 81 -91 9 -54 30 -95 68 -127 40
|
||||
-35 46 -35 46 3 0 17 16 63 35 102 27 55 35 83 35 127 l0 56 143 10 c107 8
|
||||
154 16 192 32 45 20 48 20 27 3 -12 -11 -28 -21 -35 -24 -7 -3 6 -23 34 -53
|
||||
86 -91 162 -226 224 -399 46 -127 65 -203 79 -320 l12 -100 27 46 c15 25 32
|
||||
61 38 80 19 54 29 57 29 8 0 -57 30 -176 64 -251 l26 -58 67 25 c408 154 788
|
||||
631 828 1040 4 39 9 77 11 86 4 14 -9 17 -83 22 -211 13 -423 104 -788 337
|
||||
-66 42 -137 83 -159 92 l-38 15 58 21 c92 33 169 123 187 218 5 28 3 32 -21
|
||||
37 -51 10 -295 -9 -335 -26 -35 -15 -37 -15 -28 1 18 34 187 188 258 235 241
|
||||
160 494 197 721 106 41 -16 77 -28 79 -25 9 8 -69 86 -120 119 -117 77 -294
|
||||
124 -427 114 -236 -19 -543 -208 -694 -430 -67 -97 -73 -91 -12 13 115 196
|
||||
305 358 501 427 76 27 88 28 253 27 l173 0 -45 23 c-77 39 -151 53 -281 52
|
||||
-86 0 -141 -6 -193 -20z m-553 -895 c2 -2 -1 -15 -7 -29 -8 -17 -20 -25 -36
|
||||
-25 -13 0 -38 -3 -56 -7 l-33 -6 19 31 c20 35 57 53 89 45 11 -3 22 -7 24 -9z
|
||||
m-342 -801 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 458 KiB |
@@ -0,0 +1,528 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="423.000000pt" height="637.000000pt" viewBox="0 0 423.000000 637.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,637.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M0 3185 l0 -3185 2115 0 2115 0 0 3185 0 3185 -2115 0 -2115 0 0
|
||||
-3185z m602 3011 c97 -21 173 -62 242 -132 98 -97 146 -209 146 -339 0 -130
|
||||
-48 -243 -146 -341 -292 -294 -788 -106 -821 311 -15 190 92 372 268 459 109
|
||||
53 199 65 311 42z m1985 -388 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1
|
||||
-19z m-255 -163 c4 -34 3 -35 -30 -35 -31 0 -34 2 -28 23 3 12 6 28 6 35 0 6
|
||||
11 12 24 12 20 0 25 -6 28 -35z m378 -45 c6 -11 8 -20 6 -20 -3 0 -10 9 -16
|
||||
20 -6 11 -8 20 -6 20 3 0 10 -9 16 -20z m-690 -14 c0 -2 -7 -7 -16 -10 -8 -3
|
||||
-12 -2 -9 4 6 10 25 14 25 6z m673 -23 c-7 -2 -21 -2 -30 0 -10 3 -4 5 12 5
|
||||
17 0 24 -2 18 -5z m-97 -18 c-36 -19 -45 -19 -20 0 10 8 26 14 34 15 8 0 2 -7
|
||||
-14 -15z m-659 -1 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m591
|
||||
-54 c-7 -10 -14 -17 -17 -15 -4 4 18 35 25 35 2 0 -1 -9 -8 -20z m319 -17 c-3
|
||||
-10 -5 -4 -5 12 0 17 2 24 5 18 2 -7 2 -21 0 -30z m-128 11 c1 -1 1 -7 0 -13
|
||||
-3 -6 -16 -2 -34 10 l-30 20 30 -7 c17 -4 32 -8 34 -10z m-1100 -7 c-2 -1 -13
|
||||
-9 -24 -17 -19 -14 -19 -14 -6 3 7 9 18 17 24 17 6 0 8 -1 6 -3z m1061 -12 c0
|
||||
-8 -4 -15 -10 -15 -5 0 -10 7 -10 15 0 8 5 15 10 15 6 0 10 -7 10 -15z m-1187
|
||||
-2 c-7 -2 -21 -2 -30 0 -10 3 -4 5 12 5 17 0 24 -2 18 -5z m107 -30 c10 9 13
|
||||
9 17 0 3 -7 11 -13 19 -13 7 0 19 -9 26 -20 13 -21 48 -28 48 -10 0 6 -4 10
|
||||
-10 10 -5 0 -10 5 -10 10 0 6 25 10 58 9 52 -1 54 -2 30 -12 -35 -14 -36 -27
|
||||
-2 -27 17 0 23 4 18 13 -5 8 -2 8 9 -2 21 -17 22 -65 1 -85 -14 -14 -14 -16 0
|
||||
-16 21 0 49 46 43 70 -3 13 0 20 9 20 17 0 18 12 2 28 -9 9 -2 12 31 12 38 0
|
||||
42 -2 31 -15 -7 -9 -10 -18 -6 -22 3 -4 12 2 20 12 9 13 29 20 60 22 40 3 46
|
||||
1 46 -17 0 -16 7 -20 30 -20 34 0 40 15 10 23 -11 3 -18 1 -14 -4 3 -5 0 -9
|
||||
-5 -9 -6 0 -11 7 -11 15 0 12 14 15 70 15 62 0 70 -2 70 -19 0 -32 32 -36 55
|
||||
-7 24 30 31 32 39 10 5 -13 3 -14 -7 -6 -10 9 -20 -2 -45 -48 -18 -32 -38 -61
|
||||
-45 -63 -6 -3 2 -5 18 -5 17 0 25 2 18 4 -7 3 -9 12 -6 20 4 12 8 12 13 4 5
|
||||
-9 9 -9 14 -1 4 6 2 11 -4 11 -6 0 -4 12 6 32 l17 32 19 -38 c11 -21 17 -44
|
||||
14 -52 -4 -11 7 -14 52 -13 31 0 51 3 45 6 -8 3 -13 23 -13 51 l0 46 49 -48
|
||||
49 -48 4 61 c2 45 0 60 -9 57 -7 -3 -15 -1 -18 4 -4 6 8 10 26 10 26 0 30 -3
|
||||
21 -12 -29 -29 -11 -33 143 -32 146 1 155 0 149 -18 -4 -12 0 -18 11 -18 11 0
|
||||
15 5 11 15 -3 10 3 17 21 21 24 6 33 0 76 -47 61 -68 67 -84 67 -172 0 -91 -7
|
||||
-117 -31 -117 -29 0 -35 -28 -10 -51 11 -11 21 -15 21 -9 0 6 -7 13 -15 16
|
||||
-24 10 -18 34 10 34 13 0 29 8 35 18 11 16 11 16 6 -1 -5 -17 18 -77 30 -77 2
|
||||
0 -2 14 -11 30 -18 35 -12 41 6 8 7 -13 12 -39 12 -58 -1 -31 -1 -32 7 -10 7
|
||||
22 8 21 9 -12 1 -37 -12 -51 -22 -25 -3 7 -6 5 -6 -5 -1 -14 8 -18 37 -19 20
|
||||
-1 40 -1 44 0 4 0 11 -11 14 -27 4 -15 13 -34 21 -44 8 -9 13 -30 11 -49 -2
|
||||
-25 -11 -37 -35 -51 -28 -15 -33 -15 -33 -3 0 8 8 15 18 15 10 0 23 5 30 12
|
||||
17 17 15 63 -3 78 -8 7 -16 22 -16 34 -1 18 -2 18 -6 3 -3 -10 3 -27 12 -37
|
||||
25 -27 16 -73 -15 -80 -16 -4 -26 -14 -28 -28 -7 -46 -72 -9 -72 41 0 11 -4
|
||||
15 -12 11 -7 -4 -8 -3 -4 4 14 23 -6 105 -30 127 -29 27 -32 57 -6 49 16 -5
|
||||
16 -5 -1 6 -9 6 -15 15 -12 21 4 5 1 9 -5 9 -8 0 -11 -14 -8 -40 l4 -40 -66
|
||||
-1 c-36 -1 -68 -1 -73 0 -4 1 -31 1 -60 1 -28 0 -61 0 -72 0 -217 0 -260 -2
|
||||
-274 -13 -12 -9 -13 -9 -7 1 6 10 -35 12 -201 12 -230 -1 -233 -1 -249 19 -9
|
||||
11 -13 11 -19 1 -4 -7 -2 -16 6 -22 16 -10 -52 -5 -69 6 -6 3 -13 2 -16 -2 -7
|
||||
-11 -56 -3 -75 12 -11 8 -13 8 -7 -1 4 -7 3 -13 -3 -13 -5 0 -11 6 -14 13 -4
|
||||
10 -7 10 -18 0 -14 -14 -279 -19 -279 -6 0 3 8 16 18 27 16 20 16 20 -1 7 -10
|
||||
-8 -25 -28 -33 -45 -8 -17 -12 -23 -9 -13 4 15 -3 17 -50 17 -30 0 -55 5 -55
|
||||
10 0 6 5 10 10 10 6 0 10 4 10 10 0 5 -7 7 -15 4 -8 -4 -15 -12 -15 -20 0 -12
|
||||
-36 -14 -205 -14 l-205 0 36 73 c20 39 51 88 68 108 17 20 43 56 59 80 30 48
|
||||
62 95 102 148 14 19 25 45 25 58 0 20 5 23 41 23 l41 0 -4 -49 c-2 -36 0 -47
|
||||
10 -44 6 3 12 16 12 29 0 13 4 24 8 24 13 0 53 -46 46 -52 -3 -3 10 -6 30 -5
|
||||
l35 1 -27 17 c-15 9 -35 25 -45 36 -16 19 -16 21 -1 34 9 7 31 12 50 10 19 -1
|
||||
34 2 34 8 0 17 -19 22 -41 10 -15 -8 -19 -8 -15 0 14 22 -9 10 -42 -21 l-34
|
||||
-33 4 33 c4 31 3 33 -19 27 -13 -3 -23 -1 -23 5 0 5 16 10 35 10 19 0 35 -4
|
||||
35 -10 0 -5 -4 -10 -10 -10 -5 0 -10 -7 -10 -17 0 -14 2 -14 20 2 11 10 17 22
|
||||
14 26 -3 5 27 9 65 9 43 0 71 4 71 11 0 5 5 7 10 4 18 -11 -10 -36 -31 -30
|
||||
-17 6 -19 0 -19 -50 0 -50 3 -57 25 -67 18 -8 35 -9 53 -2 24 8 28 15 32 66 5
|
||||
51 3 57 -14 55 -11 -1 -20 5 -21 16 -2 11 1 14 8 10 7 -5 27 -8 45 -8 25 -1
|
||||
31 3 27 15 -4 12 -2 11 8 -2 11 -14 16 -15 27 -5z m805 -33 c10 -11 29 -20 42
|
||||
-20 18 0 23 -5 23 -27 l0 -27 -43 42 c-23 23 -46 42 -50 42 -4 0 -7 -27 -7
|
||||
-60 0 -51 -3 -60 -17 -60 -20 0 -57 56 -47 71 3 5 16 9 30 9 15 0 24 6 24 16
|
||||
0 10 -6 14 -14 11 -10 -4 -13 -1 -9 9 8 20 47 17 68 -6z m-895 -54 c0 -41 -21
|
||||
-60 -55 -52 -21 5 -25 12 -25 46 0 40 0 40 40 40 39 0 40 -1 40 -34z m-370
|
||||
-30 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m1867 -213
|
||||
c-2 -21 -4 -6 -4 32 0 39 2 55 4 38 2 -18 2 -50 0 -70z m-2657 -190 c0 -1 -8
|
||||
0 -17 3 -10 4 2 -13 26 -36 37 -36 49 -41 78 -38 l33 4 -27 -23 -27 -23 -63
|
||||
67 c-67 73 -84 109 -33 71 17 -12 30 -23 30 -25z m71 -30 c13 -15 12 -15 -8
|
||||
-4 -24 12 -29 21 -14 21 5 0 15 -7 22 -17z m1116 -35 c-3 -8 -6 -5 -6 6 -1 11
|
||||
2 17 5 13 3 -3 4 -12 1 -19z m90 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4
|
||||
-12 1 -19z m93 2 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0
|
||||
11 -4 11 -10z m348 3 c-15 -2 -42 -2 -60 0 -18 2 -6 4 27 4 33 0 48 -2 33 -4z
|
||||
m254 -56 c-29 -29 -52 -59 -52 -66 0 -8 12 -30 26 -50 l26 -36 -31 33 c-17 18
|
||||
-31 40 -31 49 0 16 101 132 109 126 3 -2 -19 -27 -47 -56z m559 46 c13 -16 12
|
||||
-17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m-1515 -12 c-8 -13 -84 -51
|
||||
-101 -51 -12 0 -12 5 -3 26 10 21 17 25 49 23 21 -2 41 0 45 4 10 10 16 9 10
|
||||
-2z m164 -16 c5 3 11 1 15 -5 3 -5 -3 -10 -15 -10 -13 0 -19 -4 -14 -11 4 -8
|
||||
0 -8 -15 0 -11 7 -21 16 -21 21 0 14 17 12 23 -2 3 -7 6 -2 7 12 2 18 4 20 7
|
||||
7 2 -9 8 -15 13 -12z m413 -20 c-7 -21 -13 -19 -13 6 0 11 4 18 10 14 5 -3 7
|
||||
-12 3 -20z m214 3 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m34 5
|
||||
c13 -16 12 -17 -3 -4 -17 13 -22 21 -14 21 2 0 10 -8 17 -17z m722 2 c-3 -9
|
||||
-8 -14 -10 -11 -3 3 -2 9 2 15 9 16 15 13 8 -4z m-2353 -15 c-27 -7 -60 -2
|
||||
-60 9 0 4 19 5 43 2 35 -4 38 -5 17 -11z m1257 -2 c-3 -8 -6 -5 -6 6 -1 11 2
|
||||
17 5 13 3 -3 4 -12 1 -19z m20 0 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4
|
||||
-12 1 -19z m417 14 c2 -4 -4 -8 -15 -8 -10 0 -19 4 -19 8 0 4 6 8 14 8 8 0 17
|
||||
-4 20 -8z m-111 -22 c3 -11 1 -18 -4 -14 -5 3 -9 12 -9 20 0 20 7 17 13 -6z
|
||||
m505 -11 c-1 -17 5 -35 13 -40 10 -6 7 -9 -13 -9 -20 0 -26 -4 -22 -15 7 -17
|
||||
-4 -19 -26 -5 -11 7 -11 10 -2 10 7 0 10 5 6 11 -4 8 -12 3 -20 -12 l-13 -24
|
||||
-1 28 c0 20 5 27 20 27 11 0 20 -4 20 -10 0 -5 7 -7 15 -4 8 4 15 13 15 21 0
|
||||
10 -6 13 -16 9 -10 -4 -14 -2 -11 6 2 7 10 12 16 11 6 -2 11 4 11 12 0 8 2 15
|
||||
4 15 3 0 4 -14 4 -31z m-1091 15 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17
|
||||
-2 13 -5z m-1122 -36 c-41 -26 -51 -28 -73 -19 -13 7 -23 13 -21 15 9 9 88 31
|
||||
114 33 26 1 25 -1 -20 -29z m522 17 c0 -8 -4 -12 -9 -9 -5 3 -6 10 -3 15 9 13
|
||||
12 11 12 -6z m1980 9 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z
|
||||
m-343 -12 c3 -5 -1 -9 -9 -9 -8 0 -12 4 -9 9 3 4 7 8 9 8 2 0 6 -4 9 -8z m366
|
||||
-2 c-8 -5 -22 -10 -32 -10 -9 0 -19 -6 -21 -12 -3 -8 -6 -7 -6 4 -1 15 8 19
|
||||
64 26 6 1 3 -3 -5 -8z m-773 -6 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17
|
||||
-2 13 -5z m254 -11 c11 -15 11 -16 -1 -6 -11 10 -17 10 -29 0 -14 -11 -14 -10
|
||||
-2 6 7 9 15 17 16 17 1 0 9 -8 16 -17z m-51 -3 c0 -5 -2 -10 -4 -10 -3 0 -8 5
|
||||
-11 10 -3 6 -1 10 4 10 6 0 11 -4 11 -10z m-1549 -33 c-10 -9 -11 -8 -5 6 3
|
||||
10 9 15 12 12 3 -3 0 -11 -7 -18z m531 -19 l4 -38 -39 0 c-32 0 -38 3 -33 16
|
||||
3 9 6 26 6 38 0 18 6 22 29 21 27 0 30 -4 33 -37z m985 15 c0 -9 -4 -10 -14
|
||||
-2 -7 6 -13 12 -13 14 0 1 6 2 13 2 8 0 14 -6 14 -14z m133 -3 c0 -5 -4 -10
|
||||
-10 -10 -5 0 -10 5 -10 10 0 6 5 10 10 10 6 0 10 -4 10 -10z m177 4 c-3 -3
|
||||
-12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m-1786 -21 c13 -16 12 -17 -3
|
||||
-4 -17 13 -23 8 -19 -13 1 -5 -4 -5 -11 1 -7 6 -20 13 -28 17 -8 3 -5 4 7 2
|
||||
13 -2 26 0 29 5 7 12 10 12 25 -8z m984 7 c-3 -5 -11 -10 -16 -10 -6 0 -7 5
|
||||
-4 10 3 6 11 10 16 10 6 0 7 -4 4 -10z m985 -15 c-13 -14 -31 -25 -39 -24 -11
|
||||
0 -10 3 4 9 12 4 27 15 34 24 7 9 16 16 19 16 3 0 -5 -11 -18 -25z m-810 -17
|
||||
c0 -5 -16 -8 -35 -8 -19 0 -35 3 -35 8 0 4 16 7 35 7 19 0 35 -3 35 -7z m998
|
||||
-13 c-3 -3 -9 2 -12 12 -6 14 -5 15 5 6 7 -7 10 -15 7 -18z m52 7 c0 -5 -7 -9
|
||||
-15 -9 -8 0 -12 4 -9 9 3 4 9 8 15 8 5 0 9 -4 9 -8z m-700 -46 c13 -9 19 -16
|
||||
13 -16 -7 0 -15 5 -18 10 -3 6 -14 10 -23 10 -11 0 -18 8 -19 21 -2 18 0 19
|
||||
10 7 7 -8 23 -22 37 -32z m394 29 c-4 -8 -8 -15 -10 -15 -2 0 -4 7 -4 15 0 8
|
||||
4 15 10 15 5 0 7 -7 4 -15z m-1214 -10 c-14 -8 -34 -14 -45 -14 -13 0 -8 5 15
|
||||
14 46 18 61 18 30 0z m468 -17 c3 -26 1 -28 -32 -28 -31 0 -36 3 -36 23 0 31
|
||||
9 39 40 35 19 -2 26 -10 28 -30z m-621 -13 c-20 -14 -37 -29 -37 -34 0 -9 -90
|
||||
-51 -111 -51 -8 0 -1 7 15 15 15 8 35 15 43 15 7 0 25 11 38 24 31 31 67 56
|
||||
80 56 5 0 -7 -11 -28 -25z m1336 5 c-6 -23 -31 -46 -40 -36 -3 3 -1 6 6 6 6 0
|
||||
16 11 21 25 11 30 20 33 13 5z m58 3 c13 -16 12 -17 -3 -4 -17 13 -22 21 -14
|
||||
21 2 0 10 -8 17 -17z m-2121 -29 c0 -24 -8 -46 -26 -67 -30 -36 -21 -47 41
|
||||
-47 45 1 74 21 96 65 8 15 19 30 26 32 18 6 -24 -69 -50 -89 -47 -37 -186 -17
|
||||
-162 23 4 6 3 14 -3 18 -6 4 -2 23 11 53 17 36 27 48 45 48 19 0 22 -5 22 -36z
|
||||
m1808 19 c-10 -2 -26 -2 -35 0 -10 3 -2 5 17 5 19 0 27 -2 18 -5z m83 -10 c12
|
||||
-16 12 -17 -1 -7 -8 6 -22 14 -30 17 -13 5 -12 6 1 6 9 1 23 -7 30 -16z m-364
|
||||
-25 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m667 -39 c-2 -4 -15
|
||||
-2 -28 4 -14 7 -20 15 -14 18 7 4 7 9 -1 13 -6 4 -11 11 -11 16 0 4 13 -3 29
|
||||
-18 17 -14 28 -29 25 -33z m-1739 32 c-22 -4 -52 -14 -65 -24 -17 -12 -42 -17
|
||||
-80 -15 l-55 1 62 6 c40 4 69 12 80 24 11 11 31 17 58 16 l40 -2 -40 -6z
|
||||
m-206 -27 c14 -12 -19 -1 -35 12 -18 14 -18 14 6 3 14 -6 27 -13 29 -15z
|
||||
m1688 20 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m63 -8 c-7 -7
|
||||
-13 -7 -20 0 -6 6 -3 10 10 10 13 0 16 -4 10 -10z m117 -18 c-3 -8 -6 -5 -6 6
|
||||
-1 11 2 17 5 13 3 -3 4 -12 1 -19z m-640 -27 c-2 -10 0 -26 5 -35 8 -13 3 -16
|
||||
-27 -16 -30 0 -35 3 -35 23 0 14 3 18 8 10 9 -14 26 -5 35 20 9 23 21 22 14
|
||||
-2z m108 9 c3 -5 1 -10 -4 -10 -6 0 -11 5 -11 10 0 6 2 10 4 10 3 0 8 -4 11
|
||||
-10z m55 0 c0 -5 -5 -10 -11 -10 -5 0 -7 5 -4 10 3 6 8 10 11 10 2 0 4 -4 4
|
||||
-10z m-585 -28 c-3 -3 -11 0 -18 7 -9 10 -8 11 6 5 10 -3 15 -9 12 -12z m1040
|
||||
8 c3 -5 1 -10 -4 -10 -6 0 -11 5 -11 10 0 6 2 10 4 10 3 0 8 -4 11 -10z m163
|
||||
-36 c-3 -14 -5 -12 -10 9 -3 19 -2 25 4 19 6 -6 8 -18 6 -28z m-543 6 c3 -6
|
||||
-1 -7 -10 -4 -33 13 -66 -7 -100 -61 -44 -69 -62 -78 -133 -71 -32 3 -110 7
|
||||
-174 9 -70 1 -118 6 -118 12 0 10 158 4 293 -11 52 -5 61 -3 84 18 14 12 31
|
||||
36 39 51 9 15 24 37 35 48 20 20 73 26 84 9z m-609 -28 c-4 -3 -14 2 -24 12
|
||||
-16 18 -16 18 6 6 13 -6 21 -14 18 -18z m1803 -16 c-3 -3 -11 5 -18 17 -13 21
|
||||
-12 21 5 5 10 -10 16 -20 13 -22z m-1419 4 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11
|
||||
10 -3 6 -1 10 4 10 6 0 11 -4 11 -10z m-1260 -51 c0 -5 -7 -9 -15 -9 -15 0
|
||||
-20 12 -9 23 8 8 24 -1 24 -14z m910 -4 c13 -14 21 -25 18 -25 -2 0 -15 11
|
||||
-28 25 -13 14 -21 25 -18 25 2 0 15 -11 28 -25z m1637 3 c-3 -8 -6 -5 -6 6 -1
|
||||
11 2 17 5 13 3 -3 4 -12 1 -19z m276 -132 c16 -62 17 -80 3 -41 -9 22 -16 47
|
||||
-16 56 0 8 -14 28 -31 45 -17 16 -40 43 -51 59 -12 17 3 3 33 -29 30 -33 58
|
||||
-73 62 -90z m-115 66 c2 -7 -2 -10 -11 -6 -8 3 -18 1 -22 -5 -8 -14 -25 -14
|
||||
-25 0 0 5 5 7 10 4 6 -3 10 1 10 10 0 19 31 17 38 -3z m-994 -24 c-5 -9 -2 -9
|
||||
9 1 9 7 17 11 17 8 0 -3 3 -13 7 -23 5 -13 3 -15 -8 -10 -8 4 -6 1 4 -7 27
|
||||
-23 20 -37 -19 -37 -35 0 -35 1 -29 33 8 35 13 47 21 47 3 0 2 -6 -2 -12z
|
||||
m346 -2 c-7 -7 -14 -6 -21 1 -9 9 -7 12 9 10 14 -1 18 -5 12 -11z m322 -8 c-7
|
||||
-7 -12 -8 -12 -2 0 6 3 14 7 17 3 4 9 5 12 2 2 -3 -1 -11 -7 -17z m-1245 -35
|
||||
c-3 -10 -5 -4 -5 12 0 17 2 24 5 18 2 -7 2 -21 0 -30z m1288 27 c3 -5 1 -10
|
||||
-4 -10 -6 0 -11 5 -11 10 0 6 2 10 4 10 3 0 8 -4 11 -10z m-370 -9 c3 -5 2
|
||||
-12 -3 -15 -5 -3 -9 1 -9 9 0 17 3 19 12 6z m-175 -38 c0 -18 -3 -34 -7 -35
|
||||
-5 0 -19 -2 -33 -3 -23 -2 -25 1 -22 34 3 32 7 36 33 36 26 0 29 -3 29 -32z
|
||||
m680 2 c14 -19 14 -19 -2 -6 -10 7 -18 18 -18 24 0 6 1 8 3 6 1 -2 9 -13 17
|
||||
-24z m-1953 -11 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m535
|
||||
-41 c-3 -16 -7 -21 -12 -12 -6 8 -9 6 -13 -7 -4 -16 -5 -16 -6 -2 0 9 4 20 9
|
||||
23 6 3 10 16 10 28 0 16 3 18 9 9 4 -7 6 -25 3 -39z m-848 -34 c-3 -5 -22 -9
|
||||
-42 -9 -27 0 -33 3 -22 10 12 7 13 15 3 40 l-11 30 39 -31 c21 -17 37 -35 33
|
||||
-40z m351 61 c3 -5 2 -10 -4 -10 -5 0 -13 5 -16 10 -3 6 -2 10 4 10 5 0 13 -4
|
||||
16 -10z m2001 -12 c-10 -6 -22 -6 -26 -2 -5 5 3 10 18 11 22 1 24 0 8 -9z
|
||||
m164 8 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m-1774
|
||||
-101 c11 -17 14 -26 5 -21 -10 7 -12 2 -6 -25 4 -25 3 -30 -4 -19 -6 8 -11 23
|
||||
-11 33 0 10 -4 16 -8 13 -5 -3 -15 10 -24 29 -8 19 -11 32 -5 28 6 -4 8 0 4
|
||||
10 -23 57 -11 45 49 -48z m1725 78 c12 -16 12 -17 -1 -6 -8 6 -33 13 -55 16
|
||||
l-40 4 41 1 c29 1 46 -3 55 -15z m-1434 -15 c-3 -8 -6 -5 -6 6 -1 11 2 17 5
|
||||
13 3 -3 4 -12 1 -19z m1506 -45 c-10 -21 -26 -49 -35 -62 -10 -13 -18 -31 -19
|
||||
-40 0 -12 -2 -13 -6 -2 -3 7 10 42 28 77 37 69 60 88 32 27z m-1155 10 c-10
|
||||
-2 -28 -2 -40 0 -13 2 -5 4 17 4 22 1 32 -1 23 -4z m86 1 c16 -6 12 -24 -5
|
||||
-24 -6 0 -8 4 -5 9 4 5 0 12 -6 14 -7 3 -10 6 -6 6 3 1 13 -2 22 -5z m303 -41
|
||||
c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z m-1584 10 c-7 -2 -21
|
||||
-2 -30 0 -10 3 -4 5 12 5 17 0 24 -2 18 -5z m824 -15 c-3 -8 -6 -5 -6 6 -1 11
|
||||
2 17 5 13 3 -3 4 -12 1 -19z m423 15 c-8 -3 -19 -10 -25 -15 -22 -18 -119 -88
|
||||
-123 -88 -2 0 11 16 30 36 35 38 93 73 118 73 13 -1 13 -1 0 -6z m-432 -82
|
||||
c-4 -45 -43 -119 -56 -107 -2 3 0 11 6 18 10 13 12 18 12 39 0 5 5 7 12 3 6
|
||||
-4 8 -3 4 4 -6 10 14 92 23 92 2 0 1 -22 -1 -49z m769 -3 c-3 -8 -6 -5 -6 6
|
||||
-1 11 2 17 5 13 3 -3 4 -12 1 -19z m-978 -98 c-1 -41 2 -88 5 -105 6 -29 6
|
||||
-29 -4 -5 -14 31 -22 219 -9 199 5 -8 8 -48 8 -89z m481 75 c0 -7 -57 -35 -72
|
||||
-35 -7 0 5 9 27 19 48 23 45 22 45 16z m-863 -31 c-3 -3 -12 -4 -19 -1 -8 3
|
||||
-5 6 6 6 11 1 17 -2 13 -5z m148 -3 c-3 -6 3 -15 12 -21 15 -9 14 -10 -7 -4
|
||||
-14 4 -59 7 -100 6 -60 -1 -70 1 -50 10 14 5 49 7 77 5 29 -3 55 -1 58 4 4 5
|
||||
8 9 11 9 3 0 3 -4 -1 -9z m187 -38 c-10 -28 -10 -28 -11 12 -1 28 2 36 10 28
|
||||
8 -8 8 -19 1 -40z m365 11 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13
|
||||
-5z m1426 -111 c-5 -12 -63 -36 -70 -29 -2 2 10 8 26 14 30 11 31 13 32 74 l2
|
||||
63 7 -55 c4 -30 5 -60 3 -67z m-1809 71 c3 -8 2 -12 -4 -9 -6 3 -10 10 -10 16
|
||||
0 14 7 11 14 -7z m1132 -65 c5 0 9 -6 9 -13 0 -8 4 -18 8 -22 15 -16 6 -24
|
||||
-29 -24 -35 0 -35 1 -29 33 9 42 16 52 25 37 4 -6 11 -11 16 -11z m222 -1 c8
|
||||
-25 -17 -32 -47 -13 -5 3 -12 1 -16 -5 -10 -16 -25 -12 -25 8 0 15 8 18 43 17
|
||||
23 0 43 -3 45 -7z m295 -35 c-38 -5 -70 -40 -79 -87 -3 -18 -16 -46 -29 -62
|
||||
-23 -28 -25 -29 -122 -30 l-98 -2 93 7 c89 6 95 8 118 36 13 17 27 45 30 63
|
||||
10 53 40 82 82 80 37 -1 37 -1 5 -5z m64 1 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6
|
||||
6 11 1 17 -2 13 -5z m-1688 -46 c0 -31 -1 -31 -10 -10 -5 13 -7 28 -3 33 10
|
||||
16 14 9 13 -23z m28 -75 c-2 -16 -4 -5 -4 22 0 28 2 40 4 28 2 -13 2 -35 0
|
||||
-50z m-22 -120 c-10 -35 -21 -63 -26 -63 -4 0 -2 19 6 41 23 63 18 70 -9 14
|
||||
-28 -57 -33 -48 -10 16 8 24 17 52 19 62 2 10 7 28 11 40 7 20 8 18 17 -13 6
|
||||
-25 4 -51 -8 -97z m52 95 c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0 -25z
|
||||
m50 0 c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0 -25z m1166 -34 c-27
|
||||
-20 -39 -17 -18 6 10 11 22 17 27 14 5 -3 1 -12 -9 -20z m-1237 -105 c-9 -34
|
||||
-27 -75 -41 -91 -32 -38 -32 -24 0 22 14 21 31 65 38 101 6 35 13 56 15 47 2
|
||||
-10 -4 -45 -12 -79z m907 84 c-7 -2 -21 -2 -30 0 -10 3 -4 5 12 5 17 0 24 -2
|
||||
18 -5z m285 1 c-3 -3 -41 -5 -83 -5 -42 0 -80 2 -83 5 -3 4 34 6 83 6 49 0 86
|
||||
-2 83 -6z m-1138 -85 c-11 -38 -16 -44 -25 -30 -3 6 -1 11 4 11 6 0 11 8 11
|
||||
18 0 16 8 32 16 32 1 0 -1 -14 -6 -31z m740 -19 c-8 -5 -19 -10 -25 -10 -5 0
|
||||
-3 5 5 10 8 5 20 10 25 10 6 0 3 -5 -5 -10z m-850 -20 c0 -4 -6 -13 -14 -20
|
||||
-12 -9 -15 -8 -13 8 1 17 27 28 27 12z m746 -45 c-24 -24 -53 -63 -65 -87 -12
|
||||
-24 -18 -32 -15 -18 10 37 48 93 84 123 46 40 45 33 -4 -18z m-801 5 c-10 -11
|
||||
-15 -20 -11 -20 3 0 -1 -14 -9 -31 -11 -21 -34 -39 -69 -55 -57 -26 -135 -44
|
||||
-103 -24 9 6 27 13 38 15 42 8 165 95 134 95 -4 0 0 9 10 20 10 11 20 20 23
|
||||
20 3 0 -3 -9 -13 -20z m11 -38 c-17 -16 -18 -16 -5 5 7 12 15 20 18 17 3 -2
|
||||
-3 -12 -13 -22z m-46 14 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21
|
||||
21 21 13z m975 -16 c3 -5 0 -7 -8 -4 -8 3 -17 -2 -21 -12 -5 -13 -9 -14 -21
|
||||
-4 -8 6 -20 8 -27 4 -10 -5 -10 -4 -1 6 10 11 15 11 28 0 12 -10 15 -10 15 4
|
||||
0 17 25 22 35 6z m-904 -27 c-5 -10 -31 -38 -58 -63 -89 -84 -98 -86 -18 -3
|
||||
44 45 81 82 83 82 1 1 -2 -7 -7 -16z m108 -23 c0 -10 -3 -8 -9 5 -12 27 -12
|
||||
43 0 25 5 -8 9 -22 9 -30z m833 33 c-6 -2 -10 -8 -7 -12 2 -5 -9 -21 -25 -36
|
||||
-26 -25 -34 -27 -57 -19 -24 8 -31 5 -55 -21 l-28 -30 15 31 c16 32 77 71 83
|
||||
53 3 -6 9 -5 18 2 11 9 14 9 14 -1 0 -10 3 -10 15 0 8 6 14 15 13 18 -2 16 3
|
||||
22 15 21 9 0 9 -2 -1 -6z m-882 -60 c-11 -17 -11 -17 -6 0 3 10 7 26 7 35 1
|
||||
15 2 15 6 0 2 -10 -1 -25 -7 -35z m-240 22 c-14 -8 -36 -14 -50 -14 -21 1 -19
|
||||
2 8 9 18 4 36 10 39 14 4 3 11 6 17 6 6 -1 0 -7 -14 -15z m970 -5 c0 -5 -12
|
||||
-10 -27 -9 -25 0 -26 1 -8 9 27 12 35 12 35 0z m-1083 -6 c-3 -3 -12 -4 -19
|
||||
-1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m856 -11 c-7 -2 -21 -2 -30 0 -10 3 -4 5
|
||||
12 5 17 0 24 -2 18 -5z m-411 -36 c-7 -27 -7 -27 -20 -6 -8 12 -9 18 -3 14 6
|
||||
-3 14 1 17 10 10 25 14 12 6 -18z m-392 2 c19 -6 14 -7 -20 -4 -33 4 -39 2
|
||||
-25 -4 19 -9 19 -10 -2 -10 -12 -1 -24 -5 -28 -11 -3 -5 -12 -7 -19 -4 -7 3
|
||||
-16 -2 -19 -10 -7 -18 -31 -22 -25 -4 5 15 78 57 98 57 8 -1 26 -5 40 -10z
|
||||
m893 4 c-7 -2 -19 -2 -25 0 -7 3 -2 5 12 5 14 0 19 -2 13 -5z m92 -3 c3 -5 1
|
||||
-10 -4 -10 -6 0 -11 5 -11 10 0 6 2 10 4 10 3 0 8 -4 11 -10z m-739 -49 c-15
|
||||
-15 -31 -41 -36 -57 -7 -24 -8 -25 -9 -7 -1 20 52 93 67 93 3 0 -7 -13 -22
|
||||
-29z m734 25 c0 -3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6 0 10
|
||||
-2 10 -4z m-1165 -26 c-27 -12 -43 -12 -25 0 8 5 22 9 30 9 10 0 8 -3 -5 -9z
|
||||
m562 -32 c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0 -25z m-297 4 c0 -4
|
||||
-10 -13 -22 -21 -23 -14 -23 -14 -4 8 20 22 26 25 26 13z m1094 -3 c14 -7 27
|
||||
-18 30 -26 8 -19 -11 -53 -30 -53 -19 0 -34 -40 -34 -91 0 -32 -3 -39 -20 -39
|
||||
-11 0 -20 5 -20 12 0 6 -7 4 -18 -5 -25 -23 -37 -21 -56 8 -11 16 -16 46 -16
|
||||
89 0 75 13 90 91 105 24 5 45 9 46 10 1 1 13 -4 27 -10z m-794 -58 c-4 -16
|
||||
-13 -38 -20 -48 -11 -17 -11 -17 -5 2 3 11 9 32 12 48 3 15 9 27 14 27 4 0 4
|
||||
-13 -1 -29z m-183 -23 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z
|
||||
m-27 -42 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m-47
|
||||
-66 c-10 -17 -19 -26 -21 -20 -4 10 25 50 35 50 2 0 -4 -14 -14 -30z m1097 -3
|
||||
c-1 -21 -1 -21 -15 -3 -8 10 -12 23 -9 28 9 14 24 -2 24 -25z m35 23 c-3 -5
|
||||
-12 -10 -18 -10 -7 0 -6 4 3 10 19 12 23 12 15 0z m-1180 -40 c-3 -5 -12 -10
|
||||
-18 -10 -7 0 -6 4 3 10 19 12 23 12 15 0z m960 -58 c-5 -5 -25 43 -25 61 1 7
|
||||
7 -3 16 -22 8 -19 12 -36 9 -39z m-995 44 c0 -2 -7 -7 -16 -10 -8 -3 -12 -2
|
||||
-9 4 6 10 25 14 25 6z m1060 -5 c0 -5 -7 -12 -16 -15 -24 -9 -28 -7 -14 9 14
|
||||
17 30 20 30 6z m-763 -73 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z
|
||||
m-16 -41 c-10 -9 -11 -8 -5 6 3 10 9 15 12 12 3 -3 0 -11 -7 -18z m849 7 c0
|
||||
-8 -6 -14 -12 -11 -7 2 -21 0 -30 -4 -16 -9 -68 7 -68 20 0 3 25 7 55 9 45 2
|
||||
55 -1 55 -14z m-131 -120 c-19 -23 -21 -10 -7 37 l12 44 4 -33 c2 -18 -2 -40
|
||||
-9 -48z m-359 46 c0 -5 -4 -10 -10 -10 -5 0 -10 5 -10 10 0 6 5 10 10 10 6 0
|
||||
10 -4 10 -10z m450 -43 c0 -4 -11 0 -25 10 -13 10 -25 22 -25 26 0 4 11 0 25
|
||||
-10 13 -10 25 -22 25 -26z m134 18 c-4 -8 -16 -15 -27 -15 -20 0 -20 0 -1 15
|
||||
25 19 35 19 28 0z m-314 -10 c-7 -8 -16 -15 -20 -15 -15 0 -78 -70 -95 -106
|
||||
-9 -19 -19 -33 -22 -30 -14 14 54 116 78 116 6 0 7 4 4 10 -3 5 9 16 27 24 43
|
||||
19 43 19 28 1z m43 -9 c-4 -7 -23 -26 -41 -41 -17 -15 -30 -30 -27 -35 5 -9
|
||||
-27 -53 -64 -88 -31 -28 -50 -14 -24 18 39 49 89 105 117 132 30 29 53 38 39
|
||||
14z m120 -84 c20 -22 21 -24 4 -33 -23 -13 -23 -44 1 -34 9 4 31 13 48 19 18
|
||||
6 40 18 50 26 16 13 17 13 11 0 -3 -8 -18 -44 -33 -80 -15 -36 -28 -81 -28
|
||||
-102 -1 -20 -4 -34 -7 -33 -3 2 -10 -27 -17 -64 -18 -105 -25 -118 -72 -131
|
||||
-47 -13 -70 -2 -70 33 0 19 -1 19 -12 4 -9 -11 -21 -15 -35 -11 -33 9 -28 27
|
||||
14 55 l37 24 -1 102 c-2 79 2 114 18 160 29 82 36 89 68 61 l26 -23 -21 25
|
||||
c-12 14 -25 41 -28 60 l-7 35 16 -35 c9 -19 26 -45 38 -58z m-513 26 c0 -10
|
||||
-3 -10 -35 2 -14 5 -24 14 -21 19 7 10 56 -9 56 -21z m545 11 c10 -30 0 -33
|
||||
-13 -4 -6 14 -7 25 -2 25 5 0 12 -9 15 -21z m-394 -26 c-6 -10 -13 -39 -16
|
||||
-66 -4 -26 -10 -45 -15 -42 -6 3 -5 16 0 30 12 32 -5 43 -28 18 -9 -11 -13
|
||||
-12 -7 -3 11 17 68 80 72 80 2 0 -1 -8 -6 -17z m49 2 c-7 -9 -15 -13 -17 -11
|
||||
-7 7 7 26 19 26 6 0 6 -6 -2 -15z m395 -3 c-3 -3 -11 0 -18 7 -9 10 -8 11 6 5
|
||||
10 -3 15 -9 12 -12z m-202 -34 c-3 -18 -10 -39 -16 -45 -5 -7 -6 -13 -2 -13 4
|
||||
0 2 -7 -5 -15 -6 -8 -8 -20 -4 -27 4 -7 3 -9 -2 -5 -5 5 -15 -13 -24 -39 -14
|
||||
-43 -40 -72 -40 -44 0 6 5 8 11 4 7 -4 10 -1 7 7 -3 8 -13 13 -22 13 -19 -2
|
||||
-20 9 -2 59 12 33 12 39 0 44 -11 4 -12 9 -3 19 6 8 14 12 18 10 4 -3 25 11
|
||||
46 29 22 19 41 34 42 35 1 0 0 -15 -4 -32z m-633 12 c0 -5 -4 -10 -10 -10 -5
|
||||
0 -10 5 -10 10 0 6 5 10 10 10 6 0 10 -4 10 -10z m-224 -67 c-10 -10 -19 5
|
||||
-10 18 6 11 8 11 12 0 2 -7 1 -15 -2 -18z m329 17 c3 -5 -1 -10 -10 -10 -9 0
|
||||
-13 5 -10 10 3 6 8 10 10 10 2 0 7 -4 10 -10z m351 -65 c-8 -8 -18 -24 -21
|
||||
-35 -4 -11 -10 -18 -15 -15 -4 3 -1 27 8 55 15 46 16 48 29 30 12 -17 12 -22
|
||||
-1 -35z m-153 30 c-3 -9 -8 -14 -10 -11 -3 3 -2 9 2 15 9 16 15 13 8 -4z
|
||||
m-1083 -20 c0 -8 -4 -15 -10 -15 -5 0 -10 7 -10 15 0 8 5 15 10 15 6 0 10 -7
|
||||
10 -15z m400 -14 c0 -6 -4 -13 -10 -16 -5 -3 -10 1 -10 9 0 9 5 16 10 16 6 0
|
||||
10 -4 10 -9z m661 -18 c-12 -20 -14 -14 -5 12 4 9 9 14 11 11 3 -2 0 -13 -6
|
||||
-23z m-381 -14 c0 -6 -4 -7 -10 -4 -5 3 -10 11 -10 16 0 6 5 7 10 4 6 -3 10
|
||||
-11 10 -16z m375 -39 c-4 -12 -9 -19 -12 -17 -3 3 -2 15 2 27 4 12 9 19 12 17
|
||||
3 -3 2 -15 -2 -27z m-888 -16 c-9 -9 -28 6 -21 18 4 6 10 6 17 -1 6 -6 8 -13
|
||||
4 -17z m1040 20 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m-897
|
||||
-84 c0 -5 -5 -10 -11 -10 -5 0 -7 5 -4 10 3 6 8 10 11 10 2 0 4 -4 4 -10z
|
||||
m1000 -10 c0 -5 -5 -10 -11 -10 -5 0 -7 5 -4 10 3 6 8 10 11 10 2 0 4 -4 4
|
||||
-10z m-17 -98 c-9 -15 -28 -33 -42 -40 -21 -10 -19 -5 14 28 21 22 40 40 42
|
||||
40 1 0 -5 -13 -14 -28z m147 -81 c0 -5 -9 -7 -20 -4 -11 3 -20 7 -20 9 0 2 9
|
||||
4 20 4 11 0 20 -4 20 -9z m-663 -7 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1
|
||||
17 -2 13 -5z m-64 -31 c-7 -2 -19 -2 -25 0 -7 3 -2 5 12 5 14 0 19 -2 13 -5z
|
||||
m41 -1 c3 -5 -1 -9 -9 -9 -8 0 -15 4 -15 9 0 4 4 8 9 8 6 0 12 -4 15 -8z m-94
|
||||
-12 c-8 -5 -19 -10 -25 -10 -5 0 -3 5 5 10 8 5 20 10 25 10 6 0 3 -5 -5 -10z
|
||||
m18 -52 c2 -12 -3 -18 -16 -18 -24 0 -36 -14 -67 -77 l-24 -48 6 38 c3 20 1
|
||||
37 -4 37 -15 0 -32 -22 -27 -35 3 -7 1 -16 -5 -20 -7 -4 -11 4 -11 19 0 14 -5
|
||||
28 -12 32 -6 4 -9 3 -6 -2 3 -5 -1 -22 -9 -39 -13 -30 -13 -30 -8 15 l6 45
|
||||
-21 -35 c-16 -28 -19 -30 -14 -10 7 29 39 60 63 60 9 1 34 14 56 30 44 33 88
|
||||
36 93 8z m1290 -45 c2 -7 -1 -13 -8 -13 -6 0 -8 6 -5 13 4 6 -1 3 -10 -8 -10
|
||||
-11 -23 -35 -31 -52 -8 -18 -19 -33 -24 -33 -14 0 -12 27 3 33 7 3 4 6 -6 6
|
||||
-19 1 -56 -35 -57 -55 0 -5 -6 -19 -14 -30 -13 -17 -14 -15 -11 24 1 24 9 49
|
||||
16 55 9 8 8 6 -1 -8 -8 -11 10 4 40 33 40 39 61 52 79 50 14 -2 26 -9 29 -15z
|
||||
m-26 -105 c-7 -7 -12 -22 -12 -34 0 -13 -5 -26 -12 -30 -8 -5 -9 2 -5 26 7 35
|
||||
26 64 35 55 3 -3 0 -11 -6 -17z m-154 -14 c-7 -15 -14 -21 -16 -15 -2 7 2 18
|
||||
8 26 18 22 21 18 8 -11z m88 -25 c-9 -13 -16 -31 -16 -41 0 -10 -5 -18 -10
|
||||
-18 -10 0 -6 32 12 79 6 17 12 21 20 13 7 -7 6 -17 -6 -33z m-1336 27 c0 -3
|
||||
-4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6 0 10 -2 10 -4z m1225 -56
|
||||
c-3 -5 -11 -10 -16 -10 -6 0 -7 5 -4 10 3 6 11 10 16 10 6 0 7 -4 4 -10z
|
||||
m-2236 -544 c-2 -2 -15 -9 -29 -15 -24 -11 -24 -11 -6 3 16 13 49 24 35 12z
|
||||
m-419 -61 c25 -13 41 -24 35 -24 -5 0 -30 11 -55 24 -25 13 -40 24 -35 24 6 0
|
||||
30 -11 55 -24z m547 -11 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z
|
||||
m-220 -140 c543 -254 653 -307 650 -310 -2 -2 -122 52 -268 120 -647 303 -674
|
||||
316 -656 316 3 0 126 -57 274 -126z m368 48 c-3 -3 -11 0 -18 7 -9 10 -8 11 6
|
||||
5 10 -3 15 -9 12 -12z m205 -52 c-8 -5 -19 -10 -25 -10 -5 0 -3 5 5 10 8 5 20
|
||||
10 25 10 6 0 3 -5 -5 -10z m395 -200 c3 -5 1 -10 -4 -10 -6 0 -11 5 -11 10 0
|
||||
6 2 10 4 10 3 0 8 -4 11 -10z"/>
|
||||
<path d="M397 6159 c-52 -12 -134 -55 -185 -96 -124 -101 -180 -283 -136 -448
|
||||
54 -210 277 -354 490 -318 298 51 461 375 321 636 -93 175 -300 271 -490 226z
|
||||
m225 -29 c219 -67 345 -301 280 -517 -82 -270 -395 -386 -630 -234 -73 48
|
||||
-117 99 -156 181 -29 60 -31 73 -31 170 0 97 2 110 32 172 55 116 166 210 279
|
||||
237 67 16 158 12 226 -9z"/>
|
||||
<path d="M405 6126 c-249 -62 -383 -334 -276 -562 122 -260 456 -320 657 -120
|
||||
225 226 120 599 -191 681 -69 18 -121 18 -190 1z m193 -20 c74 -20 131 -56
|
||||
190 -121 70 -77 96 -146 96 -255 -1 -112 -27 -180 -99 -258 -191 -207 -512
|
||||
-158 -637 96 -30 61 -33 74 -33 162 0 86 3 101 31 160 83 175 270 264 452 216z"/>
|
||||
<path d="M420 6087 c-115 -27 -202 -98 -254 -207 -27 -57 -31 -76 -31 -150 0
|
||||
-76 3 -92 33 -152 65 -132 185 -209 327 -209 211 0 368 153 368 361 0 108 -29
|
||||
178 -107 256 -92 92 -214 129 -336 101z m220 -43 c228 -103 274 -402 87 -569
|
||||
-71 -64 -141 -88 -247 -83 -101 5 -161 32 -227 100 -85 87 -117 206 -89 319
|
||||
55 213 278 322 476 233z"/>
|
||||
<path d="M275 5738 c-27 -40 -51 -76 -53 -80 -2 -4 18 -8 45 -8 50 0 49 -1
|
||||
105 85 3 6 -6 25 -20 43 l-27 32 -50 -72z"/>
|
||||
<path d="M640 5775 l-23 -36 31 -42 c28 -39 34 -42 82 -45 l52 -3 -48 68 c-71
|
||||
103 -68 100 -94 58z"/>
|
||||
<path d="M360 5545 c0 -25 5 -45 10 -45 6 0 10 9 10 20 0 26 46 28 53 3 3 -10
|
||||
5 2 5 27 0 25 -2 37 -5 28 -6 -22 -53 -25 -53 -3 0 8 -4 15 -10 15 -5 0 -10
|
||||
-20 -10 -45z"/>
|
||||
<path d="M470 5547 c0 -42 1 -43 35 -45 19 -2 35 2 35 8 0 5 -11 10 -25 10
|
||||
-14 0 -25 5 -25 10 0 6 9 10 20 10 11 0 20 5 20 10 0 6 -9 10 -20 10 -30 0
|
||||
-24 18 8 23 22 3 20 4 -10 6 l-38 1 0 -43z"/>
|
||||
<path d="M583 5583 l27 -4 -25 -33 c-14 -18 -25 -36 -25 -40 0 -4 18 -6 40 -4
|
||||
44 2 56 18 14 18 l-26 0 26 35 27 35 -43 -1 c-30 -2 -35 -3 -15 -6z"/>
|
||||
<path d="M2290 5630 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||
-10 -4 -10 -10z"/>
|
||||
<path d="M1536 5403 c-11 -11 -6 -23 9 -23 8 0 15 4 15 9 0 13 -16 22 -24 14z"/>
|
||||
<path d="M1570 5350 c0 -33 -4 -60 -10 -60 -5 0 -10 -7 -10 -15 0 -8 5 -15 11
|
||||
-15 5 0 7 5 4 10 -4 6 6 10 22 11 15 0 22 3 16 6 -14 5 -18 53 -5 53 5 0 21
|
||||
-13 37 -30 26 -27 34 -30 89 -29 34 1 51 4 39 6 -21 4 -23 10 -23 64 0 76 -18
|
||||
77 -22 2 -3 -49 -6 -58 -23 -61 -28 -4 -72 53 -49 62 19 7 15 50 -6 53 -21 4
|
||||
-43 -12 -38 -27 3 -9 9 -8 21 4 16 16 17 16 17 -2 0 -18 -18 -32 -41 -32 -5 0
|
||||
-9 14 -9 30 0 17 -4 30 -10 30 -6 0 -10 -27 -10 -60z"/>
|
||||
<path d="M1880 5351 c0 -38 -4 -61 -12 -64 -7 -3 3 -5 22 -5 19 0 29 2 23 5
|
||||
-9 3 -13 26 -13 64 0 33 -4 59 -10 59 -6 0 -10 -26 -10 -59z"/>
|
||||
<path d="M1944 5401 c-14 -14 2 -40 37 -60 43 -25 46 -42 8 -52 -21 -6 -21 -7
|
||||
-3 -8 29 -1 59 23 51 42 -3 9 -23 25 -44 36 -37 20 -37 20 -10 21 15 0 27 6
|
||||
27 13 0 8 4 7 10 -3 8 -13 10 -13 10 2 0 12 -9 16 -41 15 -22 -1 -42 -4 -45
|
||||
-6z"/>
|
||||
<path d="M2112 5348 c3 -54 6 -63 23 -65 11 -2 14 0 8 3 -8 4 -13 27 -13 65 0
|
||||
34 -4 59 -10 59 -7 0 -10 -24 -8 -62z"/>
|
||||
<path d="M2153 5403 c-17 -6 -16 -23 1 -23 8 0 16 7 20 15 6 15 1 17 -21 8z"/>
|
||||
<path d="M2770 5320 c0 -5 5 -10 11 -10 5 0 7 5 4 10 -3 6 -8 10 -11 10 -2 0
|
||||
-4 -4 -4 -10z"/>
|
||||
<path d="M1940 5299 c0 -11 4 -18 10 -14 5 3 7 12 3 20 -7 21 -13 19 -13 -6z"/>
|
||||
<path d="M2632 5289 c2 -6 8 -10 13 -10 5 0 11 4 13 10 2 6 -4 11 -13 11 -9 0
|
||||
-15 -5 -13 -11z"/>
|
||||
<path d="M1331 5254 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
|
||||
<path d="M1830 5251 c0 -7 -4 -9 -10 -6 -5 3 -10 1 -10 -4 0 -6 4 -11 9 -11
|
||||
13 0 25 20 17 27 -3 4 -6 1 -6 -6z"/>
|
||||
<path d="M2515 5253 c-11 -3 -24 -9 -29 -14 -5 -4 8 -4 29 2 27 8 41 7 49 -1
|
||||
8 -8 7 -13 -4 -20 -9 -6 -10 -10 -3 -10 19 0 26 20 13 35 -13 15 -20 16 -55 8z"/>
|
||||
<path d="M2616 5252 c-3 -6 -1 -14 5 -17 14 -9 20 -2 10 14 -6 8 -11 9 -15 3z"/>
|
||||
<path d="M1775 5240 c-3 -5 1 -10 9 -10 9 0 16 5 16 10 0 6 -4 10 -9 10 -6 0
|
||||
-13 -4 -16 -10z"/>
|
||||
<path d="M2710 5240 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||
-10 -4 -10 -10z"/>
|
||||
<path d="M1408 5233 c6 -2 18 -2 25 0 6 3 1 5 -13 5 -14 0 -19 -2 -12 -5z"/>
|
||||
<path d="M1772 5208 c6 -18 28 -21 28 -4 0 9 -7 16 -16 16 -9 0 -14 -5 -12
|
||||
-12z"/>
|
||||
<path d="M2042 5204 c-8 -8 -22 -12 -32 -9 -10 3 -22 0 -26 -6 -4 -8 -3 -9 5
|
||||
-5 6 4 19 2 27 -5 12 -10 17 -8 29 7 23 30 20 45 -3 18z"/>
|
||||
<path d="M2443 5203 c4 -3 1 -13 -6 -22 -11 -14 -10 -14 6 -2 20 15 22 31 5
|
||||
31 -6 0 -8 -3 -5 -7z"/>
|
||||
<path d="M2531 5194 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
|
||||
<path d="M1540 5190 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||
-10 -4 -10 -10z"/>
|
||||
<path d="M2326 5181 c-3 -4 6 -6 19 -3 14 2 25 6 25 8 0 8 -39 4 -44 -5z"/>
|
||||
<path d="M2474 5159 c-12 -25 -13 -34 -3 -43 9 -8 10 -8 5 1 -9 16 13 61 33
|
||||
66 14 4 14 5 -1 6 -10 1 -24 -12 -34 -30z"/>
|
||||
<path d="M1948 5173 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||
<path d="M2889 5159 c0 -22 -1 -23 -9 -4 -8 18 -9 18 -9 2 -1 -10 -5 -16 -10
|
||||
-13 -5 3 -11 -8 -13 -24 -4 -28 -2 -30 28 -30 32 0 32 0 27 43 -7 49 -13 61
|
||||
-14 26z m-5 -44 c-4 -8 -10 -12 -15 -9 -14 8 -10 24 6 24 9 0 12 -6 9 -15z"/>
|
||||
<path d="M1728 5163 c12 -2 30 -2 40 0 9 3 -1 5 -23 4 -22 0 -30 -2 -17 -4z"/>
|
||||
<path d="M2101 5154 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
|
||||
<path d="M2150 5156 c0 -7 7 -13 15 -13 8 0 15 4 15 8 0 4 -7 9 -15 13 -9 3
|
||||
-15 0 -15 -8z"/>
|
||||
<path d="M2275 5160 c-3 -6 3 -22 14 -36 12 -15 21 -22 21 -16 0 6 -7 18 -17
|
||||
27 -14 14 -14 18 -2 26 9 5 10 9 2 9 -6 0 -15 -5 -18 -10z"/>
|
||||
<path d="M1270 5135 c0 -14 4 -25 9 -25 4 0 6 11 3 25 -2 14 -6 25 -8 25 -2 0
|
||||
-4 -11 -4 -25z"/>
|
||||
<path d="M1525 5150 c-4 -6 -15 -8 -26 -5 -13 4 -19 2 -19 -9 0 -9 6 -16 13
|
||||
-15 18 1 54 17 42 19 -5 2 4 6 20 10 l30 8 -27 1 c-15 0 -30 -4 -33 -9z"/>
|
||||
<path d="M1960 5145 c0 -8 2 -15 4 -15 2 0 6 7 10 15 3 8 1 15 -4 15 -6 0 -10
|
||||
-7 -10 -15z"/>
|
||||
<path d="M2070 5144 c0 -8 5 -12 10 -9 6 4 8 11 5 16 -9 14 -15 11 -15 -7z"/>
|
||||
<path d="M2210 5150 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||
-10 -4 -10 -10z"/>
|
||||
<path d="M2010 5140 c0 -5 7 -10 15 -10 8 0 15 5 15 10 0 6 -7 10 -15 10 -8 0
|
||||
-15 -4 -15 -10z"/>
|
||||
<path d="M2500 5134 c0 -17 22 -14 28 4 2 7 -3 12 -12 12 -9 0 -16 -7 -16 -16z"/>
|
||||
<path d="M2543 5137 c0 -7 9 -14 19 -14 11 -1 18 5 17 15 0 11 -2 13 -6 4 -3
|
||||
-9 -9 -10 -17 -3 -9 8 -13 7 -13 -2z"/>
|
||||
<path d="M2616 5141 c-4 -7 -5 -15 -2 -18 9 -9 19 4 14 18 -4 11 -6 11 -12 0z"/>
|
||||
<path d="M2400 5131 c0 -6 -6 -11 -14 -11 -32 0 -23 -17 9 -18 39 -2 42 2 20
|
||||
24 -8 9 -15 11 -15 5z"/>
|
||||
<path d="M2685 5130 c-3 -5 1 -10 9 -10 9 0 16 5 16 10 0 6 -4 10 -9 10 -6 0
|
||||
-13 -4 -16 -10z"/>
|
||||
<path d="M2166 5117 c3 -10 9 -15 12 -12 3 3 0 11 -7 18 -10 9 -11 8 -5 -6z"/>
|
||||
<path d="M2320 5115 c0 -8 7 -15 15 -15 8 0 15 4 15 9 0 5 -7 11 -15 15 -9 3
|
||||
-15 0 -15 -9z"/>
|
||||
<path d="M1201 5112 c-1 -7 -5 -11 -10 -8 -5 3 -11 -10 -13 -29 -4 -32 -2 -35
|
||||
23 -35 15 0 31 5 34 11 9 14 -3 61 -14 54 -5 -3 -12 1 -14 7 -4 10 -6 10 -6 0z"/>
|
||||
<path d="M2260 5105 c-10 -13 -9 -15 9 -15 12 0 21 6 21 15 0 8 -4 15 -9 15
|
||||
-5 0 -14 -7 -21 -15z"/>
|
||||
<path d="M1462 5090 c0 -14 2 -19 5 -12 2 6 2 18 0 25 -3 6 -5 1 -5 -13z"/>
|
||||
<path d="M1581 5094 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
|
||||
<path d="M1658 5103 c-24 -6 -23 -23 2 -23 11 0 20 7 20 15 0 8 -1 14 -2 14
|
||||
-2 -1 -11 -3 -20 -6z"/>
|
||||
<path d="M2002 5099 c2 -6 8 -10 13 -10 5 0 11 4 13 10 2 6 -4 11 -13 11 -9 0
|
||||
-15 -5 -13 -11z"/>
|
||||
<path d="M1337 5089 c7 -7 15 -10 18 -7 3 3 -2 9 -12 12 -14 6 -15 5 -6 -5z"/>
|
||||
<path d="M1710 5090 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||
-10 -4 -10 -10z"/>
|
||||
<path d="M2472 5065 c-27 -42 -37 -43 -69 -9 -18 19 -27 23 -37 15 -7 -6 -17
|
||||
-7 -22 -2 -12 12 -114 20 -114 10 0 -5 24 -9 54 -9 30 0 58 -5 61 -10 5 -8 11
|
||||
-8 20 0 9 8 17 6 29 -5 9 -9 16 -21 16 -26 0 -5 9 -9 19 -9 19 0 71 52 71 71
|
||||
0 14 -4 11 -28 -26z"/>
|
||||
<path d="M1545 5080 c-3 -5 -1 -10 4 -10 6 0 11 5 11 10 0 6 -2 10 -4 10 -3 0
|
||||
-8 -4 -11 -10z"/>
|
||||
<path d="M2536 5082 c-3 -6 -1 -14 5 -17 14 -9 20 -2 10 14 -6 8 -11 9 -15 3z"/>
|
||||
<path d="M1378 5073 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||
<path d="M2585 5071 c-3 -5 -2 -12 3 -15 5 -3 9 1 9 9 0 17 -3 19 -12 6z"/>
|
||||
<path d="M2625 5070 c3 -5 8 -10 11 -10 2 0 4 5 4 10 0 6 -5 10 -11 10 -5 0
|
||||
-7 -4 -4 -10z"/>
|
||||
<path d="M2826 5065 c-3 -8 -1 -15 4 -15 6 0 10 7 10 15 0 8 -2 15 -4 15 -2 0
|
||||
-6 -7 -10 -15z"/>
|
||||
<path d="M2928 5073 c-24 -6 -23 -23 2 -23 11 0 20 7 20 15 0 8 -1 14 -2 14
|
||||
-2 -1 -11 -3 -20 -6z"/>
|
||||
<path d="M2004 5048 c4 -18 28 -16 34 2 4 13 3 13 -10 2 -11 -9 -18 -9 -21 -2
|
||||
-3 6 -4 5 -3 -2z"/>
|
||||
<path d="M1608 5043 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||
<path d="M1670 5045 c0 -4 11 -20 25 -37 14 -16 25 -26 25 -23 0 4 -11 20 -25
|
||||
37 -14 16 -25 26 -25 23z"/>
|
||||
<path d="M1970 5040 c0 -5 5 -10 11 -10 5 0 7 5 4 10 -3 6 -8 10 -11 10 -2 0
|
||||
-4 -4 -4 -10z"/>
|
||||
<path d="M2172 5038 c6 -18 28 -21 28 -4 0 9 -7 16 -16 16 -9 0 -14 -5 -12
|
||||
-12z"/>
|
||||
<path d="M1140 5021 c0 -5 7 -11 15 -15 8 -3 15 -1 15 3 0 5 -7 11 -15 15 -8
|
||||
3 -15 1 -15 -3z"/>
|
||||
<path d="M2091 5004 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
|
||||
<path d="M2117 5004 c3 -7 9 -14 14 -14 14 0 10 17 -5 23 -10 4 -13 1 -9 -9z"/>
|
||||
<path d="M2251 5008 c-1 -20 14 -24 25 -6 4 6 3 8 -4 4 -5 -3 -13 0 -15 6 -3
|
||||
8 -6 6 -6 -4z"/>
|
||||
<path d="M1801 4994 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
|
||||
<path d="M2150 5006 c0 -9 30 -14 35 -6 4 6 -3 10 -14 10 -12 0 -21 -2 -21 -4z"/>
|
||||
<path d="M2200 5006 c0 -2 9 -6 20 -9 11 -3 20 -1 20 4 0 5 -9 9 -20 9 -11 0
|
||||
-20 -2 -20 -4z"/>
|
||||
<path d="M1023 4993 c-7 -3 -13 -9 -13 -14 0 -6 4 -8 9 -4 5 3 12 -3 14 -12 4
|
||||
-17 5 -17 6 -1 1 12 6 15 19 11 18 -6 17 -4 -8 13 -8 6 -21 9 -27 7z"/>
|
||||
<path d="M1880 4990 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||
-10 -4 -10 -10z"/>
|
||||
<path d="M1920 4990 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||
-10 -4 -10 -10z"/>
|
||||
<path d="M1955 4990 c-3 -5 -1 -10 4 -10 6 0 11 5 11 10 0 6 -2 10 -4 10 -3 0
|
||||
-8 -4 -11 -10z"/>
|
||||
<path d="M2466 4983 c-11 -11 -6 -23 9 -23 8 0 15 4 15 9 0 13 -16 22 -24 14z"/>
|
||||
<path d="M2810 4958 c0 -14 -3 -33 -6 -42 -5 -13 1 -16 33 -16 l38 0 -3 43
|
||||
c-3 40 -6 43 -33 42 -25 0 -29 -4 -29 -27z m40 -27 c0 -6 -4 -13 -10 -16 -5
|
||||
-3 -10 1 -10 9 0 9 5 16 10 16 6 0 10 -4 10 -9z"/>
|
||||
<path d="M2608 4945 c-4 -34 -3 -35 30 -35 27 0 33 3 28 16 -3 9 -6 24 -6 35
|
||||
0 13 -7 19 -24 19 -20 0 -25 -6 -28 -35z"/>
|
||||
<path d="M1431 4953 c0 -11 3 -13 6 -5 2 6 10 9 15 6 7 -4 8 -2 4 4 -11 18
|
||||
-26 14 -25 -5z"/>
|
||||
<path d="M1490 4955 c-10 -12 -10 -15 2 -15 8 0 15 7 15 15 0 8 -1 15 -2 15
|
||||
-2 0 -8 -7 -15 -15z"/>
|
||||
<path d="M1877 4954 c-8 -8 1 -24 14 -24 5 0 9 7 9 15 0 15 -12 20 -23 9z"/>
|
||||
<path d="M1000 4934 c0 -7 17 -11 44 -10 63 2 67 13 7 17 -33 3 -51 0 -51 -7z"/>
|
||||
<path d="M3006 4935 c4 -8 8 -15 10 -15 2 0 4 7 4 15 0 8 -4 15 -10 15 -5 0
|
||||
-7 -7 -4 -15z"/>
|
||||
<path d="M2113 4925 c0 -10 4 -12 13 -4 8 7 13 6 17 -3 2 -7 8 -9 13 -5 5 4 2
|
||||
12 -6 17 -22 14 -37 12 -37 -5z"/>
|
||||
<path d="M2455 4930 c3 -5 12 -7 20 -3 21 7 19 13 -6 13 -11 0 -18 -4 -14 -10z"/>
|
||||
<path d="M2545 4930 c3 -5 8 -10 11 -10 2 0 4 5 4 10 0 6 -5 10 -11 10 -5 0
|
||||
-7 -4 -4 -10z"/>
|
||||
<path d="M1330 4915 c0 -6 7 -12 15 -12 8 0 15 6 15 12 0 6 -7 12 -15 12 -8 0
|
||||
-15 -6 -15 -12z"/>
|
||||
<path d="M2175 4920 c4 -6 11 -8 16 -5 14 9 11 15 -7 15 -8 0 -12 -5 -9 -10z"/>
|
||||
<path d="M2210 4919 c0 -5 5 -7 10 -4 6 3 10 8 10 11 0 2 -4 4 -10 4 -5 0 -10
|
||||
-5 -10 -11z"/>
|
||||
<path d="M1330 4670 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||
-10 -4 -10 -10z"/>
|
||||
<path d="M1990 4600 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||
-10 -4 -10 -10z"/>
|
||||
<path d="M2765 4211 c18 -7 18 -9 3 -12 -13 -3 -15 -8 -8 -19 10 -17 15 -14
|
||||
24 18 6 18 4 22 -16 21 -22 0 -22 -1 -3 -8z"/>
|
||||
<path d="M1930 4082 c6 -13 14 -21 18 -18 3 4 -2 14 -12 24 -18 16 -18 16 -6
|
||||
-6z"/>
|
||||
<path d="M3067 3783 c-10 -9 -9 -33 1 -33 4 0 8 9 8 20 0 23 0 22 -9 13z"/>
|
||||
<path d="M1972 3590 c0 -14 2 -19 5 -12 2 6 2 18 0 25 -3 6 -5 1 -5 -13z"/>
|
||||
<path d="M2785 3290 c-2 -3 5 -6 15 -7 11 -1 22 2 25 7 3 5 -4 8 -16 7 -11 -1
|
||||
-22 -4 -24 -7z"/>
|
||||
<path d="M2717 3084 c-4 -4 -7 -18 -7 -31 0 -20 4 -23 28 -17 21 4 24 3 12 -5
|
||||
-12 -9 -10 -11 10 -11 36 0 52 14 48 41 -2 20 -9 24 -43 27 -23 2 -44 0 -48
|
||||
-4z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 78 KiB |
@@ -0,0 +1,182 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="296.000000pt" height="222.000000pt" viewBox="0 0 296.000000 222.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,222.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M1639 2085 c-32 -17 -50 -34 -57 -54 -6 -17 -35 -56 -66 -86 -53 -54
|
||||
-55 -55 -111 -55 -46 0 -63 -5 -87 -25 l-30 -25 -222 4 c-121 3 -249 8 -283
|
||||
11 -35 4 -86 2 -117 -5 -81 -17 -96 -42 -96 -158 0 -69 -4 -92 -16 -103 -9 -7
|
||||
-23 -27 -32 -44 -19 -36 -62 -97 -109 -156 -18 -22 -49 -74 -69 -116 -30 -61
|
||||
-47 -83 -93 -117 -95 -70 -131 -114 -131 -158 0 -31 4 -38 19 -38 31 0 33 -46
|
||||
4 -81 -31 -36 -23 -49 31 -49 44 0 70 18 95 68 14 27 40 28 88 2 45 -24 121
|
||||
-26 149 -5 21 16 109 20 119 6 3 -5 18 -12 33 -16 32 -7 81 15 131 57 25 23
|
||||
39 28 60 23 16 -3 49 1 76 10 l48 17 24 -29 c13 -15 31 -42 38 -60 8 -18 25
|
||||
-37 37 -44 11 -6 50 -39 85 -73 l64 -61 102 -7 c56 -4 123 -10 149 -13 45 -7
|
||||
50 -5 80 27 18 19 41 47 51 61 25 37 74 37 108 0 34 -38 53 -97 40 -122 -20
|
||||
-36 -12 -71 25 -116 35 -43 35 -43 89 -38 69 7 109 -14 99 -52 -11 -43 13 -80
|
||||
69 -110 62 -33 107 -73 107 -94 0 -35 58 -163 91 -201 19 -23 27 -25 102 -23
|
||||
45 1 83 6 85 11 1 5 43 7 96 4 90 -4 95 -4 119 21 14 13 30 43 36 64 16 59 41
|
||||
77 104 74 30 -1 65 3 80 8 25 10 27 15 27 65 0 30 -5 58 -10 61 -6 4 -17 23
|
||||
-25 42 -14 33 -14 38 2 62 32 47 43 73 43 100 0 49 -26 100 -80 158 -30 32
|
||||
-62 70 -71 84 -14 22 -26 27 -74 31 -50 4 -61 9 -96 46 -22 22 -61 55 -87 71
|
||||
-26 17 -51 35 -56 40 -4 5 -17 19 -28 31 -12 13 -29 20 -46 19 -65 -5 -84 11
|
||||
-37 33 34 15 32 28 -2 19 -18 -5 -29 -15 -31 -29 -7 -44 -62 -8 -62 40 0 36
|
||||
-28 111 -45 120 -19 11 -16 65 4 73 13 5 12 9 -9 25 l-25 20 25 1 c14 1 30 2
|
||||
36 2 16 0 18 180 3 209 -7 13 -36 52 -66 88 -30 36 -56 76 -59 90 -9 43 -19
|
||||
54 -68 79 -31 15 -57 38 -73 65 -14 23 -36 54 -49 69 -13 15 -29 47 -35 70
|
||||
-16 55 -26 66 -74 88 -53 25 -91 23 -146 -6z m-27 -179 c3 2 8 -7 10 -21 3
|
||||
-14 1 -28 -3 -31 -5 -3 -9 2 -9 10 0 9 -4 16 -10 16 -5 0 -10 -7 -10 -15 0 -8
|
||||
-5 -15 -11 -15 -7 0 -9 9 -5 23 3 12 6 28 6 36 0 10 3 11 13 2 8 -6 16 -8 19
|
||||
-5z m275 -102 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m40 -76
|
||||
c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2 -7 2 -19 0 -25z m43 14 c0 -13 -12 -22
|
||||
-22 -16 -10 6 -1 24 13 24 5 0 9 -4 9 -8z m-965 -83 c5 -14 2 -25 -6 -30 -19
|
||||
-12 -29 -11 -29 1 0 6 7 10 16 10 9 0 14 5 12 11 -2 6 -6 9 -9 7 -3 -2 -13 3
|
||||
-22 10 -13 11 -16 6 -19 -48 -2 -43 1 -60 10 -60 6 0 12 11 12 25 0 14 4 25
|
||||
10 25 5 0 17 -11 26 -25 9 -14 25 -25 36 -25 16 0 15 4 -12 26 -29 25 -29 27
|
||||
-13 40 16 11 16 15 4 36 -13 22 -13 23 6 6 24 -22 47 -23 39 -3 -3 8 -1 15 5
|
||||
15 7 0 10 -22 7 -60 l-3 -60 35 0 c47 0 80 24 80 59 0 15 -5 32 -12 39 -9 9
|
||||
-5 9 16 0 24 -12 27 -17 24 -55 -2 -33 0 -43 12 -43 12 0 14 10 12 45 -3 31 0
|
||||
45 8 45 7 0 19 8 26 18 12 16 13 16 19 0 8 -20 40 -24 51 -6 4 6 3 8 -2 5 -6
|
||||
-3 -16 -2 -23 2 -9 6 -5 10 13 13 23 5 26 2 27 -21 0 -25 0 -26 9 -3 9 22 44
|
||||
30 54 13 4 -5 -2 -7 -13 -4 -11 3 -21 -2 -25 -12 -5 -14 -2 -16 20 -12 25 4
|
||||
26 3 22 -39 -3 -39 -1 -44 17 -43 11 0 14 3 8 6 -15 6 -18 99 -3 108 6 3 7 -1
|
||||
4 -9 -9 -22 22 -21 35 2 9 15 10 14 11 -6 0 -21 4 -23 35 -19 19 3 35 3 35 2
|
||||
0 -2 3 -10 6 -19 4 -11 0 -16 -15 -16 -15 0 -19 5 -15 18 3 9 -2 4 -11 -13
|
||||
-10 -16 -24 -36 -33 -42 -14 -12 -13 -13 6 -13 12 0 21 3 21 8 -4 26 3 33 34
|
||||
30 23 -2 32 -8 31 -20 -1 -12 5 -18 17 -18 19 0 19 1 -2 43 -12 23 -18 39 -14
|
||||
35 3 -3 20 -2 37 2 l30 9 -4 -44 c-2 -26 1 -45 7 -45 6 0 9 20 7 48 l-4 47 46
|
||||
-45 46 -44 0 37 0 37 140 0 c99 0 139 -3 137 -11 -1 -6 4 -14 12 -17 10 -3 12
|
||||
0 8 12 -6 14 -1 17 25 14 25 -2 42 -15 75 -56 42 -51 43 -55 43 -125 0 -90 -7
|
||||
-117 -31 -117 -27 0 -32 -17 -9 -33 18 -12 18 -15 5 -20 -9 -4 -15 -19 -15
|
||||
-42 l0 -35 -52 -1 c-29 -1 -57 -1 -62 0 -6 1 -89 2 -185 1 -127 0 -177 -4
|
||||
-183 -13 -6 -9 -8 -9 -8 1 0 9 -46 12 -195 12 -123 0 -195 4 -195 10 0 6 -7
|
||||
10 -15 10 -8 0 -15 -4 -15 -10 0 -6 -30 -10 -70 -10 -40 0 -70 4 -70 10 0 6
|
||||
-7 10 -15 10 -8 0 -15 -4 -15 -10 0 -6 -132 -10 -365 -10 -201 0 -365 3 -365
|
||||
5 0 16 67 135 91 163 16 18 29 37 29 41 0 5 18 31 40 57 22 27 40 54 40 60 0
|
||||
6 11 23 25 38 14 15 25 35 25 45 0 14 9 20 36 23 l36 4 -4 -43 c-2 -34 0 -43
|
||||
13 -43 12 0 15 7 11 25 -2 14 0 25 6 25 6 0 19 -11 30 -25 11 -14 30 -25 43
|
||||
-25 20 0 17 4 -19 31 -51 37 -44 61 14 52 28 -5 34 -2 34 12 0 13 -6 16 -23
|
||||
11 -16 -4 -24 -1 -24 7 0 9 10 12 29 9 26 -4 28 -7 28 -51 0 -26 5 -52 12 -59
|
||||
18 -18 64 -15 79 6 13 15 12 16 -3 4 -9 -8 -27 -12 -40 -10 -20 3 -23 9 -26
|
||||
56 -2 28 1 52 7 52 5 0 7 -9 4 -20 -5 -18 -1 -20 51 -17 37 1 56 6 56 15 0 6
|
||||
-7 12 -15 12 -8 0 -15 5 -15 11 0 5 3 8 8 6 4 -3 16 -1 27 3 26 10 52 -4 60
|
||||
-31z m-105 11 c0 -5 -7 -7 -15 -4 -8 4 -12 10 -9 15 6 11 24 2 24 -11z m764 7
|
||||
c-3 -8 -11 -14 -19 -14 -21 0 -19 15 3 20 9 3 18 5 19 6 1 0 0 -5 -3 -12z
|
||||
m-934 -5 c0 -5 -11 -19 -25 -32 l-25 -23 0 31 c0 27 4 32 25 32 14 0 25 -4 25
|
||||
-8z m424 -2 c-9 -8 -54 -7 -54 2 0 5 13 7 30 6 16 -1 27 -5 24 -8z m106 6 c0
|
||||
-3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6 0 10 -2 10 -4z m-92
|
||||
-55 c5 -29 -15 -51 -44 -51 -21 0 -24 5 -24 38 0 35 1 37 32 36 26 -1 34 -6
|
||||
36 -23z m582 2 c0 -13 -1 -23 -3 -23 -2 0 -13 10 -25 23 l-21 22 25 0 c18 0
|
||||
24 -5 24 -22z m351 -444 l24 -20 -30 17 c-39 24 -40 24 -28 24 6 0 21 -9 34
|
||||
-21z m-1366 -29 c3 -5 -8 -16 -24 -25 -36 -18 -41 -19 -41 -2 0 29 50 51 65
|
||||
27z m139 -15 c-4 -8 -8 -15 -10 -15 -2 0 -4 7 -4 15 0 8 4 15 10 15 5 0 7 -7
|
||||
4 -15z m26 -15 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11
|
||||
-4 11 -10z m1295 -20 c3 -5 -1 -10 -9 -10 -8 0 -18 5 -21 10 -3 6 1 10 9 10 8
|
||||
0 18 -4 21 -10z m-52 -15 c-3 -9 -8 -14 -10 -11 -3 3 -2 9 2 15 9 16 15 13 8
|
||||
-4z m-283 -12 c0 -5 -5 -15 -10 -23 -8 -12 -10 -11 -10 8 0 12 5 22 10 22 6 0
|
||||
10 -3 10 -7z m-1090 -45 c0 -36 -2 -38 -33 -38 -32 0 -32 1 -29 38 3 33 6 37
|
||||
33 37 27 0 29 -3 29 -37z m852 -31 c9 -4 10 -6 1 -6 -12 -1 -63 59 -63 75 0 5
|
||||
11 -8 25 -28 13 -20 30 -38 37 -41z m280 66 c-12 -2 -20 -9 -17 -14 4 -5 -1
|
||||
-9 -9 -9 -9 0 -16 4 -16 9 0 12 19 20 45 19 17 -1 16 -1 -3 -5z m178 -48 c-7
|
||||
-8 -17 -15 -23 -15 -6 0 -2 7 9 15 25 19 30 19 14 0z m-718 -47 c3 -37 3 -38
|
||||
-30 -38 -33 0 -33 1 -27 33 8 34 17 44 40 44 8 0 15 -15 17 -39z m679 -5 c13
|
||||
-17 13 -17 -6 -3 -11 8 -22 16 -24 17 -2 2 0 3 6 3 6 0 17 -8 24 -17z m-62
|
||||
-36 c-2 -1 -14 -10 -26 -20 -16 -14 -23 -15 -29 -6 -4 7 -3 10 3 6 6 -4 16 0
|
||||
23 8 7 8 17 15 23 15 6 0 8 -1 6 -3z m110 -19 c11 -15 11 -18 -1 -18 -7 0 -14
|
||||
10 -15 21 -1 12 -1 20 0 18 2 -2 9 -12 16 -21z m-621 -96 c-5 -2 -16 -1 -25 2
|
||||
-14 6 -14 8 3 21 17 12 20 11 25 -3 4 -9 2 -19 -3 -20z m711 -6 c-1 -20 -2
|
||||
-20 -6 -1 -3 11 -10 27 -17 35 -10 13 -9 13 7 1 9 -7 16 -23 16 -35z m594
|
||||
-120 c4 -10 1 -13 -8 -9 -8 3 -12 9 -9 14 7 12 11 11 17 -5z m-583 -26 c9 -16
|
||||
8 -18 -5 -14 -8 4 -15 12 -15 20 0 20 7 17 20 -6z m-282 -30 c-12 -16 -25 -30
|
||||
-28 -30 -4 0 -5 14 -2 30 3 24 9 30 28 30 l25 0 -23 -30z m18 -27 c-11 -11
|
||||
-19 6 -11 24 8 17 8 17 12 0 3 -10 2 -21 -1 -24z m71 -20 c-3 -10 -5 -4 -5 12
|
||||
0 17 2 24 5 18 2 -7 2 -21 0 -30z m40 -5 c-3 -7 -5 -2 -5 12 0 14 2 19 5 13 2
|
||||
-7 2 -19 0 -25z m96 -225 c-7 -2 -21 -2 -30 0 -10 3 -4 5 12 5 17 0 24 -2 18
|
||||
-5z m313 -112 c27 10 48 4 39 -11 -3 -4 -21 -8 -40 -7 -29 1 -35 5 -34 21 1
|
||||
17 2 17 6 4 3 -14 9 -15 29 -7z m-151 -1 c-3 -5 -1 -19 5 -30 7 -13 7 -20 0
|
||||
-20 -5 0 -10 7 -10 15 0 8 -4 15 -10 15 -5 0 -10 -7 -10 -15 0 -8 -4 -15 -10
|
||||
-15 -5 0 -10 6 -10 14 0 28 12 46 32 46 10 0 16 -4 13 -10z"/>
|
||||
<path d="M1280 1653 c0 -14 12 -28 36 -42 40 -24 36 -45 -7 -39 -18 3 -26 1
|
||||
-21 -4 5 -5 22 -8 38 -6 42 5 45 42 5 62 -16 9 -35 24 -40 33 -9 16 -10 16
|
||||
-11 -4z"/>
|
||||
<path d="M1892 1571 c4 -13 18 -16 19 -4 0 4 -5 9 -11 12 -7 2 -11 -2 -8 -8z"/>
|
||||
<path d="M1800 1536 c0 -2 9 -6 20 -9 11 -3 18 -1 14 4 -5 9 -34 13 -34 5z"/>
|
||||
<path d="M1742 1523 c-17 -3 -22 -10 -20 -26 2 -17 -4 -23 -27 -28 -27 -6 -28
|
||||
-7 -5 -8 32 -1 54 13 48 30 -3 9 7 19 26 26 31 11 21 14 -22 6z"/>
|
||||
<path d="M1130 1490 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||
-10 -4 -10 -10z"/>
|
||||
<path d="M1790 1484 c-30 -16 -50 -42 -50 -63 1 -9 7 -1 15 17 9 20 21 32 33
|
||||
32 11 0 22 7 26 15 3 8 4 15 3 14 -1 -1 -13 -7 -27 -15z"/>
|
||||
<path d="M1340 1470 c0 -5 7 -10 15 -10 8 0 15 5 15 10 0 6 -7 10 -15 10 -8 0
|
||||
-15 -4 -15 -10z"/>
|
||||
<path d="M1596 1464 c-20 -12 -25 -19 -17 -27 8 -8 2 -18 -22 -38 l-32 -28 52
|
||||
-1 c28 0 55 -5 59 -11 4 -8 9 -8 17 0 8 8 19 3 40 -17 l29 -27 24 30 c13 17
|
||||
24 37 24 45 0 9 -6 5 -13 -9 -6 -13 -20 -29 -29 -35 -14 -9 -21 -6 -34 12 -9
|
||||
13 -23 22 -32 21 -34 -3 -116 4 -94 8 12 2 22 8 22 12 0 4 27 5 60 3 43 -3 60
|
||||
-1 60 8 0 8 -10 11 -30 8 -16 -3 -30 0 -30 5 0 5 -7 4 -15 -3 -11 -9 -15 -9
|
||||
-15 -1 0 7 -4 10 -9 7 -5 -3 -14 1 -21 9 -7 8 -11 15 -9 15 17 1 79 29 64 29
|
||||
-11 0 -33 -7 -49 -15z"/>
|
||||
<path d="M1450 1450 c-13 -8 -12 -10 3 -10 9 0 17 5 17 10 0 12 -1 12 -20 0z"/>
|
||||
<path d="M2120 1450 c0 -5 -3 -9 -7 -9 -24 4 -33 -4 -33 -26 0 -20 5 -25 25
|
||||
-25 22 0 25 4 25 35 0 19 -2 35 -5 35 -3 0 -5 -4 -5 -10z m0 -34 c0 -3 -4 -8
|
||||
-10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6 0 10 -2 10 -4z"/>
|
||||
<path d="M682 1430 c0 -14 2 -19 5 -12 2 6 2 18 0 25 -3 6 -5 1 -5 -13z"/>
|
||||
<path d="M893 1443 c-13 -2 -23 -11 -23 -19 0 -18 14 -18 30 0 6 8 24 17 38
|
||||
19 26 4 26 4 2 4 -14 0 -35 -2 -47 -4z"/>
|
||||
<path d="M1776 1442 c-3 -6 -1 -14 5 -17 15 -10 25 3 12 16 -7 7 -13 7 -17 1z"/>
|
||||
<path d="M613 1403 c-7 -3 -13 -16 -13 -29 0 -19 5 -24 25 -24 21 0 25 5 25
|
||||
28 0 28 -10 34 -37 25z"/>
|
||||
<path d="M1330 1400 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||
-10 -4 -10 -10z"/>
|
||||
<path d="M1060 1390 c-12 -7 -10 -9 8 -7 12 0 22 5 22 9 0 11 -12 10 -30 -2z"/>
|
||||
<path d="M2031 1374 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
|
||||
<path d="M1826 1372 c-2 -4 4 -9 15 -9 10 -1 19 2 19 8 0 11 -27 12 -34 1z"/>
|
||||
<path d="M1870 1368 c0 -4 7 -8 15 -8 8 0 15 4 15 8 0 5 -7 9 -15 9 -8 0 -15
|
||||
-4 -15 -9z"/>
|
||||
<path d="M1300 1344 c0 -8 5 -12 10 -9 6 4 8 11 5 16 -9 14 -15 11 -15 -7z"/>
|
||||
<path d="M1485 1340 c3 -5 10 -10 16 -10 5 0 9 5 9 10 0 6 -7 10 -16 10 -8 0
|
||||
-12 -4 -9 -10z"/>
|
||||
<path d="M560 1322 c0 -5 7 -9 15 -9 8 0 15 4 15 9 0 4 -7 8 -15 8 -8 0 -15
|
||||
-4 -15 -8z"/>
|
||||
<path d="M1550 1310 c0 -5 5 -10 11 -10 5 0 7 5 4 10 -3 6 -8 10 -11 10 -2 0
|
||||
-4 -4 -4 -10z"/>
|
||||
<path d="M1206 1298 c3 -4 9 -8 15 -8 5 0 9 4 9 8 0 5 -7 9 -15 9 -8 0 -12 -4
|
||||
-9 -9z"/>
|
||||
<path d="M1270 1300 c0 -5 7 -10 16 -10 8 0 12 5 9 10 -3 6 -10 10 -16 10 -5
|
||||
0 -9 -4 -9 -10z"/>
|
||||
<path d="M460 1285 c0 -8 2 -15 4 -15 2 0 6 7 10 15 3 8 1 15 -4 15 -6 0 -10
|
||||
-7 -10 -15z"/>
|
||||
<path d="M2048 1265 c-4 -34 14 -51 25 -22 4 10 6 10 6 0 1 -7 8 -13 17 -13
|
||||
13 0 15 6 9 27 -8 33 -5 29 -31 37 -19 6 -22 2 -26 -29z"/>
|
||||
<path d="M1740 1280 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||
-10 -4 -10 -10z"/>
|
||||
<path d="M1870 1260 c0 -26 4 -30 28 -30 26 0 28 3 24 30 -3 24 -9 30 -28 30
|
||||
-20 0 -24 -5 -24 -30z"/>
|
||||
<path d="M821 1264 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
|
||||
<path d="M1220 1260 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||
-10 -4 -10 -10z"/>
|
||||
<path d="M1460 1240 c0 -5 5 -10 11 -10 5 0 7 5 4 10 -3 6 -8 10 -11 10 -2 0
|
||||
-4 -4 -4 -10z"/>
|
||||
<path d="M1810 1240 c0 -5 5 -10 11 -10 5 0 7 5 4 10 -3 6 -8 10 -11 10 -2 0
|
||||
-4 -4 -4 -10z"/>
|
||||
<path d="M688 1233 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||
<path d="M690 1654 c0 -14 3 -14 15 -4 8 7 15 14 15 16 0 2 -7 4 -15 4 -8 0
|
||||
-15 -7 -15 -16z"/>
|
||||
<path d="M730 1010 c0 -5 5 -10 10 -10 6 0 10 5 10 10 0 6 -4 10 -10 10 -5 0
|
||||
-10 -4 -10 -10z"/>
|
||||
<path d="M1326 961 c-4 -7 -5 -15 -2 -18 9 -9 19 4 14 18 -4 11 -6 11 -12 0z"/>
|
||||
<path d="M2230 1300 c6 -11 13 -20 16 -20 2 0 0 9 -6 20 -6 11 -13 20 -16 20
|
||||
-2 0 0 -9 6 -20z"/>
|
||||
<path d="M2250 1261 c0 -4 -14 -7 -32 -5 -32 4 -34 -5 -1 -10 10 -2 19 -13 21
|
||||
-24 3 -17 10 -22 32 -22 16 0 31 -5 33 -10 3 -6 4 -5 3 2 -1 7 -15 14 -30 16
|
||||
-25 3 -28 7 -22 33 3 16 3 29 1 29 -3 0 -5 -4 -5 -9z"/>
|
||||
<path d="M2310 1156 c0 -2 8 -10 18 -17 15 -13 16 -12 3 4 -13 16 -21 21 -21
|
||||
13z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 666 KiB |
@@ -0,0 +1,963 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="790.000000pt" height="784.000000pt" viewBox="0 0 790.000000 784.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.16, written by Peter Selinger 2001-2019
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,784.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M320 7751 c-83 -26 -141 -74 -181 -151 l-24 -45 0 -3640 0 -3640 27
|
||||
-50 c31 -59 67 -94 128 -126 l45 -24 3640 0 3640 0 50 27 c59 31 94 67 126
|
||||
128 l24 45 0 3640 0 3640 -24 45 c-32 61 -67 97 -126 128 l-50 27 -3625 2
|
||||
c-1994 1 -3636 -2 -3650 -6z m3847 -675 c161 -72 716 -304 745 -311 13 -3 70
|
||||
1 128 9 58 9 106 12 108 8 2 -4 38 -59 80 -122 l77 -115 95 -27 c52 -15 196
|
||||
-58 318 -95 l224 -68 92 -245 c130 -343 180 -450 277 -587 45 -65 97 -138 114
|
||||
-163 l31 -45 -8 -100 c-37 -464 -36 -453 -17 -616 9 -85 23 -199 29 -254 6
|
||||
-55 22 -136 36 -180 61 -203 66 -248 38 -330 -15 -46 -74 -153 -97 -177 -6 -7
|
||||
-30 -36 -51 -63 -67 -86 -207 -215 -232 -215 -9 0 -12 -4 -9 -10 3 -5 2 -10
|
||||
-4 -10 -6 0 -31 -32 -56 -70 -25 -38 -66 -103 -92 -142 -51 -79 -321 -509
|
||||
-325 -519 -3 -6 -501 -206 -648 -259 -94 -35 -358 -144 -755 -313 -143 -60
|
||||
-265 -110 -271 -110 -12 0 -60 19 -459 188 -455 192 -490 205 -845 325 l-335
|
||||
113 -114 191 c-169 283 -344 556 -353 550 -4 -3 -5 1 -2 9 3 8 -2 20 -11 27
|
||||
-8 7 -15 10 -15 7 0 -3 -10 4 -23 16 -12 12 -49 45 -82 72 -32 28 -70 60 -82
|
||||
73 -13 12 -27 22 -31 22 -4 0 -14 8 -23 18 -8 9 -31 31 -50 47 -47 42 -120
|
||||
131 -112 138 3 4 -1 9 -10 13 -22 8 -40 97 -34 164 6 70 33 188 47 205 18 22
|
||||
29 72 55 250 59 413 59 414 40 690 -9 137 -20 297 -25 354 l-9 105 166 173
|
||||
c112 117 173 173 187 173 28 0 231 41 243 49 5 3 68 87 140 186 71 99 183 253
|
||||
247 343 65 90 128 174 140 187 15 16 92 47 261 103 132 44 404 138 605 210
|
||||
462 164 513 181 526 182 6 0 65 -24 131 -54z m2490 -5305 c141 -6 143 -6 170
|
||||
-35 16 -16 22 -25 14 -21 -7 4 -17 2 -21 -5 -6 -9 -14 -8 -36 6 -27 18 -70 19
|
||||
-1099 15 -649 -2 -1076 -7 -1085 -12 -11 -7 -8 -8 10 -4 17 4 21 3 11 -3 -7
|
||||
-5 -47 -10 -88 -11 -42 -1 -80 -4 -85 -7 -5 -3 -44 -8 -86 -10 -80 -4 -103 -7
|
||||
-162 -17 -81 -15 -231 -16 -335 -2 -60 8 -150 17 -200 20 -49 2 -106 7 -125
|
||||
10 -19 3 -43 6 -52 7 -10 1 -18 6 -18 10 0 4 -9 5 -20 3 -11 -2 -22 0 -25 5
|
||||
-6 9 -539 13 -1720 15 -509 0 -510 0 -552 -22 -24 -13 -43 -22 -44 -20 -20 62
|
||||
4 71 206 77 240 8 5170 9 5342 1z m-4749 -210 c38 -1 57 -6 72 -21 26 -26 26
|
||||
-76 1 -92 -19 -12 -19 -13 5 -35 34 -31 33 -84 -2 -112 -22 -17 -41 -21 -109
|
||||
-21 -66 0 -84 3 -89 16 -3 9 -6 69 -6 134 0 103 2 120 18 129 9 5 26 8 37 6
|
||||
11 -2 44 -4 73 -4z m322 -16 c46 -41 29 -106 -46 -175 -24 -22 -44 -42 -44
|
||||
-43 0 -2 27 -1 60 1 59 4 60 4 60 -22 l0 -26 -105 0 c-129 0 -132 7 -41 91 71
|
||||
66 96 110 76 134 -18 21 -58 19 -72 -5 -14 -21 -68 -29 -68 -9 0 6 16 27 35
|
||||
46 33 33 39 35 81 30 25 -2 53 -12 64 -22z m229 14 c52 -18 69 -79 32 -113
|
||||
-18 -17 -18 -18 5 -41 44 -44 24 -104 -42 -125 -102 -34 -198 57 -131 124 23
|
||||
23 23 24 5 46 -22 27 -23 49 -2 78 28 40 76 51 133 31z m401 -18 c34 -24 46
|
||||
-72 30 -111 -16 -38 -56 -60 -110 -60 l-40 0 0 -45 c0 -43 -1 -45 -30 -45
|
||||
l-30 0 0 139 0 140 33 3 c59 7 122 -2 147 -21z m511 -106 c27 -71 48 -136 49
|
||||
-142 0 -8 -12 -13 -29 -13 -23 0 -31 6 -40 30 -9 28 -13 30 -65 30 -51 0 -55
|
||||
-2 -65 -30 -8 -24 -16 -30 -40 -30 l-30 0 30 83 c17 45 37 98 44 117 33 89 32
|
||||
87 66 86 32 -1 33 -1 80 -131z m274 105 c0 -22 -5 -25 -42 -28 l-43 -3 0 -115
|
||||
0 -114 -30 0 -30 0 0 115 0 115 -40 0 c-38 0 -40 2 -40 30 l0 31 113 -3 112
|
||||
-3 0 -25z m245 0 l0 -30 -70 0 -70 0 0 -35 0 -35 66 0 c62 0 65 -1 62 -22 -3
|
||||
-21 -9 -23 -65 -26 l-63 -3 0 -54 c0 -54 0 -55 -30 -55 l-30 0 0 138 c0 76 3
|
||||
142 7 145 3 4 48 7 100 7 l93 0 0 -30z m241 13 c16 -10 39 -37 50 -61 65 -133
|
||||
-65 -271 -190 -204 -91 49 -94 204 -5 262 37 25 106 26 145 3z m278 6 c61 -21
|
||||
80 -101 34 -147 l-26 -26 26 -48 c15 -26 27 -51 27 -54 0 -3 -14 -4 -32 -2
|
||||
-26 2 -37 12 -58 48 -29 50 -69 67 -71 31 -1 -12 -3 -25 -4 -31 -1 -5 -3 -19
|
||||
-4 -30 -1 -14 -8 -20 -26 -20 l-25 0 0 145 0 145 64 0 c34 0 77 -5 95 -11z
|
||||
m221 -81 c19 -47 38 -89 41 -93 4 -3 22 34 42 82 l35 88 42 3 43 3 -6 -83 c-4
|
||||
-46 -7 -109 -7 -140 0 -55 -1 -58 -25 -58 -25 0 -25 1 -25 87 0 47 -3 83 -7
|
||||
79 -4 -4 -21 -42 -38 -84 -43 -106 -58 -104 -105 8 l-35 85 -3 -87 -3 -88 -29
|
||||
0 -30 0 0 138 c0 76 3 142 7 146 4 4 21 6 37 4 28 -3 33 -10 66 -90z m805 68
|
||||
c77 -50 76 -202 -1 -253 -38 -24 -116 -23 -151 3 -86 63 -81 212 9 258 39 20
|
||||
106 16 143 -8z m327 -15 c33 -37 35 -48 8 -56 -14 -4 -30 2 -52 20 -58 49
|
||||
-123 9 -123 -76 0 -43 4 -54 28 -75 34 -29 56 -30 91 -3 37 29 34 49 -9 49
|
||||
-28 0 -35 4 -35 20 0 18 7 20 66 20 l67 0 -6 -46 c-17 -155 -239 -146 -263 11
|
||||
-9 60 26 132 76 158 52 27 117 18 152 -22z m-2762 -86 l0 -114 68 -3 c61 -3
|
||||
67 -5 70 -25 3 -23 1 -23 -97 -23 l-101 0 0 140 0 140 30 0 30 0 0 -115z
|
||||
m2060 1 c0 -128 -2 -126 88 -126 35 0 42 -3 42 -20 0 -19 -7 -20 -95 -20 l-95
|
||||
0 0 140 0 140 30 0 30 0 0 -114z m840 -26 l0 -140 -25 0 -25 0 0 140 0 140 25
|
||||
0 25 0 0 -140z m182 53 l63 -88 3 88 3 87 29 0 30 0 0 -140 0 -140 -27 0 c-24
|
||||
1 -38 15 -93 92 l-65 91 -3 -92 -3 -91 -27 0 -27 0 2 137 c0 76 2 139 2 141 1
|
||||
1 12 2 25 2 19 0 38 -19 88 -87z m-3106 -378 c38 -51 1 -115 -66 -115 -39 0
|
||||
-40 -1 -40 -35 0 -24 -5 -35 -15 -35 -12 0 -15 18 -15 106 l0 106 61 -4 c45
|
||||
-3 65 -10 75 -23z m194 10 c0 -11 -12 -15 -50 -15 -49 0 -50 -1 -50 -29 0 -28
|
||||
2 -30 48 -33 59 -4 58 -22 -3 -26 -42 -3 -45 -5 -45 -33 0 -28 1 -29 50 -29
|
||||
38 0 50 -4 50 -15 0 -12 -14 -15 -70 -15 l-70 0 0 105 0 105 70 0 c56 0 70 -3
|
||||
70 -15z m194 6 c3 -5 -19 -43 -49 -86 -30 -42 -55 -78 -55 -80 0 -2 23 -5 52
|
||||
-7 30 -2 53 -8 56 -15 3 -10 -18 -13 -82 -13 -47 0 -86 3 -86 8 1 4 27 43 59
|
||||
87 l59 80 -54 3 c-39 2 -54 7 -54 17 0 12 16 15 74 15 41 0 77 -4 80 -9z m76
|
||||
-36 c0 -25 2 -45 5 -45 2 0 23 20 46 45 23 25 50 45 61 45 17 0 13 -8 -21 -46
|
||||
l-41 -47 33 -46 c50 -70 51 -71 28 -71 -13 0 -32 17 -51 46 -26 36 -34 43 -46
|
||||
33 -8 -6 -14 -27 -14 -45 0 -24 -5 -34 -15 -34 -12 0 -15 18 -15 105 0 87 3
|
||||
105 15 105 11 0 15 -12 15 -45z m200 -26 c0 -85 11 -109 49 -109 41 0 50 17
|
||||
53 100 2 59 6 75 18 75 23 0 27 -138 5 -172 -23 -34 -60 -46 -102 -32 -45 14
|
||||
-63 53 -63 132 0 66 4 77 27 77 10 0 13 -18 13 -71z m227 -6 l20 -78 24 78
|
||||
c30 100 47 100 73 -1 21 -81 27 -79 47 12 11 52 30 78 46 63 3 -4 -7 -52 -23
|
||||
-107 -25 -85 -32 -100 -48 -98 -14 2 -24 19 -37 67 -10 35 -20 65 -22 68 -3 2
|
||||
-12 -28 -22 -67 -15 -62 -20 -71 -38 -68 -17 2 -26 20 -49 98 -33 114 -33 110
|
||||
-9 110 15 0 23 -15 38 -77z m283 -28 c0 -82 -3 -105 -14 -105 -16 0 -26 50
|
||||
-26 136 0 63 4 74 27 74 10 0 13 -24 13 -105z m206 80 c25 -25 25 -45 1 -45
|
||||
-7 0 -20 9 -30 20 -37 43 -97 8 -97 -57 0 -64 58 -96 101 -57 11 10 25 14 35
|
||||
10 16 -6 15 -10 -9 -34 -40 -40 -99 -38 -138 6 -33 36 -37 74 -15 126 17 41
|
||||
39 55 89 56 27 0 45 -7 63 -25z m92 -23 l3 -42 50 0 49 0 0 46 c0 38 3 45 18
|
||||
42 15 -3 17 -17 20 -106 3 -97 2 -102 -18 -102 -17 0 -20 6 -20 45 l0 45 -50
|
||||
0 -50 0 0 -45 c0 -38 -3 -45 -20 -45 -19 0 -20 7 -20 106 0 95 2 105 18 102
|
||||
12 -2 18 -15 20 -46z m324 -52 c44 -113 43 -110 18 -110 -13 0 -22 9 -26 25
|
||||
-5 22 -12 25 -48 25 -36 0 -45 -4 -54 -25 -7 -14 -20 -25 -31 -25 -18 0 -17 4
|
||||
9 68 16 37 35 84 44 105 25 61 45 47 88 -63z m106 -8 c3 -97 2 -102 -18 -102
|
||||
-19 0 -20 6 -20 106 0 95 2 105 18 102 15 -3 17 -17 20 -106z m129 38 c56 -78
|
||||
63 -76 63 17 0 39 4 54 13 51 8 -3 13 -36 15 -106 2 -92 1 -102 -15 -102 -11
|
||||
0 -38 29 -68 72 l-50 71 -3 -72 c-3 -63 -5 -71 -22 -71 -19 0 -20 7 -20 98 0
|
||||
140 12 146 87 42z m-462 -340 c109 0 201 -3 204 -5 2 -3 -245 -4 -550 -3 -305
|
||||
1 -502 4 -439 7 63 3 215 6 337 6 123 0 223 4 223 9 0 5 6 4 13 -2 7 -6 89
|
||||
-11 212 -12z m-967 -7 c-10 -2 -26 -2 -35 0 -10 3 -2 5 17 5 19 0 27 -2 18 -5z"/>
|
||||
<path d="M4130 6898 c-45 -23 -85 -48 -88 -56 -3 -8 5 -23 19 -34 20 -17 21
|
||||
-19 4 -13 -63 22 -89 17 -200 -35 -60 -29 -151 -71 -201 -95 -84 -40 -175
|
||||
-105 -146 -105 23 0 2 -20 -50 -46 -46 -24 -52 -24 -60 -9 -6 9 -18 19 -28 23
|
||||
-16 6 -7 17 54 64 105 83 272 244 263 254 -4 5 -11 4 -15 -1 -4 -6 -27 -11
|
||||
-52 -12 -25 -1 -115 -15 -200 -30 -141 -24 -167 -32 -280 -86 -69 -32 -141
|
||||
-66 -160 -75 -19 -9 -47 -25 -62 -36 -26 -19 -29 -19 -115 -2 -154 29 -146 29
|
||||
-139 10 3 -9 13 -53 22 -99 l17 -83 61 -8 c40 -5 52 -9 34 -12 -31 -4 -37 -17
|
||||
-12 -26 12 -5 15 -13 10 -34 -4 -15 -9 -39 -11 -53 l-4 -27 42 13 c58 18 183
|
||||
84 179 96 -2 8 45 3 56 -6 1 -1 -27 -14 -63 -29 l-64 -28 -3 -111 -3 -112
|
||||
-100 -1 -100 0 90 3 c83 4 104 11 105 36 0 4 -6 7 -12 6 -42 -5 -78 2 -78 16
|
||||
0 11 12 15 43 16 l42 2 -35 6 c-45 9 -60 4 -60 -20 0 -10 -7 -19 -15 -19 -9 0
|
||||
-15 9 -15 23 -1 22 -1 22 -15 -3 l-14 -25 1 33 1 32 74 0 c58 0 73 3 73 15 0
|
||||
12 -14 15 -65 15 -74 0 -87 -6 -169 -75 -56 -47 -58 -50 -35 -56 22 -6 21 -7
|
||||
-7 -8 -16 -1 -39 -9 -50 -18 -55 -50 -56 -50 -50 -10 4 23 2 37 -5 37 -5 0 -8
|
||||
4 -5 9 10 16 -6 42 -21 36 -12 -4 -14 0 -10 15 3 11 3 20 1 20 -10 0 -134 -88
|
||||
-232 -164 -146 -114 -164 -126 -186 -126 -10 0 -66 -10 -123 -22 l-103 -21 -2
|
||||
-41 c-3 -74 1 -125 9 -140 7 -12 18 -8 60 24 31 24 58 38 67 34 14 -5 13 -10
|
||||
-5 -32 -19 -25 -19 -27 -2 -33 10 -3 24 -4 32 -1 9 3 12 1 7 -6 -12 -20 19
|
||||
-14 44 8 13 11 37 20 56 20 22 0 32 4 30 13 -3 6 -7 27 -10 46 -9 50 7 28 20
|
||||
-27 5 -26 15 -46 21 -45 6 1 8 -8 5 -22 -2 -14 -8 -25 -13 -25 -9 0 -109 -97
|
||||
-150 -146 -15 -17 -30 -40 -33 -52 -4 -11 -16 -22 -26 -25 -11 -3 -20 -4 -20
|
||||
-3 0 1 42 51 94 111 52 60 92 115 89 122 -7 17 -40 16 -136 -2 -43 -8 -80 -15
|
||||
-82 -15 -2 0 -17 -14 -34 -31 l-31 -31 0 -118 c0 -65 4 -121 9 -124 4 -3 25
|
||||
13 45 35 20 22 36 37 36 32 0 -5 -4 -13 -9 -18 -19 -20 -51 -86 -51 -105 0
|
||||
-10 -4 -22 -10 -25 -5 -3 -10 -43 -11 -88 l-1 -82 -12 60 c-13 62 -17 61 -35
|
||||
-15 -54 -224 -88 -423 -106 -622 l-7 -77 113 -3 114 -3 14 -117 c13 -114 13
|
||||
-120 -8 -176 -36 -101 -33 -113 77 -302 84 -144 185 -305 194 -308 4 -2 8 -8
|
||||
8 -13 0 -28 341 -499 398 -549 23 -21 70 -48 105 -60 34 -13 107 -45 162 -71
|
||||
55 -26 172 -73 260 -104 88 -31 207 -73 265 -95 327 -121 393 -145 473 -176
|
||||
111 -44 131 -42 317 29 344 131 794 310 980 391 91 40 185 78 208 86 29 9 55
|
||||
27 77 54 39 49 239 342 278 408 39 67 126 288 120 305 -3 8 2 19 11 26 21 16
|
||||
78 174 71 197 -4 12 1 19 14 23 11 3 22 17 26 37 4 17 31 78 61 135 54 102 54
|
||||
103 54 194 l0 91 171 0 171 0 -7 88 c-12 144 -29 255 -40 258 -5 2 -32 -28
|
||||
-60 -66 -27 -38 -53 -66 -56 -62 -4 4 -12 57 -18 117 -15 143 -33 289 -37 294
|
||||
-4 5 -34 -26 -34 -35 0 -18 -83 -155 -90 -147 -5 4 -5 35 -1 68 5 46 9 55 15
|
||||
38 4 -13 13 -23 21 -23 13 0 45 67 45 95 0 8 5 15 11 15 5 0 7 5 4 11 -5 7
|
||||
-14 4 -26 -7 -17 -16 -19 -16 -19 -1 0 10 3 17 8 17 7 0 33 89 35 122 1 9 5
|
||||
14 9 12 4 -3 8 -1 8 5 0 5 -20 17 -45 26 -34 14 -48 15 -59 6 -7 -6 -21 -8
|
||||
-31 -5 -14 6 -16 3 -12 -12 3 -10 8 -38 12 -61 l7 -42 -44 22 c-24 11 -62 21
|
||||
-85 22 -24 0 -48 6 -55 13 -9 9 2 12 53 12 36 0 68 2 71 6 3 3 -7 28 -23 57
|
||||
-33 61 -36 79 -11 70 14 -5 15 -4 6 8 -15 19 -28 93 -15 85 5 -3 12 -20 16
|
||||
-36 8 -36 21 -46 40 -30 23 19 85 136 85 160 0 12 -22 97 -50 189 -27 91 -52
|
||||
178 -55 193 -5 20 -27 38 -95 77 -48 28 -92 51 -98 51 -6 0 -8 -16 -5 -37 l4
|
||||
-38 -18 35 c-10 19 -24 34 -31 32 -7 -1 -12 2 -12 8 0 5 5 10 11 10 8 0 7 5
|
||||
-1 15 -7 9 -25 37 -39 63 -73 133 -69 129 -151 151 l-75 19 71 -5 c67 -5 73
|
||||
-4 84 16 8 15 17 20 31 16 31 -10 42 5 17 25 -13 11 -17 19 -10 20 6 0 12 -4
|
||||
12 -10 0 -5 6 -10 14 -10 8 0 17 -6 20 -12 4 -7 4 -3 2 10 -3 14 1 22 11 22 8
|
||||
0 11 -4 8 -10 -3 -5 -1 -10 4 -10 6 0 11 7 11 15 0 8 4 15 10 15 5 0 9 -3 9
|
||||
-7 -3 -20 2 -34 10 -29 9 6 9 31 0 40 -2 3 -70 12 -149 21 -118 13 -171 25
|
||||
-281 61 l-135 46 -97 -46 c-53 -25 -98 -50 -101 -55 -3 -5 9 -11 26 -15 21 -4
|
||||
34 -2 40 6 6 10 8 9 8 -2 0 -12 -16 -15 -85 -16 -63 0 -85 3 -85 13 0 7 -12
|
||||
20 -26 30 -26 17 -26 17 -5 25 20 7 21 9 7 42 -8 19 -33 62 -56 95 l-41 61
|
||||
-74 0 c-43 0 -75 4 -75 10 0 6 26 10 59 10 55 0 88 13 59 22 -6 2 4 14 23 26
|
||||
19 12 46 30 61 40 l28 19 -23 11 c-52 27 -555 167 -565 158 -2 -2 24 -25 57
|
||||
-51 34 -27 61 -50 61 -52 0 -2 -44 26 -97 62 -54 36 -103 65 -110 65 -6 0 -48
|
||||
-19 -93 -42z m0 -229 c0 -5 -7 -9 -15 -9 -15 0 -20 12 -9 23 8 8 24 -1 24 -14z
|
||||
m-130 1 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11 -4 11
|
||||
-10z m61 -136 c30 -36 61 -74 69 -84 8 -9 33 -29 55 -44 21 -15 51 -48 65 -73
|
||||
18 -34 32 -47 49 -48 13 -1 29 -9 36 -18 7 -10 17 -17 24 -17 6 0 61 -25 122
|
||||
-55 86 -42 119 -54 145 -50 25 3 34 0 34 -11 0 -12 4 -12 20 -4 11 6 20 20 20
|
||||
31 0 12 5 19 13 16 6 -2 18 3 25 12 11 14 11 14 6 -1 -5 -14 -1 -18 15 -18 14
|
||||
0 21 -6 21 -19 0 -37 19 -31 23 6 l4 38 1 -42 c1 -26 -2 -43 -9 -43 -6 0 -9
|
||||
-7 -5 -15 4 -12 -5 -15 -47 -15 -38 -1 -48 -3 -36 -10 9 -5 27 -11 40 -13 13
|
||||
-2 24 -10 24 -18 0 -16 41 -39 72 -39 12 0 24 -4 27 -9 3 -4 20 -11 38 -15 19
|
||||
-4 50 -25 77 -52 45 -46 85 -69 102 -58 5 3 9 0 9 -7 0 -6 8 -1 18 11 22 27
|
||||
46 19 36 -12 -4 -14 -2 -18 5 -14 6 4 11 2 11 -5 0 -6 -8 -9 -18 -7 -10 3 -23
|
||||
-1 -29 -7 -15 -17 3 -35 34 -35 16 0 23 -6 23 -20 0 -13 10 -24 26 -30 35 -14
|
||||
37 -13 31 10 -3 11 0 20 6 20 6 0 8 2 5 5 -8 9 -38 -6 -32 -16 3 -5 0 -9 -5
|
||||
-9 -6 0 -11 2 -11 4 0 2 -3 11 -6 20 -5 14 5 16 72 15 44 0 74 -3 67 -5 -7 -3
|
||||
-9 -12 -6 -20 4 -11 -5 -14 -38 -15 l-44 -2 50 -6 c28 -3 74 -6 103 -6 28 0
|
||||
52 -3 52 -7 0 -5 -4 -9 -10 -9 -5 -1 -14 -3 -20 -4 -5 -1 -19 -3 -30 -4 -23
|
||||
-1 -29 -41 -6 -41 8 0 16 -7 20 -15 3 -8 9 -15 13 -14 21 3 33 -2 33 -15 0
|
||||
-17 30 -30 31 -13 1 7 4 1 8 -13 4 -14 12 -25 18 -25 6 0 15 -3 19 -7 4 -4 18
|
||||
-5 32 -1 17 4 23 2 18 -6 -5 -8 40 -12 171 -13 l178 -2 -152 -3 c-84 -2 -153
|
||||
-6 -153 -10 0 -3 8 -11 17 -18 15 -11 15 -14 -6 -36 -12 -13 -17 -25 -11 -27
|
||||
5 -2 8 -8 5 -13 -3 -5 -1 -17 5 -28 11 -22 3 -54 -12 -45 -5 3 -12 -3 -15 -15
|
||||
-8 -30 -33 -27 -33 4 0 15 -7 28 -17 32 -10 4 -24 14 -31 22 -11 14 -12 13 -3
|
||||
-4 5 -11 16 -29 24 -40 17 -23 2 -69 -20 -61 -14 6 -18 -10 -4 -18 5 -3 11
|
||||
-18 13 -34 4 -26 2 -28 -27 -24 -17 2 -25 0 -19 -5 39 -30 2 -92 -64 -102 -29
|
||||
-5 -37 -11 -36 -28 0 -15 -5 -20 -18 -18 -23 5 -23 -4 0 -22 16 -12 15 -13 -7
|
||||
-11 -19 2 -31 -5 -47 -29 -12 -18 -24 -29 -28 -26 -3 4 -6 1 -6 -5 0 -6 -10
|
||||
-14 -22 -18 -12 -3 -28 -13 -36 -20 -7 -8 -24 -14 -37 -14 -13 0 -31 -8 -41
|
||||
-17 -10 -10 -27 -23 -38 -28 -12 -6 -20 -19 -18 -28 3 -20 -14 -23 -21 -4 -4
|
||||
9 -7 9 -15 -1 -5 -7 -17 -14 -26 -16 -10 -1 -21 -7 -24 -12 -7 -10 -36 -24
|
||||
-49 -23 -3 1 -10 -6 -15 -14 -4 -8 -27 -25 -50 -37 -24 -13 -54 -30 -68 -37
|
||||
-23 -14 -24 -15 -2 -10 12 3 22 2 22 -1 0 -12 -51 -31 -67 -25 -9 4 -19 -1
|
||||
-25 -10 -5 -10 -18 -17 -29 -17 -11 0 -30 -5 -42 -12 -12 -7 -33 -14 -47 -16
|
||||
-14 -2 -29 -7 -35 -13 -5 -5 -17 -9 -27 -9 -10 0 -21 -6 -24 -13 -3 -8 -18
|
||||
-14 -34 -15 -16 0 -38 -6 -50 -12 -12 -6 -28 -9 -35 -6 -8 3 -17 1 -20 -4 -3
|
||||
-5 -12 -7 -21 -3 -8 3 -14 2 -13 -3 4 -22 -2 -34 -18 -34 -13 0 -14 -3 -6 -11
|
||||
6 -6 9 -17 6 -24 -2 -7 4 -16 15 -19 11 -4 30 -20 42 -36 13 -17 32 -30 43
|
||||
-30 11 0 18 -3 14 -6 -3 -4 0 -13 8 -21 8 -8 13 -22 12 -31 -6 -35 -42 -101
|
||||
-54 -97 -13 4 -7 -20 9 -42 5 -7 5 -14 -2 -18 -5 -3 -10 -17 -10 -31 0 -13 -6
|
||||
-24 -12 -24 -10 0 -10 -2 0 -9 8 -4 13 -11 13 -15 -3 -19 1 -25 19 -31 11 -3
|
||||
20 -11 20 -16 0 -6 -5 -7 -12 -3 -7 4 -8 3 -4 -5 9 -14 26 -5 26 15 0 8 7 14
|
||||
15 14 8 0 15 7 15 15 0 8 7 15 15 15 8 0 15 5 15 10 0 6 21 34 48 62 47 51 93
|
||||
78 131 78 20 0 21 -7 23 -172 l3 -172 35 -4 c19 -2 42 -8 52 -13 10 -5 18 -6
|
||||
18 -2 0 5 17 8 37 7 36 -2 68 -27 57 -45 -3 -5 -2 -9 3 -9 4 0 6 -60 3 -134
|
||||
-5 -132 -5 -135 -34 -165 -17 -17 -40 -31 -52 -31 -30 0 -34 -8 -25 -49 8 -41
|
||||
37 -64 51 -41 8 13 10 12 10 -2 0 -10 -8 -18 -17 -19 -45 -2 -99 -19 -60 -19
|
||||
10 0 17 -5 17 -11 0 -6 -6 -9 -12 -6 -7 2 -21 0 -30 -4 -12 -7 -18 -4 -23 12
|
||||
-10 30 -25 10 -27 -33 -1 -26 -5 -35 -15 -31 -13 5 -17 16 -14 41 1 6 -5 12
|
||||
-14 12 -18 0 -21 20 -2 21 6 0 2 4 -10 9 -17 7 -23 18 -23 40 l0 30 -59 0
|
||||
c-33 0 -63 5 -66 11 -5 7 13 10 56 8 50 -2 64 0 64 12 0 16 -111 33 -177 27
|
||||
-21 -2 -38 0 -38 4 0 8 16 12 33 9 4 0 7 37 7 84 0 81 -1 85 -22 85 -13 0 -33
|
||||
3 -45 6 -22 6 -23 4 -23 -56 0 -51 3 -61 15 -56 8 3 15 1 15 -4 0 -6 -7 -10
|
||||
-15 -10 -11 0 -15 -12 -15 -49 0 -28 5 -53 10 -56 6 -4 7 -12 3 -18 -4 -7 -6
|
||||
-22 -4 -34 1 -14 -3 -23 -11 -23 -10 0 -9 -3 2 -10 21 -13 11 -19 -51 -27 -54
|
||||
-8 -54 -8 -60 -48 l-6 -40 -2 48 c-1 40 -5 50 -21 54 -11 3 -20 9 -20 15 0 5
|
||||
8 5 18 -1 17 -9 19 -6 17 42 -1 29 -3 150 -4 269 l-1 216 -32 10 c-18 6 -46
|
||||
13 -62 17 l-29 6 8 -208 c5 -114 9 -218 9 -230 1 -17 7 -23 24 -23 12 0 22 5
|
||||
22 11 0 8 4 8 15 -1 12 -10 14 -8 13 12 -2 46 2 78 10 78 9 0 8 -117 -1 -127
|
||||
-4 -3 -7 -1 -7 5 0 7 -9 12 -20 12 -22 0 -26 -10 -9 -27 9 -9 7 -11 -9 -6 -11
|
||||
3 -23 11 -26 19 -12 30 -23 11 -25 -43 -1 -31 -6 -64 -11 -74 -6 -10 -7 -31
|
||||
-4 -48 6 -27 4 -31 -15 -31 -17 0 -21 6 -22 33 0 33 -11 70 -19 66 -3 -2 -14
|
||||
2 -25 8 -16 10 -18 14 -7 24 9 10 12 10 12 1 0 -7 7 -12 15 -12 20 0 20 58 0
|
||||
84 -8 11 -15 18 -16 15 -8 -46 -14 -57 -26 -45 -4 4 -1 11 7 16 13 8 12 10 -3
|
||||
10 -38 0 -49 -26 -52 -131 -4 -99 -15 -153 -15 -71 0 37 -3 42 -23 42 -13 0
|
||||
-28 5 -35 12 -9 9 -12 7 -12 -9 0 -11 -7 -26 -15 -33 -25 -21 -43 5 -50 76 -8
|
||||
68 -20 88 -40 61 -10 -14 -28 -17 -91 -15 l-79 2 78 3 c80 4 104 19 40 26
|
||||
l-38 4 43 1 c41 2 42 3 42 36 0 33 -1 34 -50 40 -28 4 -55 4 -60 1 -13 -8 -50
|
||||
4 -50 16 0 5 7 9 15 9 22 0 21 76 -1 84 -31 12 -34 5 -34 -93 0 -54 -3 -113
|
||||
-6 -130 -6 -28 -8 -30 -19 -14 -12 15 -12 14 -8 -11 4 -20 2 -27 -6 -22 -7 5
|
||||
-11 -4 -11 -28 0 -29 -4 -36 -19 -36 -10 0 -21 -6 -24 -14 -4 -10 18 -25 78
|
||||
-50 46 -20 87 -36 92 -36 5 0 17 -6 27 -13 15 -11 15 -17 6 -42 -7 -17 -12
|
||||
-51 -11 -78 1 -43 -1 -47 -18 -38 -12 7 -22 6 -29 -1 -14 -14 -14 -13 -16 25
|
||||
-1 19 3 27 15 27 9 0 22 7 29 15 11 13 8 15 -14 15 -20 0 -26 5 -27 23 l0 22
|
||||
-11 -22 c-16 -32 -56 -36 -75 -6 -15 23 -16 23 -29 5 -13 -19 -69 -29 -58 -10
|
||||
3 5 14 6 24 3 12 -4 19 1 24 17 12 46 9 48 -59 48 -57 0 -67 3 -90 28 -29 30
|
||||
-116 204 -136 270 l-13 44 -13 -27 c-8 -14 -18 -23 -23 -20 -13 8 -13 45 1 45
|
||||
6 0 9 14 7 32 -2 27 -8 34 -33 39 -16 4 -22 7 -12 8 10 0 15 6 12 11 -3 6 1
|
||||
10 9 10 22 0 18 69 -4 72 -8 0 -19 2 -25 3 -5 2 -20 3 -32 4 -33 1 -28 21 7
|
||||
34 l31 12 -3 100 -3 100 -50 1 c-27 1 -55 -1 -62 -3 -13 -5 -23 -66 -22 -142
|
||||
0 -71 -24 -67 -27 5 -2 85 -19 53 -19 -38 0 -48 -4 -90 -8 -94 -4 -4 -7 -65
|
||||
-7 -136 l0 -129 -105 3 -105 3 0 -27 c0 -23 -4 -28 -24 -28 -13 0 -31 10 -39
|
||||
23 -14 19 -18 20 -26 7 -9 -13 -11 -12 -11 3 0 10 -4 15 -10 12 -5 -3 -10 1
|
||||
-10 10 0 9 -5 13 -10 10 -6 -3 -12 0 -15 7 -10 24 -12 88 -3 89 4 1 13 2 18 3
|
||||
19 2 11 18 -16 32 l-26 14 4 -70 c2 -39 0 -70 -4 -70 -4 0 -8 33 -8 74 0 68
|
||||
-2 74 -22 80 -17 4 -28 -1 -40 -17 l-18 -22 0 27 c0 14 -3 33 -6 41 -4 12 0
|
||||
14 18 11 16 -3 13 0 -9 11 -18 8 -33 19 -33 23 0 13 -147 75 -159 67 -8 -4
|
||||
-11 29 -12 102 -1 311 1 437 10 446 5 5 41 7 80 5 l71 -3 0 34 c0 49 6 35 14
|
||||
-31 4 -37 2 -58 -4 -58 -5 0 -10 9 -10 20 0 18 -7 20 -70 20 -66 0 -70 -1 -70
|
||||
-22 0 -20 5 -23 40 -23 51 0 52 12 3 18 -23 2 -14 4 20 3 73 0 78 -22 7 -32
|
||||
-28 -4 -50 -12 -50 -18 0 -6 -4 -5 -9 2 -13 21 -17 -21 -10 -103 3 -38 7 -56
|
||||
8 -40 2 20 5 24 8 12 3 -11 11 -16 19 -13 8 3 14 1 14 -4 0 -6 9 -10 20 -10
|
||||
11 0 20 -4 20 -10 0 -5 9 -10 20 -10 15 0 20 -7 21 -27 l1 -28 7 30 c5 19 12
|
||||
29 22 27 59 -15 79 -14 79 2 0 9 5 16 10 16 6 0 10 4 10 10 0 5 -17 12 -37 15
|
||||
-66 11 -69 13 -47 35 18 18 34 19 209 19 213 0 234 -1 233 -9 -1 -17 3 -30 11
|
||||
-30 5 0 7 9 4 20 -3 11 0 20 6 20 6 0 11 -20 12 -47 1 -46 15 -122 18 -95 1 9
|
||||
6 10 19 4 19 -10 68 -9 79 1 11 12 43 8 43 -5 0 -9 3 -9 9 1 6 9 30 15 63 17
|
||||
29 1 59 3 66 3 7 1 12 14 12 31 0 44 20 37 21 -7 0 -21 3 -32 6 -25 2 6 15 12
|
||||
28 12 31 0 56 10 50 20 -3 5 -1 11 5 15 5 3 10 1 10 -4 0 -19 29 -12 40 9 7
|
||||
13 10 85 9 188 -1 134 2 167 13 167 7 0 11 -7 8 -15 -3 -8 -5 -64 -5 -125 0
|
||||
-88 3 -110 14 -110 8 0 16 -6 19 -12 2 -7 -3 -13 -12 -13 -12 0 -16 -11 -16
|
||||
-47 0 -63 12 -82 39 -66 11 7 27 10 35 7 9 -3 23 1 31 10 9 9 23 16 32 16 8 0
|
||||
27 9 43 20 15 11 30 17 34 13 3 -3 6 1 6 11 0 9 5 14 10 11 19 -12 8 69 -12
|
||||
88 -23 22 -23 33 0 42 15 6 15 8 -5 16 -15 5 -21 14 -17 24 4 8 1 21 -5 29
|
||||
-18 21 -10 78 11 84 10 2 18 8 18 13 0 4 14 23 30 41 17 18 30 27 30 20 0 -10
|
||||
3 -10 13 0 15 13 11 48 -5 48 -6 0 -7 7 -4 16 4 10 1 14 -6 12 -7 -3 -37 8
|
||||
-67 24 -40 21 -63 27 -88 23 -28 -4 -33 -2 -33 14 0 11 -9 23 -20 26 -11 3
|
||||
-20 10 -20 15 0 4 -20 15 -45 23 -25 9 -45 13 -45 11 0 -3 -7 1 -15 10 -9 8
|
||||
-22 13 -30 10 -8 -4 -17 1 -21 9 -3 9 -12 13 -20 10 -8 -3 -14 1 -14 11 0 9
|
||||
-8 16 -20 16 -11 0 -20 5 -20 10 0 6 -10 10 -22 10 -13 0 -33 13 -47 30 -25
|
||||
33 -71 42 -71 14 0 -8 -5 -12 -10 -9 -6 4 -8 15 -5 24 3 10 0 23 -7 28 -14 11
|
||||
-68 27 -80 25 -5 -1 -8 5 -8 13 0 8 -7 15 -15 15 -7 0 -18 7 -23 16 -10 17
|
||||
-92 37 -92 23 0 -5 -5 -9 -12 -9 -9 0 -9 3 0 12 16 16 15 48 -1 48 -7 0 -29
|
||||
12 -50 26 -29 19 -36 30 -32 45 4 12 2 19 -6 19 -14 0 -59 39 -59 51 0 5 8 6
|
||||
18 2 13 -5 15 -3 5 7 -6 7 -22 14 -35 15 -36 4 -37 4 -36 23 0 9 -3 25 -7 35
|
||||
-5 13 -2 17 11 17 16 0 17 2 4 10 -8 5 -11 10 -5 10 5 0 -1 7 -14 16 -13 9
|
||||
-30 31 -37 48 -8 17 -24 45 -35 62 -20 32 -17 64 6 64 7 0 26 26 41 58 16 31
|
||||
32 59 37 60 4 2 7 14 7 27 0 31 28 54 42 34 8 -12 9 -11 5 2 -6 18 -2 25 36
|
||||
59 16 13 26 18 23 10 -4 -8 5 -28 19 -44 14 -16 25 -36 25 -43 0 -11 8 -8 29
|
||||
9 18 14 28 29 25 39 -6 21 24 33 43 18 7 -7 17 -9 20 -5 4 4 1 11 -7 16 -18
|
||||
11 -21 28 -23 138 -2 87 -1 93 18 90 11 -1 27 2 35 7 8 5 33 19 55 30 26 13
|
||||
39 26 37 37 -2 13 9 18 55 23 32 4 84 20 116 36 32 16 63 29 70 29 30 0 153
|
||||
72 172 100 14 20 31 32 55 36 111 19 164 54 214 139 14 23 48 62 76 85 32 26
|
||||
49 48 46 57 -3 8 -2 11 4 8 5 -3 31 22 57 55 26 33 53 60 59 60 5 0 35 -30 65
|
||||
-66z m-311 -54 c0 -5 -7 -10 -16 -10 -8 0 -12 5 -9 10 3 6 10 10 16 10 5 0 9
|
||||
-4 9 -10z m708 -114 c-2 -13 -10 -21 -23 -21 -23 0 -33 34 -14 45 20 13 40 -1
|
||||
37 -24z m764 -68 c-9 -9 -12 -7 -12 12 0 19 3 21 12 12 9 -9 9 -15 0 -24z
|
||||
m-1924 -177 c-4 -20 -48 -28 -48 -9 0 20 20 37 37 31 8 -3 13 -13 11 -22z
|
||||
m1552 -1 c0 -5 -5 -10 -11 -10 -5 0 -7 5 -4 10 3 6 8 10 11 10 2 0 4 -4 4 -10z
|
||||
m-2336 -34 c-6 -15 -24 -23 -24 -11 0 8 24 34 28 30 1 -1 0 -10 -4 -19z m500
|
||||
15 c3 -5 -1 -11 -9 -14 -9 -4 -12 -1 -8 9 6 16 10 17 17 5z m134 -59 c-4 -2
|
||||
-6 -8 -2 -13 3 -5 -2 -9 -12 -9 -11 0 -15 6 -11 20 3 11 2 18 -3 15 -11 -7
|
||||
-21 22 -14 40 5 11 12 7 28 -18 12 -17 19 -34 14 -35z m-75 -14 c8 -5 7 -8 -3
|
||||
-8 -21 0 -39 19 -34 36 14 45 18 48 22 14 2 -19 9 -38 15 -42z m-92 19 c-10
|
||||
-9 -11 -8 -5 6 3 10 9 15 12 12 3 -3 0 -11 -7 -18z m30 -4 c-12 -20 -14 -14
|
||||
-5 12 4 9 9 14 11 11 3 -2 0 -13 -6 -23z m99 -13 c0 -5 -5 -10 -11 -10 -5 0
|
||||
-7 5 -4 10 3 6 8 10 11 10 2 0 4 -4 4 -10z m77 -6 c-3 -3 -12 -4 -19 -1 -8 3
|
||||
-5 6 6 6 11 1 17 -2 13 -5z m1683 -4 c0 -5 -5 -10 -11 -10 -5 0 -7 5 -4 10 3
|
||||
6 8 10 11 10 2 0 4 -4 4 -10z m867 -6 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11
|
||||
1 17 -2 13 -5z m-2957 -14 c0 -5 -4 -10 -10 -10 -5 0 -10 5 -10 10 0 6 5 10
|
||||
10 10 6 0 10 -4 10 -10z m2907 -16 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1
|
||||
17 -2 13 -5z m46 -1 c-7 -2 -19 -2 -25 0 -7 3 -2 5 12 5 14 0 19 -2 13 -5z
|
||||
m-593 -17 c0 -8 -7 -16 -15 -20 -15 -5 -21 14 -8 27 11 12 23 8 23 -7z m545
|
||||
-26 c-10 -11 -21 -17 -24 -14 -3 3 3 12 13 20 28 20 32 17 11 -6z m-62 3 c-7
|
||||
-2 -19 -2 -25 0 -7 3 -2 5 12 5 14 0 19 -2 13 -5z m202 -43 c4 -7 -45 -9 -142
|
||||
-8 l-148 2 140 6 c77 3 141 7 142 8 1 1 5 -2 8 -8z m-3251 -31 c-7 -11 -34
|
||||
-12 -34 -1 0 14 11 21 26 15 8 -3 11 -9 8 -14z m2669 14 c-24 -2 -43 -8 -43
|
||||
-14 0 -5 19 -9 43 -10 23 0 36 -3 30 -6 -25 -9 -14 -30 13 -25 18 3 22 7 13
|
||||
13 -10 6 -8 8 6 7 13 -1 21 -9 21 -20 0 -14 -8 -18 -36 -19 -19 0 -50 -2 -67
|
||||
-3 -33 -4 -33 -3 -33 40 l0 44 48 -2 47 -1 -42 -4z m-2349 -57 c-16 -19 -36
|
||||
-34 -44 -33 -9 1 -16 -8 -18 -25 -2 -16 -8 -25 -15 -22 -17 6 -134 -126 -143
|
||||
-160 -4 -18 -25 -39 -62 -62 -73 -47 -93 -55 -68 -26 18 21 18 22 -9 32 -14 5
|
||||
-31 8 -36 5 -5 -4 -4 6 1 20 6 15 10 28 10 31 0 12 -23 1 -55 -27 -24 -21 -41
|
||||
-29 -53 -24 -15 6 -13 9 11 21 15 8 27 19 27 24 0 6 5 10 11 10 17 0 50 42 45
|
||||
57 -7 18 11 26 34 13 11 -6 20 -7 20 -2 0 5 6 9 13 9 19 0 147 64 147 74 0 5
|
||||
5 9 11 9 5 0 7 -4 4 -10 -3 -5 -4 -10 0 -10 3 0 10 12 15 26 6 16 16 24 24 21
|
||||
10 -4 12 0 9 14 -3 10 0 19 6 19 6 0 12 -8 12 -17 1 -17 2 -17 6 0 2 10 10 17
|
||||
16 16 21 -2 57 13 57 24 0 6 3 7 7 4 3 -4 13 2 21 14 8 11 16 18 19 15 3 -3
|
||||
-7 -21 -23 -40z m-94 9 c0 -8 -4 -15 -10 -15 -5 0 -10 7 -10 15 0 8 5 15 10
|
||||
15 6 0 10 -7 10 -15z m2680 4 c0 -4 3 -16 6 -26 6 -14 4 -16 -6 -6 -7 6 -18 9
|
||||
-25 6 -9 -3 -12 2 -9 15 5 17 34 27 34 11z m245 1 c-3 -5 -14 -10 -23 -10 -15
|
||||
0 -15 2 -2 10 20 13 33 13 25 0z m-3795 -10 c0 -5 -2 -10 -4 -10 -3 0 -8 5
|
||||
-11 10 -3 6 -1 10 4 10 6 0 11 -4 11 -10z m3487 4 c-3 -3 -12 -4 -19 -1 -8 3
|
||||
-5 6 6 6 11 1 17 -2 13 -5z m1 -19 c-9 -9 -68 -12 -68 -4 0 5 17 9 37 9 20 0
|
||||
34 -2 31 -5z m65 -31 c-7 -3 -9 -12 -6 -20 4 -11 -8 -14 -63 -13 -66 1 -68 1
|
||||
-39 14 l30 13 -30 5 c-16 2 4 4 45 5 41 0 70 -2 63 -4z m47 -9 c0 -8 -7 -15
|
||||
-15 -15 -16 0 -20 12 -8 23 11 12 23 8 23 -8z m43 -1 c11 -11 -3 -24 -18 -18
|
||||
-8 4 -12 10 -9 15 6 11 18 12 27 3z m-3003 -34 c0 -5 -7 -10 -16 -10 -8 0 -12
|
||||
5 -9 10 3 6 10 10 16 10 5 0 9 -4 9 -10z m2997 -23 c-1 -5 -7 -8 -12 -7 -5 1
|
||||
-12 -7 -16 -17 -7 -17 -8 -17 -8 0 -1 10 -9 17 -20 17 -11 0 -22 4 -25 9 -3 5
|
||||
14 8 39 7 25 0 44 -5 42 -9z m156 -44 c-7 -2 -19 -2 -25 0 -7 3 -2 5 12 5 14
|
||||
0 19 -2 13 -5z m-3285 -24 c-2 -6 -8 -10 -13 -10 -5 0 -11 4 -13 10 -2 6 4 11
|
||||
13 11 9 0 15 -5 13 -11z m3095 -60 c-35 -7 -39 -4 -22 14 11 11 18 12 32 3 16
|
||||
-10 15 -12 -10 -17z m186 -8 c-15 -5 -22 6 -14 19 6 9 10 9 16 -1 5 -8 4 -15
|
||||
-2 -18z m67 -98 c-10 -10 -19 5 -10 18 6 11 8 11 12 0 2 -7 1 -15 -2 -18z
|
||||
m-3666 -53 c0 -16 -2 -30 -4 -30 -2 0 -6 14 -8 30 -3 17 -1 30 4 30 4 0 8 -13
|
||||
8 -30z m75 10 c3 -5 1 -10 -4 -10 -6 0 -11 5 -11 10 0 6 2 10 4 10 3 0 8 -4
|
||||
11 -10z m42 -55 c-32 -30 -60 -55 -62 -55 -16 0 -1 42 20 56 14 9 22 20 19 25
|
||||
-3 5 2 6 10 3 9 -3 16 -1 16 4 0 10 18 18 45 21 5 0 -16 -24 -48 -54z m-115
|
||||
-20 c3 -13 1 -22 -3 -19 -9 5 -13 44 -5 44 2 0 6 -11 8 -25z m3548 -17 c0 -6
|
||||
-7 -5 -15 2 -8 7 -15 17 -15 22 0 6 7 5 15 -2 8 -7 15 -17 15 -22z m-3595 12
|
||||
c3 -5 1 -10 -4 -10 -6 0 -11 5 -11 10 0 6 2 10 4 10 3 0 8 -4 11 -10z m3795
|
||||
-71 c-25 -66 -40 -92 -40 -69 0 8 -22 26 -49 39 -48 22 -130 95 -86 75 11 -5
|
||||
55 -9 97 -11 62 -1 78 1 82 14 4 9 9 14 12 11 2 -3 -4 -30 -16 -59z m-3742
|
||||
-234 l-1 -50 -4 45 c-3 24 -9 50 -14 56 -5 6 -6 14 -2 18 13 12 23 -19 21 -69z
|
||||
m366 -41 c10 -25 -1 -29 -14 -5 -6 12 -7 21 -1 21 5 0 12 -7 15 -16z m-339
|
||||
-14 c3 -5 1 -10 -4 -10 -6 0 -11 5 -11 10 0 6 2 10 4 10 3 0 8 -4 11 -10z m-7
|
||||
-83 c8 -28 8 -37 0 -35 -6 2 -13 21 -15 43 -3 46 1 43 15 -8z m606 2 c-3 -5
|
||||
-10 -7 -15 -3 -5 3 -7 10 -3 15 3 5 10 7 15 3 5 -3 7 -10 3 -15z m-50 -50 c-8
|
||||
-14 -24 -10 -24 6 0 9 6 12 15 9 8 -4 12 -10 9 -15z m-474 -12 c49 -24 57 -41
|
||||
59 -129 1 -33 5 -47 14 -45 7 1 13 -12 15 -33 3 -25 14 -44 39 -67 27 -25 34
|
||||
-38 29 -55 -3 -13 -6 -67 -6 -120 0 -75 -3 -96 -13 -92 -9 3 -13 36 -16 112
|
||||
-1 58 -5 110 -7 114 -3 5 2 8 11 8 10 0 3 13 -23 38 -34 32 -41 47 -52 107 -8
|
||||
39 -15 79 -16 90 -1 11 -3 21 -4 23 -2 1 -3 7 -4 13 0 6 -21 22 -46 35 -57 29
|
||||
-40 30 20 1z m380 9 c0 -3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6
|
||||
0 10 -2 10 -4z m345 -6 c3 -5 -1 -10 -10 -10 -9 0 -13 5 -10 10 3 6 8 10 10
|
||||
10 2 0 7 -4 10 -10z m75 -20 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1 10
|
||||
4 10 6 0 11 -4 11 -10z m2249 -51 c-7 -14 -14 -18 -21 -11 -13 13 -2 32 18 32
|
||||
12 0 13 -4 3 -21z m-249 -9 c13 -8 13 -10 -2 -10 -9 0 -20 5 -23 10 -8 13 5
|
||||
13 25 0z m808 -147 c-2 -156 -2 -156 -5 -33 -3 138 -13 169 -52 171 l-26 1 25
|
||||
8 c62 20 60 25 58 -147z m-703 138 c3 -5 1 -12 -5 -16 -5 -3 -10 1 -10 9 0 18
|
||||
6 21 15 7z m572 3 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z
|
||||
m-314 -11 c-31 -3 -44 -9 -48 -24 -8 -24 -25 -25 -25 -1 0 28 9 32 64 30 50
|
||||
-1 50 -2 9 -5z m-2433 -53 c0 -5 -4 -10 -10 -10 -5 0 -10 5 -10 10 0 6 5 10
|
||||
10 10 6 0 10 -4 10 -10z m-486 -8 c-6 -4 -14 -14 -17 -22 -4 -10 -6 -8 -6 8
|
||||
-1 15 5 22 17 22 10 0 13 -3 6 -8z m323 -34 c-3 -7 -5 -2 -5 12 0 14 2 19 5
|
||||
13 2 -7 2 -19 0 -25z m503 12 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1
|
||||
10 4 10 6 0 11 -4 11 -10z m1550 -25 c0 -8 -4 -15 -10 -15 -5 0 -10 7 -10 15
|
||||
0 8 5 15 10 15 6 0 10 -7 10 -15z m100 -5 c0 -5 -4 -10 -10 -10 -5 0 -10 5
|
||||
-10 10 0 6 5 10 10 10 6 0 10 -4 10 -10z m-1915 -10 c3 -5 1 -10 -4 -10 -6 0
|
||||
-11 5 -11 10 0 6 2 10 4 10 3 0 8 -4 11 -10z m2955 -15 c-7 -8 -18 -15 -24
|
||||
-15 -6 0 -2 7 8 15 25 19 32 19 16 0z m-2595 -5 c-3 -5 -11 -10 -16 -10 -6 0
|
||||
-7 5 -4 10 3 6 11 10 16 10 6 0 7 -4 4 -10z m2298 3 c-7 -2 -19 -2 -25 0 -7 3
|
||||
-2 5 12 5 14 0 19 -2 13 -5z m-165 -33 c11 -18 10 -20 -10 -20 -13 0 -33 -3
|
||||
-45 -6 -18 -5 -23 -2 -24 12 0 15 -2 15 -6 4 -3 -8 -11 -18 -17 -22 -16 -11
|
||||
-56 -10 -56 2 0 6 10 10 23 11 21 1 21 1 -3 8 -21 6 -16 9 29 15 41 6 55 5 62
|
||||
-5 7 -11 9 -10 9 4 0 23 22 22 38 -3z m150 3 c-10 -2 -28 -2 -40 0 -13 2 -5 4
|
||||
17 4 22 1 32 -1 23 -4z m282 -8 c-7 -9 -15 -13 -17 -11 -7 7 7 26 19 26 6 0 6
|
||||
-6 -2 -15z m-910 -25 c0 -5 -5 -10 -11 -10 -5 0 -7 5 -4 10 3 6 8 10 11 10 2
|
||||
0 4 -4 4 -10z m610 -32 c0 -23 -3 -29 -9 -19 -7 11 -9 11 -14 0 -3 -8 -6 1 -6
|
||||
19 -1 22 4 32 14 32 10 0 15 -10 15 -32z m-3013 16 c-3 -3 -12 -4 -19 -1 -8 3
|
||||
-5 6 6 6 11 1 17 -2 13 -5z m56 -1 c-7 -2 -21 -2 -30 0 -10 3 -4 5 12 5 17 0
|
||||
24 -2 18 -5z m2872 -3 c-3 -5 -2 -10 4 -10 5 0 12 6 14 13 7 17 27 -11 20 -29
|
||||
-7 -19 -33 -26 -33 -8 0 13 -2 13 -16 -1 -14 -13 -19 -14 -25 -3 -7 10 -11 10
|
||||
-21 0 -21 -21 -40 -15 -32 11 9 31 14 34 24 17 6 -9 10 -10 10 -3 0 10 11 15
|
||||
53 22 5 0 5 -3 2 -9z m372 -42 c-2 -13 -4 -5 -4 17 -1 22 1 32 4 23 2 -10 2
|
||||
-28 0 -40z m-3340 26 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z
|
||||
m1853 -4 c0 -5 -4 -10 -10 -10 -5 0 -10 5 -10 10 0 6 5 10 10 10 6 0 10 -4 10
|
||||
-10z m1008 -13 c-3 -19 -10 -22 -50 -23 -39 -1 -46 1 -45 16 1 10 4 17 7 15 3
|
||||
-2 12 0 19 4 7 4 26 8 42 9 26 1 30 -3 27 -21z m-578 3 c0 -5 -4 -10 -10 -10
|
||||
-5 0 -10 5 -10 10 0 6 5 10 10 10 6 0 10 -4 10 -10z m-2377 -7 c-7 -2 -19 -2
|
||||
-25 0 -7 3 -2 5 12 5 14 0 19 -2 13 -5z m50 0 c-7 -2 -19 -2 -25 0 -7 3 -2 5
|
||||
12 5 14 0 19 -2 13 -5z m54 1 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2
|
||||
13 -5z m943 -2 c0 -13 -12 -22 -22 -16 -10 6 -1 24 13 24 5 0 9 -4 9 -8z
|
||||
m1590 -2 c0 -5 -4 -10 -10 -10 -5 0 -10 5 -10 10 0 6 5 10 10 10 6 0 10 -4 10
|
||||
-10z m-2157 -7 c-7 -2 -19 -2 -25 0 -7 3 -2 5 12 5 14 0 19 -2 13 -5z m1537
|
||||
-3 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11 -4 11 -10z
|
||||
m-1953 -6 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m90 0 c-3 -3
|
||||
-12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m2013 -4 c0 -5 -5 -10 -11 -10
|
||||
-5 0 -7 5 -4 10 3 6 8 10 11 10 2 0 4 -4 4 -10z m-1160 -20 c0 -5 -2 -10 -4
|
||||
-10 -3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11 -4 11 -10z m2200 -20 c-14 -4
|
||||
-38 -8 -55 -8 -25 -1 -27 1 -10 8 11 5 36 8 55 8 32 0 33 -1 10 -8z m-3050
|
||||
-10 c0 -12 -98 -12 -155 -1 -32 7 -21 9 58 10 59 1 97 -3 97 -9z m1950 -4 c0
|
||||
-3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6 0 10 -2 10 -4z m998
|
||||
-17 c2 -11 -8 -15 -35 -17 l-38 -2 25 20 c27 21 43 21 48 -1z m62 1 c0 -5 -8
|
||||
-10 -17 -10 -15 0 -16 2 -3 10 19 12 20 12 20 0z m225 0 c3 -6 -1 -7 -9 -4
|
||||
-18 7 -21 14 -7 14 6 0 13 -4 16 -10z m61 -21 c-4 -29 -26 -65 -26 -44 0 12
|
||||
23 75 28 75 2 0 1 -14 -2 -31z m-2638 3 c2 -7 -3 -12 -12 -12 -9 0 -16 7 -16
|
||||
16 0 17 22 14 28 -4z m2478 -87 c-3 -8 -37 -13 -116 -14 -61 -1 -166 -6 -233
|
||||
-11 -67 -5 -125 -10 -129 -10 -5 0 -8 16 -8 35 0 42 6 43 40 10 l27 -26 146 7
|
||||
c124 6 144 9 129 20 -15 12 -13 13 18 14 26 0 31 -3 20 -10 -11 -7 -4 -10 25
|
||||
-10 28 0 36 3 26 9 -12 8 -12 12 -2 25 7 9 17 13 22 10 5 -3 9 2 9 11 0 9 5
|
||||
13 10 10 6 -3 11 2 12 12 1 10 3 -2 5 -26 3 -24 2 -49 -1 -56z m-321 75 c-3
|
||||
-5 -14 -10 -23 -10 -15 0 -15 2 -2 10 20 13 33 13 25 0z m-67 -55 c0 -14 -4
|
||||
-25 -9 -25 -10 0 -11 12 -3 34 9 22 12 20 12 -9z m-288 5 c0 -5 -4 -10 -10
|
||||
-10 -5 0 -10 5 -10 10 0 6 5 10 10 10 6 0 10 -4 10 -10z m-2476 -15 c-4 -9 -1
|
||||
-15 7 -15 8 0 9 -3 4 -8 -6 -4 -53 -5 -105 -2 -57 3 -90 8 -82 13 7 5 19 6 27
|
||||
3 8 -3 15 -1 15 4 0 5 -12 11 -27 13 -16 2 16 5 69 6 83 1 97 -1 92 -14z m136
|
||||
5 c0 -10 -105 -8 -116 3 -4 4 20 7 54 7 34 0 62 -4 62 -10z m2190 -4 c0 -3 -4
|
||||
-8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6 0 10 -2 10 -4z m-1715 -25 c7
|
||||
-12 -12 -24 -25 -16 -11 7 -4 25 10 25 5 0 11 -4 15 -9z m1295 -1 c0 -5 -5
|
||||
-10 -11 -10 -5 0 -7 5 -4 10 3 6 8 10 11 10 2 0 4 -4 4 -10z m-995 -30 c17
|
||||
-34 18 -40 6 -40 -5 0 -11 8 -14 18 -2 9 -8 25 -12 35 -12 28 3 19 20 -13z
|
||||
m940 16 c8 -7 11 -16 8 -19 -5 -6 -33 17 -33 27 0 10 11 7 25 -8z m1425 4 c0
|
||||
-5 -2 -10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11 -4 11 -10z m-3360
|
||||
-18 c0 -10 -9 -13 -35 -10 -19 2 -35 0 -35 -4 0 -4 63 -8 140 -8 87 0 140 -4
|
||||
140 -10 0 -6 -58 -10 -155 -10 -97 0 -155 4 -155 10 0 6 6 10 13 11 10 0 10 2
|
||||
0 6 -7 2 -13 11 -13 19 0 11 12 14 50 13 36 -2 50 -6 50 -17z m195 -2 c-3 -5
|
||||
-44 -9 -90 -9 -75 1 -95 6 -81 20 8 8 176 -3 171 -11z m325 4 c0 -8 -4 -12
|
||||
-10 -9 -5 3 -10 10 -10 16 0 5 5 9 10 9 6 0 10 -7 10 -16z m2643 -9 c-3 -9 -8
|
||||
-14 -10 -11 -3 3 -2 9 2 15 9 16 15 13 8 -4z m174 -42 c-15 -21 -36 -44 -47
|
||||
-51 -27 -17 -18 -30 17 -26 17 2 20 1 8 -3 -65 -18 -125 -46 -125 -58 0 -8 8
|
||||
-11 23 -8 13 3 18 1 11 -4 -14 -11 -25 -53 -13 -53 15 0 10 -27 -6 -34 -17 -6
|
||||
-22 -111 -5 -121 14 -9 13 -68 -2 -83 -9 -9 -7 -12 10 -12 25 0 31 -33 10 -54
|
||||
-18 -17 -57 -26 -64 -15 -3 5 -10 7 -15 4 -5 -4 -9 8 -9 25 0 23 5 33 20 37
|
||||
16 4 20 14 20 49 0 32 -4 44 -15 44 -11 0 -15 -11 -15 -37 0 -22 -4 -33 -8
|
||||
-26 -6 9 -12 7 -25 -7 -21 -25 -21 -30 -2 -30 12 0 14 -4 7 -16 -5 -9 -7 -25
|
||||
-5 -35 3 -11 1 -19 -5 -19 -6 0 -13 12 -15 28 -4 25 -4 25 -6 -5 -1 -22 -6
|
||||
-33 -16 -33 -13 0 -15 7 -9 38 4 20 12 40 18 44 15 10 -16 20 -51 16 -28 -3
|
||||
-28 -4 -27 -71 1 -80 13 -75 -166 -79 -114 -3 -128 -6 -148 -26 -27 -27 -42
|
||||
-28 -42 -2 0 18 -7 20 -66 20 -42 0 -70 -5 -79 -14 -8 -7 -12 -16 -9 -19 3 -3
|
||||
1 -8 -5 -12 -7 -3 -11 2 -11 14 0 11 -4 22 -9 26 -6 3 -8 -4 -6 -15 2 -12 -1
|
||||
-20 -9 -20 -31 0 -38 29 -37 150 1 74 -3 120 -9 120 -16 0 -12 30 7 48 9 9 18
|
||||
16 20 15 10 -8 1 15 -12 30 -8 9 -11 17 -6 17 5 0 17 -12 26 -27 17 -26 19
|
||||
-26 26 -8 4 11 5 68 2 126 l-5 106 225 7 c123 4 239 11 258 16 18 6 42 7 52 4
|
||||
16 -5 18 -13 12 -69 -4 -34 -8 -93 -9 -130 -2 -58 1 -69 16 -73 10 -2 18 -9
|
||||
18 -14 0 -6 7 -7 16 -4 8 3 12 2 9 -3 -3 -5 -1 -12 5 -16 5 -3 10 -1 10 4 0 6
|
||||
7 11 15 11 9 0 15 9 15 24 0 28 26 41 48 24 12 -10 14 -10 8 0 -4 6 -2 12 3
|
||||
12 7 0 11 30 11 79 l0 78 93 81 c50 44 94 78 96 76 2 -2 -8 -21 -22 -41z
|
||||
m-949 20 c2 -8 -5 -13 -17 -13 -12 0 -21 6 -21 16 0 18 31 15 38 -3z m-2118
|
||||
-3 c0 -5 -9 -10 -19 -10 -11 0 -23 5 -26 10 -4 6 5 10 19 10 14 0 26 -4 26
|
||||
-10z m40 0 c0 -5 -7 -10 -15 -10 -8 0 -15 5 -15 10 0 6 7 10 15 10 8 0 15 -4
|
||||
15 -10z m90 1 c0 -5 -18 -9 -40 -9 -22 0 -40 3 -40 9 0 5 18 9 40 9 22 0 40
|
||||
-4 40 -9z m2730 -5 c0 -3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6
|
||||
0 10 -2 10 -4z m-2980 -30 c0 -11 -14 -13 -57 -11 -32 2 -88 3 -125 4 -38 1
|
||||
-68 5 -68 11 0 6 48 10 125 10 100 0 125 -3 125 -14z m920 0 c0 -20 -19 -31
|
||||
-32 -18 -6 6 -7 15 -4 21 10 16 36 13 36 -3z m880 -6 c0 -5 -2 -10 -4 -10 -3
|
||||
0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11 -4 11 -10z m-2103 -16 c-3 -3 -12 -4
|
||||
-19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m846 -23 c6 -26 -1 -33 -24 -20 -10 5
|
||||
-16 16 -13 24 9 21 31 19 37 -4z m-903 -13 c0 -18 -2 -20 -9 -8 -6 8 -7 18 -5
|
||||
22 9 14 14 9 14 -14z m30 3 c0 -6 -4 -13 -10 -16 -5 -3 -10 1 -10 9 0 9 5 16
|
||||
10 16 6 0 10 -4 10 -9z m3553 2 c-7 -2 -19 -2 -25 0 -7 3 -2 5 12 5 14 0 19
|
||||
-2 13 -5z m-3522 -26 c-10 -9 -11 -8 -5 6 3 10 9 15 12 12 3 -3 0 -11 -7 -18z
|
||||
m609 3 c0 -5 -4 -10 -10 -10 -5 0 -10 5 -10 10 0 6 5 10 10 10 6 0 10 -4 10
|
||||
-10z m298 -31 c-2 -6 -8 -10 -13 -10 -5 0 -11 4 -13 10 -2 6 4 11 13 11 9 0
|
||||
15 -5 13 -11z m1156 3 c3 -5 -1 -9 -9 -9 -8 0 -15 4 -15 9 0 4 4 8 9 8 6 0 12
|
||||
-4 15 -8z m337 -55 c-1 -12 -15 -9 -19 4 -3 6 1 10 8 8 6 -3 11 -8 11 -12z
|
||||
m89 -11 c0 -3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6 0 10 -2 10
|
||||
-4z m40 -75 c0 -6 -4 -13 -10 -16 -5 -3 -10 1 -10 9 0 9 5 16 10 16 6 0 10 -4
|
||||
10 -9z m-1930 -275 c0 -2 -9 -6 -20 -9 -11 -3 -20 -1 -20 4 0 5 9 9 20 9 11 0
|
||||
20 -2 20 -4z m1430 -20 c0 -11 -19 -15 -25 -6 -3 5 1 10 9 10 9 0 16 -2 16 -4z
|
||||
m-1450 -76 c0 10 3 11 11 3 6 -6 9 -36 7 -72 -2 -35 1 -63 7 -65 6 -3 -3 -5
|
||||
-20 -5 l-30 -1 3 77 c3 50 7 72 13 62 7 -12 9 -12 9 1z m2640 -39 c0 -6 -4
|
||||
-13 -10 -16 -5 -3 -10 1 -10 9 0 9 5 16 10 16 6 0 10 -4 10 -9z m-1440 -29 c0
|
||||
-15 -2 -15 -10 -2 -13 20 -13 33 0 25 6 -3 10 -14 10 -23z m1064 1 c-22 -91
|
||||
-101 -241 -162 -305 -23 -25 -33 -28 -89 -28 -49 0 -63 -3 -63 -15 0 -8 -4
|
||||
-15 -10 -15 -5 0 -10 5 -10 10 0 15 -50 12 -51 -2 0 -10 -2 -10 -6 0 -2 6 -14
|
||||
12 -25 12 -15 0 -18 -4 -13 -22 4 -13 12 -27 18 -33 7 -7 8 -6 4 1 -4 7 6 14
|
||||
25 18 40 8 45 2 20 -24 -17 -18 -23 -19 -46 -9 -20 10 -29 10 -38 1 -7 -7 -17
|
||||
-12 -23 -12 -21 0 -55 41 -55 65 0 20 8 26 47 37 36 10 49 19 54 38 5 16 7 19
|
||||
8 8 1 -10 5 -18 10 -18 14 0 76 47 74 56 -1 6 13 10 30 10 21 0 53 14 90 38
|
||||
71 47 200 175 193 192 -5 13 2 24 16 24 5 0 5 -12 2 -27z m496 -3 c0 -11 -4
|
||||
-20 -10 -20 -5 0 -10 9 -10 20 0 11 5 20 10 20 6 0 10 -9 10 -20z m-3220 -9
|
||||
c0 -11 -4 -22 -8 -25 -14 -9 -35 12 -29 28 9 23 37 20 37 -3z m1905 -1 c3 -5
|
||||
-1 -10 -10 -10 -9 0 -13 5 -10 10 3 6 8 10 10 10 2 0 7 -4 10 -10z m-1970 -20
|
||||
c3 -5 1 -10 -4 -10 -6 0 -11 5 -11 10 0 6 2 10 4 10 3 0 8 -4 11 -10z m2022
|
||||
-16 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m-2027 -14 c0 -5
|
||||
-7 -10 -15 -10 -8 0 -15 5 -15 10 0 6 7 10 15 10 8 0 15 -4 15 -10z m80 0 c0
|
||||
-5 -7 -10 -16 -10 -10 0 -14 -5 -10 -16 3 -8 2 -12 -4 -9 -19 12 -11 45 10 45
|
||||
11 0 20 -4 20 -10z m1702 -22 c-7 -7 -12 -8 -12 -2 0 6 3 14 7 17 3 4 9 5 12
|
||||
2 2 -3 -1 -11 -7 -17z m-1207 2 c-3 -5 1 -10 9 -10 11 0 16 -9 16 -26 0 -24
|
||||
-2 -25 -32 -19 -18 4 -39 13 -47 21 -13 11 -12 14 5 19 10 4 26 10 34 15 20
|
||||
12 22 12 15 0z m638 3 c-7 -2 -21 -2 -30 0 -10 3 -4 5 12 5 17 0 24 -2 18 -5z
|
||||
m504 -50 c-3 -10 -5 -4 -5 12 0 17 2 24 5 18 2 -7 2 -21 0 -30z m1449 11 c-6
|
||||
-31 -16 -45 -16 -21 0 18 10 47 16 47 3 0 2 -12 0 -26z m-3102 -15 c-3 -5 -10
|
||||
-7 -15 -3 -5 3 -7 10 -3 15 3 5 10 7 15 3 5 -3 7 -10 3 -15z m1256 -19 c0 -18
|
||||
-6 -20 -57 -18 l-58 1 55 7 c54 7 53 7 -30 10 l-85 4 75 6 c41 4 81 7 88 8 6
|
||||
1 12 -7 12 -18z m240 16 c0 -3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10
|
||||
11 6 0 10 -2 10 -4z m621 -45 c-25 -66 -99 -170 -125 -176 -31 -7 -166 -11
|
||||
-166 -5 0 3 29 18 63 33 35 15 76 39 92 52 l30 25 -74 -7 c-58 -5 -72 -3 -66
|
||||
6 14 24 66 39 99 30 59 -17 74 -12 113 41 20 28 41 50 45 50 4 0 0 -22 -11
|
||||
-49z m-576 11 c-6 -7 -35 -12 -35 -7 0 2 3 11 6 19 5 13 9 14 20 5 8 -7 12
|
||||
-14 9 -17z m-1565 14 c0 -3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11
|
||||
6 0 10 -2 10 -4z m474 -11 c3 -9 0 -15 -8 -15 -7 0 -28 -3 -45 -6 -27 -6 -31
|
||||
-4 -31 15 0 18 6 21 39 21 25 0 41 -5 45 -15z m79 0 c4 -9 -6 -23 -26 -37 -29
|
||||
-20 -30 -20 -14 -2 9 11 17 28 17 37 0 21 16 22 23 2z m1330 -2 c-7 -2 -19 -2
|
||||
-25 0 -7 3 -2 5 12 5 14 0 19 -2 13 -5z m457 -3 c21 -7 18 -8 -18 -9 -26 -1
|
||||
-41 3 -37 9 7 11 19 11 55 0z m-2113 -61 c4 -1 10 -3 12 -5 2 -2 -12 -4 -32
|
||||
-4 -23 0 -37 5 -37 13 0 6 -3 23 -7 37 -6 24 -5 23 25 -8 17 -18 35 -33 39
|
||||
-33z m-222 41 c3 -5 2 -10 -4 -10 -5 0 -13 5 -16 10 -3 6 -2 10 4 10 5 0 13
|
||||
-4 16 -10z m1275 2 c0 -4 -19 -6 -42 -4 -71 5 -77 10 -15 11 31 0 57 -2 57 -7z
|
||||
m617 -18 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m410 0 c-3 -3
|
||||
-12 -4 -19 -1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m-1014 -10 c42 -7 50 -21 12
|
||||
-21 -14 0 -25 3 -25 8 0 4 -26 10 -57 12 -51 3 -53 3 -13 5 25 1 62 -1 83 -4z
|
||||
m384 -51 c-3 -10 -5 -2 -5 17 0 19 2 27 5 18 2 -10 2 -26 0 -35z m-542 7 c-27
|
||||
-12 -35 -12 -35 0 0 6 12 10 28 9 24 0 25 -1 7 -9z m185 -5 c0 -8 -7 -15 -15
|
||||
-15 -8 0 -15 7 -15 15 0 8 7 15 15 15 8 0 15 -7 15 -15z m984 0 c-4 -8 -8 -15
|
||||
-10 -15 -2 0 -4 7 -4 15 0 8 4 15 10 15 5 0 7 -7 4 -15z m-1074 -5 c-20 -13
|
||||
-50 -13 -50 0 0 6 15 10 33 10 24 0 28 -3 17 -10z m335 -75 c11 0 25 3 30 6
|
||||
19 12 75 2 95 -16 16 -14 17 -20 8 -27 -14 -8 17 -13 62 -8 64 6 75 4 78 -11
|
||||
4 -21 -56 -32 -122 -23 -31 5 -46 3 -46 -5 0 -7 21 -11 55 -11 59 0 72 -14 29
|
||||
-30 -23 -9 -26 -15 -20 -40 3 -17 1 -30 -4 -30 -6 0 -10 -10 -10 -22 0 -17 -3
|
||||
-19 -12 -10 -26 26 -30 10 -4 -17 21 -22 26 -33 18 -46 -6 -11 -12 -14 -16 -7
|
||||
-4 6 -13 9 -21 6 -21 -8 -8 -24 18 -24 19 0 17 -3 -12 -21 -29 -18 -44 -20
|
||||
-115 -14 -44 3 -108 8 -141 9 -79 5 -77 5 -70 16 3 5 12 7 19 4 7 -3 18 1 25
|
||||
9 21 26 -29 30 -59 4 l-25 -22 21 25 c29 34 40 55 26 46 -8 -4 -12 0 -12 11 0
|
||||
11 -5 24 -12 31 -8 8 -8 12 -1 12 6 0 10 17 9 39 0 22 -3 39 -6 39 -24 -2 -32
|
||||
4 -27 21 4 16 -2 20 -39 26 -29 4 -48 13 -55 26 -14 27 -8 32 27 18 58 -22 74
|
||||
-21 75 3 1 17 2 19 6 6 5 -20 33 -25 33 -7 0 6 6 9 13 6 8 -3 20 3 27 14 10
|
||||
13 17 15 27 7 7 -6 13 -9 14 -7 0 2 2 12 4 22 5 25 15 34 15 14 0 -47 59 -22
|
||||
62 26 1 30 1 29 7 -8 5 -31 10 -40 26 -40z m-300 44 c5 -6 -10 -9 -44 -8 -28
|
||||
2 -51 6 -51 11 0 12 88 10 95 -3z m135 -24 c-7 -9 -15 -13 -17 -11 -6 6 20 36
|
||||
26 30 2 -2 -2 -10 -9 -19z m770 -45 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11 10 -3
|
||||
6 -1 10 4 10 6 0 11 -4 11 -10z m351 -21 c-25 -20 -72 -23 -78 -3 -2 6 10 8
|
||||
32 6 21 -3 35 0 35 7 0 6 8 11 18 11 14 -1 13 -4 -7 -21z m-600 -31 c30 0 39
|
||||
-4 35 -14 -3 -8 -1 -14 5 -14 6 0 7 -5 4 -10 -4 -6 -12 -4 -21 5 -17 17 -34
|
||||
12 -34 -10 0 -22 -29 -26 -40 -5 -13 24 -13 63 0 55 6 -3 28 -7 51 -7z m-901
|
||||
-18 c0 -5 -12 -10 -27 -9 -25 0 -26 1 -8 9 27 12 35 12 35 0z m818 -2 c-6 -17
|
||||
-36 -34 -45 -24 -4 4 1 14 11 22 24 17 39 18 34 2z m259 6 c-3 -3 -12 -4 -19
|
||||
-1 -8 3 -5 6 6 6 11 1 17 -2 13 -5z m-997 -14 c0 -5 -7 -7 -15 -4 -8 4 -15 8
|
||||
-15 10 0 2 7 4 15 4 8 0 15 -4 15 -10z m194 4 c25 -10 20 -33 -6 -29 -26 5
|
||||
-42 -3 -51 -25 -3 -8 -6 2 -6 23 -1 33 2 37 23 37 13 0 31 -3 40 -6z m893 -16
|
||||
c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m191 2 c2 -10 -6 -16
|
||||
-23 -18 -19 -1 -25 3 -25 19 0 15 5 20 22 17 13 -2 24 -10 26 -18z m-298 -10
|
||||
c0 -11 -4 -20 -10 -20 -5 0 -10 9 -10 20 0 11 5 20 10 20 6 0 10 -9 10 -20z
|
||||
m-1394 -27 c-10 -10 -19 5 -10 18 6 11 8 11 12 0 2 -7 1 -15 -2 -18z m1641 10
|
||||
c7 -6 12 -27 12 -45 -1 -27 -3 -29 -6 -8 -3 14 -14 35 -26 48 -23 25 -5 29 20
|
||||
5z m-1587 -1 c0 -5 -7 -9 -15 -9 -8 0 -15 4 -15 9 0 4 7 8 15 8 8 0 15 -4 15
|
||||
-8z m195 -21 c-3 -6 -11 -11 -17 -11 -6 0 -6 6 2 15 14 17 26 13 15 -4z m-835
|
||||
-11 c0 -5 -5 -10 -11 -10 -5 0 -7 5 -4 10 3 6 8 10 11 10 2 0 4 -4 4 -10z m50
|
||||
0 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11 -4 11 -10z
|
||||
m700 1 c0 -9 -24 -21 -41 -21 -5 0 -9 7 -9 15 0 9 9 15 25 15 14 0 25 -4 25
|
||||
-9z m1023 2 c-7 -2 -19 -2 -25 0 -7 3 -2 5 12 5 14 0 19 -2 13 -5z m210 0 c-7
|
||||
-2 -19 -2 -25 0 -7 3 -2 5 12 5 14 0 19 -2 13 -5z m-1329 -23 c-6 -6 -15 -5
|
||||
-24 1 -13 9 -12 10 3 5 9 -3 17 0 17 6 0 6 3 8 7 5 4 -4 2 -12 -3 -17z m-94 0
|
||||
c0 -5 -4 -10 -10 -10 -5 0 -10 5 -10 10 0 6 5 10 10 10 6 0 10 -4 10 -10z m30
|
||||
0 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11 -4 11 -10z
|
||||
m250 0 c0 -5 -7 -10 -16 -10 -8 0 -12 5 -9 10 3 6 10 10 16 10 5 0 9 -4 9 -10z
|
||||
m1365 0 c-3 -5 -14 -10 -23 -10 -15 0 -15 2 -2 10 20 13 33 13 25 0z m-1548
|
||||
-42 c-3 -8 -6 -5 -6 6 -1 11 2 17 5 13 3 -3 4 -12 1 -19z m90 8 c0 -8 -11 -16
|
||||
-24 -19 -27 -5 -30 8 -5 22 23 14 29 13 29 -3z m1627 -11 c-4 -8 -10 -12 -15
|
||||
-9 -14 8 -10 24 6 24 9 0 12 -6 9 -15z m-1824 -56 c0 -6 -4 -7 -10 -4 -5 3
|
||||
-10 11 -10 16 0 6 5 7 10 4 6 -3 10 -11 10 -16z m90 7 c0 -8 -9 -12 -22 -11
|
||||
-33 4 -34 4 -18 15 22 14 40 12 40 -4z m110 5 c0 -14 -60 -19 -77 -6 -14 10
|
||||
-9 13 30 13 26 1 47 -3 47 -7z m1610 4 c0 -11 -42 -25 -53 -18 -8 5 -2 10 18
|
||||
14 17 4 31 7 33 8 1 0 2 -1 2 -4z m-1142 -69 c-7 -8 -15 -12 -17 -11 -5 6 10
|
||||
25 20 25 5 0 4 -6 -3 -14z m209 -32 c-3 -3 -12 -4 -19 -1 -8 3 -5 6 6 6 11 1
|
||||
17 -2 13 -5z"/>
|
||||
<path d="M3944 6469 c-4 -13 -8 -27 -9 -31 0 -3 -3 -10 -7 -14 -17 -17 -7 -26
|
||||
11 -10 23 21 32 49 21 66 -5 9 -10 5 -16 -11z"/>
|
||||
<path d="M3835 6360 c-3 -5 -12 -7 -19 -4 -14 6 -176 -226 -176 -253 0 -11 12
|
||||
-8 50 13 39 21 60 43 101 107 43 67 50 84 40 99 -6 10 -7 18 -2 18 5 0 11 7
|
||||
15 15 6 17 0 20 -9 5z"/>
|
||||
<path d="M3938 6348 c-20 -27 -62 -83 -102 -135 -50 -64 -89 -102 -98 -97 -5
|
||||
3 -12 -4 -15 -16 -3 -12 -11 -19 -18 -16 -13 4 -30 -20 -27 -37 1 -4 -3 -6
|
||||
-10 -5 -6 2 -21 -11 -32 -29 -12 -18 -26 -30 -33 -28 -6 2 -17 -3 -23 -11 -14
|
||||
-15 -40 -19 -40 -5 0 4 9 20 20 34 13 17 17 28 10 32 -7 4 -8 11 -2 18 5 7 13
|
||||
22 16 35 6 17 3 22 -12 22 -11 0 -25 -7 -32 -15 -25 -30 -41 -18 -34 25 8 48
|
||||
-5 52 -30 8 -11 -18 -36 -59 -57 -90 -38 -56 -38 -57 -13 -47 l27 9 -24 -26
|
||||
c-63 -70 -69 -74 -91 -70 -19 4 -34 -8 -80 -62 -32 -37 -71 -88 -87 -114 -41
|
||||
-64 -92 -119 -167 -179 -35 -28 -64 -58 -64 -67 0 -10 12 -28 25 -41 14 -13
|
||||
25 -27 25 -31 0 -14 32 -21 46 -9 11 9 19 7 34 -11 10 -12 21 -27 23 -33 2 -7
|
||||
9 -7 21 0 22 12 58 5 49 -10 -4 -6 2 -8 17 -4 l22 6 -23 -25 c-13 -14 -19 -24
|
||||
-14 -22 6 2 20 -6 32 -17 21 -19 185 -85 214 -85 8 0 23 -7 33 -15 10 -8 23
|
||||
-12 29 -8 6 3 7 2 4 -4 -6 -9 94 -73 116 -73 7 0 21 -7 31 -15 11 -8 30 -15
|
||||
43 -15 13 0 23 -4 23 -8 0 -5 19 -15 43 -22 23 -7 56 -19 74 -26 38 -17 63
|
||||
-18 63 -2 0 9 3 9 12 0 26 -26 58 -14 86 35 39 67 54 80 105 87 50 8 137 -11
|
||||
115 -25 -16 -10 8 -40 27 -33 10 4 12 0 8 -15 -3 -14 0 -23 11 -27 9 -3 13
|
||||
-11 10 -16 -6 -9 73 -5 141 6 11 2 24 4 28 5 5 0 5 10 2 21 -5 16 -2 20 17 18
|
||||
18 -2 22 1 20 17 -2 18 -2 18 8 3 14 -22 38 -23 92 -1 88 34 212 133 168 133
|
||||
-5 0 -10 5 -10 10 0 6 11 8 25 4 16 -4 25 -2 25 6 0 6 10 10 23 8 14 -2 26 4
|
||||
33 17 12 22 8 45 -8 45 -6 0 -5 -8 3 -17 12 -17 12 -17 -5 -1 -19 17 -15 55 4
|
||||
43 5 -3 11 -1 11 4 1 6 2 17 3 24 1 6 -2 18 -7 24 -5 7 -7 22 -4 33 3 10 1 18
|
||||
-3 17 -4 -1 -16 7 -26 19 -23 25 -63 48 -72 40 -3 -3 5 -17 18 -31 13 -14 18
|
||||
-25 11 -25 -7 0 -9 -6 -6 -12 4 -7 -1 -4 -9 6 -9 11 -16 16 -16 11 0 -4 -9 0
|
||||
-20 10 -11 10 -17 22 -14 27 3 4 2 8 -3 7 -16 -4 -43 13 -43 28 0 8 -4 12 -8
|
||||
9 -5 -3 -6 8 -4 25 l4 29 33 -20 c40 -25 45 -25 45 -1 0 11 -22 38 -50 62 -51
|
||||
43 -61 63 -35 72 15 6 95 -77 95 -99 0 -6 28 -38 63 -71 34 -33 61 -66 59 -72
|
||||
-2 -7 2 -11 9 -10 18 3 69 -21 69 -33 0 -5 -7 -11 -15 -14 -23 -9 -18 -29 10
|
||||
-42 24 -11 25 -11 14 9 -11 21 -10 21 12 5 29 -20 39 -20 39 -1 0 8 -8 15 -17
|
||||
16 -11 0 -13 2 -5 6 7 3 28 -7 47 -21 35 -27 69 -34 80 -16 4 6 10 8 13 6 4
|
||||
-2 12 6 18 19 14 28 -6 65 -34 65 -18 1 -58 47 -49 57 3 3 16 -2 29 -11 30
|
||||
-21 38 -20 38 5 0 27 -14 53 -67 120 -55 70 -97 219 -62 219 8 0 8 4 2 13 -6
|
||||
6 -16 29 -23 50 -11 37 -13 38 -31 21 -10 -9 -21 -26 -25 -38 -9 -29 -43 -76
|
||||
-55 -76 -6 0 -2 12 9 28 10 15 22 35 25 45 6 15 4 16 -13 7 -10 -6 -23 -17
|
||||
-28 -25 -4 -9 -24 -23 -43 -33 -27 -13 -34 -22 -32 -43 2 -26 1 -27 -27 -13
|
||||
-15 8 -44 35 -65 59 -40 50 -55 56 -55 24 0 -13 30 -55 73 -103 40 -44 77 -87
|
||||
81 -93 15 -26 -11 -11 -73 42 -36 30 -66 53 -69 51 -2 -3 -13 5 -25 17 -13 13
|
||||
-22 17 -25 9 -7 -22 -31 -12 -47 18 -19 36 -59 64 -81 56 -14 -6 -45 13 -94
|
||||
58 -8 7 -38 16 -67 20 -62 8 -139 40 -147 62 -3 8 -9 13 -13 11 -5 -3 -8 8 -8
|
||||
25 0 23 -9 38 -37 61 -46 37 -60 29 -28 -16 l23 -32 -32 29 c-38 36 -76 112
|
||||
-73 146 2 14 18 39 36 56 32 30 32 32 15 53 -9 11 -22 21 -28 21 -6 0 -8 7 -5
|
||||
15 9 21 1 19 -18 -7z m-78 -267 c-17 -28 -36 -51 -41 -51 -5 0 -9 -7 -9 -17 0
|
||||
-9 -3 -13 -7 -10 -3 4 -17 0 -30 -8 -13 -9 -23 -11 -23 -5 0 6 7 13 15 16 8 3
|
||||
20 21 27 39 6 19 15 32 20 29 4 -3 8 0 8 7 0 7 12 26 27 41 43 45 51 18 13
|
||||
-41z m112 -96 c54 -54 83 -70 72 -40 -10 26 13 16 41 -17 18 -21 23 -33 15
|
||||
-38 -13 -8 25 -40 48 -40 7 0 24 -7 37 -16 34 -22 31 -11 -7 37 -39 49 -33 58
|
||||
13 19 19 -16 39 -29 44 -30 6 0 37 -21 69 -45 33 -25 63 -45 67 -45 5 0 14 12
|
||||
22 26 12 22 15 24 26 10 14 -17 15 -33 10 -112 -4 -62 -22 -66 -61 -12 -25 33
|
||||
-68 67 -68 53 0 -3 7 -21 15 -41 10 -24 11 -33 2 -28 -11 7 18 -33 34 -46 3
|
||||
-3 6 -13 6 -22 0 -14 -6 -16 -25 -11 -16 4 -23 2 -19 -4 5 -7 -5 -8 -30 -2
|
||||
-26 5 -40 4 -45 -4 -5 -8 -8 -4 -8 10 0 23 -52 68 -110 96 -50 23 -62 5 -22
|
||||
-34 24 -24 30 -35 22 -45 -6 -7 -10 -21 -8 -30 4 -25 -29 -30 -53 -8 -17 16
|
||||
-19 16 -19 1 0 -10 -5 -17 -11 -17 -6 0 -8 8 -4 19 4 13 -5 27 -30 49 -39 35
|
||||
-71 34 -58 -2 4 -11 7 -31 6 -44 -1 -15 4 -22 11 -19 7 3 13 -1 13 -9 0 -7 -5
|
||||
-10 -10 -7 -5 3 -13 0 -17 -6 -5 -9 -20 -5 -56 14 -32 17 -50 22 -53 14 -4
|
||||
-13 -131 110 -131 128 0 7 13 19 29 28 16 8 31 20 34 27 3 10 13 8 41 -6 51
|
||||
-27 56 -12 11 34 -55 56 -36 62 27 8 77 -65 83 -66 53 -12 -25 46 -25 47 -3
|
||||
23 26 -29 155 -92 163 -79 5 9 -84 70 -103 70 -7 0 -12 4 -12 10 0 5 -15 16
|
||||
-33 24 -45 18 -107 74 -107 95 0 10 -7 26 -15 37 -16 22 -20 48 -5 39 6 -3 10
|
||||
-1 10 6 0 10 3 10 12 1 21 -21 59 -13 86 18 15 17 27 30 28 30 0 0 26 -25 56
|
||||
-55z m-395 -49 c-7 -13 -15 -22 -19 -20 -3 2 -9 0 -13 -6 -4 -6 -11 -8 -16 -5
|
||||
-5 4 -9 1 -9 -4 0 -6 -6 -11 -13 -11 -7 0 -19 -6 -25 -12 -17 -17 -112 -21
|
||||
-106 -5 2 7 27 27 54 45 37 24 50 28 50 17 0 -14 3 -14 28 -2 15 8 35 13 44
|
||||
12 10 -2 20 1 24 6 11 18 12 8 1 -15z m163 -6 c0 -5 -5 -10 -11 -10 -5 0 -7 5
|
||||
-4 10 3 6 8 10 11 10 2 0 4 -4 4 -10z m390 -390 c0 -5 -4 -10 -10 -10 -5 0
|
||||
-10 5 -10 10 0 6 5 10 10 10 6 0 10 -4 10 -10z m-1065 -89 c10 -17 -12 -21
|
||||
-25 -6 -10 12 -10 15 3 15 9 0 18 -4 22 -9z m-60 -39 c-8 -8 -25 10 -19 20 4
|
||||
6 9 5 15 -3 4 -7 6 -15 4 -17z m207 -37 c-4 -26 -22 -35 -22 -12 0 10 18 37
|
||||
26 37 1 0 -1 -11 -4 -25z m352 -56 c-3 -5 -10 -7 -15 -3 -5 3 -7 10 -3 15 3 5
|
||||
10 7 15 3 5 -3 7 -10 3 -15z m42 -76 c-10 -10 -19 5 -10 18 6 11 8 11 12 0 2
|
||||
-7 1 -15 -2 -18z m912 -35 c-6 -18 -28 -21 -28 -4 0 9 7 16 16 16 9 0 14 -5
|
||||
12 -12z m-858 -118 c0 -5 -5 -10 -11 -10 -5 0 -7 5 -4 10 3 6 8 10 11 10 2 0
|
||||
4 -4 4 -10z m54 2 c11 -18 -9 -29 -40 -23 -9 1 17 31 27 31 4 0 10 -4 13 -8z
|
||||
m226 -2 c0 -5 -4 -10 -10 -10 -5 0 -10 5 -10 10 0 6 5 10 10 10 6 0 10 -4 10
|
||||
-10z m-170 -40 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11
|
||||
-4 11 -10z m140 -30 c0 -5 -4 -10 -10 -10 -5 0 -10 5 -10 10 0 6 5 10 10 10 6
|
||||
0 10 -4 10 -10z"/>
|
||||
<path d="M3880 5892 c0 -11 89 -102 101 -102 5 0 3 14 -6 30 -9 17 -19 30 -23
|
||||
30 -4 0 -20 11 -36 25 -31 27 -36 29 -36 17z"/>
|
||||
<path d="M4240 5738 c0 -18 48 -64 57 -55 8 8 -27 59 -45 65 -7 2 -12 -3 -12
|
||||
-10z"/>
|
||||
<path d="M3730 5704 c0 -10 23 -26 77 -56 50 -27 62 -21 25 13 -18 16 -37 27
|
||||
-42 24 -5 -3 -21 2 -35 11 -14 9 -25 12 -25 8z"/>
|
||||
<path d="M4040 6220 c0 -5 13 -23 29 -39 28 -29 29 -29 27 -6 0 13 -4 21 -9
|
||||
18 -4 -2 -10 2 -13 11 -6 17 -34 30 -34 16z"/>
|
||||
<path d="M4758 6093 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||
<path d="M3595 6000 c4 -6 11 -8 16 -5 14 9 11 15 -7 15 -8 0 -12 -5 -9 -10z"/>
|
||||
<path d="M4416 5915 c4 -8 10 -12 15 -9 11 6 2 24 -11 24 -5 0 -7 -7 -4 -15z"/>
|
||||
<path d="M5258 5703 c6 -2 18 -2 25 0 6 3 1 5 -13 5 -14 0 -19 -2 -12 -5z"/>
|
||||
<path d="M5060 5641 c14 -28 13 -34 -7 -27 -26 11 26 -43 60 -60 37 -20 34 -4
|
||||
-9 56 -35 49 -65 70 -44 31z"/>
|
||||
<path d="M5130 5613 c0 -5 9 -19 20 -33 l20 -25 0 26 c0 15 -7 29 -16 33 -20
|
||||
8 -24 8 -24 -1z"/>
|
||||
<path d="M2880 5565 c0 -8 2 -15 4 -15 2 0 6 7 10 15 3 8 1 15 -4 15 -6 0 -10
|
||||
-7 -10 -15z"/>
|
||||
<path d="M5572 5493 c4 -24 21 -35 30 -20 14 21 8 37 -12 37 -14 0 -20 -6 -18
|
||||
-17z"/>
|
||||
<path d="M5080 5461 c0 -11 42 -43 48 -37 2 3 -1 14 -8 25 -11 21 -40 29 -40
|
||||
12z"/>
|
||||
<path d="M3020 5381 c0 -5 5 -13 10 -16 6 -3 10 -2 10 4 0 5 -4 13 -10 16 -5
|
||||
3 -10 2 -10 -4z"/>
|
||||
<path d="M4977 5216 c-4 -10 -1 -13 9 -9 15 6 19 23 5 23 -5 0 -11 -7 -14 -14z"/>
|
||||
<path d="M3283 5183 c-13 -5 -6 -33 8 -33 12 0 55 -40 46 -41 -4 -1 -11 -2
|
||||
-17 -3 -5 0 -10 -4 -10 -8 0 -5 0 -12 0 -18 0 -5 15 -10 34 -10 42 0 68 -9 60
|
||||
-21 -3 -5 0 -9 6 -9 6 0 8 -4 5 -10 -3 -5 1 -10 9 -10 24 0 19 -16 -11 -39
|
||||
-31 -25 -28 -30 20 -33 20 -2 37 -7 37 -13 1 -5 8 -1 18 10 12 15 30 20 65 21
|
||||
46 0 47 0 23 -13 -14 -7 -30 -22 -36 -32 -11 -22 -3 -54 12 -45 5 3 15 -2 22
|
||||
-12 15 -20 46 -13 46 10 0 10 6 13 16 9 11 -4 13 -13 9 -33 -3 -16 -1 -31 4
|
||||
-35 6 -3 11 0 11 8 0 8 6 20 14 26 12 10 17 8 26 -9 9 -17 14 -19 26 -9 8 6
|
||||
14 7 14 3 0 -5 -12 -16 -26 -25 -24 -15 -24 -16 -8 -30 16 -12 17 -12 11 3 -4
|
||||
12 -2 15 8 11 8 -3 17 2 21 10 5 13 9 13 32 1 15 -8 34 -14 42 -14 11 0 11 -3
|
||||
2 -12 -18 -18 -14 -38 8 -38 11 0 20 5 20 10 0 6 5 10 11 10 8 0 8 -4 -1 -15
|
||||
-13 -15 -5 -39 11 -30 13 9 11 -9 -3 -23 -9 -9 -8 -12 5 -12 9 0 17 5 17 11 0
|
||||
5 4 8 9 5 14 -9 19 15 10 54 -5 19 -9 60 -9 91 0 55 -1 57 -31 63 -17 3 -36 3
|
||||
-42 -1 -5 -3 -7 -2 -4 4 7 10 -26 43 -62 62 -18 10 -20 9 -14 -6 6 -16 5 -16
|
||||
-10 -4 -9 7 -15 17 -12 21 2 4 -16 8 -40 8 -24 1 -47 -2 -50 -8 -3 -5 1 -10
|
||||
10 -10 9 0 14 -4 10 -9 -3 -5 2 -11 11 -13 15 -3 16 -4 2 -16 -13 -10 -19 -10
|
||||
-34 5 -17 17 -18 17 -11 0 5 -14 2 -20 -15 -25 -21 -5 -21 -6 -2 -13 18 -6 18
|
||||
-7 1 -14 -33 -14 -43 11 -19 45 12 16 22 34 22 39 0 6 7 14 16 19 21 12 9 33
|
||||
-13 25 -13 -5 -15 -2 -10 11 4 9 3 15 -2 11 -5 -3 -21 -1 -35 5 -14 5 -26 6
|
||||
-26 1 0 -5 11 -12 25 -15 13 -3 29 -15 35 -26 18 -34 -21 -25 -58 13 -39 40
|
||||
-40 47 -4 47 20 0 23 3 12 9 -8 6 -18 7 -22 5 -4 -3 -8 0 -8 6 0 7 -7 9 -16 6
|
||||
-8 -3 -12 -2 -9 4 3 5 -4 14 -15 20 -16 8 -20 8 -20 -4 0 -9 -7 -12 -19 -9
|
||||
-11 3 -17 11 -14 18 8 21 -116 80 -144 68z m51 -22 c19 -11 36 -18 39 -15 2 2
|
||||
10 -2 17 -11 25 -30 0 -27 -50 5 -46 29 -58 40 -45 40 2 0 20 -9 39 -19z m116
|
||||
-115 c0 -3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6 0 10 -2 10 -4z
|
||||
m41 -40 c-9 -11 -9 -15 1 -19 7 -2 0 -8 -15 -12 -38 -10 -45 0 -16 24 28 23
|
||||
47 28 30 7z m213 -81 c-4 -8 -1 -15 6 -15 6 0 8 -4 5 -10 -9 -15 39 -12 54 3
|
||||
11 10 12 8 7 -9 -7 -22 16 -40 35 -28 5 3 9 -2 9 -11 0 -12 -4 -14 -19 -5 -11
|
||||
5 -27 7 -36 4 -10 -4 -15 -2 -13 7 2 8 -7 15 -22 17 -14 2 -30 10 -36 18 -10
|
||||
12 -13 12 -23 0 -13 -16 -41 -11 -41 6 0 6 7 8 15 5 7 -3 24 3 37 13 28 24 29
|
||||
24 22 5z m46 5 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11
|
||||
-4 11 -10z m110 -134 c0 -3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11
|
||||
6 0 10 -2 10 -4z"/>
|
||||
<path d="M4800 5157 c-39 -37 -94 -58 -84 -33 3 8 11 13 18 10 7 -3 21 4 31
|
||||
16 11 12 13 20 6 20 -21 0 -76 -26 -90 -43 -12 -15 -11 -17 5 -17 17 0 17 -1
|
||||
-1 -14 -14 -10 -24 -11 -36 -3 -12 7 -22 6 -40 -6 -19 -14 -20 -17 -6 -17 24
|
||||
0 21 -17 -4 -23 -12 -3 -18 -10 -15 -16 11 -17 -13 -51 -37 -51 -22 -1 -22 -1
|
||||
-2 -16 12 -9 30 -12 46 -9 17 4 32 1 42 -10 10 -9 18 -11 22 -5 4 6 11 8 16 5
|
||||
5 -4 9 1 9 9 0 9 -8 16 -18 16 -10 0 -19 6 -19 14 0 8 6 12 14 9 19 -7 16 7
|
||||
-4 23 -17 12 -17 13 -1 14 19 0 38 -28 31 -47 -2 -6 11 -18 28 -27 l33 -16
|
||||
-24 25 -23 24 36 -4 c35 -5 36 -4 27 20 -11 29 3 34 19 8 9 -16 10 -16 11 4 0
|
||||
19 5 22 37 19 25 -1 43 4 55 16 23 23 23 26 -7 26 -15 0 -27 -8 -30 -19 -5
|
||||
-15 -10 -16 -32 -8 -15 5 -39 7 -55 4 -17 -4 -28 -2 -28 4 0 6 11 11 25 11 24
|
||||
0 30 9 26 38 -1 6 3 12 9 12 14 0 60 46 60 60 0 17 -14 11 -50 -23z m-70 -126
|
||||
c0 -5 -6 -11 -13 -14 -8 -3 -14 1 -14 9 0 8 6 14 14 14 7 0 13 -4 13 -9z"/>
|
||||
<path d="M4935 5172 c-50 -6 -50 -20 -1 -27 26 -4 50 -5 53 -1 13 13 -23 32
|
||||
-52 28z"/>
|
||||
<path d="M3123 5154 c0 -8 6 -14 14 -14 7 0 13 4 13 9 0 5 15 5 36 1 25 -6 34
|
||||
-5 31 3 -6 18 -94 18 -94 1z"/>
|
||||
<path d="M4858 5111 c-10 -13 -10 -14 1 -4 11 9 17 8 28 -3 11 -11 19 -12 28
|
||||
-4 10 8 16 7 22 -5 9 -15 11 -15 22 -1 15 18 9 22 -51 29 -27 3 -41 0 -50 -12z"/>
|
||||
<path d="M3170 5111 c-18 -5 -21 -9 -12 -15 17 -10 82 2 82 14 0 11 -33 11
|
||||
-70 1z"/>
|
||||
<path d="M4795 5080 c-3 -5 -1 -10 4 -10 6 0 11 5 11 10 0 6 -2 10 -4 10 -3 0
|
||||
-8 -4 -11 -10z"/>
|
||||
<path d="M3231 5063 c-12 -13 -11 -14 7 -8 17 5 21 3 16 -9 -3 -9 -1 -17 5
|
||||
-17 35 -4 45 -3 48 7 3 9 -10 18 -57 41 -3 1 -11 -5 -19 -14z"/>
|
||||
<path d="M3322 5048 c3 -7 14 -14 26 -16 18 -3 20 -8 15 -35 -5 -31 -5 -31 10
|
||||
-12 11 13 16 15 17 6 0 -11 3 -11 16 0 14 12 14 14 0 25 -9 6 -16 16 -16 21 0
|
||||
6 -10 13 -22 17 -36 9 -50 7 -46 -6z"/>
|
||||
<path d="M4536 5033 c-32 -8 -48 -29 -32 -42 10 -8 19 -6 36 9 12 11 28 17 34
|
||||
13 6 -4 5 1 -3 10 -7 9 -14 16 -15 16 0 -1 -10 -4 -20 -6z"/>
|
||||
<path d="M3315 5011 c-3 -5 -1 -12 4 -15 5 -3 11 1 15 9 6 16 -9 21 -19 6z"/>
|
||||
<path d="M4016 4994 c-8 -29 1 -64 15 -64 5 0 9 -6 9 -14 0 -7 6 -19 14 -25
|
||||
11 -10 16 -8 21 9 3 11 10 18 15 15 4 -3 11 2 14 11 3 8 2 12 -4 9 -13 -8 -13
|
||||
1 -1 24 6 10 7 28 4 40 -5 20 -7 21 -29 6 -22 -14 -25 -14 -30 0 -9 23 -21 18
|
||||
-28 -11z"/>
|
||||
<path d="M4443 5003 c-7 -2 -13 -11 -13 -18 0 -8 -7 -11 -20 -8 -22 6 -28 -12
|
||||
-7 -20 6 -3 2 -6 -11 -6 -15 -1 -21 3 -16 11 5 8 0 9 -17 5 -13 -4 -31 -7 -39
|
||||
-8 -10 0 -8 -3 5 -8 17 -8 14 -11 -22 -26 -24 -9 -43 -21 -43 -25 0 -5 -8 -6
|
||||
-18 -3 -14 3 -18 -3 -20 -28 -3 -36 -12 -51 -19 -31 -3 6 -9 12 -14 12 -4 0
|
||||
-6 -7 -2 -16 4 -10 -4 -24 -21 -39 -14 -12 -26 -27 -26 -34 0 -6 -4 -11 -10
|
||||
-11 -5 0 -10 9 -10 20 0 37 -20 21 -26 -22 -7 -39 -8 -40 -17 -17 -5 14 -11
|
||||
19 -14 12 -6 -15 -23 -17 -23 -3 0 18 -35 45 -55 42 -20 -3 -63 49 -57 69 1 6
|
||||
-2 8 -7 5 -9 -6 -8 -64 1 -118 3 -14 13 -34 22 -43 12 -12 14 -21 7 -29 -18
|
||||
-21 -9 -146 10 -146 5 0 9 -7 9 -16 0 -19 24 -13 26 7 5 54 6 54 15 24 14 -44
|
||||
19 -81 18 -164 0 -61 3 -72 15 -68 8 3 17 1 20 -6 10 -26 25 19 25 73 -1 80
|
||||
11 147 29 162 13 11 15 10 10 -9 -9 -33 25 -30 40 2 16 34 15 35 -5 29 -12 -4
|
||||
-14 -3 -6 3 14 10 27 87 14 78 -21 -12 -20 30 0 51 12 13 19 30 16 38 -3 8 1
|
||||
20 10 28 15 11 16 10 10 -11 -3 -14 0 -33 10 -47 17 -27 33 -31 33 -10 0 8 7
|
||||
17 16 20 8 3 13 10 10 15 -3 5 1 11 8 14 8 3 17 1 20 -6 3 -8 7 -9 13 -2 4 6
|
||||
22 18 38 27 24 14 30 23 28 48 -1 23 3 30 13 26 7 -3 20 1 28 9 21 21 39 19
|
||||
31 -4 -3 -11 -1 -22 5 -26 6 -4 13 7 17 25 4 22 8 28 14 18 7 -10 9 -10 9 0 0
|
||||
17 15 15 34 -4 15 -14 16 -14 16 0 0 9 7 16 16 16 11 0 14 5 10 16 -4 12 -2
|
||||
15 9 10 10 -3 15 1 15 12 0 25 -10 35 -54 55 -30 14 -41 15 -52 6 -8 -7 -17
|
||||
-10 -19 -7 -3 3 1 11 9 18 13 10 13 14 1 26 -14 15 -22 16 -42 7z m87 -72 c20
|
||||
-38 13 -53 -21 -46 -22 5 -29 4 -25 -4 5 -7 1 -9 -8 -5 -9 3 -16 10 -16 16 0
|
||||
5 4 7 9 3 5 -3 12 -1 16 4 3 6 12 8 20 4 10 -3 15 1 15 12 0 11 -5 15 -15 11
|
||||
-15 -5 -20 5 -8 17 11 12 22 8 33 -12z m-73 -2 c-9 -6 -15 -13 -13 -17 2 -4
|
||||
-9 -15 -25 -24 -16 -9 -31 -13 -33 -9 -3 4 8 15 25 25 16 9 29 21 29 27 0 5 8
|
||||
9 18 9 16 -1 16 -1 -1 -11z m-87 -46 c0 -17 -18 -35 -29 -29 -8 5 -7 11 2 21
|
||||
13 16 27 19 27 8z m80 -14 c0 -5 -4 -9 -10 -9 -5 0 -10 7 -10 16 0 8 5 12 10
|
||||
9 6 -3 10 -10 10 -16z m-130 -9 c0 -5 -4 -10 -10 -10 -5 0 -10 5 -10 10 0 6 5
|
||||
10 10 10 6 0 10 -4 10 -10z m-103 -77 c-3 -10 -5 -4 -5 12 0 17 2 24 5 18 2
|
||||
-7 2 -21 0 -30z m147 19 c7 -11 -17 -38 -40 -46 -15 -5 -24 -2 -28 10 -8 21 4
|
||||
40 15 23 6 -11 9 -10 15 4 6 17 29 23 38 9z m-366 -50 c-10 -2 -18 -8 -18 -13
|
||||
0 -6 -5 -7 -11 -4 -6 5 -4 12 8 20 10 7 22 10 28 7 5 -4 2 -8 -7 -10z m182 4
|
||||
c0 -2 -7 -7 -16 -10 -8 -3 -12 -2 -9 4 6 10 25 14 25 6z m-195 -206 c3 -5 2
|
||||
-10 -4 -10 -5 0 -13 5 -16 10 -3 6 -2 10 4 10 5 0 13 -4 16 -10z m80 -220 c3
|
||||
-5 1 -10 -4 -10 -6 0 -11 5 -11 10 0 6 2 10 4 10 3 0 8 -4 11 -10z"/>
|
||||
<path d="M4602 4938 c5 -15 28 -23 28 -10 0 5 -7 13 -16 16 -10 4 -14 1 -12
|
||||
-6z"/>
|
||||
<path d="M3497 4922 c-10 -10 -14 -22 -10 -25 7 -8 43 21 43 35 0 14 -16 9
|
||||
-33 -10z"/>
|
||||
<path d="M4625 4900 c4 -6 11 -8 16 -5 14 9 11 15 -7 15 -8 0 -12 -5 -9 -10z"/>
|
||||
<path d="M4130 4809 c0 -5 5 -7 10 -4 6 3 10 8 10 11 0 2 -4 4 -10 4 -5 0 -10
|
||||
-5 -10 -11z"/>
|
||||
<path d="M4500 4810 c0 -5 5 -10 11 -10 5 0 7 5 4 10 -3 6 -8 10 -11 10 -2 0
|
||||
-4 -4 -4 -10z"/>
|
||||
<path d="M4410 4786 c0 -9 5 -16 10 -16 6 0 10 4 10 9 0 6 -4 13 -10 16 -5 3
|
||||
-10 -1 -10 -9z"/>
|
||||
<path d="M3665 4780 c3 -5 8 -10 11 -10 2 0 4 5 4 10 0 6 -5 10 -11 10 -5 0
|
||||
-7 -4 -4 -10z"/>
|
||||
<path d="M3747 4783 c-12 -11 -8 -23 9 -23 8 0 12 -4 9 -10 -3 -6 1 -7 10 -4
|
||||
14 6 14 8 -1 25 -19 22 -18 21 -27 12z"/>
|
||||
<path d="M4167 4486 c-4 -9 8 -29 25 -48 22 -23 33 -29 36 -19 2 7 0 16 -5 20
|
||||
-5 3 -18 18 -30 33 -16 21 -22 24 -26 14z"/>
|
||||
<path d="M4221 4484 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
|
||||
<path d="M3917 4473 c-10 -10 -8 -25 2 -19 5 4 11 1 13 -6 3 -7 7 -2 10 10 6
|
||||
21 -10 31 -25 15z"/>
|
||||
<path d="M3945 4428 c-4 -16 -4 -36 0 -45 12 -32 28 12 17 45 l-10 27 -7 -27z"/>
|
||||
<path d="M4156 4428 c-9 -36 -7 -48 8 -48 21 0 28 29 12 51 -13 19 -14 19 -20
|
||||
-3z"/>
|
||||
<path d="M3890 4424 c0 -8 5 -12 10 -9 6 3 10 10 10 16 0 5 -4 9 -10 9 -5 0
|
||||
-10 -7 -10 -16z"/>
|
||||
<path d="M3997 4404 c6 -15 23 -19 23 -5 0 5 -7 11 -14 14 -10 4 -13 1 -9 -9z"/>
|
||||
<path d="M4102 4370 c1 -23 5 -43 9 -45 10 -7 39 5 39 17 0 5 -5 6 -11 2 -8
|
||||
-4 -9 0 -4 15 4 15 2 21 -9 21 -10 0 -13 6 -10 15 4 8 1 15 -5 15 -6 0 -10
|
||||
-17 -9 -40z"/>
|
||||
<path d="M4003 4364 c-16 -17 -17 -51 -1 -60 6 -4 8 -3 4 4 -3 6 -1 23 4 38
|
||||
12 31 10 37 -7 18z"/>
|
||||
<path d="M2543 4094 c8 -9 77 -25 122 -29 22 -2 30 -1 18 2 -13 2 -23 11 -23
|
||||
19 0 11 -15 14 -62 14 -34 0 -59 -3 -55 -6z"/>
|
||||
<path d="M2680 4090 c0 -5 25 -10 55 -10 30 0 55 5 55 10 0 6 -25 10 -55 10
|
||||
-30 0 -55 -4 -55 -10z"/>
|
||||
<path d="M2625 4040 c-8 -13 5 -13 25 0 13 8 13 10 -2 10 -9 0 -20 -4 -23 -10z"/>
|
||||
<path d="M2680 4042 c0 -4 18 -6 40 -4 22 2 40 6 40 8 0 2 -18 4 -40 4 -22 0
|
||||
-40 -3 -40 -8z"/>
|
||||
<path d="M2775 4040 c3 -5 8 -10 11 -10 2 0 4 5 4 10 0 6 -5 10 -11 10 -5 0
|
||||
-7 -4 -4 -10z"/>
|
||||
<path d="M2628 4013 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||
<path d="M2299 3988 c-3 -67 0 -161 5 -166 3 -3 6 38 6 91 0 54 -2 97 -5 97
|
||||
-3 0 -5 -10 -6 -22z"/>
|
||||
<path d="M2380 3985 c0 -7 7 -12 15 -11 22 3 23 19 3 22 -10 1 -18 -4 -18 -11z"/>
|
||||
<path d="M2557 3963 c-11 -10 -8 -53 3 -53 6 0 10 14 10 30 0 31 -2 35 -13 23z"/>
|
||||
<path d="M2623 3932 l0 -31 74 -3 c40 -2 83 -1 95 2 20 5 19 8 -18 29 -23 14
|
||||
-62 25 -95 28 l-56 5 0 -30z"/>
|
||||
<path d="M2670 3870 c0 -5 7 -10 16 -10 8 0 12 5 9 10 -3 6 -10 10 -16 10 -5
|
||||
0 -9 -4 -9 -10z"/>
|
||||
<path d="M2748 3863 c6 -2 18 -2 25 0 6 3 1 5 -13 5 -14 0 -19 -2 -12 -5z"/>
|
||||
<path d="M3393 3853 c-10 -3 -13 -51 -13 -189 l0 -184 -25 -6 c-20 -5 -25 -12
|
||||
-25 -39 0 -27 9 -41 47 -73 25 -22 62 -49 82 -60 l36 -21 3 290 3 289 -48 -1
|
||||
c-26 0 -54 -3 -60 -6z m82 -213 c3 -5 1 -10 -4 -10 -6 0 -11 5 -11 10 0 6 2
|
||||
10 4 10 3 0 8 -4 11 -10z m5 -250 c0 -5 -4 -10 -10 -10 -5 0 -10 5 -10 10 0 6
|
||||
5 10 10 10 6 0 10 -4 10 -10z"/>
|
||||
<path d="M3670 3845 c0 -11 11 -15 39 -15 22 0 44 6 51 15 11 13 6 15 -39 15
|
||||
-39 0 -51 -4 -51 -15z"/>
|
||||
<path d="M2670 3825 c0 -9 17 -13 60 -14 47 0 58 2 54 14 -8 19 -114 19 -114
|
||||
0z"/>
|
||||
<path d="M3662 3726 c1 -52 6 -92 10 -90 5 3 8 0 8 -5 0 -19 40 -12 41 7 0 15
|
||||
1 14 8 -2 7 -18 8 -18 14 5 12 42 8 49 -23 49 -34 0 -42 16 -7 17 12 0 38 1
|
||||
57 3 34 3 34 3 -10 10 -25 4 -35 8 -22 8 35 3 30 42 -5 43 l-28 1 25 7 c14 4
|
||||
26 15 28 24 3 14 -5 17 -48 17 l-51 0 3 -94z"/>
|
||||
<path d="M4918 3685 c-2 -60 1 -94 7 -92 13 5 19 187 6 187 -5 0 -11 -43 -13
|
||||
-95z"/>
|
||||
<path d="M3770 3750 c0 -11 5 -20 10 -20 6 0 10 9 10 20 0 11 -4 20 -10 20 -5
|
||||
0 -10 -9 -10 -20z"/>
|
||||
<path d="M2740 3740 c0 -5 11 -10 24 -10 14 0 28 5 31 10 4 6 -7 10 -24 10
|
||||
-17 0 -31 -4 -31 -10z"/>
|
||||
<path d="M3770 3680 c0 -5 5 -10 11 -10 5 0 7 5 4 10 -3 6 -8 10 -11 10 -2 0
|
||||
-4 -4 -4 -10z"/>
|
||||
<path d="M2775 3670 c3 -5 8 -10 11 -10 2 0 4 5 4 10 0 6 -5 10 -11 10 -5 0
|
||||
-7 -4 -4 -10z"/>
|
||||
<path d="M2820 3653 c0 -38 10 -73 21 -73 5 0 9 23 9 50 0 38 -4 50 -15 50
|
||||
-10 0 -15 -10 -15 -27z"/>
|
||||
<path d="M2872 3603 c4 -75 5 -78 29 -78 23 0 24 3 27 78 l3 77 -31 0 -32 0 4
|
||||
-77z m48 -55 c0 -5 -4 -8 -10 -8 -5 0 -10 10 -10 23 0 18 2 19 10 7 5 -8 10
|
||||
-18 10 -22z"/>
|
||||
<path d="M4791 3651 c-14 -4 -27 -13 -29 -20 -3 -10 1 -12 17 -8 27 7 38 -9
|
||||
11 -18 -11 -3 -20 -12 -20 -19 0 -33 14 -76 24 -76 16 1 106 68 106 80 0 6 -7
|
||||
10 -15 10 -11 0 -13 8 -8 30 5 29 4 30 -28 29 -19 -1 -45 -4 -58 -8z"/>
|
||||
<path d="M3685 3578 c4 -18 9 -36 12 -40 8 -15 23 -8 23 11 0 10 10 26 23 35
|
||||
l22 17 -22 -5 c-13 -2 -23 0 -23 5 0 5 -9 9 -21 9 -18 0 -20 -4 -14 -32z"/>
|
||||
<path d="M3870 3586 c0 -14 5 -28 10 -31 6 -3 10 0 10 9 0 8 3 21 6 30 4 11 1
|
||||
16 -10 16 -10 0 -16 -9 -16 -24z"/>
|
||||
<path d="M2750 3520 c-11 -6 -15 -20 -12 -49 l4 -41 64 0 c60 0 84 13 49 26
|
||||
-8 4 -15 12 -15 20 0 8 -3 13 -7 12 -5 -2 -9 2 -10 7 -2 6 2 10 9 10 6 0 13 6
|
||||
16 13 4 14 -74 17 -98 2z m50 -35 c0 -8 -7 -15 -15 -15 -26 0 -18 20 13 29 1
|
||||
1 2 -6 2 -14z"/>
|
||||
<path d="M4010 3492 c0 -16 32 -12 37 5 3 7 -4 11 -16 10 -12 -1 -21 -7 -21
|
||||
-15z"/>
|
||||
<path d="M2646 3445 c4 -8 8 -15 10 -15 2 0 4 7 4 15 0 8 -4 15 -10 15 -5 0
|
||||
-7 -7 -4 -15z"/>
|
||||
<path d="M4320 3410 c0 -5 -7 -10 -15 -10 -8 0 -15 -7 -15 -15 0 -12 5 -13 18
|
||||
-7 9 5 23 7 30 5 6 -3 12 0 12 6 0 6 -5 11 -11 11 -5 0 -7 5 -4 10 3 6 1 10
|
||||
-4 10 -6 0 -11 -4 -11 -10z"/>
|
||||
<path d="M2635 5588 c-22 -12 -35 -28 -35 -42 0 -6 9 0 19 11 11 12 26 23 33
|
||||
26 7 2 11 7 8 10 -3 3 -14 1 -25 -5z"/>
|
||||
<path d="M5410 5772 c0 -4 9 -8 20 -9 11 -1 18 2 15 8 -7 11 -35 12 -35 1z"/>
|
||||
<path d="M2532 4315 c9 -9 88 -13 88 -4 0 5 -21 9 -47 9 -25 0 -44 -2 -41 -5z"/>
|
||||
<path d="M5187 4133 c-40 -4 -49 -8 -57 -29 -6 -14 -23 -33 -40 -42 -29 -16
|
||||
-30 -19 -30 -89 0 -58 3 -73 15 -73 12 0 15 16 16 78 l1 77 10 -55 c5 -30 10
|
||||
-63 11 -72 1 -19 17 -25 17 -7 0 5 5 7 11 3 8 -5 8 -1 0 14 -35 65 26 131 82
|
||||
88 9 -7 17 -24 17 -38 0 -34 5 -37 45 -24 23 7 35 17 35 28 0 23 6 23 32 -2
|
||||
24 -22 38 -26 38 -9 0 21 45 4 48 -18 2 -13 8 -23 13 -23 5 0 9 -7 9 -16 0 -8
|
||||
5 -12 11 -8 8 4 9 -1 4 -17 l-7 -24 20 23 c11 13 23 19 26 13 3 -5 -1 -16 -9
|
||||
-25 -14 -13 -13 -15 3 -13 10 0 18 8 18 16 1 9 5 51 9 94 7 68 6 77 -8 72 -8
|
||||
-4 -23 2 -33 13 -23 24 -97 45 -127 37 -18 -5 -19 -4 -7 5 8 6 33 9 55 8 22
|
||||
-1 49 3 60 10 16 9 -7 11 -110 10 -71 -1 -152 -3 -178 -5z m316 -133 c-7 -28
|
||||
-13 -25 -13 6 0 14 4 23 9 20 5 -3 7 -15 4 -26z"/>
|
||||
<path d="M5421 3944 c0 -11 3 -14 6 -6 3 7 2 16 -1 19 -3 4 -6 -2 -5 -13z"/>
|
||||
<path d="M5604 3845 c8 -8 18 -15 22 -15 3 0 1 7 -6 15 -7 8 -17 15 -22 15 -5
|
||||
0 -3 -7 6 -15z"/>
|
||||
<path d="M5416 3813 c-3 -4 -6 -30 -6 -60 0 -50 -1 -53 -25 -53 -14 0 -28 6
|
||||
-31 14 -4 10 -16 12 -37 9 -40 -6 -39 -5 -43 -45 -2 -17 -10 -35 -17 -40 -6
|
||||
-4 33 -8 88 -8 110 0 131 7 121 38 -5 15 0 28 15 43 l22 22 -6 -31 c-8 -39 -5
|
||||
-39 28 -7 42 43 28 75 -28 66 -4 -1 -10 6 -13 14 -7 18 -59 47 -68 38z m4
|
||||
-147 c0 -11 -19 -15 -25 -6 -3 5 1 10 9 10 9 0 16 -2 16 -4z"/>
|
||||
<path d="M5149 3716 c-2 -2 -20 -6 -39 -7 -46 -5 -54 -18 -24 -42 14 -11 23
|
||||
-26 20 -34 -4 -8 -1 -11 5 -7 6 3 9 15 6 25 -4 16 1 19 26 20 18 1 35 1 40 0
|
||||
9 -1 9 12 1 33 -6 15 -25 21 -35 12z"/>
|
||||
<path d="M5170 3645 c0 -8 5 -15 10 -15 6 0 10 7 10 15 0 8 -4 15 -10 15 -5 0
|
||||
-10 -7 -10 -15z"/>
|
||||
<path d="M2992 3540 c0 -14 2 -19 5 -12 2 6 2 18 0 25 -3 6 -5 1 -5 -13z"/>
|
||||
<path d="M4780 3131 c0 -6 5 -13 10 -16 6 -3 10 1 10 9 0 9 -4 16 -10 16 -5 0
|
||||
-10 -4 -10 -9z"/>
|
||||
<path d="M2948 3343 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||
<path d="M4178 3143 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||
<path d="M3855 3080 c3 -5 15 -10 26 -10 11 0 17 5 14 10 -3 6 -15 10 -26 10
|
||||
-11 0 -17 -4 -14 -10z"/>
|
||||
<path d="M4210 3036 c0 -9 0 -19 -1 -23 0 -4 4 -9 10 -11 14 -5 14 35 1 43 -5
|
||||
3 -10 -1 -10 -9z"/>
|
||||
<path d="M4158 3023 c-7 -25 6 -53 14 -31 3 7 2 22 -2 32 -6 19 -7 19 -12 -1z"/>
|
||||
<path d="M3932 2854 c-10 -12 -10 -14 2 -14 17 0 30 16 19 23 -5 3 -14 -1 -21
|
||||
-9z"/>
|
||||
<path d="M4108 2843 c7 -3 16 -2 19 1 4 3 -2 6 -13 5 -11 0 -14 -3 -6 -6z"/>
|
||||
<path d="M5020 6693 c-52 -31 -89 -58 -82 -61 16 -5 15 -22 -2 -22 -10 0 -11
|
||||
-10 -5 -47 13 -80 34 -128 54 -125 48 9 118 116 129 197 4 28 10 65 13 83 3
|
||||
17 1 32 -3 32 -5 0 -52 -26 -104 -57z"/>
|
||||
<path d="M5146 6724 c-12 -42 -25 -149 -18 -155 14 -14 142 -22 142 -10 0 10
|
||||
-89 151 -110 175 -5 4 -11 0 -14 -10z"/>
|
||||
<path d="M3637 6690 c-13 -15 -14 -20 -3 -20 7 0 16 9 19 20 3 11 4 20 3 20
|
||||
-1 0 -9 -9 -19 -20z"/>
|
||||
<path d="M2878 6284 c-16 -8 -28 -16 -28 -18 0 -2 16 -6 35 -8 31 -4 35 -1 35
|
||||
19 0 27 -5 28 -42 7z"/>
|
||||
<path d="M6233 5347 c-5 -40 -7 -79 -5 -89 5 -21 19 -17 165 45 26 12 37 27
|
||||
17 27 -5 0 -34 16 -65 35 -30 19 -65 39 -79 45 -24 9 -24 8 -33 -63z"/>
|
||||
<path d="M1585 4759 c-5 -24 -45 -330 -45 -349 0 -6 33 -10 73 -10 68 0 72 1
|
||||
73 23 0 12 4 58 8 102 l7 80 -55 89 c-48 77 -56 86 -61 65z"/>
|
||||
<path d="M5904 3102 c-28 -15 -82 -46 -120 -70 -38 -24 -116 -71 -173 -105
|
||||
-57 -34 -104 -67 -103 -72 2 -19 145 -204 154 -199 4 3 8 22 9 42 0 26 3 31 8
|
||||
19 5 -15 30 18 111 145 164 257 171 268 168 268 -2 0 -26 -12 -54 -28z"/>
|
||||
<path d="M2071 3082 c10 -25 143 -247 215 -357 l80 -124 48 48 c27 27 53 59
|
||||
60 72 7 16 23 26 46 29 19 4 43 11 54 17 18 10 18 11 -1 30 -18 18 -174 109
|
||||
-358 208 -38 21 -87 49 -109 63 -21 13 -37 19 -35 14z"/>
|
||||
<path d="M5315 2724 c-63 -30 -826 -360 -960 -414 l-140 -58 -52 -73 c-28 -41
|
||||
-73 -102 -99 -137 -26 -34 -45 -65 -42 -67 5 -5 482 195 754 315 61 27 182 76
|
||||
270 108 87 33 166 63 175 66 15 7 149 177 149 190 0 14 -25 1 -181 -97 -90
|
||||
-57 -189 -119 -219 -138 -30 -19 -62 -36 -70 -38 -40 -11 -70 -12 -84 -4 -11
|
||||
6 -4 8 24 8 45 0 62 12 37 26 -9 6 -17 18 -17 27 0 30 -19 41 -51 30 -16 -5
|
||||
-34 -8 -40 -6 -12 4 104 47 435 162 103 35 190 67 193 70 2 2 0 14 -7 25 -12
|
||||
24 -33 26 -75 5z m-535 -288 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16
|
||||
21 21 21 13z"/>
|
||||
<path d="M2692 2669 c-10 -38 -9 -41 14 -49 48 -18 126 -24 134 -9 5 7 10 11
|
||||
12 9 2 -3 20 -30 39 -60 20 -30 63 -89 96 -130 55 -70 64 -77 129 -99 38 -13
|
||||
85 -32 104 -42 40 -21 369 -161 448 -191 29 -11 63 -18 74 -15 12 3 35 -1 52
|
||||
-9 22 -11 10 5 -44 57 -95 92 -78 81 89 -53 74 -59 138 -108 143 -108 16 0 -3
|
||||
162 -22 189 -9 14 -70 48 -146 83 -114 53 -732 322 -904 393 -36 15 -90 38
|
||||
-121 51 -77 33 -85 31 -97 -17z"/>
|
||||
<path d="M1848 1513 c0 -5 -2 -20 -2 -35 -2 -26 1 -28 40 -28 34 0 44 4 49 20
|
||||
4 12 1 27 -5 35 -13 15 -79 21 -82 8z"/>
|
||||
<path d="M1852 1401 c-8 -5 -12 -22 -10 -42 3 -30 7 -34 35 -37 44 -4 73 13
|
||||
73 44 0 35 -63 58 -98 35z"/>
|
||||
<path d="M2374 1506 c-13 -33 0 -51 36 -51 32 0 35 2 35 30 0 27 -4 30 -33 33
|
||||
-22 2 -34 -2 -38 -12z"/>
|
||||
<path d="M2372 1388 c-30 -30 -3 -72 44 -66 34 4 53 31 38 56 -13 21 -64 28
|
||||
-82 10z"/>
|
||||
<path d="M2740 1465 c0 -44 1 -45 33 -45 37 0 51 8 60 33 12 33 -10 57 -53 57
|
||||
l-40 0 0 -45z"/>
|
||||
<path d="M3268 1440 l-16 -50 35 0 c32 0 35 2 29 25 -8 32 -25 75 -29 75 -2 0
|
||||
-10 -22 -19 -50z"/>
|
||||
<path d="M4013 1496 c-24 -21 -28 -31 -27 -77 0 -44 5 -56 29 -76 21 -18 35
|
||||
-23 54 -18 46 11 63 37 63 96 0 45 -4 56 -26 76 -34 29 -58 29 -93 -1z"/>
|
||||
<path d="M4310 1470 c0 -40 0 -40 40 -40 46 0 68 26 50 60 -8 15 -21 20 -50
|
||||
20 -40 0 -40 0 -40 -40z"/>
|
||||
<path d="M5324 1509 c-66 -33 -54 -169 16 -184 41 -9 76 15 89 60 10 38 -1 96
|
||||
-22 113 -20 17 -60 22 -83 11z"/>
|
||||
<path d="M2877 1084 c-4 -4 -7 -20 -7 -36 0 -34 21 -45 59 -32 27 10 36 30 23
|
||||
51 -10 15 -64 28 -75 17z"/>
|
||||
<path d="M4701 1040 c-15 -46 -14 -50 14 -50 29 0 30 6 11 50 l-13 32 -12 -32z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 66 KiB |
|
After Width: | Height: | Size: 632 KiB |
|
After Width: | Height: | Size: 94 KiB |