diff --git a/apps/driver_new/.gitignore b/apps/driver_new/.gitignore new file mode 100644 index 0000000..3820a95 --- /dev/null +++ b/apps/driver_new/.gitignore @@ -0,0 +1,45 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.build/ +.buildlog/ +.history +.svn/ +.swiftpm/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ +/coverage/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/apps/driver_new/.metadata b/apps/driver_new/.metadata new file mode 100644 index 0000000..d31e83a --- /dev/null +++ b/apps/driver_new/.metadata @@ -0,0 +1,33 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "90673a4eef275d1a6692c26ac80d6d746d41a73a" + channel: "stable" + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 90673a4eef275d1a6692c26ac80d6d746d41a73a + base_revision: 90673a4eef275d1a6692c26ac80d6d746d41a73a + - platform: android + create_revision: 90673a4eef275d1a6692c26ac80d6d746d41a73a + base_revision: 90673a4eef275d1a6692c26ac80d6d746d41a73a + - platform: ios + create_revision: 90673a4eef275d1a6692c26ac80d6d746d41a73a + base_revision: 90673a4eef275d1a6692c26ac80d6d746d41a73a + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/apps/driver_new/README.md b/apps/driver_new/README.md new file mode 100644 index 0000000..cdd8c94 --- /dev/null +++ b/apps/driver_new/README.md @@ -0,0 +1,17 @@ +# driver_new + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Learn Flutter](https://docs.flutter.dev/get-started/learn-flutter) +- [Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Flutter learning resources](https://docs.flutter.dev/reference/learning-resources) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/apps/driver_new/analysis_options.yaml b/apps/driver_new/analysis_options.yaml new file mode 100644 index 0000000..0d29021 --- /dev/null +++ b/apps/driver_new/analysis_options.yaml @@ -0,0 +1,28 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at https://dart.dev/lints. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/apps/driver_new/android/.gitignore b/apps/driver_new/android/.gitignore new file mode 100755 index 0000000..16123b5 --- /dev/null +++ b/apps/driver_new/android/.gitignore @@ -0,0 +1,14 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties +gradle.properties +**/*.keystore +**/*.jks diff --git a/apps/driver_new/android/.settings/org.eclipse.buildship.core.prefs b/apps/driver_new/android/.settings/org.eclipse.buildship.core.prefs new file mode 100644 index 0000000..da0e1b9 --- /dev/null +++ b/apps/driver_new/android/.settings/org.eclipse.buildship.core.prefs @@ -0,0 +1,13 @@ +arguments=--init-script /var/folders/cn/w9j2wl8d11517_kjx3xk_vc00000gn/T/db3b08fc4a9ef609cb16b96b200fa13e563f396e9bb1ed0905fdab7bc3bc513b.gradle --init-script /var/folders/cn/w9j2wl8d11517_kjx3xk_vc00000gn/T/52cde0cfcf3e28b8b7510e992210d9614505e0911af0c190bd590d7158574963.gradle +auto.sync=true +build.scans.enabled=false +connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER) +connection.project.dir= +eclipse.preferences.version=1 +gradle.user.home= +java.home=/Users/hamzaaleghwairyeen/Library/Java/JavaVirtualMachines/openjdk-22.0.2/Contents/Home +jvm.arguments= +offline.mode=false +override.workspace.settings=true +show.console.view=true +show.executions.view=true diff --git a/apps/driver_new/android/app/build.gradle b/apps/driver_new/android/app/build.gradle new file mode 100755 index 0000000..4509918 --- /dev/null +++ b/apps/driver_new/android/app/build.gradle @@ -0,0 +1,130 @@ +plugins { + id "com.android.application" + // START: FlutterFire Configuration + id 'com.google.gms.google-services' + // END: FlutterFire Configuration + id "org.jetbrains.kotlin.android" + id "dev.flutter.flutter-gradle-plugin" +} + +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def keystoreProperties = new Properties() +def keystorePropertiesFile = rootProject.file('key.properties') +if (keystorePropertiesFile.exists()) { + keystorePropertiesFile.withReader("UTF-8") { reader -> + keystoreProperties.load(reader) + } +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') ?: '12' +def flutterVersionName = localProperties.getProperty('flutter.versionName') ?: '1.1.2' + +android { + namespace "com.sefer_driver" + compileSdk = 36 + ndkVersion "29.0.14033849" + + externalNativeBuild { + cmake { + path "src/main/cpp/CMakeLists.txt" + version "3.22.1" + } + } + // + + defaultConfig { + applicationId "com.sefer_driver" + minSdk 29 + targetSdk 36 + versionCode 152 + versionName '2.0.152' + multiDexEnabled true + ndk { + abiFilters "armeabi-v7a", "arm64-v8a" + } + externalNativeBuild { + cmake { + arguments "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON" + } + } + // استدعاء المفتاح من ملف key.properties + manifestPlaceholders += [mapsApiKey: keystoreProperties['mapsApiKey'] ?: ""] + + } + + signingConfigs { + release { + // Defensively check if properties exist to avoid NullPointerException in BundleTool + if (keystoreProperties.isEmpty()) { + println "BUILD_LOG: ERROR - No properties found in key.properties. Release build will fail." + } else { + storeFile = keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null + storePassword = keystoreProperties['storePassword'] + keyAlias = keystoreProperties['keyAlias'] + keyPassword = keystoreProperties['keyPassword'] + + // Final check to ensure no crucial signing variable is null + if (!storeFile || !storePassword || !keyAlias || !keyPassword) { + println "BUILD_LOG: ERROR - One or more signing properties are NULL. Check key.properties." + } + } + } + } + + buildTypes { + release { + // Only assign signingConfig if the release config is valid + signingConfig signingConfigs.release + + minifyEnabled true + shrinkResources true + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + coreLibraryDesugaringEnabled true + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_17 + } + + sourceSets { + main { + java.srcDirs += 'src/main/kotlin' + jniLibs.srcDirs = ['src/main/jniLibs'] + } + } +} + +flutter { + source '../..' +} + + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + // تمت الترقية لتطابق تطبيق الراكب + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5' + + // تمت الترقية لتطابق تطبيق الراكب (لتجنب ملفات 4KB القديمة) + implementation "com.stripe:stripe-android:21.4.2" + implementation 'com.stripe:paymentsheet:21.4.2' + + implementation 'com.scottyab:rootbeer-lib:0.1.0' + + // تمت الترقية لتطابق تطبيق الراكب + implementation 'com.google.android.gms:play-services-safetynet:18.1.0' + + implementation "androidx.concurrent:concurrent-futures:1.2.0" +} \ No newline at end of file diff --git a/apps/driver_new/android/app/proguard-rules.pro b/apps/driver_new/android/app/proguard-rules.pro new file mode 100755 index 0000000..9af0b7d --- /dev/null +++ b/apps/driver_new/android/app/proguard-rules.pro @@ -0,0 +1,38 @@ +# Suppress warnings for specific Google ML Kit and Stripe classes +-dontwarn com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions$Builder +-dontwarn com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions +-dontwarn com.google.mlkit.vision.text.devanagari.DevanagariTextRecognizerOptions$Builder +-dontwarn com.google.mlkit.vision.text.devanagari.DevanagariTextRecognizerOptions +-dontwarn com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions$Builder +-dontwarn com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions +-dontwarn com.google.mlkit.vision.text.korean.KoreanTextRecognizerOptions$Builder +-dontwarn com.google.mlkit.vision.text.korean.KoreanTextRecognizerOptions +-dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivity$g +-dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivityStarter$Args +-dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivityStarter$Error +-dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivityStarter +-dontwarn com.stripe.android.pushProvisioning.PushProvisioningEphemeralKeyProvider + +# Keep rules for Google ML Kit +-keep class com.google.mlkit.vision.** { *; } +-keep class com.google.mlkit.vision.text.** { *; } +-keep class com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions { *; } +-keep class com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions$Builder { *; } +-keep class com.google.mlkit.vision.text.devanagari.DevanagariTextRecognizerOptions { *; } +-keep class com.google.mlkit.vision.text.devanagari.DevanagariTextRecognizerOptions$Builder { *; } +-keep class com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions { *; } +-keep class com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions$Builder { *; } +-keep class com.google.mlkit.vision.text.korean.KoreanTextRecognizerOptions { *; } +-keep class com.google.mlkit.vision.text.korean.KoreanTextRecognizerOptions$Builder { *; } + +# Keep rules for Stripe +-keep class com.stripe.android.** { *; } +-keep class com.stripe.android.pushProvisioning.** { *; } +-keep class com.yalantis.ucrop.** { *; } +-keep class com.yalantis.ucrop.util.** { *; } + +# منع قراءة كود RootDetection +#-keep class com.sefer_driver.RootDetection { *; } +-keep class com.sefer_driver.RootDetection { + native ; + } \ No newline at end of file diff --git a/apps/driver_new/android/app/src/debug/AndroidManifest.xml b/apps/driver_new/android/app/src/debug/AndroidManifest.xml new file mode 100755 index 0000000..399f698 --- /dev/null +++ b/apps/driver_new/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/apps/driver_new/android/app/src/main/AndroidManifest.xml b/apps/driver_new/android/app/src/main/AndroidManifest.xml new file mode 100755 index 0000000..d82148f --- /dev/null +++ b/apps/driver_new/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,176 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/driver_new/android/app/src/main/cpp/CMakeLists.txt b/apps/driver_new/android/app/src/main/cpp/CMakeLists.txt new file mode 100755 index 0000000..8c11893 --- /dev/null +++ b/apps/driver_new/android/app/src/main/cpp/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 3.10.2) # 3.10.2 is fine, but no need to go as high as 3.31.5 +project(sefer_driver) # Good + +# Add your C++ source file(s) to create a SHARED library. +add_library(native-lib SHARED native-lib.cpp) + +# Find the Android log library. +find_library(log-lib log) + +# Link your library against the log library. This is essential for debugging. +target_link_libraries(native-lib ${log-lib}) \ No newline at end of file diff --git a/apps/driver_new/android/app/src/main/cpp/native-lib.cpp b/apps/driver_new/android/app/src/main/cpp/native-lib.cpp new file mode 100755 index 0000000..2238fda --- /dev/null +++ b/apps/driver_new/android/app/src/main/cpp/native-lib.cpp @@ -0,0 +1,167 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // Add this line + + +#define LOG_TAG "NativeLib" +#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) + +// Function to check for common root binaries +bool isRooted() { + std::string paths[] = { + "/system/app/Superuser.apk", + "/system/xbin/su", + "/system/bin/su", + "/system/bin/magisk", + "/system/xbin/magisk", + "/sbin/magisk" + }; + + for (const auto &path : paths) { + std::ifstream file(path); + if (file.good()) { + return true; + } + } + return false; +} + +// Function to check for the presence of files or directories commonly associated with Frida. +bool checkFridaFiles() { + std::string fridaFiles[] = { + "/data/local/tmp/re.frida.server", //Common Frida server path + "/data/local/tmp/frida-server", + "/usr/lib/libfrida-gadget.so", // Frida gadget (injected library) + "/usr/lib64/libfrida-gadget.so", + "/data/local/re.frida.server", + + }; + + for (const auto &path : fridaFiles) { + if (access(path.c_str(), F_OK) != -1) { + LOGE("Frida file detected: %s", path.c_str()); + return true; + } + } + return false; +} + +// Checks for open ports commonly used by Frida. This is less reliable, as ports can be changed. +bool checkFridaPorts() { + int sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == -1) { + return false; // Couldn't create socket, not a strong indicator. + } + + sockaddr_in sa; + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_port = htons(27042); // Default Frida port + inet_pton(AF_INET, "127.0.0.1", &sa.sin_addr); + + if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) != -1) { + LOGE("Frida default port (27042) is open."); + close(sock); + return true; + } + + close(sock); + return false; +} + +// Check the maps file of the current process for any suspicious entries. +bool checkMaps() { + std::ifstream mapsFile("/proc/self/maps"); + std::string line; + + if (mapsFile.is_open()) { + while (std::getline(mapsFile, line)) { + // Look for lines that indicate injected libraries, especially Frida. + if (line.find("frida") != std::string::npos || + line.find("gum-js-") != std::string::npos) { // Gum is Frida's JavaScript engine + LOGE("Suspicious entry in /proc/self/maps: %s", line.c_str()); + return true; + } + } + mapsFile.close(); + } else + { + LOGE("Could not open /proc/self/maps"); + return false; + } + return false; +} + +// Check loaded modules. +bool checkLoadedModules() { + bool found = false; + dl_iterate_phdr([](struct dl_phdr_info *info, size_t size, void *data) { + bool *found_ptr = static_cast(data); + if (std::string(info->dlpi_name).find("frida") != std::string::npos) { + LOGE("Frida module detected: %s", info->dlpi_name); + *found_ptr = true; + return 1; // Stop iterating + } + return 0; // Continue iterating + }, &found); + + return found; +} + + +// This is a simple ptrace check. More sophisticated checks are possible (and necessary for robust detection). +//bool checkPtrace() { +// // Attempt to ptrace ourselves. If another process is already tracing us, this will fail. +// if (ptrace(PTRACE_TRACEME, 0, 1, 0) < 0) { +// LOGE("ptrace failed. Debugger or tracer detected."); +// return true; // Likely being traced +// } +// // Detach. If attached, need to detach to not interfere. +// ptrace(PTRACE_DETACH, 0, 0, 0); +// return false; +//} + +extern "C" +JNIEXPORT jboolean JNICALL +Java_com_sefer_1driver_RootDetection_isNativeRooted(JNIEnv *env, jobject /* this */) { + + if (isRooted()) { + return JNI_TRUE; + } + + if (checkFridaFiles()) { + return JNI_TRUE; + } + + if (checkFridaPorts()) { + return JNI_TRUE; + } + if (checkMaps()) { + return JNI_TRUE; + } + + if (checkLoadedModules()) { + return JNI_TRUE; + } + +// if (checkPtrace()) { +// return JNI_TRUE; +// } + + return JNI_FALSE; +} \ No newline at end of file diff --git a/apps/driver_new/android/app/src/main/java/com/sefer_driver/MyFirebaseMessagingService.kt b/apps/driver_new/android/app/src/main/java/com/sefer_driver/MyFirebaseMessagingService.kt new file mode 100755 index 0000000..6fb47a0 --- /dev/null +++ b/apps/driver_new/android/app/src/main/java/com/sefer_driver/MyFirebaseMessagingService.kt @@ -0,0 +1,15 @@ +package com.sefer_driver + +import android.app.IntentService +import android.content.Intent +import android.content.Context + +// TODO: Rename actions, choose action names that describe tasks that this +// IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS +private const val ACTION_FOO = "com.sefer_driver.action.FOO" +private const val ACTION_BAZ = "com.sefer_driver.action.BAZ" + +// TODO: Rename parameters +private const val EXTRA_PARAM1 = "com.sefer_driver.extra.PARAM1" +private const val EXTRA_PARAM2 = "com.sefer_driver.extra.PARAM2" + diff --git a/apps/driver_new/android/app/src/main/kotlin/com/sefer_driver/MainActivity.kt b/apps/driver_new/android/app/src/main/kotlin/com/sefer_driver/MainActivity.kt new file mode 100755 index 0000000..c79a62a --- /dev/null +++ b/apps/driver_new/android/app/src/main/kotlin/com/sefer_driver/MainActivity.kt @@ -0,0 +1,190 @@ +package com.sefer_driver + +import android.app.AlertDialog +import android.content.Intent +import android.os.Bundle +import android.util.Log +import android.widget.LinearLayout +import android.widget.ProgressBar +import android.widget.TextView +import androidx.core.view.setPadding +import com.scottyab.rootbeer.RootBeer +import io.flutter.embedding.android.FlutterFragmentActivity +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.plugin.common.MethodChannel +import java.io.File +import java.util.Timer +import kotlin.concurrent.schedule + +class MainActivity : FlutterFragmentActivity() { + private val SECURITY_CHANNEL = "com.sefer_driver/security" + private val APP_CONTROL_CHANNEL = "com.sefer_driver/app_control" + + // 🔴 1. تعريف القناة لتكون متاحة للوصول من الدوال الأخرى + private var appControlChannel: MethodChannel? = null + + override fun configureFlutterEngine(flutterEngine: FlutterEngine) { + super.configureFlutterEngine(flutterEngine) + + // 🔴 2. تهيئة القناة هنا + appControlChannel = + MethodChannel(flutterEngine.dartExecutor.binaryMessenger, APP_CONTROL_CHANNEL) + + // Channel for security checks (isRooted) + MethodChannel(flutterEngine.dartExecutor.binaryMessenger, SECURITY_CHANNEL) + .setMethodCallHandler { call, result -> + when (call.method) { + "isNativeRooted" -> result.success(isDeviceCompromised()) + else -> result.notImplemented() + } + } + + // Channel for app control (bringing to foreground & overlay events) + appControlChannel?.setMethodCallHandler { call, result -> + when (call.method) { + "bringToForeground" -> { + Log.d("MainActivity", "Received bringToForeground request") + val intent = + Intent(this, MainActivity::class.java).apply { + action = Intent.ACTION_MAIN + addCategory(Intent.CATEGORY_LAUNCHER) + addFlags( + Intent.FLAG_ACTIVITY_NEW_TASK or + Intent.FLAG_ACTIVITY_CLEAR_TOP or + Intent.FLAG_ACTIVITY_SINGLE_TOP + ) + } + try { + startActivity(intent) + Log.d("MainActivity", "App brought to foreground successfully") + result.success(true) + } catch (e: Exception) { + Log.e("MainActivity", "Error bringing app to foreground", e) + result.error("ACTIVITY_START_FAILED", e.message, e.stackTraceToString()) + } + } + else -> result.notImplemented() + } + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + Log.d("MainActivity", "MainActivity onCreate") + if (isDeviceCompromised()) { + showSecurityWarningDialog() + } + + // 🔴 3. فحص نية فتح التطبيق (هل جاء من زر قبول النافذة؟) + checkIntentForOverlayAccept(intent) + } + + override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + setIntent(intent) + Log.d("MainActivity", "Received new intent: ${intent.action}") + + // 🔴 4. فحص نية التطبيق عند الفتح من الخلفية + checkIntentForOverlayAccept(intent) + } + + // ========================================================================= + // 🔴 5. الدالة السحرية لالتقاط زر القبول وإرساله للـ Flutter 🔴 + // ========================================================================= + private fun checkIntentForOverlayAccept(intent: Intent) { + val acceptedTripId = intent.getStringExtra("acceptedTripId") + if (acceptedTripId != null) { + Log.d("MainActivity", "✅ Trip accepted via Native Intent: $acceptedTripId") + // إرسال الإشارة عبر القناة لتطبيق فلاتر + appControlChannel?.invokeMethod("onOverlayTripAccepted", acceptedTripId) + // مسح البيانات حتى لا تتكرر العملية إذا أغلق السائق التطبيق وفتحه يدوياً + intent.removeExtra("acceptedTripId") + } + } + + // ========================================================================= + // --- دوال الحماية الخاصة بك (لم يتم المساس بها) --- + // ========================================================================= + private fun isDeviceCompromised(): Boolean { + return try { + val isRootedByRootBeer = RootBeer(this).isRooted + Log.d("MainActivity", "Root check result: $isRootedByRootBeer") + isRootedByRootBeer + } catch (e: Exception) { + Log.e("MainActivity", "Security check error: ${e.message}", e) + true // Fail-safe: assume compromised if check fails + } + } + + private fun showSecurityWarningDialog() { + var secondsRemaining = 10 + val progressBar = + ProgressBar(this, null, android.R.attr.progressBarStyleHorizontal).apply { + max = 10 + progress = 10 + } + val textView = + TextView(this).apply { + text = getString(R.string.security_warning_message) + textAlignment = TextView.TEXT_ALIGNMENT_CENTER + } + val layout = + LinearLayout(this).apply { + orientation = LinearLayout.VERTICAL + setPadding(48) + addView(textView) + addView(progressBar) + } + val dialog = + AlertDialog.Builder(this) + .setTitle(getString(R.string.security_warning_title)) + .setView(layout) + .setCancelable(false) + .create() + dialog.show() + val timer = Timer() + timer.schedule(0, 1000) { + secondsRemaining-- + runOnUiThread { + progressBar.progress = secondsRemaining + if (secondsRemaining <= 0) { + timer.cancel() + dialog.dismiss() + clearAppDataAndExit() + } + } + } + } + + private fun clearAppDataAndExit() { + try { + Runtime.getRuntime().exec("pm clear $packageName") + Log.d("MainActivity", "Cleared app data via package manager") + } catch (e: Exception) { + Log.e("MainActivity", "Error clearing app data: ${e.message}", e) + clearCache() + clearAppData() + } + finishAffinity() + System.exit(0) + } + + private fun clearCache() { + deleteDir(cacheDir) + deleteDir(externalCacheDir) + Log.d("MainActivity", "Cleared cache directories") + } + + private fun clearAppData() { + Log.d("MainActivity", "App data clearing skipped (commented out)") + } + + private fun deleteDir(dir: File?): Boolean { + if (dir != null && dir.isDirectory) { + dir.list()?.forEach { deleteDir(File(dir, it)) } + } + val deleted = dir?.delete() ?: false + Log.d("MainActivity", "Deleted directory ${dir?.path}: $deleted") + return deleted + } +} diff --git a/apps/driver_new/android/app/src/main/kotlin/com/sefer_driver/MyApplication.kt b/apps/driver_new/android/app/src/main/kotlin/com/sefer_driver/MyApplication.kt new file mode 100755 index 0000000..75b7ece --- /dev/null +++ b/apps/driver_new/android/app/src/main/kotlin/com/sefer_driver/MyApplication.kt @@ -0,0 +1,41 @@ +package com.sefer_driver + +import android.app.Application +import android.content.Intent +import io.flutter.embedding.engine.FlutterEngine +import io.flutter.embedding.engine.dart.DartExecutor +import io.flutter.plugin.common.MethodChannel + +class MyApplication : Application() { + companion object { + lateinit var instance: MyApplication + private set + + val flutterEngine: FlutterEngine by lazy { + FlutterEngine(instance).apply { + dartExecutor.executeDartEntrypoint(DartExecutor.DartEntrypoint.createDefault()) + } + } + } + + override fun onCreate() { + super.onCreate() + instance = this + + MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "com.sefer_driver/app_lifecycle") + .setMethodCallHandler { call, result -> + if (call.method == "bringAppToForeground") { + bringAppToForeground() + result.success(null) + } else { + result.notImplemented() + } + } + } + + private fun bringAppToForeground() { + val intent = Intent(applicationContext, MainActivity::class.java) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_REORDER_TO_FRONT) + startActivity(intent) + } +} diff --git a/apps/driver_new/android/app/src/main/kotlin/com/sefer_driver/RootDetection.kt b/apps/driver_new/android/app/src/main/kotlin/com/sefer_driver/RootDetection.kt new file mode 100755 index 0000000..7dbadd6 --- /dev/null +++ b/apps/driver_new/android/app/src/main/kotlin/com/sefer_driver/RootDetection.kt @@ -0,0 +1,10 @@ + +package com.sefer_driver + +object RootDetection { + init { + System.loadLibrary("native-lib") // Load the native library + } + + external fun isNativeRooted(): Boolean // Declare the external function +} diff --git a/apps/driver_new/android/app/src/main/kotlin/com/sefer_driver/SafetyNetCheck.kt b/apps/driver_new/android/app/src/main/kotlin/com/sefer_driver/SafetyNetCheck.kt new file mode 100755 index 0000000..1b8593b --- /dev/null +++ b/apps/driver_new/android/app/src/main/kotlin/com/sefer_driver/SafetyNetCheck.kt @@ -0,0 +1,109 @@ +import android.content.Context +import android.util.Base64 +import android.util.Log +import com.google.android.gms.safetynet.SafetyNet +import com.google.android.gms.safetynet.SafetyNetApi +import com.google.android.gms.tasks.OnFailureListener +import com.google.android.gms.tasks.OnSuccessListener +import org.json.JSONObject +import java.io.IOException +import java.security.GeneralSecurityException +import java.security.SecureRandom +import java.util.Arrays + +object SafetyNetCheck { + + private const val TAG = "SafetyNetCheck" + + fun checkSafetyNet(context: Context, apiKey: String, callback: (Boolean) -> Unit) { + // Generate a nonce. A good nonce is large, random, and used only once. + val nonce = generateNonce() + + SafetyNet.getClient(context).attest(nonce, apiKey) + .addOnSuccessListener { response -> + // Success! Now, *verify* the response. + val jwsResult = response.jwsResult + if (jwsResult != null) { + try { + val isSafe = SafetyNetResponseVerifier.verify(jwsResult) + Log.d(TAG, "SafetyNet verification result: $isSafe") + callback(isSafe) // Now passing a *verified* result. + } catch (e: Exception) { + Log.e(TAG, "Error verifying SafetyNet response: ${e.message}", e) + callback(false) // Treat verification errors as failures. + } + } else { + Log.e(TAG, "SafetyNet jwsResult is null") + callback(false) // Null result is a failure. + } + } + .addOnFailureListener { e -> + Log.e(TAG, "SafetyNet attest API call failed: ${e.message}", e) + callback(false) // API call failure. + } + } + + + // Helper function to generate a nonce. + private fun generateNonce(): ByteArray { + val byteGenerator = SecureRandom() + val nonce = ByteArray(32) + byteGenerator.nextBytes(nonce) + return nonce + } +} + + + +// Helper class to verify the SafetyNet response. +object SafetyNetResponseVerifier { + + private const val TAG = "SafetyNetVerifier" + + // This method *must* be implemented on a *backend server* for real security. + // This is just a *simplified example* for demonstration purposes and is + // *not* suitable for production without a backend check. + @Throws(GeneralSecurityException::class, IOException::class) + fun verify(jwsResult: String): Boolean { + // 1. Parse the JWS: Split into header, payload, and signature. + val parts = jwsResult.split(".") + if (parts.size != 3) { + Log.e(TAG, "Invalid JWS format") + return false // Invalid JWS format + } + + val header = parts[0] + val payload = parts[1] + val signature = parts[2] + + // 2. Decode the payload (it's Base64 encoded). + val decodedPayload = Base64.decode(payload, Base64.DEFAULT) + val payloadJson = JSONObject(String(decodedPayload)) + + // 3. Check the ctsProfileMatch and basicIntegrity. + val ctsProfileMatch = payloadJson.optBoolean("ctsProfileMatch", false) + val basicIntegrity = payloadJson.optBoolean("basicIntegrity", false) + + Log.d(TAG, "ctsProfileMatch: $ctsProfileMatch, basicIntegrity: $basicIntegrity") + + // 4. **CRITICAL: In a real application, you *must* send the JWS to your + // backend server for verification. The server should use the + // Google SafetyNet API (or a library that wraps it) to verify + // the signature and check the fields. This prevents attackers + // from tampering with the response on the device.** + // + // // Example (pseudo-code) of what the backend check would do: + // // GoogleCredential credential = ...; + // // SafetyNet safetyNet = new SafetyNet.Builder(httpTransport, jsonFactory) + // // .setApplicationName("YourAppName") + // // .setHttpRequestInitializer(credential) + // // .build(); + // // SafetyNetApi.VerifyJwsRequest request = safetyNet.safetynet().verifyJws(jwsResult); + // // SafetyNetApi.VerifyJwsResponse response = request.execute(); + // // return response.isValidSignature() && response.getCtsProfileMatch() && response.getBasicIntegrity(); + + // 5. For this *example* (without a backend), we'll just check the fields. + // This is *NOT SECURE* for production! + return ctsProfileMatch && basicIntegrity + } +} \ No newline at end of file diff --git a/apps/driver_new/android/app/src/main/res/drawable-v21/launch_background.xml b/apps/driver_new/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100755 index 0000000..f74085f --- /dev/null +++ b/apps/driver_new/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/apps/driver_new/android/app/src/main/res/drawable/app_icon.png b/apps/driver_new/android/app/src/main/res/drawable/app_icon.png new file mode 100755 index 0000000..c811875 Binary files /dev/null and b/apps/driver_new/android/app/src/main/res/drawable/app_icon.png differ diff --git a/apps/driver_new/android/app/src/main/res/drawable/launch_background.xml b/apps/driver_new/android/app/src/main/res/drawable/launch_background.xml new file mode 100755 index 0000000..f0bf5d4 --- /dev/null +++ b/apps/driver_new/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/apps/driver_new/android/app/src/main/res/drawable/launcher_icon.png b/apps/driver_new/android/app/src/main/res/drawable/launcher_icon.png new file mode 100755 index 0000000..cb1d9cd Binary files /dev/null and b/apps/driver_new/android/app/src/main/res/drawable/launcher_icon.png differ diff --git a/apps/driver_new/android/app/src/main/res/layout/custom_notification.xml b/apps/driver_new/android/app/src/main/res/layout/custom_notification.xml new file mode 100755 index 0000000..b9b0215 --- /dev/null +++ b/apps/driver_new/android/app/src/main/res/layout/custom_notification.xml @@ -0,0 +1,21 @@ + + + + + + + + \ No newline at end of file diff --git a/apps/driver_new/android/app/src/main/res/mipmap-hdpi/launcher_icon.png b/apps/driver_new/android/app/src/main/res/mipmap-hdpi/launcher_icon.png new file mode 100755 index 0000000..d382e98 Binary files /dev/null and b/apps/driver_new/android/app/src/main/res/mipmap-hdpi/launcher_icon.png differ diff --git a/apps/driver_new/android/app/src/main/res/mipmap-mdpi/launcher_icon.png b/apps/driver_new/android/app/src/main/res/mipmap-mdpi/launcher_icon.png new file mode 100755 index 0000000..ba38ec5 Binary files /dev/null and b/apps/driver_new/android/app/src/main/res/mipmap-mdpi/launcher_icon.png differ diff --git a/apps/driver_new/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png b/apps/driver_new/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png new file mode 100755 index 0000000..c00c762 Binary files /dev/null and b/apps/driver_new/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png differ diff --git a/apps/driver_new/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png b/apps/driver_new/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png new file mode 100755 index 0000000..71d0444 Binary files /dev/null and b/apps/driver_new/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png differ diff --git a/apps/driver_new/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png b/apps/driver_new/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png new file mode 100755 index 0000000..f46d9d0 Binary files /dev/null and b/apps/driver_new/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png differ diff --git a/apps/driver_new/android/app/src/main/res/raw/app_icon.png b/apps/driver_new/android/app/src/main/res/raw/app_icon.png new file mode 100755 index 0000000..96cc55a Binary files /dev/null and b/apps/driver_new/android/app/src/main/res/raw/app_icon.png differ diff --git a/apps/driver_new/android/app/src/main/res/raw/cancel.wav b/apps/driver_new/android/app/src/main/res/raw/cancel.wav new file mode 100755 index 0000000..dbe6e7c Binary files /dev/null and b/apps/driver_new/android/app/src/main/res/raw/cancel.wav differ diff --git a/apps/driver_new/android/app/src/main/res/raw/ding.wav b/apps/driver_new/android/app/src/main/res/raw/ding.wav new file mode 100755 index 0000000..c53cd50 Binary files /dev/null and b/apps/driver_new/android/app/src/main/res/raw/ding.wav differ diff --git a/apps/driver_new/android/app/src/main/res/raw/iphone_ringtone.wav b/apps/driver_new/android/app/src/main/res/raw/iphone_ringtone.wav new file mode 100755 index 0000000..aee314f Binary files /dev/null and b/apps/driver_new/android/app/src/main/res/raw/iphone_ringtone.wav differ diff --git a/apps/driver_new/android/app/src/main/res/raw/order.wav b/apps/driver_new/android/app/src/main/res/raw/order.wav new file mode 100755 index 0000000..b2b0ba2 Binary files /dev/null and b/apps/driver_new/android/app/src/main/res/raw/order.wav differ diff --git a/apps/driver_new/android/app/src/main/res/raw/order1.wav b/apps/driver_new/android/app/src/main/res/raw/order1.wav new file mode 100755 index 0000000..919fdda Binary files /dev/null and b/apps/driver_new/android/app/src/main/res/raw/order1.wav differ diff --git a/apps/driver_new/android/app/src/main/res/raw/promo.wav b/apps/driver_new/android/app/src/main/res/raw/promo.wav new file mode 100755 index 0000000..3bb2d03 Binary files /dev/null and b/apps/driver_new/android/app/src/main/res/raw/promo.wav differ diff --git a/apps/driver_new/android/app/src/main/res/raw/start.wav b/apps/driver_new/android/app/src/main/res/raw/start.wav new file mode 100755 index 0000000..0655506 Binary files /dev/null and b/apps/driver_new/android/app/src/main/res/raw/start.wav differ diff --git a/apps/driver_new/android/app/src/main/res/raw/tone1.mp3 b/apps/driver_new/android/app/src/main/res/raw/tone1.mp3 new file mode 100755 index 0000000..e32e61b Binary files /dev/null and b/apps/driver_new/android/app/src/main/res/raw/tone1.mp3 differ diff --git a/apps/driver_new/android/app/src/main/res/raw/tone2.wav b/apps/driver_new/android/app/src/main/res/raw/tone2.wav new file mode 100755 index 0000000..0582d47 Binary files /dev/null and b/apps/driver_new/android/app/src/main/res/raw/tone2.wav differ diff --git a/apps/driver_new/android/app/src/main/res/values-ar/strings.xml b/apps/driver_new/android/app/src/main/res/values-ar/strings.xml new file mode 100755 index 0000000..6b7cb35 --- /dev/null +++ b/apps/driver_new/android/app/src/main/res/values-ar/strings.xml @@ -0,0 +1,6 @@ + + تحذير أمني + تم اكتشاف مشكلة أمنية أو تعديل على هذا الجهاز. لا يمكن تشغيل التطبيق على هذا الجهاز. + إغلاق التطبيق + الجهاز آمن. الاستمرار بشكل طبيعي. + \ No newline at end of file diff --git a/apps/driver_new/android/app/src/main/res/values-night/styles.xml b/apps/driver_new/android/app/src/main/res/values-night/styles.xml new file mode 100755 index 0000000..60a2b7e --- /dev/null +++ b/apps/driver_new/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/apps/driver_new/android/app/src/main/res/values/strings.xml b/apps/driver_new/android/app/src/main/res/values/strings.xml new file mode 100755 index 0000000..e045415 --- /dev/null +++ b/apps/driver_new/android/app/src/main/res/values/strings.xml @@ -0,0 +1,15 @@ + + My App + high_importance_channel + kffk + AIzaSyB04YNW3LbvmQ5lX1t2bOwEU18- + FCM Notifications + Notifications from Firebase Cloud Messaging + Security Warning + A security issue or modification has been detected on + this device. The app cannot run on this device. + Exit App + Device is secure. Proceeding normally. + + + \ No newline at end of file diff --git a/apps/driver_new/android/app/src/main/res/values/styles.xml b/apps/driver_new/android/app/src/main/res/values/styles.xml new file mode 100755 index 0000000..80796a9 --- /dev/null +++ b/apps/driver_new/android/app/src/main/res/values/styles.xml @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/apps/driver_new/android/app/src/main/res/xml/network_security_config.xml b/apps/driver_new/android/app/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..7328fde --- /dev/null +++ b/apps/driver_new/android/app/src/main/res/xml/network_security_config.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + tripz-egypt.com + + + + + + + + + + + \ No newline at end of file diff --git a/apps/driver_new/android/app/src/profile/AndroidManifest.xml b/apps/driver_new/android/app/src/profile/AndroidManifest.xml new file mode 100755 index 0000000..399f698 --- /dev/null +++ b/apps/driver_new/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/apps/driver_new/android/build.gradle b/apps/driver_new/android/build.gradle new file mode 100755 index 0000000..4b28098 --- /dev/null +++ b/apps/driver_new/android/build.gradle @@ -0,0 +1,52 @@ +buildscript { + ext.kotlin_version = '2.3.10' + repositories { + google() + mavenCentral() + } + dependencies { + classpath 'com.android.tools.build:gradle:8.13.2' + classpath 'com.google.gms:google-services:4.3.15' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = '../build' + +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" + project.evaluationDependsOn(':app') + + def setupAndroid = { + if (project.plugins.hasPlugin('com.android.library') || project.plugins.hasPlugin('com.android.application')) { + project.android { + if (namespace == null || namespace == "") { + namespace = project.group + } + compileSdk 36 + defaultConfig { + targetSdk 36 + } + } + } + } + + if (project.state.executed) { + setupAndroid() + } else { + project.afterEvaluate { + setupAndroid() + } + } +} + +tasks.register("clean", Delete) { + delete rootProject.buildDir +} \ No newline at end of file diff --git a/apps/driver_new/android/gradle/wrapper/gradle-wrapper.properties b/apps/driver_new/android/gradle/wrapper/gradle-wrapper.properties new file mode 100755 index 0000000..a667694 --- /dev/null +++ b/apps/driver_new/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ + + +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-all.zip diff --git a/apps/driver_new/android/settings.gradle b/apps/driver_new/android/settings.gradle new file mode 100755 index 0000000..9dae921 --- /dev/null +++ b/apps/driver_new/android/settings.gradle @@ -0,0 +1,25 @@ +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + }() + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version '8.13.2' apply false + id "com.google.gms.google-services" version "4.3.15" apply false + id "org.jetbrains.kotlin.android" version "2.3.10" apply false +} + +include ":app" + diff --git a/apps/driver_new/assets/aggrement.wav b/apps/driver_new/assets/aggrement.wav new file mode 100644 index 0000000..c82ef23 Binary files /dev/null and b/apps/driver_new/assets/aggrement.wav differ diff --git a/apps/driver_new/assets/alert.wav b/apps/driver_new/assets/alert.wav new file mode 100644 index 0000000..8722536 Binary files /dev/null and b/apps/driver_new/assets/alert.wav differ diff --git a/apps/driver_new/assets/fonts/IBMPlexSansArabic-Bold.ttf b/apps/driver_new/assets/fonts/IBMPlexSansArabic-Bold.ttf new file mode 100644 index 0000000..d67d9e8 Binary files /dev/null and b/apps/driver_new/assets/fonts/IBMPlexSansArabic-Bold.ttf differ diff --git a/apps/driver_new/assets/fonts/IBMPlexSansArabic-Medium.ttf b/apps/driver_new/assets/fonts/IBMPlexSansArabic-Medium.ttf new file mode 100644 index 0000000..09ec8da Binary files /dev/null and b/apps/driver_new/assets/fonts/IBMPlexSansArabic-Medium.ttf differ diff --git a/apps/driver_new/assets/fonts/IBMPlexSansArabic-Regular.ttf b/apps/driver_new/assets/fonts/IBMPlexSansArabic-Regular.ttf new file mode 100644 index 0000000..5e19284 Binary files /dev/null and b/apps/driver_new/assets/fonts/IBMPlexSansArabic-Regular.ttf differ diff --git a/apps/driver_new/assets/fonts/IBMPlexSansArabic-SemiBold.ttf b/apps/driver_new/assets/fonts/IBMPlexSansArabic-SemiBold.ttf new file mode 100644 index 0000000..6b48c75 Binary files /dev/null and b/apps/driver_new/assets/fonts/IBMPlexSansArabic-SemiBold.ttf differ diff --git a/apps/driver_new/assets/fonts/Inter-Bold.ttf b/apps/driver_new/assets/fonts/Inter-Bold.ttf new file mode 100644 index 0000000..15e908f Binary files /dev/null and b/apps/driver_new/assets/fonts/Inter-Bold.ttf differ diff --git a/apps/driver_new/assets/fonts/Inter-Medium.ttf b/apps/driver_new/assets/fonts/Inter-Medium.ttf new file mode 100644 index 0000000..9342730 Binary files /dev/null and b/apps/driver_new/assets/fonts/Inter-Medium.ttf differ diff --git a/apps/driver_new/assets/fonts/Inter-Regular.ttf b/apps/driver_new/assets/fonts/Inter-Regular.ttf new file mode 100644 index 0000000..c544be4 Binary files /dev/null and b/apps/driver_new/assets/fonts/Inter-Regular.ttf differ diff --git a/apps/driver_new/assets/fonts/Inter-SemiBold.ttf b/apps/driver_new/assets/fonts/Inter-SemiBold.ttf new file mode 100644 index 0000000..a32e2b8 Binary files /dev/null and b/apps/driver_new/assets/fonts/Inter-SemiBold.ttf differ diff --git a/apps/driver_new/assets/fonts/digit.ttf b/apps/driver_new/assets/fonts/digit.ttf new file mode 100755 index 0000000..5dbe6f9 Binary files /dev/null and b/apps/driver_new/assets/fonts/digit.ttf differ diff --git a/apps/driver_new/assets/images/1.png b/apps/driver_new/assets/images/1.png new file mode 100644 index 0000000..5cc4c86 Binary files /dev/null and b/apps/driver_new/assets/images/1.png differ diff --git a/apps/driver_new/assets/images/2.png b/apps/driver_new/assets/images/2.png new file mode 100644 index 0000000..69005af Binary files /dev/null and b/apps/driver_new/assets/images/2.png differ diff --git a/apps/driver_new/assets/images/3.png b/apps/driver_new/assets/images/3.png new file mode 100644 index 0000000..4040f40 Binary files /dev/null and b/apps/driver_new/assets/images/3.png differ diff --git a/apps/driver_new/assets/images/4.png b/apps/driver_new/assets/images/4.png new file mode 100644 index 0000000..15b4d56 Binary files /dev/null and b/apps/driver_new/assets/images/4.png differ diff --git a/apps/driver_new/assets/images/5.png b/apps/driver_new/assets/images/5.png new file mode 100644 index 0000000..4440755 Binary files /dev/null and b/apps/driver_new/assets/images/5.png differ diff --git a/apps/driver_new/assets/images/6.png b/apps/driver_new/assets/images/6.png new file mode 100755 index 0000000..23df2c0 Binary files /dev/null and b/apps/driver_new/assets/images/6.png differ diff --git a/apps/driver_new/assets/images/A.png b/apps/driver_new/assets/images/A.png new file mode 100755 index 0000000..246b9d2 Binary files /dev/null and b/apps/driver_new/assets/images/A.png differ diff --git a/apps/driver_new/assets/images/arrow.png b/apps/driver_new/assets/images/arrow.png new file mode 100755 index 0000000..3d3db75 Binary files /dev/null and b/apps/driver_new/assets/images/arrow.png differ diff --git a/apps/driver_new/assets/images/b.png b/apps/driver_new/assets/images/b.png new file mode 100755 index 0000000..b22f96c Binary files /dev/null and b/apps/driver_new/assets/images/b.png differ diff --git a/apps/driver_new/assets/images/brand.png b/apps/driver_new/assets/images/brand.png new file mode 100755 index 0000000..9282720 Binary files /dev/null and b/apps/driver_new/assets/images/brand.png differ diff --git a/apps/driver_new/assets/images/car.png b/apps/driver_new/assets/images/car.png new file mode 100755 index 0000000..5932743 Binary files /dev/null and b/apps/driver_new/assets/images/car.png differ diff --git a/apps/driver_new/assets/images/car_back.png b/apps/driver_new/assets/images/car_back.png new file mode 100755 index 0000000..72c8a89 Binary files /dev/null and b/apps/driver_new/assets/images/car_back.png differ diff --git a/apps/driver_new/assets/images/car_front.png b/apps/driver_new/assets/images/car_front.png new file mode 100755 index 0000000..81c974f Binary files /dev/null and b/apps/driver_new/assets/images/car_front.png differ diff --git a/apps/driver_new/assets/images/cashMTN.png b/apps/driver_new/assets/images/cashMTN.png new file mode 100644 index 0000000..bae958b Binary files /dev/null and b/apps/driver_new/assets/images/cashMTN.png differ diff --git a/apps/driver_new/assets/images/driver_license.png b/apps/driver_new/assets/images/driver_license.png new file mode 100755 index 0000000..aa6a06f Binary files /dev/null and b/apps/driver_new/assets/images/driver_license.png differ diff --git a/apps/driver_new/assets/images/id_back.png b/apps/driver_new/assets/images/id_back.png new file mode 100755 index 0000000..7c4d8d3 Binary files /dev/null and b/apps/driver_new/assets/images/id_back.png differ diff --git a/apps/driver_new/assets/images/id_front.png b/apps/driver_new/assets/images/id_front.png new file mode 100755 index 0000000..290e187 Binary files /dev/null and b/apps/driver_new/assets/images/id_front.png differ diff --git a/apps/driver_new/assets/images/lady1.png b/apps/driver_new/assets/images/lady1.png new file mode 100755 index 0000000..2797b75 Binary files /dev/null and b/apps/driver_new/assets/images/lady1.png differ diff --git a/apps/driver_new/assets/images/logo.gif b/apps/driver_new/assets/images/logo.gif new file mode 100755 index 0000000..5fa1d0d Binary files /dev/null and b/apps/driver_new/assets/images/logo.gif differ diff --git a/apps/driver_new/assets/images/logo.png b/apps/driver_new/assets/images/logo.png new file mode 100755 index 0000000..c811875 Binary files /dev/null and b/apps/driver_new/assets/images/logo.png differ diff --git a/apps/driver_new/assets/images/logo1.png b/apps/driver_new/assets/images/logo1.png new file mode 100755 index 0000000..8507dbc Binary files /dev/null and b/apps/driver_new/assets/images/logo1.png differ diff --git a/apps/driver_new/assets/images/mtn.png b/apps/driver_new/assets/images/mtn.png new file mode 100644 index 0000000..6aa6618 Binary files /dev/null and b/apps/driver_new/assets/images/mtn.png differ diff --git a/apps/driver_new/assets/images/non_id_front.jpeg b/apps/driver_new/assets/images/non_id_front.jpeg new file mode 100755 index 0000000..3108cb3 Binary files /dev/null and b/apps/driver_new/assets/images/non_id_front.jpeg differ diff --git a/apps/driver_new/assets/images/notepad.png b/apps/driver_new/assets/images/notepad.png new file mode 100755 index 0000000..9536a4d Binary files /dev/null and b/apps/driver_new/assets/images/notepad.png differ diff --git a/apps/driver_new/assets/images/on1.png b/apps/driver_new/assets/images/on1.png new file mode 100755 index 0000000..c9881c6 Binary files /dev/null and b/apps/driver_new/assets/images/on1.png differ diff --git a/apps/driver_new/assets/images/on2.png b/apps/driver_new/assets/images/on2.png new file mode 100755 index 0000000..3b6d28c Binary files /dev/null and b/apps/driver_new/assets/images/on2.png differ diff --git a/apps/driver_new/assets/images/on3.png b/apps/driver_new/assets/images/on3.png new file mode 100755 index 0000000..88af4ae Binary files /dev/null and b/apps/driver_new/assets/images/on3.png differ diff --git a/apps/driver_new/assets/images/picker.png b/apps/driver_new/assets/images/picker.png new file mode 100755 index 0000000..6a35bf3 Binary files /dev/null and b/apps/driver_new/assets/images/picker.png differ diff --git a/apps/driver_new/assets/images/s.png b/apps/driver_new/assets/images/s.png new file mode 100755 index 0000000..dd3b7b8 Binary files /dev/null and b/apps/driver_new/assets/images/s.png differ diff --git a/apps/driver_new/assets/images/shamCash.png b/apps/driver_new/assets/images/shamCash.png new file mode 100644 index 0000000..ab13ac0 Binary files /dev/null and b/apps/driver_new/assets/images/shamCash.png differ diff --git a/apps/driver_new/assets/images/shamcashsend.png b/apps/driver_new/assets/images/shamcashsend.png new file mode 100644 index 0000000..0814517 Binary files /dev/null and b/apps/driver_new/assets/images/shamcashsend.png differ diff --git a/apps/driver_new/assets/images/syriatel.jpeg b/apps/driver_new/assets/images/syriatel.jpeg new file mode 100644 index 0000000..331117b Binary files /dev/null and b/apps/driver_new/assets/images/syriatel.jpeg differ diff --git a/apps/driver_new/assets/order.mp3 b/apps/driver_new/assets/order.mp3 new file mode 100755 index 0000000..b2b0ba2 Binary files /dev/null and b/apps/driver_new/assets/order.mp3 differ diff --git a/apps/driver_new/assets/order1.wav b/apps/driver_new/assets/order1.wav new file mode 100755 index 0000000..919fdda Binary files /dev/null and b/apps/driver_new/assets/order1.wav differ diff --git a/apps/driver_new/ios/.gitignore b/apps/driver_new/ios/.gitignore new file mode 100755 index 0000000..7a7f987 --- /dev/null +++ b/apps/driver_new/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/apps/driver_new/ios/Flutter/AppFrameworkInfo.plist b/apps/driver_new/ios/Flutter/AppFrameworkInfo.plist new file mode 100755 index 0000000..7c56964 --- /dev/null +++ b/apps/driver_new/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 12.0 + + diff --git a/apps/driver_new/ios/Flutter/Debug.xcconfig b/apps/driver_new/ios/Flutter/Debug.xcconfig new file mode 100755 index 0000000..ec97fc6 --- /dev/null +++ b/apps/driver_new/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/apps/driver_new/ios/Flutter/Release.xcconfig b/apps/driver_new/ios/Flutter/Release.xcconfig new file mode 100755 index 0000000..c4855bf --- /dev/null +++ b/apps/driver_new/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/apps/driver_new/ios/Podfile b/apps/driver_new/ios/Podfile new file mode 100755 index 0000000..20f45c9 --- /dev/null +++ b/apps/driver_new/ios/Podfile @@ -0,0 +1,59 @@ +platform :ios, '14.0' +$iOSVersion = '14.0' # or your desired version + +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! :linkage => :dynamic + pod 'Firebase', :modular_headers => true + + # Explicitly enable modular headers for firebase_messaging and other Firebase-related pods + pod 'FirebaseMessaging', :modular_headers => true + pod 'FirebaseCore', :modular_headers => true + pod 'FirebaseAuth', :modular_headers => true + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) + + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + installer.pods_project.build_configurations.each do |config| + config.build_settings["EXCLUDED_ARCHS[sdk=*]"] = "armv7" + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = $iOSVersion + end + + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + target.build_configurations.each do |config| + if Gem::Version.new($iOSVersion) > Gem::Version.new(config.build_settings['IPHONEOS_DEPLOYMENT_TARGET']) + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = $iOSVersion + end + end + end +end \ No newline at end of file diff --git a/apps/driver_new/ios/Runner.xcodeproj/project.pbxproj b/apps/driver_new/ios/Runner.xcodeproj/project.pbxproj new file mode 100755 index 0000000..d08eb55 --- /dev/null +++ b/apps/driver_new/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,832 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; + 38BFC4984B1B26A880FE76DE /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AC5295B6ADEC13901A4281A /* Pods_RunnerTests.framework */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 3CEA26D0738D4C4B62323122 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A1987A597103D3E58DD06571 /* Pods_Runner.framework */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + C604FDB02D6C8D6A00CF8873 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = C604FDAF2D6C8D6000CF8873 /* Constants.swift */; }; + C604FDB22D6C953400CF8873 /* JailbreakDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C604FDB12D6C953100CF8873 /* JailbreakDetection.swift */; }; + C604FDB52D6C96D000CF8873 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C604FDB32D6C96D000CF8873 /* Localizable.strings */; }; + C624C4642BD56D34002834AF /* tone1.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = C624C45C2BD56D34002834AF /* tone1.mp3 */; }; + C624C4652BD56D34002834AF /* start.wav in Resources */ = {isa = PBXBuildFile; fileRef = C624C45D2BD56D34002834AF /* start.wav */; }; + C624C4672BD56D34002834AF /* promo.wav in Resources */ = {isa = PBXBuildFile; fileRef = C624C45F2BD56D34002834AF /* promo.wav */; }; + C624C4682BD56D34002834AF /* cancel.wav in Resources */ = {isa = PBXBuildFile; fileRef = C624C4602BD56D34002834AF /* cancel.wav */; }; + C624C4692BD56D34002834AF /* iphone_ringtone.wav in Resources */ = {isa = PBXBuildFile; fileRef = C624C4612BD56D34002834AF /* iphone_ringtone.wav */; }; + C624C46A2BD56D34002834AF /* order1.wav in Resources */ = {isa = PBXBuildFile; fileRef = C624C4622BD56D34002834AF /* order1.wav */; }; + C628BC3F2C31427000E4D33B /* ding.wav in Resources */ = {isa = PBXBuildFile; fileRef = C628BC3E2C31427000E4D33B /* ding.wav */; }; + C638D7C62D884B7A009B4DF9 /* SecurityChecks.m in Sources */ = {isa = PBXBuildFile; fileRef = C638D7C52D884B7A009B4DF9 /* SecurityChecks.m */; }; + C638D7C82D884BE3009B4DF9 /* Config.plist in Resources */ = {isa = PBXBuildFile; fileRef = C638D7C72D884BE2009B4DF9 /* Config.plist */; }; + C690B4752A80554500E1D66E /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = C690B4742A80554500E1D66E /* GoogleService-Info.plist */; }; + C6B15AA12B5FB24600746405 /* order.wav in Resources */ = {isa = PBXBuildFile; fileRef = C6B15A9F2B5FB24600746405 /* order.wav */; }; + C6B15AA22B5FB24600746405 /* tone2.wav in Resources */ = {isa = PBXBuildFile; fileRef = C6B15AA02B5FB24600746405 /* tone2.wav */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97C146ED1CF9000F007C117D; + remoteInfo = Runner; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 0116059C9A3684AC66E6EA10 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + 0A588BA0B74F002C38F0E4F0 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 169535ADE82517D8C1F876D0 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 20CE5C1BB6B23CE4706F0F53 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 2AC5295B6ADEC13901A4281A /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A1987A597103D3E58DD06571 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + C604FDAF2D6C8D6000CF8873 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; + C604FDB12D6C953100CF8873 /* JailbreakDetection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JailbreakDetection.swift; sourceTree = ""; }; + C604FDB42D6C96D000CF8873 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + C624C45C2BD56D34002834AF /* tone1.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; name = tone1.mp3; path = ../../android/app/src/main/res/raw/tone1.mp3; sourceTree = ""; }; + C624C45D2BD56D34002834AF /* start.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = start.wav; path = ../../android/app/src/main/res/raw/start.wav; sourceTree = ""; }; + C624C45F2BD56D34002834AF /* promo.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = promo.wav; path = ../../android/app/src/main/res/raw/promo.wav; sourceTree = ""; }; + C624C4602BD56D34002834AF /* cancel.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = cancel.wav; path = ../../android/app/src/main/res/raw/cancel.wav; sourceTree = ""; }; + C624C4612BD56D34002834AF /* iphone_ringtone.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = iphone_ringtone.wav; path = ../../android/app/src/main/res/raw/iphone_ringtone.wav; sourceTree = ""; }; + C624C4622BD56D34002834AF /* order1.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = order1.wav; path = ../../android/app/src/main/res/raw/order1.wav; sourceTree = ""; }; + C628BC3E2C31427000E4D33B /* ding.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = ding.wav; path = ../../android/app/src/main/res/raw/ding.wav; sourceTree = ""; }; + C638D7C42D884B54009B4DF9 /* SecurityChecks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecurityChecks.h; sourceTree = ""; }; + C638D7C52D884B7A009B4DF9 /* SecurityChecks.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecurityChecks.m; sourceTree = ""; }; + C638D7C72D884BE2009B4DF9 /* Config.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Config.plist; sourceTree = ""; }; + C690B4742A80554500E1D66E /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + C69588332A8C1F6B00C3AC67 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; + C6B15A9F2B5FB24600746405 /* order.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = order.wav; sourceTree = ""; }; + C6B15AA02B5FB24600746405 /* tone2.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = tone2.wav; sourceTree = ""; }; + F13EEC8BD3BD109D175EA06D /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + F8C2B267C197A536F06ED67A /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 7AD318F74F39A70FCC91E66D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 38BFC4984B1B26A880FE76DE /* Pods_RunnerTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 3CEA26D0738D4C4B62323122 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C8082294A63A400263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C807B294A618700263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 5684D45491D29A320AB8001A /* Pods */ = { + isa = PBXGroup; + children = ( + 169535ADE82517D8C1F876D0 /* Pods-Runner.debug.xcconfig */, + F13EEC8BD3BD109D175EA06D /* Pods-Runner.release.xcconfig */, + 20CE5C1BB6B23CE4706F0F53 /* Pods-Runner.profile.xcconfig */, + 0A588BA0B74F002C38F0E4F0 /* Pods-RunnerTests.debug.xcconfig */, + F8C2B267C197A536F06ED67A /* Pods-RunnerTests.release.xcconfig */, + 0116059C9A3684AC66E6EA10 /* Pods-RunnerTests.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 331C8082294A63A400263BE5 /* RunnerTests */, + 5684D45491D29A320AB8001A /* Pods */, + A3767309D6B5681282917CC7 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + 331C8081294A63A400263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + C69588332A8C1F6B00C3AC67 /* Runner.entitlements */, + C638D7C52D884B7A009B4DF9 /* SecurityChecks.m */, + C6B15A9F2B5FB24600746405 /* order.wav */, + C6B15AA02B5FB24600746405 /* tone2.wav */, + C624C4602BD56D34002834AF /* cancel.wav */, + C624C4612BD56D34002834AF /* iphone_ringtone.wav */, + C628BC3E2C31427000E4D33B /* ding.wav */, + C624C4622BD56D34002834AF /* order1.wav */, + C624C45F2BD56D34002834AF /* promo.wav */, + C624C45D2BD56D34002834AF /* start.wav */, + C624C45C2BD56D34002834AF /* tone1.mp3 */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + C690B4742A80554500E1D66E /* GoogleService-Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + C604FDB12D6C953100CF8873 /* JailbreakDetection.swift */, + C604FDB32D6C96D000CF8873 /* Localizable.strings */, + C604FDAF2D6C8D6000CF8873 /* Constants.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + C638D7C42D884B54009B4DF9 /* SecurityChecks.h */, + C638D7C72D884BE2009B4DF9 /* Config.plist */, + ); + path = Runner; + sourceTree = ""; + }; + A3767309D6B5681282917CC7 /* Frameworks */ = { + isa = PBXGroup; + children = ( + A1987A597103D3E58DD06571 /* Pods_Runner.framework */, + 2AC5295B6ADEC13901A4281A /* Pods_RunnerTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C8080294A63A400263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 6A195BB0776CA9E53EAA143A /* [CP] Check Pods Manifest.lock */, + 331C807D294A63A400263BE5 /* Sources */, + 331C807F294A63A400263BE5 /* Resources */, + 7AD318F74F39A70FCC91E66D /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 331C8086294A63A400263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 495F1A7DF9442FE345F87EDB /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 87F758C3C5B8AE624C4BE481 /* [CP] Embed Pods Frameworks */, + 99A28AAD8EACCE6238494873 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C8080294A63A400263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 97C146ED1CF9000F007C117D; + }; + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + 331C8080294A63A400263BE5 /* RunnerTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C807F294A63A400263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C6B15AA22B5FB24600746405 /* tone2.wav in Resources */, + C624C4652BD56D34002834AF /* start.wav in Resources */, + C624C4672BD56D34002834AF /* promo.wav in Resources */, + C624C46A2BD56D34002834AF /* order1.wav in Resources */, + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + C624C4682BD56D34002834AF /* cancel.wav in Resources */, + C6B15AA12B5FB24600746405 /* order.wav in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + C628BC3F2C31427000E4D33B /* ding.wav in Resources */, + C690B4752A80554500E1D66E /* GoogleService-Info.plist in Resources */, + C604FDB52D6C96D000CF8873 /* Localizable.strings in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + C638D7C82D884BE3009B4DF9 /* Config.plist in Resources */, + C624C4692BD56D34002834AF /* iphone_ringtone.wav in Resources */, + C624C4642BD56D34002834AF /* tone1.mp3 in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 495F1A7DF9442FE345F87EDB /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 6A195BB0776CA9E53EAA143A /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 87F758C3C5B8AE624C4BE481 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + 99A28AAD8EACCE6238494873 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C807D294A63A400263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + C638D7C62D884B7A009B4DF9 /* SecurityChecks.m in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + C604FDB02D6C8D6A00CF8873 /* Constants.swift in Sources */, + C604FDB22D6C953400CF8873 /* JailbreakDetection.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; + C604FDB32D6C96D000CF8873 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + C604FDB42D6C96D000CF8873 /* en */, + ); + name = Localizable.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 63CVT8G5P8; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = "Sefer Driver"; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.travel"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.sefer.driver; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 331C8088294A63A400263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0A588BA0B74F002C38F0E4F0 /* Pods-RunnerTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 63CVT8G5P8; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.sefer.driver.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Debug; + }; + 331C8089294A63A400263BE5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = F8C2B267C197A536F06ED67A /* Pods-RunnerTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 63CVT8G5P8; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.sefer.driver.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Release; + }; + 331C808A294A63A400263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0116059C9A3684AC66E6EA10 /* Pods-RunnerTests.profile.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = 63CVT8G5P8; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.sefer.driver.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 63CVT8G5P8; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = "Sefer Driver"; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.travel"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.sefer.driver; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEVELOPMENT_TEAM = 63CVT8G5P8; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = "Sefer Driver"; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.travel"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.sefer.driver; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C8088294A63A400263BE5 /* Debug */, + 331C8089294A63A400263BE5 /* Release */, + 331C808A294A63A400263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/apps/driver_new/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/apps/driver_new/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100755 index 0000000..919434a --- /dev/null +++ b/apps/driver_new/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/apps/driver_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/apps/driver_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100755 index 0000000..18d9810 --- /dev/null +++ b/apps/driver_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/apps/driver_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/apps/driver_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100755 index 0000000..f9b0d7c --- /dev/null +++ b/apps/driver_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/apps/driver_new/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/apps/driver_new/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100755 index 0000000..e3773d4 --- /dev/null +++ b/apps/driver_new/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/driver_new/ios/Runner.xcworkspace/contents.xcworkspacedata b/apps/driver_new/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100755 index 0000000..21a3cc1 --- /dev/null +++ b/apps/driver_new/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/apps/driver_new/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/apps/driver_new/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100755 index 0000000..18d9810 --- /dev/null +++ b/apps/driver_new/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/apps/driver_new/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/apps/driver_new/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100755 index 0000000..f9b0d7c --- /dev/null +++ b/apps/driver_new/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/apps/driver_new/ios/Runner/AppDelegate.swift b/apps/driver_new/ios/Runner/AppDelegate.swift new file mode 100755 index 0000000..326c490 --- /dev/null +++ b/apps/driver_new/ios/Runner/AppDelegate.swift @@ -0,0 +1,149 @@ +import UIKit +import Flutter +import FirebaseCore +import CoreLocation + +@main +@objc class AppDelegate: FlutterAppDelegate { + + let locationManager = CLLocationManager() + + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + + // تهيئة Firebase + FirebaseApp.configure() + GeneratedPluginRegistrant.register(with: self) + + // التأكد من أن الجهاز غير مخترق قبل تشغيل التطبيق + if SecurityChecks.isDeviceCompromised() { + showSecurityAlert() + return false + } + + // تهيئة قنوات الاتصال مع Flutter + setupMethodChannel() + + // ضبط مدير الموقع لمتابعة تغييرات الأذونات + locationManager.delegate = self + locationManager.requestWhenInUseAuthorization() // طلب الأذونات فقط عند الحاجة + + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } + + // MARK: - تهيئة القناة بين Swift و Flutter + func setupMethodChannel() { + guard let controller = window?.rootViewController as? FlutterViewController else { + return + } + + let channel = FlutterMethodChannel(name: "com.sefer_driver/security", + binaryMessenger: controller.binaryMessenger) + channel.setMethodCallHandler { call, result in + switch call.method { + case "isNativeRooted": + result(SecurityChecks.isDeviceCompromised()) + default: + result(FlutterMethodNotImplemented) + } + } + } + + // MARK: - عرض تنبيه عند اكتشاف جهاز مخترق + func showSecurityAlert() { + guard let rootVC = UIApplication.shared.keyWindow?.rootViewController else { + exit(0) + } + + let alert = UIAlertController( + title: "Security Warning".localized, + message: "Compromised device detected. Exiting.".localized, + preferredStyle: .alert + ) + + alert.addAction(UIAlertAction(title: "OK".localized, style: .destructive) { _ in + self.obfuscatedExit() + }) + + if #available(iOS 15.0, *) { + alert.popoverPresentationController?.sourceView = rootVC.view + alert.popoverPresentationController?.sourceRect = CGRect(x: rootVC.view.bounds.midX, y: rootVC.view.bounds.midY, width: 0, height: 0) + alert.popoverPresentationController?.permittedArrowDirections = [] + alert.presentationController?.delegate = self + + if let presentationController = alert.presentationController as? UISheetPresentationController { + presentationController.detents = [.medium()] + presentationController.preferredCornerRadius = 20 + presentationController.prefersEdgeAttachedInCompactHeight = true + presentationController.prefersGrabberVisible = false + } + } + + rootVC.present(alert, animated: true, completion: nil) + } + + // MARK: - إخفاء عملية الخروج بطريقة مشفرة + func obfuscatedExit() { + let selector = NSSelectorFromString(String(format: "%@%@", "ex", "it:")) + if responds(to: selector) { + perform(selector, with: 0) + } + } + + // MARK: - تحميل مفاتيح API بطريقة آمنة + func loadConfig() -> [String: Any]? { + guard let path = Bundle.main.path(forResource: "Config", ofType: "plist"), + let config = NSDictionary(contentsOfFile: path) as? [String: Any] else { + return nil + } + return config + } +} + +// MARK: - التعامل مع أذونات الموقع بطريقة آمنة +extension AppDelegate: CLLocationManagerDelegate { + func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { + if #available(iOS 14.0, *) { + let status = manager.authorizationStatus + switch status { + case .authorizedWhenInUse, .authorizedAlways: + print("Authorization granted") + case .denied, .restricted: + print("Authorization denied") + case .notDetermined: + manager.requestWhenInUseAuthorization() + @unknown default: + break + } + } else { + // لنظام iOS 13 وما قبله، نستخدم الطريقة القديمة + let status = CLLocationManager.authorizationStatus() + switch status { + case .authorizedWhenInUse, .authorizedAlways: + print("Authorization granted") + case .denied, .restricted: + print("Authorization denied") + case .notDetermined: + manager.requestWhenInUseAuthorization() + @unknown default: + break + } + } + } +} + +// MARK: - منع إغلاق التنبيهات الأمنية +extension AppDelegate: UIAdaptivePresentationControllerDelegate { + func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool { + return false + } +} + +// MARK: - دعم الترجمة للنصوص +extension String { + var localized: String { + return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "") + } +} diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png new file mode 100755 index 0000000..b8b1256 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/100.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/102.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/102.png new file mode 100755 index 0000000..c099ce0 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/102.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png new file mode 100755 index 0000000..360d0c8 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/1024.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/108.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/108.png new file mode 100755 index 0000000..55d8e8f Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/108.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png new file mode 100755 index 0000000..bcecac5 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/114.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png new file mode 100755 index 0000000..390799d Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/120.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png new file mode 100755 index 0000000..f8bf6c9 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/128.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png new file mode 100755 index 0000000..e272c49 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/144.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png new file mode 100755 index 0000000..2747a44 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/152.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png new file mode 100755 index 0000000..fcb6d77 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/16.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png new file mode 100755 index 0000000..337ca39 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/167.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/172.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/172.png new file mode 100755 index 0000000..9b26d07 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/172.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png new file mode 100755 index 0000000..c6b49f7 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/180.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/196.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/196.png new file mode 100755 index 0000000..1e32ea7 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/196.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png new file mode 100755 index 0000000..88039b3 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/20.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/216.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/216.png new file mode 100755 index 0000000..b5a67ca Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/216.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/234.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/234.png new file mode 100755 index 0000000..192635b Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/234.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png new file mode 100755 index 0000000..830d356 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/256.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/258.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/258.png new file mode 100755 index 0000000..e7adea6 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/258.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png new file mode 100755 index 0000000..62dd2ae Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/29.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png new file mode 100755 index 0000000..6dcb454 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/32.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png new file mode 100755 index 0000000..ba727b0 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/40.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/48.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/48.png new file mode 100755 index 0000000..ded0445 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/48.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png new file mode 100755 index 0000000..fe7b959 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/50.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png new file mode 100755 index 0000000..207a10d Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/512.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/55.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/55.png new file mode 100755 index 0000000..f115281 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/55.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png new file mode 100755 index 0000000..b67fa63 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/57.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png new file mode 100755 index 0000000..7011399 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/58.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png new file mode 100755 index 0000000..3d98bd6 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/60.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png new file mode 100755 index 0000000..d7aa056 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/64.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/66.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/66.png new file mode 100755 index 0000000..2f25a3e Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/66.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png new file mode 100755 index 0000000..93905f9 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/72.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png new file mode 100755 index 0000000..8dcf758 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/76.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png new file mode 100755 index 0000000..3e8a65f Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/80.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png new file mode 100755 index 0000000..722bedf Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/87.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/88.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/88.png new file mode 100755 index 0000000..0b9fd37 Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/88.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/92.png b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/92.png new file mode 100755 index 0000000..ac011bd Binary files /dev/null and b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/92.png differ diff --git a/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100755 index 0000000..1319290 --- /dev/null +++ b/apps/driver_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1 @@ +{"images":[{"size":"60x60","expected-size":"180","filename":"180.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"40x40","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"60x60","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"57x57","expected-size":"57","filename":"57.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"57x57","expected-size":"114","filename":"114.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"60","filename":"60.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"1024x1024","filename":"1024.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"72x72","expected-size":"72","filename":"72.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"76x76","expected-size":"152","filename":"152.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"50x50","expected-size":"100","filename":"100.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"76x76","expected-size":"76","filename":"76.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"50x50","expected-size":"50","filename":"50.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"72x72","expected-size":"144","filename":"144.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"40x40","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"83.5x83.5","expected-size":"167","filename":"167.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"20x20","expected-size":"20","filename":"20.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"idiom":"watch","filename":"172.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"38mm","scale":"2x","size":"86x86","expected-size":"172","role":"quickLook"},{"idiom":"watch","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"38mm","scale":"2x","size":"40x40","expected-size":"80","role":"appLauncher"},{"idiom":"watch","filename":"88.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"40mm","scale":"2x","size":"44x44","expected-size":"88","role":"appLauncher"},{"idiom":"watch","filename":"102.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"45mm","scale":"2x","size":"51x51","expected-size":"102","role":"appLauncher"},{"idiom":"watch","filename":"108.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"49mm","scale":"2x","size":"54x54","expected-size":"108","role":"appLauncher"},{"idiom":"watch","filename":"92.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"41mm","scale":"2x","size":"46x46","expected-size":"92","role":"appLauncher"},{"idiom":"watch","filename":"100.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"44mm","scale":"2x","size":"50x50","expected-size":"100","role":"appLauncher"},{"idiom":"watch","filename":"196.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"42mm","scale":"2x","size":"98x98","expected-size":"196","role":"quickLook"},{"idiom":"watch","filename":"216.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"44mm","scale":"2x","size":"108x108","expected-size":"216","role":"quickLook"},{"idiom":"watch","filename":"234.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"45mm","scale":"2x","size":"117x117","expected-size":"234","role":"quickLook"},{"idiom":"watch","filename":"258.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"49mm","scale":"2x","size":"129x129","expected-size":"258","role":"quickLook"},{"idiom":"watch","filename":"48.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"38mm","scale":"2x","size":"24x24","expected-size":"48","role":"notificationCenter"},{"idiom":"watch","filename":"55.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"42mm","scale":"2x","size":"27.5x27.5","expected-size":"55","role":"notificationCenter"},{"idiom":"watch","filename":"66.png","folder":"Assets.xcassets/AppIcon.appiconset/","subtype":"45mm","scale":"2x","size":"33x33","expected-size":"66","role":"notificationCenter"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"watch","role":"companionSettings","scale":"3x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"watch","role":"companionSettings","scale":"2x"},{"size":"1024x1024","expected-size":"1024","filename":"1024.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"watch-marketing","scale":"1x"},{"size":"128x128","expected-size":"128","filename":"128.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"256x256","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"128x128","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"256x256","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"512x512","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"16","filename":"16.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"64","filename":"64.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"512x512","expected-size":"1024","filename":"1024.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"}]} \ No newline at end of file diff --git a/apps/driver_new/ios/Runner/Base.lproj/LaunchScreen.storyboard b/apps/driver_new/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100755 index 0000000..f2e259c --- /dev/null +++ b/apps/driver_new/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/driver_new/ios/Runner/Base.lproj/Main.storyboard b/apps/driver_new/ios/Runner/Base.lproj/Main.storyboard new file mode 100755 index 0000000..19d3697 --- /dev/null +++ b/apps/driver_new/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/driver_new/ios/Runner/Config.plist b/apps/driver_new/ios/Runner/Config.plist new file mode 100755 index 0000000..9e656c2 --- /dev/null +++ b/apps/driver_new/ios/Runner/Config.plist @@ -0,0 +1,8 @@ + + + + + APIKey + AIzaSyCf2mW2h0HD8ZYjwh4VOa2ladw6MJkCDTM + + diff --git a/apps/driver_new/ios/Runner/Constants.swift b/apps/driver_new/ios/Runner/Constants.swift new file mode 100755 index 0000000..75776b7 --- /dev/null +++ b/apps/driver_new/ios/Runner/Constants.swift @@ -0,0 +1,12 @@ +// +// Constants.swift +// Runner +// +// Created by Hamza Aleghwairyeen on 24/02/2025. +// + +import Foundation + +struct Constants { + static let googleMapsAPIKey = "AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0" +} diff --git a/apps/driver_new/ios/Runner/Constants1.swift b/apps/driver_new/ios/Runner/Constants1.swift new file mode 100755 index 0000000..704a451 --- /dev/null +++ b/apps/driver_new/ios/Runner/Constants1.swift @@ -0,0 +1,8 @@ +// +// Constants1.swift +// Runner +// +// Created by Hamza Aleghwairyeen on 16/03/2025. +// + +import Foundation diff --git a/apps/driver_new/ios/Runner/Info.plist b/apps/driver_new/ios/Runner/Info.plist new file mode 100755 index 0000000..ad7c2d6 --- /dev/null +++ b/apps/driver_new/ios/Runner/Info.plist @@ -0,0 +1,109 @@ + + + + + LSMinimumSystemVersion + 12.0 + UIBackgroundModes + + fetch + location + remote-notification + + BGTaskSchedulerPermittedIdentifiers + + $(PRODUCT_BUNDLE_IDENTIFIER) + + NSContactsUsageDescription + This app requires contacts access to function properly. + CADisableMinimumFrameDurationOnPhone + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Tripz Driver + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleGetInfoString + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Tripz Driver + CFBundlePackageType + APPL + CFBundleShortVersionString + 109 + CFBundleSignature + ???? + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + com.googleusercontent.apps.594687661098-9fnj82nef9oagl98prigdf8qne3ddbto + + + + CFBundleVersion + 5.0.109 + FirebaseAppDelegateProxyEnabled + NO + GMSApiKey + YOUR_API_KEY + LSApplicationCategoryType + + LSApplicationQueriesSchemes + + googlechromes + comgooglemaps + + LSRequiresIPhoneOS + + NSCameraUsageDescription + This app requires access to your camera in order to scan QR codes and capture images + for uploading and access to connect to a call. + NSFaceIDUsageDescription + Use Face ID to securely authenticate payment accounts. + NSLocationAlwaysAndWhenInUseUsageDescription + This app needs access to your location to provide you with the best ride experience. + Your location data will be used to find the nearest available cars and connect you with + the closest captain for efficient and convenient rides. + NSLocationAlwaysUsageDescription + This app needs access to location. + NSLocationWhenInUseUsageDescription + This app needs access to your location to provide you with the best ride experience. + Your location data will be used to find the nearest available cars and connect you with + the closest captain for efficient and convenient rides. + NSMicrophoneUsageDescription + This app requires access to your microphone to record audio, allowing you to add + voice recordings to your photos and videos and access to connect to a call. + NSPhotoLibraryUsageDescription + Explanation of why your app needs access to the photo library. + UIApplicationSupportsIndirectInputEvents + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/apps/driver_new/ios/Runner/JailbreakDetection.swift b/apps/driver_new/ios/Runner/JailbreakDetection.swift new file mode 100755 index 0000000..17eb672 --- /dev/null +++ b/apps/driver_new/ios/Runner/JailbreakDetection.swift @@ -0,0 +1,26 @@ +// +// JailbreakDetection.swift +// Runner +// +// Created by Hamza Aleghwairyeen on 24/02/2025. +// + + +import Foundation + +class JailbreakDetection { + static func isJailbroken() -> Bool { + let paths = [ + "/Applications/Cydia.app", + "/Library/MobileSubstrate/MobileSubstrate.dylib", + "/usr/sbin/sshd", + "/etc/apt" + ] + for path in paths { + if FileManager.default.fileExists(atPath: path) { + return true + } + } + return false + } +} diff --git a/apps/driver_new/ios/Runner/KeychainHelper.swift b/apps/driver_new/ios/Runner/KeychainHelper.swift new file mode 100755 index 0000000..a7418db --- /dev/null +++ b/apps/driver_new/ios/Runner/KeychainHelper.swift @@ -0,0 +1,8 @@ +// +// KeychainHelper.swift +// Runner +// +// Created by Hamza Aleghwairyeen on 16/03/2025. +// + +import Foundation diff --git a/apps/driver_new/ios/Runner/Runner-Bridging-Header.h b/apps/driver_new/ios/Runner/Runner-Bridging-Header.h new file mode 100755 index 0000000..2dd4564 --- /dev/null +++ b/apps/driver_new/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1,2 @@ +#import "GeneratedPluginRegistrant.h" +#import "SecurityChecks.h" diff --git a/apps/driver_new/ios/Runner/Runner.entitlements b/apps/driver_new/ios/Runner/Runner.entitlements new file mode 100755 index 0000000..80b5221 --- /dev/null +++ b/apps/driver_new/ios/Runner/Runner.entitlements @@ -0,0 +1,12 @@ + + + + + aps-environment + development + com.apple.developer.applesignin + + Default + + + diff --git a/apps/driver_new/ios/Runner/SecurityChecks.h b/apps/driver_new/ios/Runner/SecurityChecks.h new file mode 100755 index 0000000..7c62f85 --- /dev/null +++ b/apps/driver_new/ios/Runner/SecurityChecks.h @@ -0,0 +1,16 @@ +// +// SecurityChecks.h +// Runner +// +// Created by Hamza Aleghwairyeen on 17/03/2025. +// + +// SecurityChecks.h +#import +#import // Import UIKit + +@interface SecurityChecks : NSObject + ++ (BOOL)isDeviceCompromised; // Combined check + +@end diff --git a/apps/driver_new/ios/Runner/SecurityChecks.m b/apps/driver_new/ios/Runner/SecurityChecks.m new file mode 100755 index 0000000..b9ab3e3 --- /dev/null +++ b/apps/driver_new/ios/Runner/SecurityChecks.m @@ -0,0 +1,197 @@ +// +// SecurityChecks.m +// Runner +// +// Created by Hamza Aleghwairyeen on 17/03/2025. +// + +#import + + + +#import "SecurityChecks.h" +#import +#include +#import +#include // For _dyld_image_count and _dyld_get_image_name +#include // for fork() +#include //for socket, connect +#include // for sockaddr_in +#include // for inet_pton + +@implementation SecurityChecks + ++ (BOOL)isDeviceJailbroken { + // (Same jailbreak checks as before - from previous responses) + // 1. Check for common jailbreak files + NSArray *jailbreakPaths = @[ + @"/Applications/Cydia.app", +// #if !TARGET_IPHONE_SIMULATOR +// @"/bin/bash", +// #endif + @"/Library/MobileSubstrate/MobileSubstrate.dylib", + @"/bin/bash", + @"/usr/sbin/sshd", + @"/etc/apt", + @"/private/var/lib/apt/", + @"/private/var/tmp/cydia.log", + ]; + + for (NSString *path in jailbreakPaths) { + if ([[NSFileManager defaultManager] fileExistsAtPath:path]) { + NSLog(@"Jailbreak file detected: %@", path); + return YES; + } + } + + // 2. Check if we can write outside the sandbox (a strong indicator) + NSError *error = nil; + NSString *testPath = @"/private/jailbreaktest.txt"; + [@"test" writeToFile:testPath atomically:YES encoding:NSUTF8StringEncoding error:&error]; + + if (!error) { + // If we can write, it's jailbroken. Remove the file immediately. + [[NSFileManager defaultManager] removeItemAtPath:testPath error:nil]; + NSLog(@"Sandbox write test indicates jailbreak."); + return YES; + } + //3: Check for existence of the symbolic link /Applications. + struct stat s; + if (lstat("/Applications", &s) == 0) { + if (S_ISLNK(s.st_mode)) { + NSLog(@"Symbolic link /Applications exists, jailbroken"); + return YES; + } + } + + //4:Check for dyld Libraries + uint32_t count = _dyld_image_count(); + for (uint32_t i = 0 ; i < count ; ++i) { + const char *dyld = _dyld_get_image_name(i); + if (strstr(dyld, "MobileSubstrate") != NULL || strstr(dyld, "libcycript") != NULL) { + NSLog(@"Suspicious dyld library found: %s", dyld); + return YES; + } + } + + //5 Check if fork() is available. Sandboxed apps should not be able to call fork(). + #if !TARGET_IPHONE_SIMULATOR // Don't run this on the simulator + int pid = fork(); + if (pid == 0) + { + //in child, exit immediately to avoid crashing. + exit(0); + } else if (pid > 0) + { + NSLog(@"Fork available. Likely jailbroken."); + return YES; // Fork succeeded; likely jailbroken + } + #endif + + return NO; // No jailbreak indicators found +} ++ (BOOL)isDebuggerAttached { + int mib[4]; + struct kinfo_proc info; + size_t size = sizeof(info); + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); + + sysctl(mib, 4, &info, &size, NULL, 0); + + return (info.kp_proc.p_flag & P_TRACED) != 0; +} + +// Check for Frida's default port ++ (BOOL)isFridaListeningOnDefaultPort { + int sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == -1) { + return NO; // Couldn't create socket + } + + struct sockaddr_in sa; + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_port = htons(27042); // Default Frida port + inet_pton(AF_INET, "127.0.0.1", &sa.sin_addr); + + if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) != -1) { + NSLog(@"Frida default port (27042) is open."); + close(sock); + return YES; + } + + close(sock); + return NO; +} + + ++ (BOOL)isFridaDetected { + int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 }; + size_t length; + struct kinfo_proc *procs, *proc; + + sysctl(name, 3, NULL, &length, NULL, 0); + procs = malloc(length); + sysctl(name, 3, procs, &length, NULL, 0); + + for (proc = procs; (char *)proc < (char *)procs + length; proc++) { + if (strstr(proc->kp_proc.p_comm, "frida") != NULL) { + free(procs); + return YES; + } + } + + free(procs); + return NO; +} +// Check for loaded dylibs that indicate Frida ++(BOOL) checkForFridaDylib{ + uint32_t count = _dyld_image_count(); + for (uint32_t i = 0 ; i < count ; ++i) { + const char *dyld = _dyld_get_image_name(i); + if (strstr(dyld, "FridaGadget") != NULL) { // Look for FridaGadget + NSLog(@"FridaGadget dylib found: %s", dyld); + return YES; + } + } + return NO; +} + +// Check process name ++ (BOOL)checkProcessName { + NSString* processName = [[NSProcessInfo processInfo] processName]; + if ([processName containsString:@"Frida"]) { + return YES; + } + return NO; +} + +// A combined check for jailbreak and Frida ++ (BOOL)isDeviceCompromised { + if ([SecurityChecks isDeviceJailbroken]) { + return YES; + } + if ([SecurityChecks isFridaListeningOnDefaultPort]) { + return YES; + } + if ([SecurityChecks checkForFridaDylib]) { + return YES; + } + if([SecurityChecks checkProcessName]){ + return YES; + } + if ([SecurityChecks isDebuggerAttached]) { + return YES; + } +// if ([SecurityChecks isFridaDetected]) { +// return YES; +// } + + return NO; +} + +@end diff --git a/apps/driver_new/ios/Runner/en.lproj/Localizable.strings b/apps/driver_new/ios/Runner/en.lproj/Localizable.strings new file mode 100755 index 0000000..dda4b9d --- /dev/null +++ b/apps/driver_new/ios/Runner/en.lproj/Localizable.strings @@ -0,0 +1,7 @@ +/* + Localizable.strings + Runner + + Created by Hamza Aleghwairyeen on 24/02/2025. + +*/ diff --git a/apps/driver_new/ios/Runner/order.wav b/apps/driver_new/ios/Runner/order.wav new file mode 100755 index 0000000..b2b0ba2 Binary files /dev/null and b/apps/driver_new/ios/Runner/order.wav differ diff --git a/apps/driver_new/ios/Runner/tone2.wav b/apps/driver_new/ios/Runner/tone2.wav new file mode 100755 index 0000000..0582d47 Binary files /dev/null and b/apps/driver_new/ios/Runner/tone2.wav differ diff --git a/apps/driver_new/ios/RunnerTests/RunnerTests.swift b/apps/driver_new/ios/RunnerTests/RunnerTests.swift new file mode 100755 index 0000000..86a7c3b --- /dev/null +++ b/apps/driver_new/ios/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Flutter +import UIKit +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/apps/driver_new/ios/firebase_app_id_file.json b/apps/driver_new/ios/firebase_app_id_file.json new file mode 100755 index 0000000..5236662 --- /dev/null +++ b/apps/driver_new/ios/firebase_app_id_file.json @@ -0,0 +1,7 @@ +{ + "file_generated_by": "FlutterFire CLI", + "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", + "GOOGLE_APP_ID": "1:594687661098:ios:6f69eee1449be943595f53", + "FIREBASE_PROJECT_ID": "ride-b1bd8", + "GCM_SENDER_ID": "594687661098" +} \ No newline at end of file diff --git a/apps/driver_new/lib/app/app.dart b/apps/driver_new/lib/app/app.dart new file mode 100644 index 0000000..a4c82c4 --- /dev/null +++ b/apps/driver_new/lib/app/app.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; + +import '../core/theme/app_theme.dart'; +import 'router.dart'; + +class TripzApp extends StatelessWidget { + const TripzApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp.router( + title: 'Tripz', + debugShowCheckedModeBanner: false, + routerConfig: appRouter, + theme: AppTheme.light(), + darkTheme: AppTheme.dark(), + // اللغات الأربع تُستكمل في م2 مع ملفات الترجمة. + locale: const Locale('ar'), + supportedLocales: const [Locale('ar'), Locale('en')], + localizationsDelegates: const [ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + ); + } +} diff --git a/apps/driver_new/lib/app/router.dart b/apps/driver_new/lib/app/router.dart new file mode 100644 index 0000000..a16ed24 --- /dev/null +++ b/apps/driver_new/lib/app/router.dart @@ -0,0 +1,19 @@ +import 'package:go_router/go_router.dart'; + +import '../features/splash/splash_page.dart'; + +/// جدول التوجيه — يمتدّ في م3 (المصادقة) وم4 (الخريطة). +class AppRoutes { + const AppRoutes._(); + static const splash = '/'; +} + +final appRouter = GoRouter( + initialLocation: AppRoutes.splash, + routes: [ + GoRoute( + path: AppRoutes.splash, + builder: (context, state) => const SplashPage(), + ), + ], +); diff --git a/apps/driver_new/lib/core/config/app_config.dart b/apps/driver_new/lib/core/config/app_config.dart new file mode 100644 index 0000000..7f213b6 --- /dev/null +++ b/apps/driver_new/lib/core/config/app_config.dart @@ -0,0 +1,36 @@ +/// إعداد البناء — كل قيمة هنا `const` تُمرَّر عبر `--dart-define` عند البناء. +/// +/// هذا هو أساس نموذج lite/pro/max (docs/37 §6.25): بناء مولَّد بأعلام ثابتة، +/// لا فروع كود. القيم الافتراضية تشير للسيرفر التجريبي. +class AppConfig { + const AppConfig._(); + + /// أصل الـAPI **مع** `/api` — كما في docs/38. + static const String apiBaseUrl = String.fromEnvironment( + 'API_BASE_URL', + defaultValue: 'https://tripz-api.intaleqapp.com/api', + ); + + /// أصل الـWebSocket — بلا `/api` (docs/38 §9). + static const String wsBaseUrl = String.fromEnvironment( + 'WS_BASE_URL', + defaultValue: 'https://tripz-api.intaleqapp.com', + ); + + /// **slug** المستأجر لا الـUUID — مصيدة docs/38 §12.9. + static const String tenantSlug = String.fromEnvironment( + 'TENANT_SLUG', + defaultValue: 'siro', + ); + + /// يحدّد هوية المستخدم على الخادم: نفس الرقم بدورين = حسابان منفصلان + /// (docs/38 §1). **يُثبَّت عند البناء ولا يتغيّر في وقت التشغيل أبداً.** + static const String appRole = 'driver'; + + /// هامش التجديد الاستباقي. عمر التوكن 15 دقيقة فقط (docs/38 §2)، فالانتظار + /// حتى 401 يعني فشل طلب في منتصف رحلة. + static const Duration tokenRefreshLeeway = Duration(seconds: 60); + + static const Duration connectTimeout = Duration(seconds: 20); + static const Duration receiveTimeout = Duration(seconds: 30); +} diff --git a/apps/driver_new/lib/core/di/injector.dart b/apps/driver_new/lib/core/di/injector.dart new file mode 100644 index 0000000..257480c --- /dev/null +++ b/apps/driver_new/lib/core/di/injector.dart @@ -0,0 +1,31 @@ +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:get_it/get_it.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +import '../network/api_client.dart'; +import '../storage/token_store.dart'; + +final sl = GetIt.instance; + +/// يُنادى مرة واحدة قبل `runApp`. +Future setupInjector() async { + sl.registerSingleton( + await SharedPreferences.getInstance(), + ); + + const secure = FlutterSecureStorage( + iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock), + ); + + final tokens = TokenStore(secure); + await tokens.load(); + sl.registerSingleton(tokens); + + sl.registerSingleton( + ApiClient.create( + tokens: tokens, + // يُربط بالتوجيه في م3 (إخراج للمستخدم عند انتهاء الجلسة). + onSessionExpired: () async {}, + ), + ); +} diff --git a/apps/driver_new/lib/core/network/api_client.dart b/apps/driver_new/lib/core/network/api_client.dart new file mode 100644 index 0000000..7b96ded --- /dev/null +++ b/apps/driver_new/lib/core/network/api_client.dart @@ -0,0 +1,55 @@ +import 'package:dio/dio.dart'; + +import '../config/app_config.dart'; +import '../storage/token_store.dart'; +import 'api_exception.dart'; +import 'auth_interceptor.dart'; + +/// الواجهة الوحيدة للخادم. لا تُنشأ `Dio` في أي مكان آخر. +class ApiClient { + ApiClient._(this._dio); + + final Dio _dio; + + factory ApiClient.create({ + required TokenStore tokens, + required Future Function() onSessionExpired, + }) { + final options = BaseOptions( + baseUrl: AppConfig.apiBaseUrl, + connectTimeout: AppConfig.connectTimeout, + receiveTimeout: AppConfig.receiveTimeout, + contentType: Headers.jsonContentType, + // نتولّى كل ما ليس 2xx بأنفسنا في ApiException. + validateStatus: (s) => s != null && s >= 200 && s < 300, + ); + + final dio = Dio(options); + dio.interceptors.add(AuthInterceptor( + tokens: tokens, + refreshClient: Dio(options), + onSessionExpired: onSessionExpired, + )); + return ApiClient._(dio); + } + + Future get(String path, {Map? query}) => + _send(() => _dio.get(path, queryParameters: query)); + + Future post(String path, {Object? body}) => + _send(() => _dio.post(path, data: body)); + + Future patch(String path, {Object? body}) => + _send(() => _dio.patch(path, data: body)); + + Future delete(String path) => _send(() => _dio.delete(path)); + + Future _send(Future> Function() call) async { + try { + final res = await call(); + return res.data as T; + } on DioException catch (e) { + throw ApiException.from(e); + } + } +} diff --git a/apps/driver_new/lib/core/network/api_exception.dart b/apps/driver_new/lib/core/network/api_exception.dart new file mode 100644 index 0000000..6514cc1 --- /dev/null +++ b/apps/driver_new/lib/core/network/api_exception.dart @@ -0,0 +1,65 @@ +import 'package:dio/dio.dart'; + +/// خطأ موحّد تراه طبقة الميزات — لا `DioException` يتسرّب فوق طبقة الشبكة. +class ApiException implements Exception { + const ApiException({ + required this.message, + this.statusCode, + this.kind = ApiErrorKind.unknown, + }); + + final String message; + final int? statusCode; + final ApiErrorKind kind; + + bool get isUnauthorized => statusCode == 401; + bool get isForbidden => statusCode == 403; + + /// حدّ المعدّل — `send-otp` ثلاث مرات كل خمس دقائق (docs/38 §2). الواجهة + /// تعرض عدّاداً تنازلياً بدل رسالة خطأ عامة. + bool get isRateLimited => statusCode == 429; + + factory ApiException.from(DioException e) { + switch (e.type) { + case DioExceptionType.connectionTimeout: + case DioExceptionType.sendTimeout: + case DioExceptionType.receiveTimeout: + return const ApiException( + message: 'انتهت مهلة الاتصال', + kind: ApiErrorKind.timeout, + ); + case DioExceptionType.connectionError: + return const ApiException( + message: 'تعذّر الاتصال بالخادم', + kind: ApiErrorKind.network, + ); + case DioExceptionType.cancel: + return const ApiException( + message: 'أُلغي الطلب', + kind: ApiErrorKind.cancelled, + ); + default: + final code = e.response?.statusCode; + return ApiException( + message: _messageOf(e.response?.data) ?? 'حدث خطأ غير متوقّع', + statusCode: code, + kind: ApiErrorKind.server, + ); + } + } + + /// NestJS يرجّع `message` نصاً أو مصفوفة نصوص (أخطاء التحقق). + static String? _messageOf(dynamic data) { + if (data is Map) { + final m = data['message']; + if (m is String && m.isNotEmpty) return m; + if (m is List && m.isNotEmpty) return m.join('\n'); + } + return null; + } + + @override + String toString() => 'ApiException($statusCode): $message'; +} + +enum ApiErrorKind { network, timeout, server, cancelled, unknown } diff --git a/apps/driver_new/lib/core/network/auth_interceptor.dart b/apps/driver_new/lib/core/network/auth_interceptor.dart new file mode 100644 index 0000000..7ee3f2e --- /dev/null +++ b/apps/driver_new/lib/core/network/auth_interceptor.dart @@ -0,0 +1,125 @@ +import 'dart:async'; + +import 'package:dio/dio.dart'; + +import '../config/app_config.dart'; +import '../storage/token_store.dart'; + +/// يثبّت ترويسات كل طلب، ويجدّد التوكن **استباقياً** قبل انتهائه. +/// +/// عمر `access_token` خمس عشرة دقيقة فقط (docs/38 §2). لذلك لا ننتظر 401: +/// نجدّد قبل الإرسال إن قاربت الصلاحية. الـ401 يبقى شبكة أمان لا الآلية. +/// +/// التجديد **بطلقة واحدة**: عشرة طلبات متزامنة بتوكن منتهٍ تُنتج نداء تجديد +/// واحداً لا عشرة — وإلا أبطل الخادم رمز التحديث تحت أقدامنا. +class AuthInterceptor extends Interceptor { + AuthInterceptor({ + required TokenStore tokens, + required Dio refreshClient, + required Future Function() onSessionExpired, + }) : _tokens = tokens, + _refreshClient = refreshClient, + _onSessionExpired = onSessionExpired; + + final TokenStore _tokens; + + /// عميل منفصل بلا هذا الـinterceptor — وإلا استدعى التجديدُ نفسَه. + final Dio _refreshClient; + + final Future Function() _onSessionExpired; + + Future? _inFlight; + + @override + Future onRequest( + RequestOptions options, + RequestInterceptorHandler handler, + ) async { + options.headers['x-tenant-id'] = AppConfig.tenantSlug; + options.headers['x-app-role'] = AppConfig.appRole; + + final deviceId = await _tokens.deviceId(); + if (deviceId != null) options.headers['x-device-id'] = deviceId; + + // نقاط المصادقة لا تحمل توكناً ولا تُشغّل تجديداً. + if (!_needsAuth(options.path)) return handler.next(options); + + if (_tokens.isLoggedIn && + _tokens.isAccessExpired(AppConfig.tokenRefreshLeeway)) { + await _refresh(); + } + + final access = _tokens.accessToken; + if (access != null && access.isNotEmpty) { + options.headers['Authorization'] = 'Bearer $access'; + } + handler.next(options); + } + + @override + Future onError( + DioException err, + ErrorInterceptorHandler handler, + ) async { + final options = err.requestOptions; + final retried = options.extra['__retried'] == true; + + if (err.response?.statusCode != 401 || + retried || + !_needsAuth(options.path) || + !_tokens.isLoggedIn) { + return handler.next(err); + } + + if (!await _refresh()) return handler.next(err); + + options.extra['__retried'] = true; + options.headers['Authorization'] = 'Bearer ${_tokens.accessToken}'; + try { + handler.resolve(await _refreshClient.fetch(options)); + } on DioException catch (e) { + handler.next(e); + } + } + + static bool _needsAuth(String path) => + !path.startsWith('/auth/') && + !path.startsWith('/maps/') && + !path.startsWith('/tenant/config'); + + Future _refresh() { + return _inFlight ??= _doRefresh().whenComplete(() => _inFlight = null); + } + + Future _doRefresh() async { + final refresh = _tokens.refreshToken; + if (refresh == null || refresh.isEmpty) return false; + try { + final deviceId = await _tokens.deviceId(); + final res = await _refreshClient.post>( + '/auth/refresh', + data: {'refresh_token': refresh}, + options: Options(headers: { + 'x-tenant-id': AppConfig.tenantSlug, + 'x-app-role': AppConfig.appRole, + 'x-device-id': ?deviceId, + }), + ); + final body = res.data; + final access = body?['access_token'] as String?; + if (access == null || access.isEmpty) return false; + await _tokens.save( + accessToken: access, + // الخادم قد لا يدوّر رمز التحديث — نحتفظ بالقديم حينها. + refreshToken: (body?['refresh_token'] as String?) ?? refresh, + signingKey: body?['signing_key'] as String?, + ); + return true; + } on DioException { + // رمز تحديث ميّت = جلسة منتهية. لا معنى للمحاولة مجدداً. + await _tokens.clear(); + await _onSessionExpired(); + return false; + } + } +} diff --git a/apps/driver_new/lib/core/storage/token_store.dart b/apps/driver_new/lib/core/storage/token_store.dart new file mode 100644 index 0000000..9e37f68 --- /dev/null +++ b/apps/driver_new/lib/core/storage/token_store.dart @@ -0,0 +1,86 @@ +import 'dart:convert'; + +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; + +/// مخزن الرموز — التخزين الآمن وحده. لا يُكتب توكن في `SharedPreferences`. +class TokenStore { + TokenStore(this._storage); + + final FlutterSecureStorage _storage; + + static const _kAccess = 'access_token'; + static const _kRefresh = 'refresh_token'; + static const _kSigning = 'signing_key'; + static const _kDeviceId = 'device_id'; + + // نسخة في الذاكرة: الـinterceptor يقرأ التوكن عند كل طلب، وقراءة Keychain + // في كل مرة عمل ثقيل على المسار الساخن. + String? _access; + String? _refresh; + + Future load() async { + _access = await _storage.read(key: _kAccess); + _refresh = await _storage.read(key: _kRefresh); + } + + String? get accessToken => _access; + String? get refreshToken => _refresh; + bool get isLoggedIn => _refresh != null && _refresh!.isNotEmpty; + + Future save({ + required String accessToken, + required String refreshToken, + String? signingKey, + }) async { + _access = accessToken; + _refresh = refreshToken; + await _storage.write(key: _kAccess, value: accessToken); + await _storage.write(key: _kRefresh, value: refreshToken); + if (signingKey != null) { + await _storage.write(key: _kSigning, value: signingKey); + } + } + + Future clear() async { + _access = null; + _refresh = null; + await _storage.delete(key: _kAccess); + await _storage.delete(key: _kRefresh); + await _storage.delete(key: _kSigning); + // مُعرّف الجهاز لا يُمسح عند الخروج — هو بصمة الجهاز لا بصمة الجلسة. + } + + /// مفتاح توقيع الطلبات — يعود مع رد الدخول (docs/38 §8). يُستهلك في م3. + Future signingKey() => _storage.read(key: _kSigning); + + Future deviceId() => _storage.read(key: _kDeviceId); + Future setDeviceId(String id) => + _storage.write(key: _kDeviceId, value: id); + + /// هل انتهت صلاحية التوكن (أو ستنتهي خلال [leeway])؟ + /// + /// قراءة محليّة لحقل `exp` — بلا حزمة خارجية. أي عطب في التوكن يُعامل + /// كمنتهٍ: الأسوأ تجديد زائد، لا طلب فاشل. + bool isAccessExpired(Duration leeway) { + final token = _access; + if (token == null || token.isEmpty) return true; + final exp = _expiryOf(token); + if (exp == null) return true; + return DateTime.now().add(leeway).isAfter(exp); + } + + static DateTime? _expiryOf(String jwt) { + try { + final parts = jwt.split('.'); + if (parts.length != 3) return null; + final payload = json.decode( + utf8.decode(base64Url.decode(base64Url.normalize(parts[1]))), + ) as Map; + final exp = payload['exp']; + if (exp is! int) return null; + return DateTime.fromMillisecondsSinceEpoch(exp * 1000); + } catch (_) { + return null; + } + } +} diff --git a/apps/driver_new/lib/core/theme/app_theme.dart b/apps/driver_new/lib/core/theme/app_theme.dart new file mode 100644 index 0000000..e082d46 --- /dev/null +++ b/apps/driver_new/lib/core/theme/app_theme.dart @@ -0,0 +1,26 @@ +import 'package:flutter/material.dart'; + +/// سمة مبدئية — تُستبدل بنظام التصميم الكامل في م2 (docs/26). +/// الغرض الآن: تثبيت الخطوط وأن يقلع التطبيق بشكل صحيح، لا أكثر. +class AppTheme { + const AppTheme._(); + + static const seed = Color(0xFF1F6FEB); + static const arabicFont = 'IBMPlexSansArabic'; + + static ThemeData light() => _base(Brightness.light); + static ThemeData dark() => _base(Brightness.dark); + + static ThemeData _base(Brightness brightness) { + final scheme = ColorScheme.fromSeed( + seedColor: seed, + brightness: brightness, + ); + return ThemeData( + useMaterial3: true, + colorScheme: scheme, + fontFamily: arabicFont, + scaffoldBackgroundColor: scheme.surface, + ); + } +} diff --git a/apps/driver_new/lib/features/splash/splash_page.dart b/apps/driver_new/lib/features/splash/splash_page.dart new file mode 100644 index 0000000..9854908 --- /dev/null +++ b/apps/driver_new/lib/features/splash/splash_page.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; + +import '../../core/config/app_config.dart'; + +/// شاشة الإقلاع. في م3 تتولّى استعادة الجلسة والتوجيه؛ الآن تثبت فقط أن +/// السقالة والأصول والخطوط تعمل (بوابة م1). +class SplashPage extends StatelessWidget { + const SplashPage({super.key}); + + @override + Widget build(BuildContext context) { + final scheme = Theme.of(context).colorScheme; + return Scaffold( + body: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Image.asset( + 'assets/images/logo.png', + width: 140, + height: 140, + fit: BoxFit.contain, + ), + const SizedBox(height: 24), + Text( + 'Tripz', + style: Theme.of(context).textTheme.headlineMedium?.copyWith( + fontWeight: FontWeight.w700, + color: scheme.primary, + ), + ), + const SizedBox(height: 8), + Text( + AppConfig.appRole == 'driver' ? 'تطبيق السائق' : 'تطبيق الراكب', + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + color: scheme.onSurfaceVariant, + ), + ), + const SizedBox(height: 32), + const SizedBox( + width: 28, + height: 28, + child: CircularProgressIndicator(strokeWidth: 2.5), + ), + ], + ), + ), + ); + } +} diff --git a/apps/driver_new/lib/main.dart b/apps/driver_new/lib/main.dart new file mode 100644 index 0000000..b5a5ff8 --- /dev/null +++ b/apps/driver_new/lib/main.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; + +import 'app/app.dart'; +import 'core/di/injector.dart'; + +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + await setupInjector(); + runApp(const TripzApp()); +} diff --git a/apps/driver_new/pubspec.lock b/apps/driver_new/pubspec.lock new file mode 100644 index 0000000..f21bfbd --- /dev/null +++ b/apps/driver_new/pubspec.lock @@ -0,0 +1,647 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + args: + dependency: transitive + description: + name: args + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 + url: "https://pub.dev" + source: hosted + version: "2.7.0" + async: + dependency: transitive + description: + name: async + sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37 + url: "https://pub.dev" + source: hosted + version: "2.13.1" + bloc: + dependency: transitive + description: + name: bloc + sha256: e03b235924e4f509c27b5d6b2f949200e0a91149a9818b4f65eeb56662b75413 + url: "https://pub.dev" + source: hosted + version: "9.2.1" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + characters: + dependency: transitive + description: + name: characters + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b + url: "https://pub.dev" + source: hosted + version: "1.4.1" + clock: + dependency: transitive + description: + name: clock + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + url: "https://pub.dev" + source: hosted + version: "1.1.2" + code_assets: + dependency: transitive + description: + name: code_assets + sha256: bf394f466ba9205f1812a0433b392d6af280f155f56651eda7c18cc32ed493b8 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + collection: + dependency: transitive + description: + name: collection + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + url: "https://pub.dev" + source: hosted + version: "1.19.1" + crypto: + dependency: transitive + description: + name: crypto + sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf + url: "https://pub.dev" + source: hosted + version: "3.0.7" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: "41e005c33bd814be4d3096aff55b1908d419fde52ca656c8c47719ec745873cd" + url: "https://pub.dev" + source: hosted + version: "1.0.9" + dio: + dependency: "direct main" + description: + name: dio + sha256: "0df44ebba85e503958eb75d07eedd3c86275a58c1d3eda2f2ce8f0a2c3abbb3c" + url: "https://pub.dev" + source: hosted + version: "5.11.0" + dio_web_adapter: + dependency: transitive + description: + name: dio_web_adapter + sha256: "0786d0b7295a373de356fc0af4f6f1d0ab2844ed31b19dfc5e7556b70e24212c" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + equatable: + dependency: "direct main" + description: + name: equatable + sha256: "3bce007a596ff8b3119c45d68aaef631272537c03d30e5d4534dd24bf4c5eaa2" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" + url: "https://pub.dev" + source: hosted + version: "1.3.3" + ffi: + dependency: transitive + description: + name: ffi + sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + ffi_leak_tracker: + dependency: transitive + description: + name: ffi_leak_tracker + sha256: "4093d4ef9ca06ffe2786e73bfb25e22aa92112b9bb4ec941f11e3e6b61489a97" + url: "https://pub.dev" + source: hosted + version: "0.1.2" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_bloc: + dependency: "direct main" + description: + name: flutter_bloc + sha256: cf51747952201a455a1c840f8171d273be009b932c75093020f9af64f2123e38 + url: "https://pub.dev" + source: hosted + version: "9.1.1" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1" + url: "https://pub.dev" + source: hosted + version: "6.0.0" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_secure_storage: + dependency: "direct main" + description: + name: flutter_secure_storage + sha256: "7686b1d6a29985dcbb808c59518226e603e3bfa7c0ddfd1a0d00e4cda77c868e" + url: "https://pub.dev" + source: hosted + version: "10.3.1" + flutter_secure_storage_darwin: + dependency: transitive + description: + name: flutter_secure_storage_darwin + sha256: "82329fa5cdf343773b1b6897dea959105a29f092454259edff92f9f6637e8149" + url: "https://pub.dev" + source: hosted + version: "0.3.2" + flutter_secure_storage_linux: + dependency: transitive + description: + name: flutter_secure_storage_linux + sha256: a5f35ddab43cf5c8215d2feb4ce1957851f28c5c37e6f04335066a0602087bf5 + url: "https://pub.dev" + source: hosted + version: "3.0.1" + flutter_secure_storage_platform_interface: + dependency: transitive + description: + name: flutter_secure_storage_platform_interface + sha256: "06686df417f34fe9f963ed217b7fdce250e2f637ddd6c374d7eb054549770633" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + flutter_secure_storage_web: + dependency: transitive + description: + name: flutter_secure_storage_web + sha256: "073a62b3aeb866ab4ce795f960413948e51e5a42a9b0c8333b6daf5bb3208a1c" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + flutter_secure_storage_windows: + dependency: transitive + description: + name: flutter_secure_storage_windows + sha256: "471951813a97006d899db4948acc654a4f28c440083ea08178935ce20b173ec1" + url: "https://pub.dev" + source: hosted + version: "4.2.2" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + get_it: + dependency: "direct main" + description: + name: get_it + sha256: ae78de7c3f2304b8d81f2bb6e320833e5e81de942188542328f074978cc0efa9 + url: "https://pub.dev" + source: hosted + version: "8.3.0" + go_router: + dependency: "direct main" + description: + name: go_router + sha256: f02fd7d2a4dc512fec615529824fdd217fecb3a3d3de68360293a551f21634b3 + url: "https://pub.dev" + source: hosted + version: "14.8.1" + hooks: + dependency: transitive + description: + name: hooks + sha256: "9a62a50b50b769a737bc0a8ff381f333529df3ab746b2f6b02e83760231455ba" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + url: "https://pub.dev" + source: hosted + version: "4.1.2" + intl: + dependency: transitive + description: + name: intl + sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + url: "https://pub.dev" + source: hosted + version: "0.20.2" + jni: + dependency: transitive + description: + name: jni + sha256: f038e58b4dc2c9037f50e233175086337e0b305e356d28211bf55f21c504cbd3 + url: "https://pub.dev" + source: hosted + version: "1.0.3" + jni_flutter: + dependency: transitive + description: + name: jni_flutter + sha256: "7b717011ea40d04fd47c2731d3d1d36eb99eba3435c2753d62489e8c3c9991d5" + url: "https://pub.dev" + source: hosted + version: "1.0.2" + jni_util: + dependency: transitive + description: + name: jni_util + sha256: "1ba86da04a5f2bf18fde2edb235587e70c5b0fc5bd4ba955f46b00942c3fc35f" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" + url: "https://pub.dev" + source: hosted + version: "11.0.2" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + url: "https://pub.dev" + source: hosted + version: "3.0.10" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + lints: + dependency: transitive + description: + name: lints + sha256: "12f842a479589fea194fe5c5a3095abc7be0c1f2ddfa9a0e76aed1dbd26a87df" + url: "https://pub.dev" + source: hosted + version: "6.1.0" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.dev" + source: hosted + version: "1.3.0" + matcher: + dependency: transitive + description: + name: matcher + sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6" + url: "https://pub.dev" + source: hosted + version: "0.12.18" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" + url: "https://pub.dev" + source: hosted + version: "0.13.0" + meta: + dependency: transitive + description: + name: meta + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + url: "https://pub.dev" + source: hosted + version: "1.17.0" + mime: + dependency: transitive + description: + name: mime + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + nested: + dependency: transitive + description: + name: nested + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + objective_c: + dependency: transitive + description: + name: objective_c + sha256: b7fb95a6d9a4f009edd63dc5ac69f07420b23a16161c6dd8660290b59c602e8e + url: "https://pub.dev" + source: hosted + version: "9.5.0" + package_config: + dependency: transitive + description: + name: package_config + sha256: ffcf4cf3d6c0b74ac43708d9f56625506e8a68aa935abe9d267a7330f320eb5d + url: "https://pub.dev" + source: hosted + version: "3.0.0" + path: + dependency: transitive + description: + name: path + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + url: "https://pub.dev" + source: hosted + version: "1.9.1" + path_provider: + dependency: transitive + description: + name: path_provider + sha256: a7f4874f987173da295a61c181b8ee71dab59b332a486b391babf26a1b884825 + url: "https://pub.dev" + source: hosted + version: "2.1.6" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: "69cbd515a62b94d32a7944f086b2f82b4ac40a1d45bebfc00813a430ab2dabcd" + url: "https://pub.dev" + source: hosted + version: "2.3.1" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "2a376b7d6392d80cd3705782d2caa734ca4727776db0b6ec36ef3f1855197699" + url: "https://pub.dev" + source: hosted + version: "2.6.0" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: "58c2005f147315b11e9b4a7bc889cd5203e250cba8e3f012dae259b4972b5c16" + url: "https://pub.dev" + source: hosted + version: "2.2.2" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "484838772624c3a4b94f1e44a3e19897fee738f2d5c4ce448443b0417f7c9dda" + url: "https://pub.dev" + source: hosted + version: "2.1.3" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 + url: "https://pub.dev" + source: hosted + version: "2.3.0" + platform: + dependency: transitive + description: + name: platform + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + url: "https://pub.dev" + source: hosted + version: "3.1.6" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + provider: + dependency: transitive + description: + name: provider + sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272" + url: "https://pub.dev" + source: hosted + version: "6.1.5+1" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + record_use: + dependency: transitive + description: + name: record_use + sha256: "2551bd8eecfe95d14ae75f6021ad0248be5c27f138c2ec12fcb52b500b3ba1ed" + url: "https://pub.dev" + source: hosted + version: "0.6.0" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: c3025c5534b01739267eb7d76959bbc25a6d10f6988e1c2a3036940133dd10bf + url: "https://pub.dev" + source: hosted + version: "2.5.5" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: e8d4762b1e2e8578fc4d0fd548cebf24afd24f49719c08974df92834565e2c53 + url: "https://pub.dev" + source: hosted + version: "2.4.23" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f" + url: "https://pub.dev" + source: hosted + version: "2.5.6" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "649dc798a33931919ea356c4305c2d1f81619ea6e92244070b520187b5140ef9" + url: "https://pub.dev" + source: hosted + version: "2.4.2" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 + url: "https://pub.dev" + source: hosted + version: "2.4.3" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + source_span: + dependency: transitive + description: + name: source_span + sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab" + url: "https://pub.dev" + source: hosted + version: "1.10.2" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + url: "https://pub.dev" + source: hosted + version: "1.12.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + url: "https://pub.dev" + source: hosted + version: "1.4.1" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + url: "https://pub.dev" + source: hosted + version: "1.2.2" + test_api: + dependency: transitive + description: + name: test_api + sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636" + url: "https://pub.dev" + source: hosted + version: "0.7.9" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + url: "https://pub.dev" + source: hosted + version: "2.2.0" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360" + url: "https://pub.dev" + source: hosted + version: "15.2.0" + web: + dependency: transitive + description: + name: web + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + win32: + dependency: transitive + description: + name: win32 + sha256: ba6f4bba816c8d7e3c1580e170f3786d216951cc6b94babc3b814c08d2cb2738 + url: "https://pub.dev" + source: hosted + version: "6.3.0" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + yaml: + dependency: transitive + description: + name: yaml + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + url: "https://pub.dev" + source: hosted + version: "3.1.3" +sdks: + dart: ">=3.11.0 <4.0.0" + flutter: ">=3.38.4" diff --git a/apps/driver_new/pubspec.yaml b/apps/driver_new/pubspec.yaml new file mode 100644 index 0000000..acbab90 --- /dev/null +++ b/apps/driver_new/pubspec.yaml @@ -0,0 +1,78 @@ +name: driver_new +description: "تطبيق السائق — Tripz. مبنيّ من الصفر على Bloc/Cubit وباك إند NestJS (docs/37)." +publish_to: "none" + +# يطابق هوية النشر في android/app/build.gradle — لا يُغيَّر إلا مع رفع إصدار +# حقيقي في المتجر (docs/37 §2.ج). +version: 2.0.152+152 + +environment: + sdk: ^3.11.0 + +dependencies: + flutter: + sdk: flutter + flutter_localizations: + sdk: flutter + + # الحالة والتوجيه والحقن — الإصدارات موحّدة حرفياً مع rider_new (docs/23 §9): + # تباعدهما يعني سلوكاً مختلفاً في كود مشترك. + flutter_bloc: ^9.1.1 + equatable: ^2.0.7 + get_it: ^8.0.3 + go_router: ^14.6.2 + + # الشبكة + dio: ^5.9.1 + + # التخزين — الرموز في التخزين الآمن، والتفضيلات في العادي + flutter_secure_storage: ^10.0.0 + shared_preferences: ^2.3.3 + + cupertino_icons: ^1.0.8 + +# باقي الحزم تُضاف في مرحلتها لا قبلها (docs/37 §1.7): +# م3: device_info_plus · crypto (توقيع الطلبات وبصمة الجهاز) +# م4: الخريطة · geolocator · socket_io_client +# م5: التقييم والمحفظة م6: الإشعارات والدردشة + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^6.0.0 + +flutter: + uses-material-design: true + + assets: + - assets/ + - assets/images/ + - shorebird.yaml + + fonts: + # عربية — تايبوغرافيا نظام التصميم (docs/26) + - family: IBMPlexSansArabic + fonts: + - asset: assets/fonts/IBMPlexSansArabic-Regular.ttf + weight: 400 + - asset: assets/fonts/IBMPlexSansArabic-Medium.ttf + weight: 500 + - asset: assets/fonts/IBMPlexSansArabic-SemiBold.ttf + weight: 600 + - asset: assets/fonts/IBMPlexSansArabic-Bold.ttf + weight: 700 + # لاتينية + - family: Inter + fonts: + - asset: assets/fonts/Inter-Regular.ttf + weight: 400 + - asset: assets/fonts/Inter-Medium.ttf + weight: 500 + - asset: assets/fonts/Inter-SemiBold.ttf + weight: 600 + - asset: assets/fonts/Inter-Bold.ttf + weight: 700 + # أرقام العدّادات (الأجرة/المؤقّت) + - family: Digit + fonts: + - asset: assets/fonts/digit.ttf diff --git a/apps/driver_new/shorebird.yaml b/apps/driver_new/shorebird.yaml new file mode 100755 index 0000000..4c0bb21 --- /dev/null +++ b/apps/driver_new/shorebird.yaml @@ -0,0 +1,14 @@ +# This file is used to configure the Shorebird updater used by your app. +# Learn more at https://docs.shorebird.dev +# This file does not contain any sensitive information and should be checked into version control. + +# Your app_id is the unique identifier assigned to your app. +# It is used to identify your app when requesting patches from Shorebird's servers. +# It is not a secret and can be shared publicly. +app_id: 68cc9345-6270-439e-ae58-437fb195836d + +# auto_update controls if Shorebird should automatically update in the background on launch. +# If auto_update: false, you will need to use package:shorebird_code_push to trigger updates. +# https://pub.dev/packages/shorebird_code_push +# Uncomment the following line to disable automatic updates. +# auto_update: false diff --git a/apps/rider_new/.gitignore b/apps/rider_new/.gitignore new file mode 100644 index 0000000..3820a95 --- /dev/null +++ b/apps/rider_new/.gitignore @@ -0,0 +1,45 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.build/ +.buildlog/ +.history +.svn/ +.swiftpm/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ +/coverage/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/apps/rider_new/.metadata b/apps/rider_new/.metadata new file mode 100644 index 0000000..d31e83a --- /dev/null +++ b/apps/rider_new/.metadata @@ -0,0 +1,33 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: "90673a4eef275d1a6692c26ac80d6d746d41a73a" + channel: "stable" + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 90673a4eef275d1a6692c26ac80d6d746d41a73a + base_revision: 90673a4eef275d1a6692c26ac80d6d746d41a73a + - platform: android + create_revision: 90673a4eef275d1a6692c26ac80d6d746d41a73a + base_revision: 90673a4eef275d1a6692c26ac80d6d746d41a73a + - platform: ios + create_revision: 90673a4eef275d1a6692c26ac80d6d746d41a73a + base_revision: 90673a4eef275d1a6692c26ac80d6d746d41a73a + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/apps/rider_new/README.md b/apps/rider_new/README.md new file mode 100644 index 0000000..57e6af4 --- /dev/null +++ b/apps/rider_new/README.md @@ -0,0 +1,17 @@ +# rider_new + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Learn Flutter](https://docs.flutter.dev/get-started/learn-flutter) +- [Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Flutter learning resources](https://docs.flutter.dev/reference/learning-resources) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/apps/rider_new/analysis_options.yaml b/apps/rider_new/analysis_options.yaml new file mode 100644 index 0000000..61b6c4d --- /dev/null +++ b/apps/rider_new/analysis_options.yaml @@ -0,0 +1,29 @@ +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/apps/rider_new/android/.gitignore b/apps/rider_new/android/.gitignore new file mode 100644 index 0000000..ff01b1d --- /dev/null +++ b/apps/rider_new/android/.gitignore @@ -0,0 +1,15 @@ +gradle-wrapper.jar +/.gradle +/captures/ +/gradlew +/gradlew.bat +/local.properties +GeneratedPluginRegistrant.java +/.cxx + +# Remember to never publicly share your keystore. +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app +key.properties +gradle.properties +**/*.keystore +**/*.jks diff --git a/apps/rider_new/android/app/build.gradle b/apps/rider_new/android/app/build.gradle new file mode 100644 index 0000000..5b6de45 --- /dev/null +++ b/apps/rider_new/android/app/build.gradle @@ -0,0 +1,90 @@ + +plugins { + id "com.android.application" + // START: FlutterFire Configuration + id 'com.google.gms.google-services' + // END: FlutterFire Configuration + id "kotlin-android" + // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. + id "dev.flutter.flutter-gradle-plugin" +} + +def keystoreProperties = new Properties() +def keystorePropertiesFile = rootProject.file('key.properties') +// Load keystore properties if the file exists +if (keystorePropertiesFile.exists()) { + keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) +} +android { + namespace = "com.mobileapp.store.ride" + compileSdk = 36 + ndkVersion "29.0.14033849" + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + coreLibraryDesugaringEnabled true + } + externalNativeBuild { + cmake { + path "src/main/cpp/CMakeLists.txt" + version "3.22.1" + } + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_1_8 + } + sourceSets { + main { + jniLibs.srcDirs = ['src/main/jniLibs'] + } + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId = "com.mobileapp.store.ride" + // You can update the following values to match your application needs. + // For more information, see: https://flutter.dev/to/review-gradle-config. + minSdk = 29 + targetSdk = 36 + versionCode 135 + versionName "2.0.135" + multiDexEnabled = true + ndk { + abiFilters "armeabi-v7a", "arm64-v8a" + } + } + + signingConfigs { + release { + // Check if properties are defined before using them + storeFile = keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null + storePassword = keystoreProperties['storePassword'] + keyAlias = keystoreProperties['keyAlias'] + keyPassword = keystoreProperties['keyPassword'] + } + } + + buildTypes { + release { + signingConfig signingConfigs.release + minifyEnabled true + shrinkResources true + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } +} + +flutter { + source = "../.." +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5' + implementation "com.stripe:stripe-android:21.4.2" + implementation 'com.stripe:paymentsheet:21.4.2' + implementation 'com.scottyab:rootbeer-lib:0.1.0' + implementation 'com.google.android.gms:play-services-safetynet:18.1.0' +} \ No newline at end of file diff --git a/apps/rider_new/android/app/proguard-rules.pro b/apps/rider_new/android/app/proguard-rules.pro new file mode 100644 index 0000000..8843bb1 --- /dev/null +++ b/apps/rider_new/android/app/proguard-rules.pro @@ -0,0 +1,44 @@ +# Suppress warnings for specific Google ML Kit and Stripe classes +-dontwarn com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions$Builder +-dontwarn com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions +-dontwarn com.google.mlkit.vision.text.devanagari.DevanagariTextRecognizerOptions$Builder +-dontwarn com.google.mlkit.vision.text.devanagari.DevanagariTextRecognizerOptions +-dontwarn com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions$Builder +-dontwarn com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions +-dontwarn com.google.mlkit.vision.text.korean.KoreanTextRecognizerOptions$Builder +-dontwarn com.google.mlkit.vision.text.korean.KoreanTextRecognizerOptions +-dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivity$g +-dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivityStarter$Args +-dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivityStarter$Error +-dontwarn com.stripe.android.pushProvisioning.PushProvisioningActivityStarter +-dontwarn com.stripe.android.pushProvisioning.PushProvisioningEphemeralKeyProvider + +# NEW: Add the -dontwarn rules from missing_rules.txt +-dontwarn com.stripe.android.view.AddPaymentMethodActivityStarter$Args$Builder +-dontwarn com.stripe.android.view.AddPaymentMethodActivityStarter$Args +-dontwarn com.stripe.android.view.AddPaymentMethodActivityStarter$Result$Canceled +-dontwarn com.stripe.android.view.AddPaymentMethodActivityStarter$Result$Companion +-dontwarn com.stripe.android.view.AddPaymentMethodActivityStarter$Result$Failure +-dontwarn com.stripe.android.view.AddPaymentMethodActivityStarter$Result$Success +-dontwarn com.stripe.android.view.AddPaymentMethodActivityStarter$Result +-dontwarn com.stripe.android.view.AddPaymentMethodActivityStarter + +# Keep rules for Google ML Kit +-keep class com.google.mlkit.vision.** { *; } +-keep class com.google.mlkit.vision.text.** { *; } +-keep class com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions { *; } +-keep class com.google.mlkit.vision.text.chinese.ChineseTextRecognizerOptions$Builder { *; } +-keep class com.google.mlkit.vision.text.devanagari.DevanagariTextRecognizerOptions { *; } +-keep class com.google.mlkit.vision.text.devanagari.DevanagariTextRecognizerOptions$Builder { *; } +-keep class com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions { *; } +-keep class com.google.mlkit.vision.text.japanese.JapaneseTextRecognizerOptions$Builder { *; } +-keep class com.google.mlkit.vision.text.korean.KoreanTextRecognizerOptions { *; } +-keep class com.google.mlkit.vision.text.korean.KoreanTextRecognizerOptions$Builder { *; } + +# Keep rules for Stripe (Use the broad rule - most reliable) +-keep class com.stripe.android.** { *; } + +# Keep rule for RootDetection +-keep class com.mobileapp.store.ride.RootDetection { + native ; +} \ No newline at end of file diff --git a/apps/rider_new/android/app/src/debug/AndroidManifest.xml b/apps/rider_new/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/apps/rider_new/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/apps/rider_new/android/app/src/main/AndroidManifest.xml b/apps/rider_new/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..3908172 --- /dev/null +++ b/apps/rider_new/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/apps/rider_new/android/app/src/main/cpp/CMakeLists.txt b/apps/rider_new/android/app/src/main/cpp/CMakeLists.txt new file mode 100644 index 0000000..6099f41 --- /dev/null +++ b/apps/rider_new/android/app/src/main/cpp/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.10.2) # Use 3.10.2 for consistency. +project(ride) + +add_library(native-lib SHARED native-lib.cpp) + +find_library(log-lib log) + +target_link_libraries(native-lib ${log-lib}) \ No newline at end of file diff --git a/apps/rider_new/android/app/src/main/cpp/native-lib.cpp b/apps/rider_new/android/app/src/main/cpp/native-lib.cpp new file mode 100644 index 0000000..cd96d10 --- /dev/null +++ b/apps/rider_new/android/app/src/main/cpp/native-lib.cpp @@ -0,0 +1,166 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // Add this line + + +#define LOG_TAG "NativeLib" +#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) +#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) + +// Function to check for common root binaries +bool isRooted() { + std::string paths[] = { + "/system/app/Superuser.apk", + "/system/xbin/su", + "/system/bin/su", + "/system/bin/magisk", + "/system/xbin/magisk", + "/sbin/magisk" + }; + + for (const auto &path : paths) { + std::ifstream file(path); + if (file.good()) { + return true; + } + } + return false; +} + +// Function to check for the presence of files or directories commonly associated with Frida. +bool checkFridaFiles() { + std::string fridaFiles[] = { + "/data/local/tmp/re.frida.server", //Common Frida server path + "/data/local/tmp/frida-server", + "/usr/lib/libfrida-gadget.so", // Frida gadget (injected library) + "/usr/lib64/libfrida-gadget.so", + "/data/local/re.frida.server", + + }; + + for (const auto &path : fridaFiles) { + if (access(path.c_str(), F_OK) != -1) { + LOGE("Frida file detected: %s", path.c_str()); + return true; + } + } + return false; +} + +// Checks for open ports commonly used by Frida. This is less reliable, as ports can be changed. +bool checkFridaPorts() { + int sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == -1) { + return false; // Couldn't create socket, not a strong indicator. + } + + sockaddr_in sa; + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_port = htons(27042); // Default Frida port + inet_pton(AF_INET, "127.0.0.1", &sa.sin_addr); + + if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) != -1) { + LOGE("Frida default port (27042) is open."); + close(sock); + return true; + } + + close(sock); + return false; +} + +// Check the maps file of the current process for any suspicious entries. +bool checkMaps() { + std::ifstream mapsFile("/proc/self/maps"); + std::string line; + + if (mapsFile.is_open()) { + while (std::getline(mapsFile, line)) { + // Look for lines that indicate injected libraries, especially Frida. + if (line.find("frida") != std::string::npos || + line.find("gum-js-") != std::string::npos) { // Gum is Frida's JavaScript engine + LOGE("Suspicious entry in /proc/self/maps: %s", line.c_str()); + return true; + } + } + mapsFile.close(); + } else + { + LOGE("Could not open /proc/self/maps"); + return false; + } + return false; +} + +// Check loaded modules. +bool checkLoadedModules() { + bool found = false; + dl_iterate_phdr([](struct dl_phdr_info *info, size_t size, void *data) { + bool *found_ptr = static_cast(data); + if (std::string(info->dlpi_name).find("frida") != std::string::npos) { + LOGE("Frida module detected: %s", info->dlpi_name); + *found_ptr = true; + return 1; // Stop iterating + } + return 0; // Continue iterating + }, &found); + + return found; +} + + +// This is a simple ptrace check. More sophisticated checks are possible (and necessary for robust detection). +//bool checkPtrace() { +// // Attempt to ptrace ourselves. If another process is already tracing us, this will fail. +// if (ptrace(PTRACE_TRACEME, 0, 1, 0) < 0) { +// LOGE("ptrace failed. Debugger or tracer detected."); +// return true; // Likely being traced +// } +// // Detach. If attached, need to detach to not interfere. +// ptrace(PTRACE_DETACH, 0, 0, 0); +// return false; +//} + +extern "C" +JNIEXPORT jboolean JNICALL +Java_com_mobileapp_store_ride_RootDetection_isNativeRooted(JNIEnv *env, jobject /* this */) { + + if (isRooted()) { + return JNI_TRUE; + } + + if (checkFridaFiles()) { + return JNI_TRUE; + } + + if (checkFridaPorts()) { + return JNI_TRUE; + } + if (checkMaps()) { + return JNI_TRUE; + } + + if (checkLoadedModules()) { + return JNI_TRUE; + } + +// if (checkPtrace()) { +// return JNI_TRUE; +// } + + return JNI_FALSE; +} \ No newline at end of file diff --git a/apps/rider_new/android/app/src/main/kotlin/com/mobileapp/store/ride/MainActivity.kt b/apps/rider_new/android/app/src/main/kotlin/com/mobileapp/store/ride/MainActivity.kt new file mode 100644 index 0000000..66da379 --- /dev/null +++ b/apps/rider_new/android/app/src/main/kotlin/com/mobileapp/store/ride/MainActivity.kt @@ -0,0 +1,203 @@ +package com.mobileapp.store.ride + +import android.app.AlertDialog +import android.os.Bundle +import android.util.Log +import android.widget.LinearLayout +import android.widget.ProgressBar +import android.widget.TextView +import androidx.core.view.setPadding +import com.scottyab.rootbeer.RootBeer +import io.flutter.embedding.android.FlutterFragmentActivity +import java.io.File +import java.util.Timer +import kotlin.concurrent.schedule +import io.flutter.embedding.engine.FlutterEngine // Import FlutterEngine +import io.flutter.plugin.common.MethodChannel // Import MethodChannel +import io.flutter.plugin.common.MethodCall // Import MethodCall +import io.flutter.plugin.common.MethodChannel.Result // Import Result + + +class MainActivity : FlutterFragmentActivity() { + + private lateinit var channel: MethodChannel // Declare a MethodChannel variable + + override fun configureFlutterEngine(flutterEngine: FlutterEngine) { + super.configureFlutterEngine(flutterEngine) + + // Initialize the MethodChannel + channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "com.mobileapp.store.ride/security") + + // Set a MethodCallHandler to handle method calls from Flutter + channel.setMethodCallHandler { call, result -> + when (call.method) { + "isNativeRooted" -> { + val isCompromised = isDeviceCompromised() + result.success(isCompromised) // Send the result back to Flutter + } + else -> { + result.notImplemented() // Handle unknown method calls + } + } + } + } + + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + // Perform all checks. The order can matter; you might want to prioritize + // the faster checks first. + if (isDeviceCompromised()) { + showSecurityWarningDialog() + } + } + + private fun isDeviceCompromised(): Boolean { + return try { + nativeRootCheck() || rootBeerCheck() //|| !safetyNetCheck() + } catch (e: Exception) { + Log.e("DEBUG", "Error during security checks: ${e.message}", e) + true // Consider the device compromised on error + } + } + + private fun nativeRootCheck(): Boolean { + Log.d("DEBUG", "Starting native root detection...") + return try { + val isNativeRooted = RootDetection.isNativeRooted() + Log.d("DEBUG", "Native root detection result: $isNativeRooted") + isNativeRooted + } catch (e: Exception) { + Log.e("DEBUG", "Error in native root detection: ${e.message}", e) + true // Consider rooted on exception + } + } + + private fun rootBeerCheck(): Boolean { + Log.d("DEBUG", "Starting RootBeer root detection...") + val rootBeer = RootBeer(this) + val isRooted = rootBeer.isRooted + Log.d("DEBUG", "RootBeer detection result: $isRooted") + return isRooted + } + + private fun safetyNetCheck(): Boolean { + Log.d("DEBUG", "Starting SafetyNet check...") + var isSafe = false // Initialize a variable to store result + val semaphore = java.util.concurrent.Semaphore(0) // Create a semaphore + + SafetyNetCheck.checkSafetyNet(this, getString(R.string.api_key_safety)) { result -> + isSafe = result + Log.d("DEBUG", "SafetyNet check result: $isSafe") + semaphore.release() // Release the semaphore when the callback is executed + } + + try { + semaphore.acquire() // Wait for the callback to complete + } catch (e: InterruptedException) { + Log.e("DEBUG", "Interrupted while waiting for SafetyNet check", e) + return false // Or handle as appropriate for your app + } + return isSafe + } + + private fun showSecurityWarningDialog() { + var secondsRemaining = 10 // Start at 10 seconds + + // Create views programmatically + val progressBar = ProgressBar(this, null, android.R.attr.progressBarStyleHorizontal) + progressBar.max = 10 // Set max to 10 for 10 seconds + progressBar.progress = 10 // Start full + val textView = TextView(this) + textView.text = getString(R.string.security_warning_message) // Your message + textView.textAlignment = TextView.TEXT_ALIGNMENT_CENTER + + val layout = LinearLayout(this) + layout.orientation = LinearLayout.VERTICAL + layout.setPadding(48) + layout.addView(textView) + layout.addView(progressBar) + + val dialog = + AlertDialog.Builder(this) + .setTitle(getString(R.string.security_warning_title)) // Your title + .setView(layout) // Set the custom layout + .setCancelable( + false + ) // Prevent dismissing by tapping outside or back button + .create() + + dialog.show() + + // Use a Timer to update the progress bar and countdown + val timer = Timer() + timer.schedule(0, 1000) { // Update every 1000ms (1 second) + secondsRemaining-- + runOnUiThread { // Update UI on the main thread + progressBar.progress = + secondsRemaining // Set the progress bar to show remaining seconds + if (secondsRemaining <= 0) { + timer.cancel() // Stop the timer + dialog.dismiss() // Dismiss the dialog + clearAppDataAndExit() // Clear data and exit + } + } + } + } + + private fun clearAppDataAndExit() { + try { + val packageName = applicationContext.packageName + val runtime = Runtime.getRuntime() + runtime.exec("pm clear $packageName") // Clear app data + } catch (e: Exception) { + clearCache() + clearAppData() + } + + finishAffinity() // Finish all activities from this app + System.exit(0) // Terminate the app's process + } + + private fun clearCache() { + try { + val cacheDir = cacheDir + if (cacheDir != null && cacheDir.isDirectory) { + deleteDir(cacheDir) + } + val externalCacheDir = externalCacheDir + if (externalCacheDir != null && externalCacheDir.isDirectory) { + deleteDir(externalCacheDir) + } + } catch (e: Exception) { + Log.e("DEBUG", "Error clearing cache: ${e.message}", e) + } + } + + private fun clearAppData() { + try { + val dataDir = applicationContext.dataDir + if (dataDir != null && dataDir.isDirectory) { + deleteDir(dataDir) + } + } catch (e: Exception) { + Log.e("DEBUG", "Error clearing app data: ${e.message}", e) + } + } + + private fun deleteDir(dir: File?): Boolean { + if (dir != null && dir.isDirectory) { + val children = dir.list() + if (children != null) { + for (child in children) { + val success = deleteDir(File(dir, child)) + if (!success) { + return false + } + } + } + } + return dir?.delete() ?: false + } +} \ No newline at end of file diff --git a/apps/rider_new/android/app/src/main/kotlin/com/mobileapp/store/ride/RootDetection.kt b/apps/rider_new/android/app/src/main/kotlin/com/mobileapp/store/ride/RootDetection.kt new file mode 100644 index 0000000..98fbc9a --- /dev/null +++ b/apps/rider_new/android/app/src/main/kotlin/com/mobileapp/store/ride/RootDetection.kt @@ -0,0 +1,9 @@ +package com.mobileapp.store.ride + +object RootDetection { + init { + System.loadLibrary("native-lib") // Load the native library + } + + external fun isNativeRooted(): Boolean // Declare the external function +} diff --git a/apps/rider_new/android/app/src/main/kotlin/com/mobileapp/store/ride/SafetyNetCheck.kt b/apps/rider_new/android/app/src/main/kotlin/com/mobileapp/store/ride/SafetyNetCheck.kt new file mode 100644 index 0000000..1b8593b --- /dev/null +++ b/apps/rider_new/android/app/src/main/kotlin/com/mobileapp/store/ride/SafetyNetCheck.kt @@ -0,0 +1,109 @@ +import android.content.Context +import android.util.Base64 +import android.util.Log +import com.google.android.gms.safetynet.SafetyNet +import com.google.android.gms.safetynet.SafetyNetApi +import com.google.android.gms.tasks.OnFailureListener +import com.google.android.gms.tasks.OnSuccessListener +import org.json.JSONObject +import java.io.IOException +import java.security.GeneralSecurityException +import java.security.SecureRandom +import java.util.Arrays + +object SafetyNetCheck { + + private const val TAG = "SafetyNetCheck" + + fun checkSafetyNet(context: Context, apiKey: String, callback: (Boolean) -> Unit) { + // Generate a nonce. A good nonce is large, random, and used only once. + val nonce = generateNonce() + + SafetyNet.getClient(context).attest(nonce, apiKey) + .addOnSuccessListener { response -> + // Success! Now, *verify* the response. + val jwsResult = response.jwsResult + if (jwsResult != null) { + try { + val isSafe = SafetyNetResponseVerifier.verify(jwsResult) + Log.d(TAG, "SafetyNet verification result: $isSafe") + callback(isSafe) // Now passing a *verified* result. + } catch (e: Exception) { + Log.e(TAG, "Error verifying SafetyNet response: ${e.message}", e) + callback(false) // Treat verification errors as failures. + } + } else { + Log.e(TAG, "SafetyNet jwsResult is null") + callback(false) // Null result is a failure. + } + } + .addOnFailureListener { e -> + Log.e(TAG, "SafetyNet attest API call failed: ${e.message}", e) + callback(false) // API call failure. + } + } + + + // Helper function to generate a nonce. + private fun generateNonce(): ByteArray { + val byteGenerator = SecureRandom() + val nonce = ByteArray(32) + byteGenerator.nextBytes(nonce) + return nonce + } +} + + + +// Helper class to verify the SafetyNet response. +object SafetyNetResponseVerifier { + + private const val TAG = "SafetyNetVerifier" + + // This method *must* be implemented on a *backend server* for real security. + // This is just a *simplified example* for demonstration purposes and is + // *not* suitable for production without a backend check. + @Throws(GeneralSecurityException::class, IOException::class) + fun verify(jwsResult: String): Boolean { + // 1. Parse the JWS: Split into header, payload, and signature. + val parts = jwsResult.split(".") + if (parts.size != 3) { + Log.e(TAG, "Invalid JWS format") + return false // Invalid JWS format + } + + val header = parts[0] + val payload = parts[1] + val signature = parts[2] + + // 2. Decode the payload (it's Base64 encoded). + val decodedPayload = Base64.decode(payload, Base64.DEFAULT) + val payloadJson = JSONObject(String(decodedPayload)) + + // 3. Check the ctsProfileMatch and basicIntegrity. + val ctsProfileMatch = payloadJson.optBoolean("ctsProfileMatch", false) + val basicIntegrity = payloadJson.optBoolean("basicIntegrity", false) + + Log.d(TAG, "ctsProfileMatch: $ctsProfileMatch, basicIntegrity: $basicIntegrity") + + // 4. **CRITICAL: In a real application, you *must* send the JWS to your + // backend server for verification. The server should use the + // Google SafetyNet API (or a library that wraps it) to verify + // the signature and check the fields. This prevents attackers + // from tampering with the response on the device.** + // + // // Example (pseudo-code) of what the backend check would do: + // // GoogleCredential credential = ...; + // // SafetyNet safetyNet = new SafetyNet.Builder(httpTransport, jsonFactory) + // // .setApplicationName("YourAppName") + // // .setHttpRequestInitializer(credential) + // // .build(); + // // SafetyNetApi.VerifyJwsRequest request = safetyNet.safetynet().verifyJws(jwsResult); + // // SafetyNetApi.VerifyJwsResponse response = request.execute(); + // // return response.isValidSignature() && response.getCtsProfileMatch() && response.getBasicIntegrity(); + + // 5. For this *example* (without a backend), we'll just check the fields. + // This is *NOT SECURE* for production! + return ctsProfileMatch && basicIntegrity + } +} \ No newline at end of file diff --git a/apps/rider_new/android/app/src/main/res/drawable-hdpi/android12splash.png b/apps/rider_new/android/app/src/main/res/drawable-hdpi/android12splash.png new file mode 100644 index 0000000..05b0cb9 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable-hdpi/android12splash.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable-hdpi/splash.png b/apps/rider_new/android/app/src/main/res/drawable-hdpi/splash.png new file mode 100644 index 0000000..05b0cb9 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable-hdpi/splash.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable-mdpi/android12splash.png b/apps/rider_new/android/app/src/main/res/drawable-mdpi/android12splash.png new file mode 100644 index 0000000..6694368 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable-mdpi/android12splash.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable-mdpi/splash.png b/apps/rider_new/android/app/src/main/res/drawable-mdpi/splash.png new file mode 100644 index 0000000..6694368 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable-mdpi/splash.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable-night-hdpi/android12splash.png b/apps/rider_new/android/app/src/main/res/drawable-night-hdpi/android12splash.png new file mode 100644 index 0000000..05b0cb9 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable-night-hdpi/android12splash.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable-night-mdpi/android12splash.png b/apps/rider_new/android/app/src/main/res/drawable-night-mdpi/android12splash.png new file mode 100644 index 0000000..6694368 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable-night-mdpi/android12splash.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable-night-xhdpi/android12splash.png b/apps/rider_new/android/app/src/main/res/drawable-night-xhdpi/android12splash.png new file mode 100644 index 0000000..769f7c4 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable-night-xhdpi/android12splash.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png b/apps/rider_new/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png new file mode 100644 index 0000000..5fd14db Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable-night-xxhdpi/android12splash.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png b/apps/rider_new/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png new file mode 100644 index 0000000..1c91252 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable-night-xxxhdpi/android12splash.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable-v21/background.png b/apps/rider_new/android/app/src/main/res/drawable-v21/background.png new file mode 100644 index 0000000..8e21404 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable-v21/background.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable-v21/launch_background.xml b/apps/rider_new/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..3cc4948 --- /dev/null +++ b/apps/rider_new/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/apps/rider_new/android/app/src/main/res/drawable-xhdpi/android12splash.png b/apps/rider_new/android/app/src/main/res/drawable-xhdpi/android12splash.png new file mode 100644 index 0000000..769f7c4 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable-xhdpi/android12splash.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable-xhdpi/splash.png b/apps/rider_new/android/app/src/main/res/drawable-xhdpi/splash.png new file mode 100644 index 0000000..769f7c4 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable-xhdpi/splash.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable-xxhdpi/android12splash.png b/apps/rider_new/android/app/src/main/res/drawable-xxhdpi/android12splash.png new file mode 100644 index 0000000..5fd14db Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable-xxhdpi/android12splash.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable-xxhdpi/splash.png b/apps/rider_new/android/app/src/main/res/drawable-xxhdpi/splash.png new file mode 100644 index 0000000..5fd14db Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable-xxhdpi/splash.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable-xxxhdpi/android12splash.png b/apps/rider_new/android/app/src/main/res/drawable-xxxhdpi/android12splash.png new file mode 100644 index 0000000..1c91252 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable-xxxhdpi/android12splash.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable-xxxhdpi/splash.png b/apps/rider_new/android/app/src/main/res/drawable-xxxhdpi/splash.png new file mode 100644 index 0000000..1c91252 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable-xxxhdpi/splash.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable/app_icon.png b/apps/rider_new/android/app/src/main/res/drawable/app_icon.png new file mode 100644 index 0000000..ab0309f Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable/app_icon.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable/background.png b/apps/rider_new/android/app/src/main/res/drawable/background.png new file mode 100644 index 0000000..8e21404 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable/background.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable/icon_share.png b/apps/rider_new/android/app/src/main/res/drawable/icon_share.png new file mode 100644 index 0000000..ae92be6 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable/icon_share.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable/icon_support.png b/apps/rider_new/android/app/src/main/res/drawable/icon_support.png new file mode 100644 index 0000000..5a9fef9 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable/icon_support.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable/icon_user.png b/apps/rider_new/android/app/src/main/res/drawable/icon_user.png new file mode 100644 index 0000000..c8802f2 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable/icon_user.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable/icon_wallet.png b/apps/rider_new/android/app/src/main/res/drawable/icon_wallet.png new file mode 100644 index 0000000..551f8a4 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/drawable/icon_wallet.png differ diff --git a/apps/rider_new/android/app/src/main/res/drawable/launch_background.xml b/apps/rider_new/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..3cc4948 --- /dev/null +++ b/apps/rider_new/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/apps/rider_new/android/app/src/main/res/mipmap-hdpi/launcher_icon.png b/apps/rider_new/android/app/src/main/res/mipmap-hdpi/launcher_icon.png new file mode 100644 index 0000000..5f35220 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/mipmap-hdpi/launcher_icon.png differ diff --git a/apps/rider_new/android/app/src/main/res/mipmap-mdpi/launcher_icon.png b/apps/rider_new/android/app/src/main/res/mipmap-mdpi/launcher_icon.png new file mode 100644 index 0000000..3a2be81 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/mipmap-mdpi/launcher_icon.png differ diff --git a/apps/rider_new/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png b/apps/rider_new/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png new file mode 100644 index 0000000..2165361 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/mipmap-xhdpi/launcher_icon.png differ diff --git a/apps/rider_new/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png b/apps/rider_new/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png new file mode 100644 index 0000000..7514dfe Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/mipmap-xxhdpi/launcher_icon.png differ diff --git a/apps/rider_new/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png b/apps/rider_new/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png new file mode 100644 index 0000000..8df33f2 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/mipmap-xxxhdpi/launcher_icon.png differ diff --git a/apps/rider_new/android/app/src/main/res/raw/app_icon.png b/apps/rider_new/android/app/src/main/res/raw/app_icon.png new file mode 100644 index 0000000..96cc55a Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/raw/app_icon.png differ diff --git a/apps/rider_new/android/app/src/main/res/raw/cancel.wav b/apps/rider_new/android/app/src/main/res/raw/cancel.wav new file mode 100644 index 0000000..dbe6e7c Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/raw/cancel.wav differ diff --git a/apps/rider_new/android/app/src/main/res/raw/ding.wav b/apps/rider_new/android/app/src/main/res/raw/ding.wav new file mode 100644 index 0000000..c53cd50 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/raw/ding.wav differ diff --git a/apps/rider_new/android/app/src/main/res/raw/promo.wav b/apps/rider_new/android/app/src/main/res/raw/promo.wav new file mode 100644 index 0000000..3bb2d03 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/raw/promo.wav differ diff --git a/apps/rider_new/android/app/src/main/res/raw/start.wav b/apps/rider_new/android/app/src/main/res/raw/start.wav new file mode 100644 index 0000000..0655506 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/raw/start.wav differ diff --git a/apps/rider_new/android/app/src/main/res/raw/tone1.mp3 b/apps/rider_new/android/app/src/main/res/raw/tone1.mp3 new file mode 100644 index 0000000..e32e61b Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/raw/tone1.mp3 differ diff --git a/apps/rider_new/android/app/src/main/res/raw/tone2.wav b/apps/rider_new/android/app/src/main/res/raw/tone2.wav new file mode 100644 index 0000000..0582d47 Binary files /dev/null and b/apps/rider_new/android/app/src/main/res/raw/tone2.wav differ diff --git a/apps/rider_new/android/app/src/main/res/values-ar/strings.xml b/apps/rider_new/android/app/src/main/res/values-ar/strings.xml new file mode 100644 index 0000000..6b7cb35 --- /dev/null +++ b/apps/rider_new/android/app/src/main/res/values-ar/strings.xml @@ -0,0 +1,6 @@ + + تحذير أمني + تم اكتشاف مشكلة أمنية أو تعديل على هذا الجهاز. لا يمكن تشغيل التطبيق على هذا الجهاز. + إغلاق التطبيق + الجهاز آمن. الاستمرار بشكل طبيعي. + \ No newline at end of file diff --git a/apps/rider_new/android/app/src/main/res/values-night-v31/styles.xml b/apps/rider_new/android/app/src/main/res/values-night-v31/styles.xml new file mode 100644 index 0000000..1b8e45f --- /dev/null +++ b/apps/rider_new/android/app/src/main/res/values-night-v31/styles.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/apps/rider_new/android/app/src/main/res/values-night/styles.xml b/apps/rider_new/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..90b2656 --- /dev/null +++ b/apps/rider_new/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,24 @@ + + + + + + + + + diff --git a/apps/rider_new/android/app/src/main/res/values-v31/styles.xml b/apps/rider_new/android/app/src/main/res/values-v31/styles.xml new file mode 100644 index 0000000..8012d02 --- /dev/null +++ b/apps/rider_new/android/app/src/main/res/values-v31/styles.xml @@ -0,0 +1,22 @@ + + + + + + + diff --git a/apps/rider_new/android/app/src/main/res/values/strings.xml b/apps/rider_new/android/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..6bf8cf7 --- /dev/null +++ b/apps/rider_new/android/app/src/main/res/values/strings.xml @@ -0,0 +1,15 @@ + + My App + + + high_importance_channel + AIzaSyCyfwRXTwSTLOFQSQgN5p7QZgGJVZnEKq0 + Security Warning + AIzaSyB04YNW3LbvmQ5lX1t2bOwEU18-KUoovzw + + A security issue or modification has been detected on + this device. The app cannot run on this device. + Exit App + Device is secure. Proceeding normally. + + \ No newline at end of file diff --git a/apps/rider_new/android/app/src/main/res/values/styles.xml b/apps/rider_new/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..ec51116 --- /dev/null +++ b/apps/rider_new/android/app/src/main/res/values/styles.xml @@ -0,0 +1,24 @@ + + + + + + + + + diff --git a/apps/rider_new/android/app/src/profile/AndroidManifest.xml b/apps/rider_new/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/apps/rider_new/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/apps/rider_new/android/build.gradle b/apps/rider_new/android/build.gradle new file mode 100644 index 0000000..e3d1a86 --- /dev/null +++ b/apps/rider_new/android/build.gradle @@ -0,0 +1,37 @@ +buildscript { + ext.kotlin_version = '1.9.10' + repositories { + google() + mavenCentral() + } + + dependencies { + // START: FlutterFire Configuration +// classpath 'com.google.gms:google-services:4.4.2' +// // END: FlutterFire Configuration +// classpath 'com.android.tools.build:gradle:7.3.1' + classpath 'com.google.gms:google-services:4.3.15' + // END: FlutterFire Configuration + classpath 'com.android.tools.build:gradle:8.8.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +tasks.register("clean", Delete) { + delete rootProject.buildDir +} diff --git a/apps/rider_new/android/gradle/wrapper/gradle-wrapper.properties b/apps/rider_new/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..8970476 --- /dev/null +++ b/apps/rider_new/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +#Thu Aug 03 17:06:53 EET 2023 +distributionBase=GRADLE_USER_HOME +# distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip +distributionPath=wrapper/dists +zipStorePath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip \ No newline at end of file diff --git a/apps/rider_new/android/settings.gradle b/apps/rider_new/android/settings.gradle new file mode 100644 index 0000000..05abf8b --- /dev/null +++ b/apps/rider_new/android/settings.gradle @@ -0,0 +1,28 @@ +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + }() + + includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} + +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version '8.13.0' apply false + // START: FlutterFire Configuration + id "com.google.gms.google-services" version "4.3.10" apply false + // END: FlutterFire Configuration + id "org.jetbrains.kotlin.android" version "2.2.20" apply false +} + +include ":app" diff --git a/apps/rider_new/assets/fonts/IBMPlexSansArabic-Bold.ttf b/apps/rider_new/assets/fonts/IBMPlexSansArabic-Bold.ttf new file mode 100644 index 0000000..d67d9e8 Binary files /dev/null and b/apps/rider_new/assets/fonts/IBMPlexSansArabic-Bold.ttf differ diff --git a/apps/rider_new/assets/fonts/IBMPlexSansArabic-Medium.ttf b/apps/rider_new/assets/fonts/IBMPlexSansArabic-Medium.ttf new file mode 100644 index 0000000..09ec8da Binary files /dev/null and b/apps/rider_new/assets/fonts/IBMPlexSansArabic-Medium.ttf differ diff --git a/apps/rider_new/assets/fonts/IBMPlexSansArabic-Regular.ttf b/apps/rider_new/assets/fonts/IBMPlexSansArabic-Regular.ttf new file mode 100644 index 0000000..5e19284 Binary files /dev/null and b/apps/rider_new/assets/fonts/IBMPlexSansArabic-Regular.ttf differ diff --git a/apps/rider_new/assets/fonts/IBMPlexSansArabic-SemiBold.ttf b/apps/rider_new/assets/fonts/IBMPlexSansArabic-SemiBold.ttf new file mode 100644 index 0000000..6b48c75 Binary files /dev/null and b/apps/rider_new/assets/fonts/IBMPlexSansArabic-SemiBold.ttf differ diff --git a/apps/rider_new/assets/fonts/Inter-Bold.ttf b/apps/rider_new/assets/fonts/Inter-Bold.ttf new file mode 100644 index 0000000..15e908f Binary files /dev/null and b/apps/rider_new/assets/fonts/Inter-Bold.ttf differ diff --git a/apps/rider_new/assets/fonts/Inter-Medium.ttf b/apps/rider_new/assets/fonts/Inter-Medium.ttf new file mode 100644 index 0000000..9342730 Binary files /dev/null and b/apps/rider_new/assets/fonts/Inter-Medium.ttf differ diff --git a/apps/rider_new/assets/fonts/Inter-Regular.ttf b/apps/rider_new/assets/fonts/Inter-Regular.ttf new file mode 100644 index 0000000..c544be4 Binary files /dev/null and b/apps/rider_new/assets/fonts/Inter-Regular.ttf differ diff --git a/apps/rider_new/assets/fonts/Inter-SemiBold.ttf b/apps/rider_new/assets/fonts/Inter-SemiBold.ttf new file mode 100644 index 0000000..a32e2b8 Binary files /dev/null and b/apps/rider_new/assets/fonts/Inter-SemiBold.ttf differ diff --git a/apps/rider_new/assets/fonts/digit.ttf b/apps/rider_new/assets/fonts/digit.ttf new file mode 100644 index 0000000..5dbe6f9 Binary files /dev/null and b/apps/rider_new/assets/fonts/digit.ttf differ diff --git a/apps/rider_new/assets/fonts/josefin.ttf b/apps/rider_new/assets/fonts/josefin.ttf new file mode 100644 index 0000000..98deb67 Binary files /dev/null and b/apps/rider_new/assets/fonts/josefin.ttf differ diff --git a/apps/rider_new/assets/fonts/mohanad.ttf b/apps/rider_new/assets/fonts/mohanad.ttf new file mode 100644 index 0000000..854341c Binary files /dev/null and b/apps/rider_new/assets/fonts/mohanad.ttf differ diff --git a/apps/rider_new/assets/images/2.png b/apps/rider_new/assets/images/2.png new file mode 100644 index 0000000..7567e84 Binary files /dev/null and b/apps/rider_new/assets/images/2.png differ diff --git a/apps/rider_new/assets/images/A.png b/apps/rider_new/assets/images/A.png new file mode 100644 index 0000000..246b9d2 Binary files /dev/null and b/apps/rider_new/assets/images/A.png differ diff --git a/apps/rider_new/assets/images/b.png b/apps/rider_new/assets/images/b.png new file mode 100644 index 0000000..b22f96c Binary files /dev/null and b/apps/rider_new/assets/images/b.png differ diff --git a/apps/rider_new/assets/images/balash.png b/apps/rider_new/assets/images/balash.png new file mode 100644 index 0000000..84977a2 Binary files /dev/null and b/apps/rider_new/assets/images/balash.png differ diff --git a/apps/rider_new/assets/images/blob.png b/apps/rider_new/assets/images/blob.png new file mode 100644 index 0000000..e45e42c Binary files /dev/null and b/apps/rider_new/assets/images/blob.png differ diff --git a/apps/rider_new/assets/images/brand.png b/apps/rider_new/assets/images/brand.png new file mode 100644 index 0000000..9282720 Binary files /dev/null and b/apps/rider_new/assets/images/brand.png differ diff --git a/apps/rider_new/assets/images/bus.png b/apps/rider_new/assets/images/bus.png new file mode 100644 index 0000000..a1e3958 Binary files /dev/null and b/apps/rider_new/assets/images/bus.png differ diff --git a/apps/rider_new/assets/images/car.png b/apps/rider_new/assets/images/car.png new file mode 100644 index 0000000..b078ecc Binary files /dev/null and b/apps/rider_new/assets/images/car.png differ diff --git a/apps/rider_new/assets/images/car3.png b/apps/rider_new/assets/images/car3.png new file mode 100644 index 0000000..41627ae Binary files /dev/null and b/apps/rider_new/assets/images/car3.png differ diff --git a/apps/rider_new/assets/images/carspeed.png b/apps/rider_new/assets/images/carspeed.png new file mode 100644 index 0000000..b8b2d37 Binary files /dev/null and b/apps/rider_new/assets/images/carspeed.png differ diff --git a/apps/rider_new/assets/images/cashMTN.png b/apps/rider_new/assets/images/cashMTN.png new file mode 100644 index 0000000..bae958b Binary files /dev/null and b/apps/rider_new/assets/images/cashMTN.png differ diff --git a/apps/rider_new/assets/images/education.png b/apps/rider_new/assets/images/education.png new file mode 100644 index 0000000..fcadd1b Binary files /dev/null and b/apps/rider_new/assets/images/education.png differ diff --git a/apps/rider_new/assets/images/electric.png b/apps/rider_new/assets/images/electric.png new file mode 100644 index 0000000..b2889b8 Binary files /dev/null and b/apps/rider_new/assets/images/electric.png differ diff --git a/apps/rider_new/assets/images/electric_car.jpg b/apps/rider_new/assets/images/electric_car.jpg new file mode 100644 index 0000000..b57b770 Binary files /dev/null and b/apps/rider_new/assets/images/electric_car.jpg differ diff --git a/apps/rider_new/assets/images/employmentType.png b/apps/rider_new/assets/images/employmentType.png new file mode 100644 index 0000000..8fdcf14 Binary files /dev/null and b/apps/rider_new/assets/images/employmentType.png differ diff --git a/apps/rider_new/assets/images/freeRide.png b/apps/rider_new/assets/images/freeRide.png new file mode 100644 index 0000000..0667d42 Binary files /dev/null and b/apps/rider_new/assets/images/freeRide.png differ diff --git a/apps/rider_new/assets/images/gender.png b/apps/rider_new/assets/images/gender.png new file mode 100644 index 0000000..134dccb Binary files /dev/null and b/apps/rider_new/assets/images/gender.png differ diff --git a/apps/rider_new/assets/images/jeep.png b/apps/rider_new/assets/images/jeep.png new file mode 100644 index 0000000..8f1cbf3 Binary files /dev/null and b/apps/rider_new/assets/images/jeep.png differ diff --git a/apps/rider_new/assets/images/lady.png b/apps/rider_new/assets/images/lady.png new file mode 100644 index 0000000..76277fe Binary files /dev/null and b/apps/rider_new/assets/images/lady.png differ diff --git a/apps/rider_new/assets/images/lady1.png b/apps/rider_new/assets/images/lady1.png new file mode 100644 index 0000000..2797b75 Binary files /dev/null and b/apps/rider_new/assets/images/lady1.png differ diff --git a/apps/rider_new/assets/images/login_hero.png b/apps/rider_new/assets/images/login_hero.png new file mode 100644 index 0000000..34bd669 Binary files /dev/null and b/apps/rider_new/assets/images/login_hero.png differ diff --git a/apps/rider_new/assets/images/logo.gif b/apps/rider_new/assets/images/logo.gif new file mode 100644 index 0000000..6bb621e Binary files /dev/null and b/apps/rider_new/assets/images/logo.gif differ diff --git a/apps/rider_new/assets/images/logo.png b/apps/rider_new/assets/images/logo.png new file mode 100644 index 0000000..34bd669 Binary files /dev/null and b/apps/rider_new/assets/images/logo.png differ diff --git a/apps/rider_new/assets/images/maritalStatus.png b/apps/rider_new/assets/images/maritalStatus.png new file mode 100644 index 0000000..121d555 Binary files /dev/null and b/apps/rider_new/assets/images/maritalStatus.png differ diff --git a/apps/rider_new/assets/images/moto.png b/apps/rider_new/assets/images/moto.png new file mode 100644 index 0000000..8257812 Binary files /dev/null and b/apps/rider_new/assets/images/moto.png differ diff --git a/apps/rider_new/assets/images/moto1.png b/apps/rider_new/assets/images/moto1.png new file mode 100644 index 0000000..80322db Binary files /dev/null and b/apps/rider_new/assets/images/moto1.png differ diff --git a/apps/rider_new/assets/images/mtn.png b/apps/rider_new/assets/images/mtn.png new file mode 100644 index 0000000..6aa6618 Binary files /dev/null and b/apps/rider_new/assets/images/mtn.png differ diff --git a/apps/rider_new/assets/images/name_hero.png b/apps/rider_new/assets/images/name_hero.png new file mode 100644 index 0000000..34bd669 Binary files /dev/null and b/apps/rider_new/assets/images/name_hero.png differ diff --git a/apps/rider_new/assets/images/notepad.png b/apps/rider_new/assets/images/notepad.png new file mode 100644 index 0000000..9536a4d Binary files /dev/null and b/apps/rider_new/assets/images/notepad.png differ diff --git a/apps/rider_new/assets/images/on1.png b/apps/rider_new/assets/images/on1.png new file mode 100644 index 0000000..4f75853 Binary files /dev/null and b/apps/rider_new/assets/images/on1.png differ diff --git a/apps/rider_new/assets/images/on2.png b/apps/rider_new/assets/images/on2.png new file mode 100644 index 0000000..83b4e38 Binary files /dev/null and b/apps/rider_new/assets/images/on2.png differ diff --git a/apps/rider_new/assets/images/on3.png b/apps/rider_new/assets/images/on3.png new file mode 100644 index 0000000..3fe9574 Binary files /dev/null and b/apps/rider_new/assets/images/on3.png differ diff --git a/apps/rider_new/assets/images/onboarding_1.png b/apps/rider_new/assets/images/onboarding_1.png new file mode 100644 index 0000000..7f04ae5 Binary files /dev/null and b/apps/rider_new/assets/images/onboarding_1.png differ diff --git a/apps/rider_new/assets/images/onboarding_2.png b/apps/rider_new/assets/images/onboarding_2.png new file mode 100644 index 0000000..2b08791 Binary files /dev/null and b/apps/rider_new/assets/images/onboarding_2.png differ diff --git a/apps/rider_new/assets/images/onboarding_3.png b/apps/rider_new/assets/images/onboarding_3.png new file mode 100644 index 0000000..cdcb027 Binary files /dev/null and b/apps/rider_new/assets/images/onboarding_3.png differ diff --git a/apps/rider_new/assets/images/picker.png b/apps/rider_new/assets/images/picker.png new file mode 100644 index 0000000..6a35bf3 Binary files /dev/null and b/apps/rider_new/assets/images/picker.png differ diff --git a/apps/rider_new/assets/images/pinkBike.png b/apps/rider_new/assets/images/pinkBike.png new file mode 100644 index 0000000..0ed4ec5 Binary files /dev/null and b/apps/rider_new/assets/images/pinkBike.png differ diff --git a/apps/rider_new/assets/images/roundtrip.png b/apps/rider_new/assets/images/roundtrip.png new file mode 100644 index 0000000..c6088ba Binary files /dev/null and b/apps/rider_new/assets/images/roundtrip.png differ diff --git a/apps/rider_new/assets/images/sedan.png b/apps/rider_new/assets/images/sedan.png new file mode 100644 index 0000000..c69e86d Binary files /dev/null and b/apps/rider_new/assets/images/sedan.png differ diff --git a/apps/rider_new/assets/images/shamCash.png b/apps/rider_new/assets/images/shamCash.png new file mode 100644 index 0000000..ab13ac0 Binary files /dev/null and b/apps/rider_new/assets/images/shamCash.png differ diff --git a/apps/rider_new/assets/images/shamcashsend.png b/apps/rider_new/assets/images/shamcashsend.png new file mode 100644 index 0000000..0814517 Binary files /dev/null and b/apps/rider_new/assets/images/shamcashsend.png differ diff --git a/apps/rider_new/assets/images/splash_logo.png b/apps/rider_new/assets/images/splash_logo.png new file mode 100644 index 0000000..34bd669 Binary files /dev/null and b/apps/rider_new/assets/images/splash_logo.png differ diff --git a/apps/rider_new/assets/images/syriatel.png b/apps/rider_new/assets/images/syriatel.png new file mode 100644 index 0000000..2facd27 Binary files /dev/null and b/apps/rider_new/assets/images/syriatel.png differ diff --git a/apps/rider_new/assets/start.wav b/apps/rider_new/assets/start.wav new file mode 100644 index 0000000..0655506 Binary files /dev/null and b/apps/rider_new/assets/start.wav differ diff --git a/apps/rider_new/assets/style.json b/apps/rider_new/assets/style.json new file mode 100644 index 0000000..feed983 --- /dev/null +++ b/apps/rider_new/assets/style.json @@ -0,0 +1,2178 @@ +{ + "version": 8, + "name": "Siro Premium — Light v2.9", + "metadata": { + "brand": "Siro", + "version": "2.10.0-light", + "description": "Siro light theme — buildings at close zoom only, on-road labels, improved arrows" + }, + "center": [ + 36.276008, + 33.513685 + ], + "zoom": 15, + "glyphs": "https://cdn.protomaps.com/fonts/pbf/{fontstack}/{range}.pbf", + "sprite": "https://demotiles.maplibre.org/styles/osm-bright-gl-style/sprite", + "sources": { + "local-osm-polygons": { + "type": "vector", + "tiles": [ + "https://tiles.intaleqapp.com/planet_osm_polygon/{z}/{x}/{y}" + ], + "maxzoom": 14, + "attribution": "© Siro | © OpenStreetMap contributors" + }, + "local-osm-lines": { + "type": "vector", + "tiles": [ + "https://tiles.intaleqapp.com/planet_osm_line/{z}/{x}/{y}" + ], + "maxzoom": 14 + }, + "local-osm-points": { + "type": "vector", + "tiles": [ + "https://tiles.intaleqapp.com/planet_osm_point/{z}/{x}/{y}" + ], + "maxzoom": 14 + }, + "places_egypt": { + "type": "vector", + "tiles": [ + "https://tiles.intaleqapp.com/places_egypt/{z}/{x}/{y}" + ], + "maxzoom": 14 + }, + "places_syria": { + "type": "vector", + "tiles": [ + "https://tiles.intaleqapp.com/places_syria/{z}/{x}/{y}" + ], + "maxzoom": 14 + }, + "places_jordan": { + "type": "vector", + "tiles": [ + "https://tiles.intaleqapp.com/places_jordan/{z}/{x}/{y}" + ], + "maxzoom": 14 + }, + "overture_buildings": { + "type": "vector", + "tiles": [ + "https://tiles.intaleqapp.com/overture_building/{z}/{x}/{y}" + ], + "maxzoom": 14 + }, + "overture_segments": { + "type": "vector", + "tiles": [ + "https://tiles.intaleqapp.com/overture_segment/{z}/{x}/{y}" + ], + "maxzoom": 14 + } + }, + "layers": [ + { + "id": "background", + "type": "background", + "paint": { + "background-color": "#EEF2F7" + } + }, + { + "id": "landuse-residential", + "type": "fill", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "==", + "landuse", + "residential" + ], + "paint": { + "fill-color": "#F0F4F8", + "fill-opacity": 1.0 + } + }, + { + "id": "landuse-commercial", + "type": "fill", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "==", + "landuse", + "commercial" + ], + "paint": { + "fill-color": "#FAF5EE", + "fill-opacity": 1.0 + } + }, + { + "id": "landuse-cemetery", + "type": "fill", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "==", + "landuse", + "cemetery" + ], + "paint": { + "fill-color": "#B8D4BA", + "fill-opacity": 1.0 + } + }, + { + "id": "landuse-military", + "type": "fill", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "==", + "landuse", + "military" + ], + "paint": { + "fill-color": "#E2D9CC", + "fill-opacity": 1.0 + } + }, + { + "id": "landuse-industrial", + "type": "fill", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "in", + "landuse", + "industrial", + "railway" + ], + "paint": { + "fill-color": "#E4E8EE", + "fill-opacity": 1 + } + }, + { + "id": "park-layer", + "type": "fill", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "any", + [ + "in", + "leisure", + "park", + "garden", + "nature_reserve", + "pitch", + "playground" + ], + [ + "in", + "landuse", + "grass", + "meadow", + "forest" + ], + [ + "in", + "natural", + "wood", + "scrub", + "heath" + ] + ], + "paint": { + "fill-color": [ + "match", + [ + "get", + "leisure" + ], + "pitch", + "#9ED4A0", + "playground", + "#B8E6B8", + "#C5E8C5" + ], + "fill-opacity": 0.85 + } + }, + { + "id": "park-outline", + "type": "line", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "in", + "leisure", + "park", + "garden", + "nature_reserve" + ], + "paint": { + "line-color": "#9ED4A0", + "line-width": 0.8, + "line-opacity": 0.6 + } + }, + { + "id": "water-polygon", + "type": "fill", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "any", + [ + "in", + "natural", + "water", + "lake", + "bay" + ], + [ + "==", + "waterway", + "riverbank" + ], + [ + "in", + "landuse", + "basin", + "reservoir" + ], + [ + "==", + "amenity", + "fountain" + ] + ], + "paint": { + "fill-color": "#9ECFE8", + "fill-opacity": 0.95 + } + }, + { + "id": "water-polygon-outline", + "type": "line", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "any", + [ + "in", + "natural", + "water", + "lake", + "bay" + ], + [ + "==", + "waterway", + "riverbank" + ], + [ + "in", + "landuse", + "basin", + "reservoir" + ] + ], + "paint": { + "line-color": "#6BB8D8", + "line-width": 0.8, + "line-opacity": 0.8 + } + }, + { + "id": "waterway-river", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "all", + [ + "in", + "waterway", + "river", + "canal" + ], + [ + "!=", + "intermittent", + "yes" + ], + [ + "!=", + "seasonal", + "yes" + ], + [ + "!=", + "tunnel", + "yes" + ] + ], + "paint": { + "line-color": "#6BB8D8", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 1.5, + 14, + 4, + 16, + 7 + ], + "line-opacity": 0.95 + } + }, + { + "id": "waterway-stream-drain", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "all", + [ + "in", + "waterway", + "stream", + "drain", + "ditch" + ], + [ + "!=", + "intermittent", + "yes" + ], + [ + "!=", + "seasonal", + "yes" + ], + [ + "!=", + "tunnel", + "yes" + ] + ], + "minzoom": 13, + "paint": { + "line-color": "#7FBFD8", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 13, + 0.8, + 16, + 2.5 + ], + "line-opacity": 0.85 + } + }, + { + "id": "railway-area", + "type": "fill", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "==", + "landuse", + "railway" + ], + "paint": { + "fill-color": "#DDE2EA", + "fill-opacity": 0.9 + } + }, + { + "id": "railway-rail-casing", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "all", + [ + "in", + "railway", + "rail", + "narrow_gauge", + "preserved" + ], + [ + "!=", + "service", + "yard" + ], + [ + "!=", + "service", + "siding" + ] + ], + "minzoom": 8, + "paint": { + "line-color": "#B0B8C5", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 8, + 2, + 12, + 4, + 16, + 8 + ] + } + }, + { + "id": "railway-rail-core", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "all", + [ + "in", + "railway", + "rail", + "narrow_gauge", + "preserved" + ], + [ + "!=", + "service", + "yard" + ], + [ + "!=", + "service", + "siding" + ] + ], + "minzoom": 8, + "paint": { + "line-color": "#6B7A8E", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 8, + 1, + 12, + 2.5, + 16, + 5 + ], + "line-dasharray": [ + 6, + 4 + ] + } + }, + { + "id": "railway-subway-casing", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "railway", + "subway", + "light_rail", + "tram", + "monorail" + ], + "minzoom": 10, + "paint": { + "line-color": [ + "match", + [ + "get", + "railway" + ], + "subway", + "#CC2233", + "light_rail", + "#0066CC", + "tram", + "#8833BB", + "monorail", + "#008855", + "#BB3344" + ], + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 3, + 14, + 6, + 16, + 10 + ] + } + }, + { + "id": "railway-subway-core", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "railway", + "subway", + "light_rail", + "tram", + "monorail" + ], + "minzoom": 10, + "paint": { + "line-color": [ + "match", + [ + "get", + "railway" + ], + "subway", + "#FF3347", + "light_rail", + "#2288FF", + "tram", + "#AA44EE", + "monorail", + "#00BB66", + "#FF4455" + ], + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 1.5, + 14, + 3.5, + 16, + 6 + ] + } + }, + { + "id": "road-casing-track-path", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "track", + "path", + "footway", + "cycleway", + "steps" + ], + "minzoom": 14, + "paint": { + "line-color": "#D4D8DF", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 14, + 1, + 16, + 4 + ], + "line-dasharray": [ + 4, + 3 + ] + } + }, + { + "id": "road-casing-minor", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "residential", + "service", + "unclassified", + "living_street", + "pedestrian" + ], + "paint": { + "line-color": "#D4D8DF", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 12, + 1.5, + 16, + 10 + ], + "line-opacity": 0.7 + } + }, + { + "id": "road-core-minor", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "residential", + "service", + "unclassified", + "living_street", + "pedestrian" + ], + "paint": { + "line-color": "#FFFFFF", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 12, + 0.8, + 16, + 8 + ] + } + }, + { + "id": "road-casing-tertiary", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "tertiary", + "tertiary_link" + ], + "paint": { + "line-color": "#C9CED8", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 11, + 2, + 16, + 14 + ], + "line-opacity": 0.75 + } + }, + { + "id": "road-core-tertiary", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "tertiary", + "tertiary_link" + ], + "paint": { + "line-color": "#FFFFFF", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 11, + 1.2, + 16, + 11 + ] + } + }, + { + "id": "road-casing-secondary", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "secondary", + "secondary_link" + ], + "paint": { + "line-color": "#C4CFDE", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 11, + 2.5, + 16, + 16 + ], + "line-opacity": 0.8 + } + }, + { + "id": "road-core-secondary", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "secondary", + "secondary_link" + ], + "paint": { + "line-color": "#F8FBFF", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 11, + 1.8, + 16, + 13 + ] + } + }, + { + "id": "road-casing-primary", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "primary", + "primary_link" + ], + "paint": { + "line-color": "#C8B868", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 3, + 16, + 18 + ], + "line-opacity": 0.7 + } + }, + { + "id": "road-core-primary", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "primary", + "primary_link" + ], + "paint": { + "line-color": "#EDD870", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 2, + 16, + 14 + ] + } + }, + { + "id": "road-casing-motorway", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "motorway", + "motorway_link", + "trunk", + "trunk_link" + ], + "paint": { + "line-color": "#C8A84B", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 9, + 4, + 16, + 20 + ], + "line-opacity": 0.75 + } + }, + { + "id": "road-core-motorway", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "motorway", + "motorway_link", + "trunk", + "trunk_link" + ], + "paint": { + "line-color": "#F0C040", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 9, + 2.5, + 16, + 16 + ] + } + }, + { + "id": "road-direction-arrows", + "type": "symbol", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "minzoom": 15, + "filter": [ + "all", + [ + "in", + "highway", + "motorway", + "trunk", + "primary", + "secondary", + "tertiary", + "residential", + "unclassified", + "living_street" + ], + [ + "==", + "oneway", + "yes" + ] + ], + "layout": { + "symbol-placement": "line", + "symbol-spacing": 120, + "text-field": "→", + "text-font": [ + "Noto Sans Regular" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + 16, + 17, + 22, + 19, + 28 + ], + "text-keep-upright": false, + "text-rotation-alignment": "map", + "text-pitch-alignment": "viewport", + "text-allow-overlap": true, + "text-ignore-placement": true, + "text-padding": 0, + "text-letter-spacing": -0.1 + }, + "paint": { + "text-color": "rgba(80,96,120,0.55)", + "text-halo-color": "rgba(255,255,255,0.25)", + "text-halo-width": 1 + } + }, + { + "id": "building-fill-flat", + "type": "fill", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "has", + "building" + ], + "minzoom": 15, + "maxzoom": 16, + "paint": { + "fill-color": "#DDD8D0", + "fill-opacity": 0.85, + "fill-outline-color": "#C4BEB4" + } + }, + { + "id": "building-3d", + "type": "fill-extrusion", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "minzoom": 16, + "filter": [ + "has", + "building" + ], + "paint": { + "fill-extrusion-color": "#DDD8D0", + "fill-extrusion-height": [ + "coalesce", + [ + "to-number", + [ + "get", + "height" + ] + ], + [ + "*", + [ + "to-number", + [ + "get", + "building:levels" + ], + 2 + ], + 3.5 + ], + 7 + ], + "fill-extrusion-base": [ + "coalesce", + [ + "to-number", + [ + "get", + "min_height" + ] + ], + 0 + ], + "fill-extrusion-opacity": 0.8, + "fill-extrusion-vertical-gradient": true + } + }, + { + "id": "building-3d-overture", + "type": "fill-extrusion", + "source": "overture_buildings", + "source-layer": "overture_building", + "minzoom": 16, + "paint": { + "fill-extrusion-color": [ + "match", + [ + "get", + "subtype" + ], + "commercial", + "#D8D0C0", + "retail", + "#E0D0B8", + "industrial", + "#C8D0DC", + "religious", + "#C8D4EC", + "education", + "#D4E0C4", + "medical", + "#E8D4D4", + "#DDD8D0" + ], + "fill-extrusion-height": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 16, + [ + "coalesce", + [ + "to-number", + [ + "get", + "height" + ] + ], + [ + "*", + [ + "coalesce", + [ + "to-number", + [ + "get", + "num_floors" + ] + ], + 3 + ], + 3.5 + ], + 9 + ], + 18, + [ + "coalesce", + [ + "to-number", + [ + "get", + "height" + ] + ], + [ + "*", + [ + "coalesce", + [ + "to-number", + [ + "get", + "num_floors" + ] + ], + 3 + ], + 3.5 + ], + 12 + ] + ], + "fill-extrusion-base": [ + "coalesce", + [ + "to-number", + [ + "get", + "min_height" + ] + ], + 0 + ], + "fill-extrusion-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + 0, + 16, + 0.6, + 17, + 0.88 + ], + "fill-extrusion-vertical-gradient": true + } + }, + { + "id": "overture-building-footprint", + "type": "fill", + "source": "overture_buildings", + "source-layer": "overture_building", + "minzoom": 15, + "maxzoom": 16, + "paint": { + "fill-color": "#DDD8D0", + "fill-opacity": 0.82, + "fill-outline-color": "#C4BEB4" + } + }, + { + "id": "railway-label", + "type": "symbol", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "railway", + "rail", + "subway", + "light_rail", + "tram" + ], + "minzoom": 13, + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 10, + "symbol-placement": "line", + "text-padding": 6, + "text-allow-overlap": false + }, + "paint": { + "text-color": [ + "match", + [ + "get", + "railway" + ], + "subway", + "#CC2233", + "light_rail", + "#0055BB", + "tram", + "#7722AA", + "#4A5568" + ], + "text-halo-color": "rgba(255,255,255,0.93)", + "text-halo-width": 2 + } + }, + { + "id": "waterway-label", + "type": "symbol", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "all", + [ + "in", + "waterway", + "river", + "canal" + ], + [ + "!=", + "intermittent", + "yes" + ], + [ + "has", + "name" + ] + ], + "minzoom": 12, + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 11, + "symbol-placement": "line", + "text-letter-spacing": 0.1 + }, + "paint": { + "text-color": "#2E86AB", + "text-halo-color": "rgba(255,255,255,0.93)", + "text-halo-width": 2 + } + }, + { + "id": "building-number-polygon", + "type": "symbol", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "minzoom": 17, + "filter": [ + "has", + "addr:housenumber" + ], + "layout": { + "text-field": "{addr:housenumber}", + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 10, + "text-allow-overlap": false + }, + "paint": { + "text-color": "#5A5048", + "text-halo-color": "rgba(255,255,255,0.93)", + "text-halo-width": 1.5 + } + }, + { + "id": "building-number-point", + "type": "symbol", + "source": "local-osm-points", + "source-layer": "planet_osm_point", + "minzoom": 17, + "filter": [ + "has", + "addr:housenumber" + ], + "layout": { + "text-field": "{addr:housenumber}", + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 10, + "text-allow-overlap": false + }, + "paint": { + "text-color": "#5A5048", + "text-halo-color": "rgba(255,255,255,0.93)", + "text-halo-width": 1.5 + } + }, + { + "id": "overture-building-names", + "type": "symbol", + "source": "overture_buildings", + "source-layer": "overture_building", + "minzoom": 17, + "filter": [ + "has", + "names" + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "names" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 10, + "text-anchor": "center", + "text-allow-overlap": false, + "text-max-width": 8 + }, + "paint": { + "text-color": "#5A5048", + "text-halo-color": "rgba(255,255,255,0.93)", + "text-halo-width": 1.5 + } + }, + { + "id": "road-labels-minor", + "type": "symbol", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "residential", + "service", + "unclassified", + "living_street" + ], + "minzoom": 16, + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 16, + 10, + 18, + 13 + ], + "symbol-placement": "line", + "text-rotation-alignment": "map", + "text-pitch-alignment": "viewport", + "text-keep-upright": true, + "text-max-angle": 25, + "symbol-spacing": 300, + "text-letter-spacing": 0.04, + "text-padding": 8, + "text-allow-overlap": false + }, + "paint": { + "text-color": "#4A5568", + "text-halo-color": "rgba(255,255,255,0.93)", + "text-halo-width": 1.8 + } + }, + { + "id": "road-labels-major", + "type": "symbol", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "primary", + "secondary", + "tertiary", + "motorway", + "trunk" + ], + "minzoom": 12, + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Bold" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 12, + 10, + 14, + 13, + 18, + 16 + ], + "symbol-placement": "line", + "text-rotation-alignment": "map", + "text-pitch-alignment": "viewport", + "text-keep-upright": true, + "text-max-angle": 22, + "symbol-spacing": 350, + "text-letter-spacing": 0.05, + "text-padding": 12, + "text-allow-overlap": false + }, + "paint": { + "text-color": "#1A2332", + "text-halo-color": "rgba(255,255,255,0.93)", + "text-halo-width": 2.5 + } + }, + { + "id": "overture-street-names", + "type": "symbol", + "source": "overture_segments", + "source-layer": "overture_segment", + "minzoom": 14, + "filter": [ + "has", + "names" + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "names" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 14, + 9, + 16, + 12, + 18, + 14 + ], + "symbol-placement": "line", + "text-rotation-alignment": "map", + "text-pitch-alignment": "viewport", + "text-keep-upright": true, + "text-max-angle": 28, + "symbol-spacing": 280, + "text-letter-spacing": 0.04, + "text-padding": 15, + "text-allow-overlap": false + }, + "paint": { + "text-color": "#4A5568", + "text-halo-color": "rgba(255,255,255,0.93)", + "text-halo-width": 2 + } + }, + { + "id": "poi-hospital", + "type": "symbol", + "source": "local-osm-points", + "source-layer": "planet_osm_point", + "minzoom": 13, + "filter": [ + "==", + "amenity", + "hospital" + ], + "layout": { + "icon-image": "hospital", + "icon-size": 1.0, + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 11, + "text-offset": [ + 0, + 1.2 + ], + "text-anchor": "top", + "text-allow-overlap": false + }, + "paint": { + "text-color": "#C0392B", + "text-halo-color": "rgba(255,255,255,0.93)", + "text-halo-width": 2 + } + }, + { + "id": "poi-pharmacy", + "type": "symbol", + "source": "local-osm-points", + "source-layer": "planet_osm_point", + "minzoom": 15, + "filter": [ + "==", + "amenity", + "pharmacy" + ], + "layout": { + "icon-image": "pharmacy", + "icon-size": 0.8, + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 11, + "text-offset": [ + 0, + 1.2 + ], + "text-anchor": "top", + "text-allow-overlap": false + }, + "paint": { + "text-color": "#1A7A3C", + "text-halo-color": "rgba(255,255,255,0.93)", + "text-halo-width": 2 + } + }, + { + "id": "poi-place-of-worship", + "type": "symbol", + "source": "local-osm-points", + "source-layer": "planet_osm_point", + "minzoom": 14, + "filter": [ + "==", + "amenity", + "place_of_worship" + ], + "layout": { + "icon-image": "tourist", + "icon-size": 0.8, + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 11, + "text-offset": [ + 0, + 1.2 + ], + "text-anchor": "top", + "text-allow-overlap": false + }, + "paint": { + "text-color": "#1A6B3A", + "text-halo-color": "rgba(255,255,255,0.93)", + "text-halo-width": 2 + } + }, + { + "id": "poi-school", + "type": "symbol", + "source": "local-osm-points", + "source-layer": "planet_osm_point", + "minzoom": 14, + "filter": [ + "in", + "amenity", + "school", + "university", + "college" + ], + "layout": { + "icon-image": "college", + "icon-size": 0.8, + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 11, + "text-offset": [ + 0, + 1.2 + ], + "text-anchor": "top", + "text-allow-overlap": false + }, + "paint": { + "text-color": "#5A4A8A", + "text-halo-color": "rgba(255,255,255,0.93)", + "text-halo-width": 2 + } + }, + { + "id": "poi-restaurant-cafe", + "type": "symbol", + "source": "local-osm-points", + "source-layer": "planet_osm_point", + "minzoom": 16, + "filter": [ + "in", + "amenity", + "restaurant", + "cafe", + "fast_food" + ], + "layout": { + "icon-image": [ + "match", + [ + "get", + "amenity" + ], + "cafe", + "cafe", + "restaurant" + ], + "icon-size": 0.8, + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 10, + "text-offset": [ + 0, + 1.2 + ], + "text-anchor": "top" + }, + "paint": { + "text-color": "#3D4A5C", + "text-halo-color": "rgba(255,255,255,0.93)", + "text-halo-width": 1.5 + } + }, + { + "id": "poi-transit-station", + "type": "symbol", + "source": "local-osm-points", + "source-layer": "planet_osm_point", + "minzoom": 12, + "filter": [ + "any", + [ + "==", + "railway", + "station" + ], + [ + "==", + "railway", + "halt" + ], + [ + "==", + "railway", + "tram_stop" + ], + [ + "==", + "station", + "subway" + ], + [ + "==", + "amenity", + "bus_station" + ] + ], + "layout": { + "icon-image": "rail", + "icon-size": 1, + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 11, + "text-offset": [ + 0, + 1.4 + ], + "text-anchor": "top", + "text-allow-overlap": false + }, + "paint": { + "text-color": "#CC2233", + "text-halo-color": "rgba(255,255,255,0.93)", + "text-halo-width": 2 + } + }, + { + "id": "place-labels-area", + "type": "symbol", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "minzoom": 10, + "filter": [ + "has", + "name" + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 10, + 14, + 13 + ], + "text-padding": 8, + "text-allow-overlap": false + }, + "paint": { + "text-color": "#34495E", + "text-halo-color": "rgba(255,255,255,0.93)", + "text-halo-width": 2 + } + }, + { + "id": "place-labels-point", + "type": "symbol", + "source": "local-osm-points", + "source-layer": "planet_osm_point", + "minzoom": 10, + "filter": [ + "any", + [ + "in", + "place", + "city", + "town", + "village", + "suburb", + "neighbourhood", + "hamlet", + "locality", + "quarter" + ], + [ + "in", + "natural", + "peak", + "spring" + ] + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + [ + "match", + [ + "get", + "place" + ], + "city", + 16, + "town", + 14, + 11 + ], + 14, + [ + "match", + [ + "get", + "place" + ], + "city", + 20, + "town", + 16, + 13 + ], + 17, + 14 + ], + "text-letter-spacing": [ + "match", + [ + "get", + "place" + ], + "city", + 0.08, + "town", + 0.05, + 0.02 + ], + "text-anchor": "center", + "text-padding": 10, + "text-allow-overlap": false + }, + "paint": { + "text-color": [ + "match", + [ + "get", + "place" + ], + "city", + "#1A2740", + "town", + "#2C3E50", + "suburb", + "#34495E", + "neighbourhood", + "#34495E", + "#34495E" + ], + "text-halo-color": "rgba(255,255,255,0.93)", + "text-halo-width": [ + "match", + [ + "get", + "place" + ], + "city", + 3, + "town", + 2.5, + 2 + ] + } + }, + { + "id": "places-egypt-labels", + "type": "symbol", + "source": "places_egypt", + "source-layer": "places_egypt", + "minzoom": 12, + "filter": [ + "!in", + "category", + "street" + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name_ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Bold" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 12, + 9, + 16, + 13 + ], + "text-offset": [ + 0, + 1.5 + ], + "text-anchor": "top", + "text-padding": 8, + "text-allow-overlap": false + }, + "paint": { + "text-color": "#2D3748", + "text-halo-color": "rgba(255,255,255,0.93)", + "text-halo-width": 2 + } + }, + { + "id": "places-syria-labels", + "type": "symbol", + "source": "places_syria", + "source-layer": "places_syria", + "minzoom": 10, + "filter": [ + "!in", + "category", + "street" + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name_ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Bold" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 12, + 9, + 16, + 13 + ], + "text-offset": [ + 0, + 1.5 + ], + "text-anchor": "top", + "text-padding": 8, + "text-allow-overlap": false + }, + "paint": { + "text-color": "#2D3748", + "text-halo-color": "rgba(255,255,255,0.93)", + "text-halo-width": 2 + } + }, + { + "id": "places-jordan-labels", + "type": "symbol", + "source": "places_jordan", + "source-layer": "places_jordan", + "minzoom": 10, + "filter": [ + "!in", + "category", + "street" + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name_ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Bold" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 12, + 9, + 16, + 13 + ], + "text-offset": [ + 0, + 1.5 + ], + "text-anchor": "top", + "text-padding": 8, + "text-allow-overlap": false + }, + "paint": { + "text-color": "#2D3748", + "text-halo-color": "rgba(255,255,255,0.93)", + "text-halo-width": 2 + } + } + ] +} \ No newline at end of file diff --git a/apps/rider_new/assets/style_dark.json b/apps/rider_new/assets/style_dark.json new file mode 100644 index 0000000..182c721 --- /dev/null +++ b/apps/rider_new/assets/style_dark.json @@ -0,0 +1,2178 @@ +{ + "version": 8, + "name": "Siro Premium — Dark v2.9", + "metadata": { + "brand": "Siro", + "version": "2.10.0-dark", + "description": "Siro dark theme — buildings at close zoom only, on-road labels, improved arrows" + }, + "center": [ + 36.276008, + 33.513685 + ], + "zoom": 15, + "glyphs": "https://cdn.protomaps.com/fonts/pbf/{fontstack}/{range}.pbf", + "sprite": "https://demotiles.maplibre.org/styles/osm-bright-gl-style/sprite", + "sources": { + "local-osm-polygons": { + "type": "vector", + "tiles": [ + "https://tiles.intaleqapp.com/planet_osm_polygon/{z}/{x}/{y}" + ], + "maxzoom": 14, + "attribution": "© Siro | © OpenStreetMap contributors" + }, + "local-osm-lines": { + "type": "vector", + "tiles": [ + "https://tiles.intaleqapp.com/planet_osm_line/{z}/{x}/{y}" + ], + "maxzoom": 14 + }, + "local-osm-points": { + "type": "vector", + "tiles": [ + "https://tiles.intaleqapp.com/planet_osm_point/{z}/{x}/{y}" + ], + "maxzoom": 14 + }, + "places_egypt": { + "type": "vector", + "tiles": [ + "https://tiles.intaleqapp.com/places_egypt/{z}/{x}/{y}" + ], + "maxzoom": 14 + }, + "places_syria": { + "type": "vector", + "tiles": [ + "https://tiles.intaleqapp.com/places_syria/{z}/{x}/{y}" + ], + "maxzoom": 14 + }, + "places_jordan": { + "type": "vector", + "tiles": [ + "https://tiles.intaleqapp.com/places_jordan/{z}/{x}/{y}" + ], + "maxzoom": 14 + }, + "overture_buildings": { + "type": "vector", + "tiles": [ + "https://tiles.intaleqapp.com/overture_building/{z}/{x}/{y}" + ], + "maxzoom": 14 + }, + "overture_segments": { + "type": "vector", + "tiles": [ + "https://tiles.intaleqapp.com/overture_segment/{z}/{x}/{y}" + ], + "maxzoom": 14 + } + }, + "layers": [ + { + "id": "background", + "type": "background", + "paint": { + "background-color": "#141920" + } + }, + { + "id": "landuse-residential", + "type": "fill", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "==", + "landuse", + "residential" + ], + "paint": { + "fill-color": "#1A2130", + "fill-opacity": 0.9 + } + }, + { + "id": "landuse-commercial", + "type": "fill", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "==", + "landuse", + "commercial" + ], + "paint": { + "fill-color": "#1E1C18", + "fill-opacity": 0.9 + } + }, + { + "id": "landuse-cemetery", + "type": "fill", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "==", + "landuse", + "cemetery" + ], + "paint": { + "fill-color": "#1A2E1A", + "fill-opacity": 0.9 + } + }, + { + "id": "landuse-military", + "type": "fill", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "==", + "landuse", + "military" + ], + "paint": { + "fill-color": "#28241C", + "fill-opacity": 0.9 + } + }, + { + "id": "landuse-industrial", + "type": "fill", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "in", + "landuse", + "industrial", + "railway" + ], + "paint": { + "fill-color": "#1C2028", + "fill-opacity": 1 + } + }, + { + "id": "park-layer", + "type": "fill", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "any", + [ + "in", + "leisure", + "park", + "garden", + "nature_reserve", + "pitch", + "playground" + ], + [ + "in", + "landuse", + "grass", + "meadow", + "forest" + ], + [ + "in", + "natural", + "wood", + "scrub", + "heath" + ] + ], + "paint": { + "fill-color": [ + "match", + [ + "get", + "leisure" + ], + "pitch", + "#1A3020", + "playground", + "#1C2A1C", + "#172217" + ], + "fill-opacity": 0.85 + } + }, + { + "id": "park-outline", + "type": "line", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "in", + "leisure", + "park", + "garden", + "nature_reserve" + ], + "paint": { + "line-color": "#1A3020", + "line-width": 0.8, + "line-opacity": 0.6 + } + }, + { + "id": "water-polygon", + "type": "fill", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "any", + [ + "in", + "natural", + "water", + "lake", + "bay" + ], + [ + "==", + "waterway", + "riverbank" + ], + [ + "in", + "landuse", + "basin", + "reservoir" + ], + [ + "==", + "amenity", + "fountain" + ] + ], + "paint": { + "fill-color": "#0D2A40", + "fill-opacity": 0.95 + } + }, + { + "id": "water-polygon-outline", + "type": "line", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "any", + [ + "in", + "natural", + "water", + "lake", + "bay" + ], + [ + "==", + "waterway", + "riverbank" + ], + [ + "in", + "landuse", + "basin", + "reservoir" + ] + ], + "paint": { + "line-color": "#1A4A6A", + "line-width": 0.8, + "line-opacity": 0.8 + } + }, + { + "id": "waterway-river", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "all", + [ + "in", + "waterway", + "river", + "canal" + ], + [ + "!=", + "intermittent", + "yes" + ], + [ + "!=", + "seasonal", + "yes" + ], + [ + "!=", + "tunnel", + "yes" + ] + ], + "paint": { + "line-color": "#1A4A6A", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 1.5, + 14, + 4, + 16, + 7 + ], + "line-opacity": 0.95 + } + }, + { + "id": "waterway-stream-drain", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "all", + [ + "in", + "waterway", + "stream", + "drain", + "ditch" + ], + [ + "!=", + "intermittent", + "yes" + ], + [ + "!=", + "seasonal", + "yes" + ], + [ + "!=", + "tunnel", + "yes" + ] + ], + "minzoom": 13, + "paint": { + "line-color": "#153A52", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 13, + 0.8, + 16, + 2.5 + ], + "line-opacity": 0.85 + } + }, + { + "id": "railway-area", + "type": "fill", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "==", + "landuse", + "railway" + ], + "paint": { + "fill-color": "#202830", + "fill-opacity": 0.9 + } + }, + { + "id": "railway-rail-casing", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "all", + [ + "in", + "railway", + "rail", + "narrow_gauge", + "preserved" + ], + [ + "!=", + "service", + "yard" + ], + [ + "!=", + "service", + "siding" + ] + ], + "minzoom": 8, + "paint": { + "line-color": "#3A4050", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 8, + 2, + 12, + 4, + 16, + 8 + ] + } + }, + { + "id": "railway-rail-core", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "all", + [ + "in", + "railway", + "rail", + "narrow_gauge", + "preserved" + ], + [ + "!=", + "service", + "yard" + ], + [ + "!=", + "service", + "siding" + ] + ], + "minzoom": 8, + "paint": { + "line-color": "#4A5568", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 8, + 1, + 12, + 2.5, + 16, + 5 + ], + "line-dasharray": [ + 6, + 4 + ] + } + }, + { + "id": "railway-subway-casing", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "railway", + "subway", + "light_rail", + "tram", + "monorail" + ], + "minzoom": 10, + "paint": { + "line-color": [ + "match", + [ + "get", + "railway" + ], + "subway", + "#AA1122", + "light_rail", + "#0055AA", + "tram", + "#7722AA", + "monorail", + "#007744", + "#BB3344" + ], + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 3, + 14, + 6, + 16, + 10 + ] + } + }, + { + "id": "railway-subway-core", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "railway", + "subway", + "light_rail", + "tram", + "monorail" + ], + "minzoom": 10, + "paint": { + "line-color": [ + "match", + [ + "get", + "railway" + ], + "subway", + "#FF4455", + "light_rail", + "#33AAFF", + "tram", + "#CC55FF", + "monorail", + "#00DD88", + "#FF4455" + ], + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 1.5, + 14, + 3.5, + 16, + 6 + ] + } + }, + { + "id": "road-casing-track-path", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "track", + "path", + "footway", + "cycleway", + "steps" + ], + "minzoom": 14, + "paint": { + "line-color": "#252C38", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 14, + 1, + 16, + 4 + ], + "line-dasharray": [ + 4, + 3 + ] + } + }, + { + "id": "road-casing-minor", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "residential", + "service", + "unclassified", + "living_street", + "pedestrian" + ], + "paint": { + "line-color": "#252C38", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 12, + 1.5, + 16, + 10 + ], + "line-opacity": 0.7 + } + }, + { + "id": "road-core-minor", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "residential", + "service", + "unclassified", + "living_street", + "pedestrian" + ], + "paint": { + "line-color": "#2E3848", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 12, + 0.8, + 16, + 8 + ] + } + }, + { + "id": "road-casing-tertiary", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "tertiary", + "tertiary_link" + ], + "paint": { + "line-color": "#2A3040", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 11, + 2, + 16, + 14 + ], + "line-opacity": 0.75 + } + }, + { + "id": "road-core-tertiary", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "tertiary", + "tertiary_link" + ], + "paint": { + "line-color": "#38465A", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 11, + 1.2, + 16, + 11 + ] + } + }, + { + "id": "road-casing-secondary", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "secondary", + "secondary_link" + ], + "paint": { + "line-color": "#3A3010", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 11, + 2.5, + 16, + 16 + ], + "line-opacity": 0.8 + } + }, + { + "id": "road-core-secondary", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "secondary", + "secondary_link" + ], + "paint": { + "line-color": "#4A3E18", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 11, + 1.8, + 16, + 13 + ] + } + }, + { + "id": "road-casing-primary", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "primary", + "primary_link" + ], + "paint": { + "line-color": "#5A4A10", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 3, + 16, + 18 + ], + "line-opacity": 0.7 + } + }, + { + "id": "road-core-primary", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "primary", + "primary_link" + ], + "paint": { + "line-color": "#7A6418", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 2, + 16, + 14 + ] + } + }, + { + "id": "road-casing-motorway", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "motorway", + "motorway_link", + "trunk", + "trunk_link" + ], + "paint": { + "line-color": "#6A5010", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 9, + 4, + 16, + 20 + ], + "line-opacity": 0.75 + } + }, + { + "id": "road-core-motorway", + "type": "line", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "motorway", + "motorway_link", + "trunk", + "trunk_link" + ], + "paint": { + "line-color": "#8A6A18", + "line-width": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 9, + 2.5, + 16, + 16 + ] + } + }, + { + "id": "road-direction-arrows", + "type": "symbol", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "minzoom": 15, + "filter": [ + "all", + [ + "in", + "highway", + "motorway", + "trunk", + "primary", + "secondary", + "tertiary", + "residential", + "unclassified", + "living_street" + ], + [ + "==", + "oneway", + "yes" + ] + ], + "layout": { + "symbol-placement": "line", + "symbol-spacing": 120, + "text-field": "→", + "text-font": [ + "Noto Sans Regular" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + 16, + 17, + 22, + 19, + 28 + ], + "text-keep-upright": false, + "text-rotation-alignment": "map", + "text-pitch-alignment": "viewport", + "text-allow-overlap": true, + "text-ignore-placement": true, + "text-padding": 0, + "text-letter-spacing": -0.1 + }, + "paint": { + "text-color": "rgba(160,180,210,0.5)", + "text-halo-color": "rgba(0,0,0,0.3)", + "text-halo-width": 1 + } + }, + { + "id": "building-fill-flat", + "type": "fill", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "filter": [ + "has", + "building" + ], + "minzoom": 15, + "maxzoom": 16, + "paint": { + "fill-color": "#252C38", + "fill-opacity": 0.85, + "fill-outline-color": "#1E2530" + } + }, + { + "id": "building-3d", + "type": "fill-extrusion", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "minzoom": 16, + "filter": [ + "has", + "building" + ], + "paint": { + "fill-extrusion-color": "#252C38", + "fill-extrusion-height": [ + "coalesce", + [ + "to-number", + [ + "get", + "height" + ] + ], + [ + "*", + [ + "to-number", + [ + "get", + "building:levels" + ], + 2 + ], + 3.5 + ], + 7 + ], + "fill-extrusion-base": [ + "coalesce", + [ + "to-number", + [ + "get", + "min_height" + ] + ], + 0 + ], + "fill-extrusion-opacity": 0.8, + "fill-extrusion-vertical-gradient": true + } + }, + { + "id": "building-3d-overture", + "type": "fill-extrusion", + "source": "overture_buildings", + "source-layer": "overture_building", + "minzoom": 16, + "paint": { + "fill-extrusion-color": [ + "match", + [ + "get", + "subtype" + ], + "commercial", + "#2A3A50", + "retail", + "#2E3A4A", + "industrial", + "#1E2A38", + "religious", + "#24203A", + "education", + "#1E3024", + "medical", + "#3A2020", + "#2A3245" + ], + "fill-extrusion-height": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 16, + [ + "coalesce", + [ + "to-number", + [ + "get", + "height" + ] + ], + [ + "*", + [ + "coalesce", + [ + "to-number", + [ + "get", + "num_floors" + ] + ], + 3 + ], + 3.5 + ], + 9 + ], + 18, + [ + "coalesce", + [ + "to-number", + [ + "get", + "height" + ] + ], + [ + "*", + [ + "coalesce", + [ + "to-number", + [ + "get", + "num_floors" + ] + ], + 3 + ], + 3.5 + ], + 12 + ] + ], + "fill-extrusion-base": [ + "coalesce", + [ + "to-number", + [ + "get", + "min_height" + ] + ], + 0 + ], + "fill-extrusion-opacity": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 15, + 0, + 16, + 0.6, + 17, + 0.88 + ], + "fill-extrusion-vertical-gradient": true + } + }, + { + "id": "overture-building-footprint", + "type": "fill", + "source": "overture_buildings", + "source-layer": "overture_building", + "minzoom": 15, + "maxzoom": 16, + "paint": { + "fill-color": "#252C38", + "fill-opacity": 0.82, + "fill-outline-color": "#1E2530" + } + }, + { + "id": "railway-label", + "type": "symbol", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "railway", + "rail", + "subway", + "light_rail", + "tram" + ], + "minzoom": 13, + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 10, + "symbol-placement": "line", + "text-padding": 6, + "text-allow-overlap": false + }, + "paint": { + "text-color": [ + "match", + [ + "get", + "railway" + ], + "subway", + "#FF5566", + "light_rail", + "#0055BB", + "tram", + "#7722AA", + "#4A5568" + ], + "text-halo-color": "rgba(20,25,32,0.92)", + "text-halo-width": 2 + } + }, + { + "id": "waterway-label", + "type": "symbol", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "all", + [ + "in", + "waterway", + "river", + "canal" + ], + [ + "!=", + "intermittent", + "yes" + ], + [ + "has", + "name" + ] + ], + "minzoom": 12, + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 11, + "symbol-placement": "line", + "text-letter-spacing": 0.1 + }, + "paint": { + "text-color": "#4AA8D8", + "text-halo-color": "rgba(20,25,32,0.92)", + "text-halo-width": 2 + } + }, + { + "id": "building-number-polygon", + "type": "symbol", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "minzoom": 17, + "filter": [ + "has", + "addr:housenumber" + ], + "layout": { + "text-field": "{addr:housenumber}", + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 10, + "text-allow-overlap": false + }, + "paint": { + "text-color": "#8898A8", + "text-halo-color": "rgba(20,25,32,0.92)", + "text-halo-width": 1.5 + } + }, + { + "id": "building-number-point", + "type": "symbol", + "source": "local-osm-points", + "source-layer": "planet_osm_point", + "minzoom": 17, + "filter": [ + "has", + "addr:housenumber" + ], + "layout": { + "text-field": "{addr:housenumber}", + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 10, + "text-allow-overlap": false + }, + "paint": { + "text-color": "#8898A8", + "text-halo-color": "rgba(20,25,32,0.92)", + "text-halo-width": 1.5 + } + }, + { + "id": "overture-building-names", + "type": "symbol", + "source": "overture_buildings", + "source-layer": "overture_building", + "minzoom": 17, + "filter": [ + "has", + "names" + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "names" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 10, + "text-anchor": "center", + "text-allow-overlap": false, + "text-max-width": 8 + }, + "paint": { + "text-color": "#8898A8", + "text-halo-color": "rgba(20,25,32,0.92)", + "text-halo-width": 1.5 + } + }, + { + "id": "road-labels-minor", + "type": "symbol", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "residential", + "service", + "unclassified", + "living_street" + ], + "minzoom": 16, + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 16, + 10, + 18, + 13 + ], + "symbol-placement": "line", + "text-rotation-alignment": "map", + "text-pitch-alignment": "viewport", + "text-keep-upright": true, + "text-max-angle": 25, + "symbol-spacing": 300, + "text-letter-spacing": 0.04, + "text-padding": 8, + "text-allow-overlap": false + }, + "paint": { + "text-color": "#8BA0B8", + "text-halo-color": "rgba(20,25,32,0.92)", + "text-halo-width": 1.8 + } + }, + { + "id": "road-labels-major", + "type": "symbol", + "source": "local-osm-lines", + "source-layer": "planet_osm_line", + "filter": [ + "in", + "highway", + "primary", + "secondary", + "tertiary", + "motorway", + "trunk" + ], + "minzoom": 12, + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Bold" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 12, + 10, + 14, + 13, + 18, + 16 + ], + "symbol-placement": "line", + "text-rotation-alignment": "map", + "text-pitch-alignment": "viewport", + "text-keep-upright": true, + "text-max-angle": 22, + "symbol-spacing": 350, + "text-letter-spacing": 0.05, + "text-padding": 12, + "text-allow-overlap": false + }, + "paint": { + "text-color": "#C8D8E8", + "text-halo-color": "rgba(20,25,32,0.92)", + "text-halo-width": 2.5 + } + }, + { + "id": "overture-street-names", + "type": "symbol", + "source": "overture_segments", + "source-layer": "overture_segment", + "minzoom": 14, + "filter": [ + "has", + "names" + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "names" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 14, + 9, + 16, + 12, + 18, + 14 + ], + "symbol-placement": "line", + "text-rotation-alignment": "map", + "text-pitch-alignment": "viewport", + "text-keep-upright": true, + "text-max-angle": 28, + "symbol-spacing": 280, + "text-letter-spacing": 0.04, + "text-padding": 15, + "text-allow-overlap": false + }, + "paint": { + "text-color": "#8BA0B8", + "text-halo-color": "rgba(20,25,32,0.92)", + "text-halo-width": 2 + } + }, + { + "id": "poi-hospital", + "type": "symbol", + "source": "local-osm-points", + "source-layer": "planet_osm_point", + "minzoom": 13, + "filter": [ + "==", + "amenity", + "hospital" + ], + "layout": { + "icon-image": "hospital", + "icon-size": 1.0, + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 11, + "text-offset": [ + 0, + 1.2 + ], + "text-anchor": "top", + "text-allow-overlap": false + }, + "paint": { + "text-color": "#FF6B6B", + "text-halo-color": "rgba(20,25,32,0.92)", + "text-halo-width": 2 + } + }, + { + "id": "poi-pharmacy", + "type": "symbol", + "source": "local-osm-points", + "source-layer": "planet_osm_point", + "minzoom": 15, + "filter": [ + "==", + "amenity", + "pharmacy" + ], + "layout": { + "icon-image": "pharmacy", + "icon-size": 0.8, + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 11, + "text-offset": [ + 0, + 1.2 + ], + "text-anchor": "top", + "text-allow-overlap": false + }, + "paint": { + "text-color": "#4ADB80", + "text-halo-color": "rgba(20,25,32,0.92)", + "text-halo-width": 2 + } + }, + { + "id": "poi-place-of-worship", + "type": "symbol", + "source": "local-osm-points", + "source-layer": "planet_osm_point", + "minzoom": 14, + "filter": [ + "==", + "amenity", + "place_of_worship" + ], + "layout": { + "icon-image": "tourist", + "icon-size": 0.8, + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 11, + "text-offset": [ + 0, + 1.2 + ], + "text-anchor": "top", + "text-allow-overlap": false + }, + "paint": { + "text-color": "#4ACA78", + "text-halo-color": "rgba(20,25,32,0.92)", + "text-halo-width": 2 + } + }, + { + "id": "poi-school", + "type": "symbol", + "source": "local-osm-points", + "source-layer": "planet_osm_point", + "minzoom": 14, + "filter": [ + "in", + "amenity", + "school", + "university", + "college" + ], + "layout": { + "icon-image": "college", + "icon-size": 0.8, + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 11, + "text-offset": [ + 0, + 1.2 + ], + "text-anchor": "top", + "text-allow-overlap": false + }, + "paint": { + "text-color": "#A888E8", + "text-halo-color": "rgba(20,25,32,0.92)", + "text-halo-width": 2 + } + }, + { + "id": "poi-restaurant-cafe", + "type": "symbol", + "source": "local-osm-points", + "source-layer": "planet_osm_point", + "minzoom": 16, + "filter": [ + "in", + "amenity", + "restaurant", + "cafe", + "fast_food" + ], + "layout": { + "icon-image": [ + "match", + [ + "get", + "amenity" + ], + "cafe", + "cafe", + "restaurant" + ], + "icon-size": 0.8, + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 10, + "text-offset": [ + 0, + 1.2 + ], + "text-anchor": "top" + }, + "paint": { + "text-color": "#A0B8D0", + "text-halo-color": "rgba(20,25,32,0.92)", + "text-halo-width": 1.5 + } + }, + { + "id": "poi-transit-station", + "type": "symbol", + "source": "local-osm-points", + "source-layer": "planet_osm_point", + "minzoom": 12, + "filter": [ + "any", + [ + "==", + "railway", + "station" + ], + [ + "==", + "railway", + "halt" + ], + [ + "==", + "railway", + "tram_stop" + ], + [ + "==", + "station", + "subway" + ], + [ + "==", + "amenity", + "bus_station" + ] + ], + "layout": { + "icon-image": "rail", + "icon-size": 1, + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": 11, + "text-offset": [ + 0, + 1.4 + ], + "text-anchor": "top", + "text-allow-overlap": false + }, + "paint": { + "text-color": "#FF5566", + "text-halo-color": "rgba(20,25,32,0.92)", + "text-halo-width": 2 + } + }, + { + "id": "place-labels-area", + "type": "symbol", + "source": "local-osm-polygons", + "source-layer": "planet_osm_polygon", + "minzoom": 10, + "filter": [ + "has", + "name" + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + 10, + 14, + 13 + ], + "text-padding": 8, + "text-allow-overlap": false + }, + "paint": { + "text-color": "#8AA0B8", + "text-halo-color": "rgba(20,25,32,0.92)", + "text-halo-width": 2 + } + }, + { + "id": "place-labels-point", + "type": "symbol", + "source": "local-osm-points", + "source-layer": "planet_osm_point", + "minzoom": 10, + "filter": [ + "any", + [ + "in", + "place", + "city", + "town", + "village", + "suburb", + "neighbourhood", + "hamlet", + "locality", + "quarter" + ], + [ + "in", + "natural", + "peak", + "spring" + ] + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name:ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Regular" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 10, + [ + "match", + [ + "get", + "place" + ], + "city", + 16, + "town", + 14, + 11 + ], + 14, + [ + "match", + [ + "get", + "place" + ], + "city", + 20, + "town", + 16, + 13 + ], + 17, + 14 + ], + "text-letter-spacing": [ + "match", + [ + "get", + "place" + ], + "city", + 0.08, + "town", + 0.05, + 0.02 + ], + "text-anchor": "center", + "text-padding": 10, + "text-allow-overlap": false + }, + "paint": { + "text-color": [ + "match", + [ + "get", + "place" + ], + "city", + "#D0E0F0", + "town", + "#B8CDE0", + "suburb", + "#8AA0B8", + "neighbourhood", + "#8AA0B8", + "#8AA0B8" + ], + "text-halo-color": "rgba(20,25,32,0.92)", + "text-halo-width": [ + "match", + [ + "get", + "place" + ], + "city", + 3, + "town", + 2.5, + 2 + ] + } + }, + { + "id": "places-egypt-labels", + "type": "symbol", + "source": "places_egypt", + "source-layer": "places_egypt", + "minzoom": 12, + "filter": [ + "!in", + "category", + "street" + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name_ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Bold" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 12, + 9, + 16, + 13 + ], + "text-offset": [ + 0, + 1.5 + ], + "text-anchor": "top", + "text-padding": 8, + "text-allow-overlap": false + }, + "paint": { + "text-color": "#A8C0D8", + "text-halo-color": "rgba(20,25,32,0.92)", + "text-halo-width": 2 + } + }, + { + "id": "places-syria-labels", + "type": "symbol", + "source": "places_syria", + "source-layer": "places_syria", + "minzoom": 10, + "filter": [ + "!in", + "category", + "street" + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name_ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Bold" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 12, + 9, + 16, + 13 + ], + "text-offset": [ + 0, + 1.5 + ], + "text-anchor": "top", + "text-padding": 8, + "text-allow-overlap": false + }, + "paint": { + "text-color": "#A8C0D8", + "text-halo-color": "rgba(20,25,32,0.92)", + "text-halo-width": 2 + } + }, + { + "id": "places-jordan-labels", + "type": "symbol", + "source": "places_jordan", + "source-layer": "places_jordan", + "minzoom": 10, + "filter": [ + "!in", + "category", + "street" + ], + "layout": { + "text-field": [ + "coalesce", + [ + "get", + "name_ar" + ], + [ + "get", + "name" + ], + "" + ], + "text-font": [ + "Noto Sans Bold" + ], + "text-size": [ + "interpolate", + [ + "linear" + ], + [ + "zoom" + ], + 12, + 9, + 16, + 13 + ], + "text-offset": [ + 0, + 1.5 + ], + "text-anchor": "top", + "text-padding": 8, + "text-allow-overlap": false + }, + "paint": { + "text-color": "#A8C0D8", + "text-halo-color": "rgba(20,25,32,0.92)", + "text-halo-width": 2 + } + } + ] +} \ No newline at end of file diff --git a/apps/rider_new/ios/.gitignore b/apps/rider_new/ios/.gitignore new file mode 100644 index 0000000..7a7f987 --- /dev/null +++ b/apps/rider_new/ios/.gitignore @@ -0,0 +1,34 @@ +**/dgph +*.mode1v3 +*.mode2v3 +*.moved-aside +*.pbxuser +*.perspectivev3 +**/*sync/ +.sconsign.dblite +.tags* +**/.vagrant/ +**/DerivedData/ +Icon? +**/Pods/ +**/.symlinks/ +profile +xcuserdata +**/.generated/ +Flutter/App.framework +Flutter/Flutter.framework +Flutter/Flutter.podspec +Flutter/Generated.xcconfig +Flutter/ephemeral/ +Flutter/app.flx +Flutter/app.zip +Flutter/flutter_assets/ +Flutter/flutter_export_environment.sh +ServiceDefinitions.json +Runner/GeneratedPluginRegistrant.* + +# Exceptions to above rules. +!default.mode1v3 +!default.mode2v3 +!default.pbxuser +!default.perspectivev3 diff --git a/apps/rider_new/ios/Flutter/AppFrameworkInfo.plist b/apps/rider_new/ios/Flutter/AppFrameworkInfo.plist new file mode 100644 index 0000000..391a902 --- /dev/null +++ b/apps/rider_new/ios/Flutter/AppFrameworkInfo.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + + diff --git a/apps/rider_new/ios/Flutter/Debug.xcconfig b/apps/rider_new/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..ec97fc6 --- /dev/null +++ b/apps/rider_new/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/apps/rider_new/ios/Flutter/Release.xcconfig b/apps/rider_new/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..c4855bf --- /dev/null +++ b/apps/rider_new/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/apps/rider_new/ios/Podfile b/apps/rider_new/ios/Podfile new file mode 100644 index 0000000..e351348 --- /dev/null +++ b/apps/rider_new/ios/Podfile @@ -0,0 +1,56 @@ +# Uncomment this line to define a global platform for your project +platform :ios, '16.1' +$iOSVersion = '16.1' # or newer version + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) + target 'RunnerTests' do + inherit! :search_paths + end +end + +post_install do |installer| + # add these lines: + installer.pods_project.build_configurations.each do |config| + config.build_settings["EXCLUDED_ARCHS[sdk=*]"] = "armv7" + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = $iOSVersion + end + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + # add these lines: + target.build_configurations.each do |config| + if Gem::Version.new($iOSVersion) > Gem::Version.new(config.build_settings['IPHONEOS_DEPLOYMENT_TARGET']) + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = $iOSVersion + end + end + end +end + diff --git a/apps/rider_new/ios/Runner.xcodeproj/project.pbxproj b/apps/rider_new/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..d6f57ea --- /dev/null +++ b/apps/rider_new/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,842 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXBuildFile section */ + 0E2EB9A18A85A8C79C1A5B17 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 27958A27956787B6764BC14F /* Pods_RunnerTests.framework */; }; + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + C60CA7372BE9EF38002095B2 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = C60CA7362BE9EF38002095B2 /* GoogleService-Info.plist */; }; + C6229B682D610CB20014397D /* JailbreakDetection.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6229B672D610C970014397D /* JailbreakDetection.swift */; }; + C624C4642BD56D34002834AF /* tone1.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = C624C45C2BD56D34002834AF /* tone1.mp3 */; }; + C624C4652BD56D34002834AF /* start.wav in Resources */ = {isa = PBXBuildFile; fileRef = C624C45D2BD56D34002834AF /* start.wav */; }; + C624C4672BD56D34002834AF /* promo.wav in Resources */ = {isa = PBXBuildFile; fileRef = C624C45F2BD56D34002834AF /* promo.wav */; }; + C624C4682BD56D34002834AF /* cancel.wav in Resources */ = {isa = PBXBuildFile; fileRef = C624C4602BD56D34002834AF /* cancel.wav */; }; + C628BC412C316B1200E4D33B /* ding.wav in Resources */ = {isa = PBXBuildFile; fileRef = C628BC402C316B1100E4D33B /* ding.wav */; }; + C6372AD92D81BDE000C44265 /* SecurityChecks.m in Sources */ = {isa = PBXBuildFile; fileRef = C6372AD82D81BDE000C44265 /* SecurityChecks.m */; }; + C6372ADF2D81C68C00C44265 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C6372ADE2D81C68700C44265 /* Localizable.strings */; }; + C6372AE42D81F10E00C44265 /* KeychainHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6372AE32D81F10A00C44265 /* KeychainHelper.swift */; }; + C6372AE62D82EB9C00C44265 /* Config.plist in Resources */ = {isa = PBXBuildFile; fileRef = C6372AE52D82EB9C00C44265 /* Config.plist */; }; + C6B15AA12B5FB24600746405 /* order.wav in Resources */ = {isa = PBXBuildFile; fileRef = C6B15A9F2B5FB24600746405 /* order.wav */; }; + C6B15AA22B5FB24600746405 /* tone2.wav in Resources */ = {isa = PBXBuildFile; fileRef = C6B15AA02B5FB24600746405 /* tone2.wav */; }; + C6B450142D67556C001427AA /* Constants1.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6B450132D67556B001427AA /* Constants1.swift */; }; + D529E7C8240CCC30BB7358A2 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B099132D71B1299FCDFD9C8 /* Pods_Runner.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97C146ED1CF9000F007C117D; + remoteInfo = Runner; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + C6E5BC612DCFF5F800471574 /* Embed Foundation Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + ); + name = "Embed Foundation Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 08CDD9E654C52E05FEE40E98 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 27958A27956787B6764BC14F /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 3B099132D71B1299FCDFD9C8 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 42939EAD96568C1F3F0E8006 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; + 43385D55BAC53942A4B30B22 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; + 45F2ED245254D48D155DD716 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + C60CA7362BE9EF38002095B2 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "GoogleService-Info.plist"; path = "GoogleService-Info.plist"; sourceTree = ""; }; + C6229B672D610C970014397D /* JailbreakDetection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JailbreakDetection.swift; sourceTree = ""; }; + C624C45C2BD56D34002834AF /* tone1.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; name = tone1.mp3; path = ../../android/app/src/main/res/raw/tone1.mp3; sourceTree = ""; }; + C624C45D2BD56D34002834AF /* start.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = start.wav; path = ../../android/app/src/main/res/raw/start.wav; sourceTree = ""; }; + C624C45F2BD56D34002834AF /* promo.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = promo.wav; path = ../../android/app/src/main/res/raw/promo.wav; sourceTree = ""; }; + C624C4602BD56D34002834AF /* cancel.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = cancel.wav; path = ../../android/app/src/main/res/raw/cancel.wav; sourceTree = ""; }; + C628BC402C316B1100E4D33B /* ding.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; name = ding.wav; path = ../../android/app/src/main/res/raw/ding.wav; sourceTree = ""; }; + C6372AD72D81BDA900C44265 /* SecurityChecks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecurityChecks.h; sourceTree = ""; }; + C6372AD82D81BDE000C44265 /* SecurityChecks.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecurityChecks.m; sourceTree = ""; }; + C6372ADE2D81C68700C44265 /* Localizable.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = ""; }; + C6372AE32D81F10A00C44265 /* KeychainHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainHelper.swift; sourceTree = ""; }; + C6372AE52D82EB9C00C44265 /* Config.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Config.plist; sourceTree = ""; }; + C69588332A8C1F6B00C3AC67 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; + C6B15A9F2B5FB24600746405 /* order.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = order.wav; sourceTree = ""; }; + C6B15AA02B5FB24600746405 /* tone2.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = tone2.wav; sourceTree = ""; }; + C6B450132D67556B001427AA /* Constants1.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants1.swift; sourceTree = ""; }; + C6E5BC4C2DCFF5F600471574 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; + C6E5BC4E2DCFF5F600471574 /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; + CAF37DC30C17166B851DBC8C /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + F231BA28015FE2C634809733 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 7AD318F74F39A70FCC91E66D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 0E2EB9A18A85A8C79C1A5B17 /* Pods_RunnerTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D529E7C8240CCC30BB7358A2 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 331C8082294A63A400263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C807B294A618700263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; + 5684D45491D29A320AB8001A /* Pods */ = { + isa = PBXGroup; + children = ( + 08CDD9E654C52E05FEE40E98 /* Pods-Runner.debug.xcconfig */, + F231BA28015FE2C634809733 /* Pods-Runner.release.xcconfig */, + CAF37DC30C17166B851DBC8C /* Pods-Runner.profile.xcconfig */, + 43385D55BAC53942A4B30B22 /* Pods-RunnerTests.debug.xcconfig */, + 45F2ED245254D48D155DD716 /* Pods-RunnerTests.release.xcconfig */, + 42939EAD96568C1F3F0E8006 /* Pods-RunnerTests.profile.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 331C8082294A63A400263BE5 /* RunnerTests */, + 5684D45491D29A320AB8001A /* Pods */, + B3041BA408DBB12F66846F39 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + 331C8081294A63A400263BE5 /* RunnerTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + C6372AE32D81F10A00C44265 /* KeychainHelper.swift */, + C6372ADE2D81C68700C44265 /* Localizable.strings */, + C6229B672D610C970014397D /* JailbreakDetection.swift */, + C6372AD72D81BDA900C44265 /* SecurityChecks.h */, + C6372AD82D81BDE000C44265 /* SecurityChecks.m */, + C69588332A8C1F6B00C3AC67 /* Runner.entitlements */, + C6B15A9F2B5FB24600746405 /* order.wav */, + C6B15AA02B5FB24600746405 /* tone2.wav */, + C624C4602BD56D34002834AF /* cancel.wav */, + C628BC402C316B1100E4D33B /* ding.wav */, + C624C45F2BD56D34002834AF /* promo.wav */, + C624C45D2BD56D34002834AF /* start.wav */, + C624C45C2BD56D34002834AF /* tone1.mp3 */, + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + C60CA7362BE9EF38002095B2 /* GoogleService-Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + C6B450132D67556B001427AA /* Constants1.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + C6372AE52D82EB9C00C44265 /* Config.plist */, + ); + path = Runner; + sourceTree = ""; + }; + B3041BA408DBB12F66846F39 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 3B099132D71B1299FCDFD9C8 /* Pods_Runner.framework */, + 27958A27956787B6764BC14F /* Pods_RunnerTests.framework */, + C6E5BC4C2DCFF5F600471574 /* WidgetKit.framework */, + C6E5BC4E2DCFF5F600471574 /* SwiftUI.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 331C8080294A63A400263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + E21B2D2CCD3CE8A2142D0F2C /* [CP] Check Pods Manifest.lock */, + 331C807D294A63A400263BE5 /* Sources */, + 331C807F294A63A400263BE5 /* Resources */, + 7AD318F74F39A70FCC91E66D /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 331C8086294A63A400263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 3F036A01BF594E9B01799541 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 854CC60BC5A3FC7474EC1FBF /* [CP] Embed Pods Frameworks */, + 7ADB08D4DE3D2A2E09575068 /* [CP] Copy Pods Resources */, + C6E5BC612DCFF5F800471574 /* Embed Foundation Extensions */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = YES; + LastSwiftUpdateCheck = 1620; + LastUpgradeCheck = 1510; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 331C8080294A63A400263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 97C146ED1CF9000F007C117D; + }; + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + 331C8080294A63A400263BE5 /* RunnerTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 331C807F294A63A400263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C6B15AA22B5FB24600746405 /* tone2.wav in Resources */, + C624C4652BD56D34002834AF /* start.wav in Resources */, + C624C4672BD56D34002834AF /* promo.wav in Resources */, + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + C624C4682BD56D34002834AF /* cancel.wav in Resources */, + C6B15AA12B5FB24600746405 /* order.wav in Resources */, + C6372AE62D82EB9C00C44265 /* Config.plist in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + C628BC412C316B1200E4D33B /* ding.wav in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + C6372ADF2D81C68C00C44265 /* Localizable.strings in Resources */, + C624C4642BD56D34002834AF /* tone1.mp3 in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + C60CA7372BE9EF38002095B2 /* GoogleService-Info.plist in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 3F036A01BF594E9B01799541 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 7ADB08D4DE3D2A2E09575068 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 854CC60BC5A3FC7474EC1FBF /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + E21B2D2CCD3CE8A2142D0F2C /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C807D294A63A400263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C6229B682D610CB20014397D /* JailbreakDetection.swift in Sources */, + C6372AE42D81F10E00C44265 /* KeychainHelper.swift in Sources */, + C6372AD92D81BDE000C44265 /* SecurityChecks.m in Sources */, + C6B450142D67556C001427AA /* Constants1.swift in Sources */, + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + COPY_PHASE_STRIP = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEPLOYMENT_POSTPROCESSING = YES; + DEVELOPMENT_TEAM = 63CVT8G5P8; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = Sefer; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.travel"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.mobileapp.store.ride; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 331C8088294A63A400263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 43385D55BAC53942A4B30B22 /* Pods-RunnerTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.mobileapp.store.ride.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Debug; + }; + 331C8089294A63A400263BE5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 45F2ED245254D48D155DD716 /* Pods-RunnerTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.mobileapp.store.ride.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Release; + }; + 331C808A294A63A400263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 42939EAD96568C1F3F0E8006 /* Pods-RunnerTests.profile.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.mobileapp.store.ride.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + COPY_PHASE_STRIP = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEPLOYMENT_POSTPROCESSING = YES; + DEVELOPMENT_TEAM = 63CVT8G5P8; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = Sefer; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.travel"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.mobileapp.store.ride; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; + COPY_PHASE_STRIP = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + DEPLOYMENT_POSTPROCESSING = YES; + DEVELOPMENT_TEAM = 63CVT8G5P8; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = Sefer; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.travel"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.mobileapp.store.ride; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C8088294A63A400263BE5 /* Debug */, + 331C8089294A63A400263BE5 /* Release */, + 331C808A294A63A400263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/apps/rider_new/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/apps/rider_new/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/apps/rider_new/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/apps/rider_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/apps/rider_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/apps/rider_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/apps/rider_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/apps/rider_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/apps/rider_new/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/apps/rider_new/ios/Runner.xcodeproj/xcshareddata/xcschemes/MyWidgetHome1Extension.xcscheme b/apps/rider_new/ios/Runner.xcodeproj/xcshareddata/xcschemes/MyWidgetHome1Extension.xcscheme new file mode 100644 index 0000000..56fcbd2 --- /dev/null +++ b/apps/rider_new/ios/Runner.xcodeproj/xcshareddata/xcschemes/MyWidgetHome1Extension.xcscheme @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/rider_new/ios/Runner.xcodeproj/xcshareddata/xcschemes/MyWidgetHomeExtension.xcscheme b/apps/rider_new/ios/Runner.xcodeproj/xcshareddata/xcschemes/MyWidgetHomeExtension.xcscheme new file mode 100644 index 0000000..2c79358 --- /dev/null +++ b/apps/rider_new/ios/Runner.xcodeproj/xcshareddata/xcschemes/MyWidgetHomeExtension.xcscheme @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/rider_new/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/apps/rider_new/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..e3773d4 --- /dev/null +++ b/apps/rider_new/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/rider_new/ios/Runner.xcworkspace/contents.xcworkspacedata b/apps/rider_new/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..21a3cc1 --- /dev/null +++ b/apps/rider_new/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/apps/rider_new/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/apps/rider_new/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/apps/rider_new/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/apps/rider_new/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/apps/rider_new/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/apps/rider_new/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/apps/rider_new/ios/Runner/AppDelegate.swift b/apps/rider_new/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..2fd6003 --- /dev/null +++ b/apps/rider_new/ios/Runner/AppDelegate.swift @@ -0,0 +1,139 @@ + +import UIKit +import Flutter +import FirebaseCore +@main +@objc class AppDelegate: FlutterAppDelegate { + + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + + FirebaseApp.configure() + GeneratedPluginRegistrant.register(with: self) + + // Perform security checks *before* showing the main UI + if SecurityChecks.isDeviceCompromised() { // Call Objective-C method + showSecurityAlert() + return false // Prevent app from launching further + } + //setup method channel + setupMethodChannel() + + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } + + func setupMethodChannel(){ + guard let controller = window?.rootViewController as? FlutterViewController else { + return + } + + let channel = FlutterMethodChannel(name: "com.mobileapp.store.ride/security", + binaryMessenger: controller.binaryMessenger) + channel.setMethodCallHandler { call, result in + switch call.method { + case "isNativeRooted": + // We already check this in isDeviceCompromised, + // so we can just return the result directly. + result(SecurityChecks.isDeviceCompromised()) + default: + result(FlutterMethodNotImplemented) + } + + } + } + + func showSecurityAlert() { + guard let rootVC = UIApplication.shared.keyWindow?.rootViewController else { + // Handle the case where rootVC is nil (extremely unlikely, but good practice) + exit(0) +// return + } + + let alert = UIAlertController( + title: "Security Warning".localized, // Use localized strings! + message: "Compromised device detected. Exiting.".localized, + preferredStyle: .alert + ) + + // Add an "OK" button with an obfuscated action + alert.addAction(UIAlertAction(title: "OK".localized, style: .destructive) { _ in + // More robust exit (see explanation below) + self.obfuscatedExit() + }) + + // Use a presentationDetents to prevent dismissing + if #available(iOS 15.0, *) { + alert.popoverPresentationController?.sourceView = rootVC.view + alert.popoverPresentationController?.sourceRect = CGRect(x: rootVC.view.bounds.midX, y: rootVC.view.bounds.midY, width: 0, height: 0) + alert.popoverPresentationController?.permittedArrowDirections = [] + alert.presentationController?.delegate = self + if let presentationController = alert.presentationController as? UISheetPresentationController { + presentationController.detents = [.medium()] // Set a fixed height if desired + presentationController.preferredCornerRadius = 20; + presentationController.prefersEdgeAttachedInCompactHeight = true;// Set corner radius + presentationController.prefersGrabberVisible = false // Optional: show a grabber + } + + } else { + // Fallback on earlier versions + } + + rootVC.present(alert, animated: true, completion: nil) + } + + // Obfuscated Exit (Example - you'll need a more robust solution) + func obfuscatedExit() { + // This is a *very* basic example. A real obfuscation would be MUCH more complex. + let selector = NSSelectorFromString(String(format: "%@%@", "ex", "it:")) + if responds(to: selector) { + perform(selector, with: 0) // Call exit(0) indirectly + } + } + + // MARK: - Secure API Key Storage (Example) + func getAPIKey() -> String { + // DO NOT store API keys directly in your code! + // Load it from a more secure location, such as: + // 1. A configuration file that is *not* checked into source control. + // 2. Keychain Services (recommended for iOS). + // 3. A backend server (best option). + + // This is just a placeholder. Replace with your actual key loading. + // In a real app, you'd fetch this from a secure source. + guard let filePath = Bundle.main.path(forResource: "keys", ofType: "plist"), + let plist = NSDictionary(contentsOfFile: filePath), + let apiKey = plist["google_maps_api_key"] as? String else { + fatalError("Couldn't find keys or API Key") // Ensure a crash if not found + } + + return apiKey + } + func loadConfig() -> [String: Any]? { + guard let path = Bundle.main.path(forResource: "Config", ofType: "plist"), + let config = NSDictionary(contentsOfFile: path) as? [String: Any] else { + return nil // Or handle the error appropriately + } + return config + } + + +} +// Add for prevent dismissing +extension AppDelegate: UIAdaptivePresentationControllerDelegate { + func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool { + return false + } + + func presentationControllerDidAttemptToDismiss(_ presentationController: UIPresentationController) { + + } +} + +// Add String extension +extension String { + var localized: String { + return NSLocalizedString(self, tableName: nil, bundle: Bundle.main, value: "", comment: "") + } +} diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..be71788 --- /dev/null +++ b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,158 @@ +{ + "images": [ + { + "size": "20x20", + "idiom": "iphone", + "filename": "Icon-App-20x20@2x.png", + "scale": "2x" + }, + { + "size": "20x20", + "idiom": "iphone", + "filename": "Icon-App-20x20@3x.png", + "scale": "3x" + }, + { + "size": "29x29", + "idiom": "iphone", + "filename": "Icon-App-29x29@1x.png", + "scale": "1x" + }, + { + "size": "29x29", + "idiom": "iphone", + "filename": "Icon-App-29x29@2x.png", + "scale": "2x" + }, + { + "size": "29x29", + "idiom": "iphone", + "filename": "Icon-App-29x29@3x.png", + "scale": "3x" + }, + { + "size": "40x40", + "idiom": "iphone", + "filename": "Icon-App-40x40@2x.png", + "scale": "2x" + }, + { + "size": "40x40", + "idiom": "iphone", + "filename": "Icon-App-40x40@3x.png", + "scale": "3x" + }, + { + "size": "57x57", + "idiom": "iphone", + "filename": "Icon-App-57x57@1x.png", + "scale": "1x" + }, + { + "size": "57x57", + "idiom": "iphone", + "filename": "Icon-App-57x57@2x.png", + "scale": "2x" + }, + { + "size": "60x60", + "idiom": "iphone", + "filename": "Icon-App-60x60@2x.png", + "scale": "2x" + }, + { + "size": "60x60", + "idiom": "iphone", + "filename": "Icon-App-60x60@3x.png", + "scale": "3x" + }, + { + "size": "20x20", + "idiom": "ipad", + "filename": "Icon-App-20x20@1x.png", + "scale": "1x" + }, + { + "size": "20x20", + "idiom": "ipad", + "filename": "Icon-App-20x20@2x.png", + "scale": "2x" + }, + { + "size": "29x29", + "idiom": "ipad", + "filename": "Icon-App-29x29@1x.png", + "scale": "1x" + }, + { + "size": "29x29", + "idiom": "ipad", + "filename": "Icon-App-29x29@2x.png", + "scale": "2x" + }, + { + "size": "40x40", + "idiom": "ipad", + "filename": "Icon-App-40x40@1x.png", + "scale": "1x" + }, + { + "size": "40x40", + "idiom": "ipad", + "filename": "Icon-App-40x40@2x.png", + "scale": "2x" + }, + { + "size": "50x50", + "idiom": "ipad", + "filename": "Icon-App-50x50@1x.png", + "scale": "1x" + }, + { + "size": "50x50", + "idiom": "ipad", + "filename": "Icon-App-50x50@2x.png", + "scale": "2x" + }, + { + "size": "72x72", + "idiom": "ipad", + "filename": "Icon-App-72x72@1x.png", + "scale": "1x" + }, + { + "size": "72x72", + "idiom": "ipad", + "filename": "Icon-App-72x72@2x.png", + "scale": "2x" + }, + { + "size": "76x76", + "idiom": "ipad", + "filename": "Icon-App-76x76@1x.png", + "scale": "1x" + }, + { + "size": "76x76", + "idiom": "ipad", + "filename": "Icon-App-76x76@2x.png", + "scale": "2x" + }, + { + "size": "83.5x83.5", + "idiom": "ipad", + "filename": "Icon-App-83.5x83.5@2x.png", + "scale": "2x" + }, + { + "size": "1024x1024", + "idiom": "ios-marketing", + "filename": "Icon-App-1024x1024@1x.png", + "scale": "1x" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} \ No newline at end of file diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000..cb46088 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png new file mode 100644 index 0000000..36f3434 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png new file mode 100644 index 0000000..d34f885 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000..3f24811 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png new file mode 100644 index 0000000..844093e Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000..5620f77 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png new file mode 100644 index 0000000..6654589 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png new file mode 100644 index 0000000..d34f885 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000..2cde9d8 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000..2f0d4d8 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png new file mode 100644 index 0000000..83c8425 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png new file mode 100644 index 0000000..cfc89be Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png new file mode 100644 index 0000000..0e71812 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png new file mode 100644 index 0000000..7310a1f Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000..2f0d4d8 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000..c18828b Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png new file mode 100644 index 0000000..5f35220 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png new file mode 100644 index 0000000..7514dfe Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000..8dbb617 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png new file mode 100644 index 0000000..4f8bef7 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png new file mode 100644 index 0000000..184dc96 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/Contents.json b/apps/rider_new/ios/Runner/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/apps/rider_new/ios/Runner/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json b/apps/rider_new/ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json new file mode 100644 index 0000000..9f447e1 --- /dev/null +++ b/apps/rider_new/ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "background.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png b/apps/rider_new/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png new file mode 100644 index 0000000..8e21404 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/apps/rider_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json new file mode 100644 index 0000000..00cabce --- /dev/null +++ b/apps/rider_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "filename" : "LaunchImage.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "LaunchImage@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "LaunchImage@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/apps/rider_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png new file mode 100644 index 0000000..6694368 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/apps/rider_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000..769f7c4 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/apps/rider_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000..5fd14db Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/icon_share.imageset/Contents.json b/apps/rider_new/ios/Runner/Assets.xcassets/icon_share.imageset/Contents.json new file mode 100644 index 0000000..028dbdf --- /dev/null +++ b/apps/rider_new/ios/Runner/Assets.xcassets/icon_share.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "icon_share.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/icon_share.imageset/icon_share.png b/apps/rider_new/ios/Runner/Assets.xcassets/icon_share.imageset/icon_share.png new file mode 100644 index 0000000..ae92be6 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/icon_share.imageset/icon_share.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/icon_support.imageset/Contents.json b/apps/rider_new/ios/Runner/Assets.xcassets/icon_support.imageset/Contents.json new file mode 100644 index 0000000..cc0fc26 --- /dev/null +++ b/apps/rider_new/ios/Runner/Assets.xcassets/icon_support.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "icon_support.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/icon_support.imageset/icon_support.png b/apps/rider_new/ios/Runner/Assets.xcassets/icon_support.imageset/icon_support.png new file mode 100644 index 0000000..5a9fef9 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/icon_support.imageset/icon_support.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/icon_user.imageset/Contents.json b/apps/rider_new/ios/Runner/Assets.xcassets/icon_user.imageset/Contents.json new file mode 100644 index 0000000..32ae8f7 --- /dev/null +++ b/apps/rider_new/ios/Runner/Assets.xcassets/icon_user.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "icon_user.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/icon_user.imageset/icon_user.png b/apps/rider_new/ios/Runner/Assets.xcassets/icon_user.imageset/icon_user.png new file mode 100644 index 0000000..c8802f2 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/icon_user.imageset/icon_user.png differ diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/icon_wallet.imageset/Contents.json b/apps/rider_new/ios/Runner/Assets.xcassets/icon_wallet.imageset/Contents.json new file mode 100644 index 0000000..3800eed --- /dev/null +++ b/apps/rider_new/ios/Runner/Assets.xcassets/icon_wallet.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "filename" : "icon_wallet.png", + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/apps/rider_new/ios/Runner/Assets.xcassets/icon_wallet.imageset/icon_wallet.png b/apps/rider_new/ios/Runner/Assets.xcassets/icon_wallet.imageset/icon_wallet.png new file mode 100644 index 0000000..551f8a4 Binary files /dev/null and b/apps/rider_new/ios/Runner/Assets.xcassets/icon_wallet.imageset/icon_wallet.png differ diff --git a/apps/rider_new/ios/Runner/Base.lproj/LaunchScreen.storyboard b/apps/rider_new/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..6f0f33c --- /dev/null +++ b/apps/rider_new/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/rider_new/ios/Runner/Base.lproj/Main.storyboard b/apps/rider_new/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/apps/rider_new/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/apps/rider_new/ios/Runner/Config.plist b/apps/rider_new/ios/Runner/Config.plist new file mode 100644 index 0000000..508df79 --- /dev/null +++ b/apps/rider_new/ios/Runner/Config.plist @@ -0,0 +1,10 @@ + + + + + APIKey + AIzaSyCf2mW2h0HD8ZYjwh4VOa2ladw6MJkCDTM + Environment + development + + diff --git a/apps/rider_new/ios/Runner/Constants1.swift b/apps/rider_new/ios/Runner/Constants1.swift new file mode 100644 index 0000000..e240caa --- /dev/null +++ b/apps/rider_new/ios/Runner/Constants1.swift @@ -0,0 +1,12 @@ +// +// Constants1.swift +// Runner +// +// Created by Hamza Aleghwairyeen on 20/02/2025. +// + +import Foundation + +struct Constants { + static let googleMapsAPIKey = "AIzaSyD0a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q" +} diff --git a/apps/rider_new/ios/Runner/Info.plist b/apps/rider_new/ios/Runner/Info.plist new file mode 100644 index 0000000..31e941a --- /dev/null +++ b/apps/rider_new/ios/Runner/Info.plist @@ -0,0 +1,103 @@ + + + + + LSApplicationQueriesSchemes + + googlechromes + comgooglemaps + + NSContactsUsageDescription + This app requires contacts access to function properly. + LSMinimumSystemVersion + 12.0 + CFBundleURLTypes + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + com.googleusercontent.apps.594687661098-8e26699cris2k3nj5msj1osi59it9kpf + + + + CADisableMinimumFrameDurationOnPhone + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Tripz + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleGetInfoString + + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + Tripz + CFBundlePackageType + APPL + CFBundleShortVersionString + 106 + CFBundleSignature + ???? + CFBundleVersion + 5.0.996 + NSHumanReadableCopyright + + FirebaseAppDelegateProxyEnabled + NO + GMSApiKey + YOUR_API_KEY + LSApplicationCategoryType + + LSRequiresIPhoneOS + + NSCameraUsageDescription + Sovo app requires access to your camera in order to scan QR codes and capture images for uploading and access to connect to a call. + NSFaceIDUsageDescription + Use Face ID to securely authenticate payment accounts. + NSLocationAlwaysAndWhenInUseUsageDescription + This app needs access to your location to provide you with the best ride experience. Your location data will be used to find the nearest available cars and connect you with the closest captain for efficient and convenient rides. + NSLocationAlwaysUsageDescription + This app needs access to location. + NSLocationWhenInUseUsageDescription + This app needs access to your location to provide you with the best ride experience. Your location data will be used to find the nearest available cars and connect you with the closest captain for efficient and convenient rides. + NSMicrophoneUsageDescription + This app requires access to your microphone to record audio, allowing you to add voice recordings to your photos and videos and access to connect to a call. + NSPhotoLibraryUsageDescription + Explanation of why your app needs access to the photo library. + UIApplicationSupportsIndirectInputEvents + + UIBackgroundModes + + fetch + location + remote-notification + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + UIStatusBarHidden + + + diff --git a/apps/rider_new/ios/Runner/JailbreakDetection.swift b/apps/rider_new/ios/Runner/JailbreakDetection.swift new file mode 100644 index 0000000..504e30e --- /dev/null +++ b/apps/rider_new/ios/Runner/JailbreakDetection.swift @@ -0,0 +1,25 @@ +// +// JailbreakDetection.swift +// Runner +// +// Created by Hamza Aleghwairyeen on 15/02/2025. +// + +import Foundation + +class JailbreakDetection { + static func isJailbroken() -> Bool { + let paths = [ + "/Applications/Cydia.app", + "/Library/MobileSubstrate/MobileSubstrate.dylib", + "/usr/sbin/sshd", + "/etc/apt" + ] + for path in paths { + if FileManager.default.fileExists(atPath: path) { + return true + } + } + return false + } +} diff --git a/apps/rider_new/ios/Runner/KeychainHelper.swift b/apps/rider_new/ios/Runner/KeychainHelper.swift new file mode 100644 index 0000000..8e62bc2 --- /dev/null +++ b/apps/rider_new/ios/Runner/KeychainHelper.swift @@ -0,0 +1,59 @@ +// +// KeychainHelper.swift +// Runner +// +// Created by Hamza Aleghwairyeen on 12/03/2025. +// + +import Foundation +import Security + +class KeychainHelper { + static let shared = KeychainHelper() + + private init() {} + + // حفظ البيانات في Keychain + func save(key: String, value: String) { + let data = value.data(using: .utf8)! + + let query: [String: Any] = [ + kSecClass as String: kSecClassGenericPassword, + kSecAttrAccount as String: key, + kSecValueData as String: data, + kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlockedThisDeviceOnly + ] + + SecItemDelete(query as CFDictionary) // حذف أي قيمة قديمة بنفس المفتاح + SecItemAdd(query as CFDictionary, nil) // إضافة القيمة الجديدة + } + + // استرجاع البيانات من Keychain + func get(key: String) -> String? { + let query: [String: Any] = [ + kSecClass as String: kSecClassGenericPassword, + kSecAttrAccount as String: key, + kSecReturnData as String: kCFBooleanTrue!, + kSecMatchLimit as String: kSecMatchLimitOne + ] + + var dataTypeRef: AnyObject? + let status = SecItemCopyMatching(query as CFDictionary, &dataTypeRef) + + guard status == errSecSuccess, let data = dataTypeRef as? Data else { + return nil + } + + return String(data: data, encoding: .utf8) + } + + // حذف البيانات من Keychain + func delete(key: String) { + let query: [String: Any] = [ + kSecClass as String: kSecClassGenericPassword, + kSecAttrAccount as String: key + ] + + SecItemDelete(query as CFDictionary) + } +} diff --git a/apps/rider_new/ios/Runner/Localizable.strings b/apps/rider_new/ios/Runner/Localizable.strings new file mode 100644 index 0000000..dd8ea57 --- /dev/null +++ b/apps/rider_new/ios/Runner/Localizable.strings @@ -0,0 +1,10 @@ +// +// Localizable.strings +// Runner +// +// Created by Hamza Aleghwairyeen on 12/03/2025. +// + +"Security Warning" = "تحذير أمني"; +"Compromised device detected. Exiting." = "تم اكتشاف جهاز مُخترق. جارٍ الخروج."; +"OK" = "موافق"; diff --git a/apps/rider_new/ios/Runner/Runner 2025-03-13 15-43-51/DistributionSummary.plist b/apps/rider_new/ios/Runner/Runner 2025-03-13 15-43-51/DistributionSummary.plist new file mode 100644 index 0000000..5512065 --- /dev/null +++ b/apps/rider_new/ios/Runner/Runner 2025-03-13 15-43-51/DistributionSummary.plist @@ -0,0 +1,1660 @@ + + + + + Tripz.ipa + + + architectures + + arm64 + + buildNumber + 5.0.98 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + embeddedBinaries + + + architectures + + arm64 + + buildNumber + 1.0 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + App.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 1.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + AppAuth.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 1.7.6 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + FBLPromises.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 2.4.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + FirebaseAppCheckInterop.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 11.6.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + FirebaseAuth.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 11.4.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + FirebaseAuthInterop.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 11.6.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + FirebaseCore.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 11.4.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + FirebaseCoreExtension.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 11.4.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + FirebaseCoreInternal.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 11.6.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + FirebaseInstallations.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 11.4.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + FirebaseMessaging.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 11.4.0 + + + architectures + + arm64 + + buildNumber + 1.0 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + Flutter.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 1.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + GTMAppAuth.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 4.1.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + GTMSessionFetcher.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 3.5.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + GoogleDataTransport.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 10.1.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + GoogleSignIn.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 7.1.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + GoogleUtilities.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 8.0.2 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + IOSSecuritySuite.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 1.9.11 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + RecaptchaInterop.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 100.0.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + Stripe.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 23.30.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + StripeApplePay.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 23.30.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + StripeCore.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 23.30.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + StripeFinancialConnections.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 23.30.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + StripePaymentSheet.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 23.30.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + StripePayments.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 23.30.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + StripePaymentsUI.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 23.30.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + StripeUICore.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 23.30.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + TOCropViewController.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 2.7.4 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + audio_session.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + device_info_plus.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + flutter_app_group_directory.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + flutter_contacts.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + flutter_local_notifications.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + flutter_secure_storage.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 6.0.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + geolocator_apple.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 1.2.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + image_cropper.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.4 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + image_picker_ios.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + jailbreak_root_detection.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 1.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + just_audio.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + live_activities.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + local_auth_darwin.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + location.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + nanopb.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 3.30910.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + package_info_plus.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.4.5 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + path_provider_foundation.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + quick_actions_ios.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + record_darwin.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 1.0.0 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + share.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + sign_in_with_apple.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + sqflite_darwin.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.4 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + stripe_ios.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + uni_links.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + url_launcher_ios.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + vibration.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 1.7.5 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + video_player_avfoundation.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + wakelock_plus.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + architectures + + arm64 + + buildNumber + 1 + certificate + + SHA1 + 0DC7C14BF54BBD12B1B1125DDF97C7F90395C9EF + dateExpires + 16/07/2025 + type + Cloud Managed Apple Distribution + + name + webview_flutter_wkwebview.framework + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 0.0.1 + + + entitlements + + application-identifier + 63CVT8G5P8.com.mobileapp.store.ride + aps-environment + production + com.apple.developer.applesignin + + Default + + com.apple.developer.team-identifier + 63CVT8G5P8 + get-task-allow + + + name + Runner.app + profile + + UUID + aa6f6d7b-1caf-4321-958b-1047982a17e7 + dateExpires + 16/07/2025 + name + iOS Team Ad Hoc Provisioning Profile: com.mobileapp.store.ride + + team + + id + 63CVT8G5P8 + name + Hamza Ayed + + versionNumber + 98 + + + + diff --git a/apps/rider_new/ios/Runner/Runner 2025-03-13 15-43-51/ExportOptions.plist b/apps/rider_new/ios/Runner/Runner 2025-03-13 15-43-51/ExportOptions.plist new file mode 100644 index 0000000..2f64685 --- /dev/null +++ b/apps/rider_new/ios/Runner/Runner 2025-03-13 15-43-51/ExportOptions.plist @@ -0,0 +1,18 @@ + + + + + destination + export + method + release-testing + signingStyle + automatic + stripSwiftSymbols + + teamID + 63CVT8G5P8 + thinning + <none> + + diff --git a/apps/rider_new/ios/Runner/Runner-Bridging-Header.h b/apps/rider_new/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..2dd4564 --- /dev/null +++ b/apps/rider_new/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1,2 @@ +#import "GeneratedPluginRegistrant.h" +#import "SecurityChecks.h" diff --git a/apps/rider_new/ios/Runner/Runner.entitlements b/apps/rider_new/ios/Runner/Runner.entitlements new file mode 100644 index 0000000..80b5221 --- /dev/null +++ b/apps/rider_new/ios/Runner/Runner.entitlements @@ -0,0 +1,12 @@ + + + + + aps-environment + development + com.apple.developer.applesignin + + Default + + + diff --git a/apps/rider_new/ios/Runner/SecurityChecks.h b/apps/rider_new/ios/Runner/SecurityChecks.h new file mode 100644 index 0000000..b41f391 --- /dev/null +++ b/apps/rider_new/ios/Runner/SecurityChecks.h @@ -0,0 +1,24 @@ +// +// SecurityChecks.h +// Runner +// +// Created by Hamza Aleghwairyeen on 12/03/2025. +// + +//#ifndef SecurityChecks_h +//#define SecurityChecks_h +// +// +//#endif /* SecurityChecks_h */ + + + +// SecurityChecks.h +#import +#import // Import UIKit + +@interface SecurityChecks : NSObject + ++ (BOOL)isDeviceCompromised; // Combined check + +@end diff --git a/apps/rider_new/ios/Runner/SecurityChecks.m b/apps/rider_new/ios/Runner/SecurityChecks.m new file mode 100644 index 0000000..752d891 --- /dev/null +++ b/apps/rider_new/ios/Runner/SecurityChecks.m @@ -0,0 +1,197 @@ +// +// SecurityChecks.m +// Runner +// +// Created by Hamza Aleghwairyeen on 12/03/2025. +// + +#import + + + +#import "SecurityChecks.h" +#import +#include +#import +#include // For _dyld_image_count and _dyld_get_image_name +#include // for fork() +#include //for socket, connect +#include // for sockaddr_in +#include // for inet_pton + +@implementation SecurityChecks + ++ (BOOL)isDeviceJailbroken { + // (Same jailbreak checks as before - from previous responses) + // 1. Check for common jailbreak files + NSArray *jailbreakPaths = @[ + @"/Applications/Cydia.app", +// #if !TARGET_IPHONE_SIMULATOR +// @"/bin/bash", +// #endif + @"/Library/MobileSubstrate/MobileSubstrate.dylib", + @"/bin/bash", + @"/usr/sbin/sshd", + @"/etc/apt", + @"/private/var/lib/apt/", + @"/private/var/tmp/cydia.log", + ]; + + for (NSString *path in jailbreakPaths) { + if ([[NSFileManager defaultManager] fileExistsAtPath:path]) { + NSLog(@"Jailbreak file detected: %@", path); + return YES; + } + } + + // 2. Check if we can write outside the sandbox (a strong indicator) + NSError *error = nil; + NSString *testPath = @"/private/jailbreaktest.txt"; + [@"test" writeToFile:testPath atomically:YES encoding:NSUTF8StringEncoding error:&error]; + + if (!error) { + // If we can write, it's jailbroken. Remove the file immediately. + [[NSFileManager defaultManager] removeItemAtPath:testPath error:nil]; + NSLog(@"Sandbox write test indicates jailbreak."); + return YES; + } + //3: Check for existence of the symbolic link /Applications. + struct stat s; + if (lstat("/Applications", &s) == 0) { + if (S_ISLNK(s.st_mode)) { + NSLog(@"Symbolic link /Applications exists, jailbroken"); + return YES; + } + } + + //4:Check for dyld Libraries + uint32_t count = _dyld_image_count(); + for (uint32_t i = 0 ; i < count ; ++i) { + const char *dyld = _dyld_get_image_name(i); + if (strstr(dyld, "MobileSubstrate") != NULL || strstr(dyld, "libcycript") != NULL) { + NSLog(@"Suspicious dyld library found: %s", dyld); + return YES; + } + } + + //5 Check if fork() is available. Sandboxed apps should not be able to call fork(). + #if !TARGET_IPHONE_SIMULATOR // Don't run this on the simulator + int pid = fork(); + if (pid == 0) + { + //in child, exit immediately to avoid crashing. + exit(0); + } else if (pid > 0) + { + NSLog(@"Fork available. Likely jailbroken."); + return YES; // Fork succeeded; likely jailbroken + } + #endif + + return NO; // No jailbreak indicators found +} ++ (BOOL)isDebuggerAttached { + int mib[4]; + struct kinfo_proc info; + size_t size = sizeof(info); + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); + + sysctl(mib, 4, &info, &size, NULL, 0); + + return (info.kp_proc.p_flag & P_TRACED) != 0; +} + +// Check for Frida's default port ++ (BOOL)isFridaListeningOnDefaultPort { + int sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == -1) { + return NO; // Couldn't create socket + } + + struct sockaddr_in sa; + memset(&sa, 0, sizeof(sa)); + sa.sin_family = AF_INET; + sa.sin_port = htons(27042); // Default Frida port + inet_pton(AF_INET, "127.0.0.1", &sa.sin_addr); + + if (connect(sock, (struct sockaddr *)&sa, sizeof(sa)) != -1) { + NSLog(@"Frida default port (27042) is open."); + close(sock); + return YES; + } + + close(sock); + return NO; +} + + ++ (BOOL)isFridaDetected { + int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 }; + size_t length; + struct kinfo_proc *procs, *proc; + + sysctl(name, 3, NULL, &length, NULL, 0); + procs = malloc(length); + sysctl(name, 3, procs, &length, NULL, 0); + + for (proc = procs; (char *)proc < (char *)procs + length; proc++) { + if (strstr(proc->kp_proc.p_comm, "frida") != NULL) { + free(procs); + return YES; + } + } + + free(procs); + return NO; +} +// Check for loaded dylibs that indicate Frida ++(BOOL) checkForFridaDylib{ + uint32_t count = _dyld_image_count(); + for (uint32_t i = 0 ; i < count ; ++i) { + const char *dyld = _dyld_get_image_name(i); + if (strstr(dyld, "FridaGadget") != NULL) { // Look for FridaGadget + NSLog(@"FridaGadget dylib found: %s", dyld); + return YES; + } + } + return NO; +} + +// Check process name ++ (BOOL)checkProcessName { + NSString* processName = [[NSProcessInfo processInfo] processName]; + if ([processName containsString:@"Frida"]) { + return YES; + } + return NO; +} + +// A combined check for jailbreak and Frida ++ (BOOL)isDeviceCompromised { + if ([SecurityChecks isDeviceJailbroken]) { + return YES; + } + if ([SecurityChecks isFridaListeningOnDefaultPort]) { + return YES; + } + if ([SecurityChecks checkForFridaDylib]) { + return YES; + } + if([SecurityChecks checkProcessName]){ + return YES; + } +// if ([SecurityChecks isDebuggerAttached]) { +// return YES; +// } +// if ([SecurityChecks isFridaDetected]) { +// return YES; +// } + + return NO; +} + +@end diff --git a/apps/rider_new/ios/Runner/order.wav b/apps/rider_new/ios/Runner/order.wav new file mode 100644 index 0000000..b2b0ba2 Binary files /dev/null and b/apps/rider_new/ios/Runner/order.wav differ diff --git a/apps/rider_new/ios/Runner/tone2.wav b/apps/rider_new/ios/Runner/tone2.wav new file mode 100644 index 0000000..0582d47 Binary files /dev/null and b/apps/rider_new/ios/Runner/tone2.wav differ diff --git a/apps/rider_new/ios/RunnerTests/RunnerTests.swift b/apps/rider_new/ios/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..86a7c3b --- /dev/null +++ b/apps/rider_new/ios/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Flutter +import UIKit +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/apps/rider_new/ios/firebase_app_id_file.json b/apps/rider_new/ios/firebase_app_id_file.json new file mode 100644 index 0000000..5236662 --- /dev/null +++ b/apps/rider_new/ios/firebase_app_id_file.json @@ -0,0 +1,7 @@ +{ + "file_generated_by": "FlutterFire CLI", + "purpose": "FirebaseAppID & ProjectID for this Firebase app in this directory", + "GOOGLE_APP_ID": "1:594687661098:ios:6f69eee1449be943595f53", + "FIREBASE_PROJECT_ID": "ride-b1bd8", + "GCM_SENDER_ID": "594687661098" +} \ No newline at end of file diff --git a/apps/rider_new/lib/app/app.dart b/apps/rider_new/lib/app/app.dart new file mode 100644 index 0000000..a4c82c4 --- /dev/null +++ b/apps/rider_new/lib/app/app.dart @@ -0,0 +1,28 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; + +import '../core/theme/app_theme.dart'; +import 'router.dart'; + +class TripzApp extends StatelessWidget { + const TripzApp({super.key}); + + @override + Widget build(BuildContext context) { + return MaterialApp.router( + title: 'Tripz', + debugShowCheckedModeBanner: false, + routerConfig: appRouter, + theme: AppTheme.light(), + darkTheme: AppTheme.dark(), + // اللغات الأربع تُستكمل في م2 مع ملفات الترجمة. + locale: const Locale('ar'), + supportedLocales: const [Locale('ar'), Locale('en')], + localizationsDelegates: const [ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + ); + } +} diff --git a/apps/rider_new/lib/app/router.dart b/apps/rider_new/lib/app/router.dart new file mode 100644 index 0000000..a16ed24 --- /dev/null +++ b/apps/rider_new/lib/app/router.dart @@ -0,0 +1,19 @@ +import 'package:go_router/go_router.dart'; + +import '../features/splash/splash_page.dart'; + +/// جدول التوجيه — يمتدّ في م3 (المصادقة) وم4 (الخريطة). +class AppRoutes { + const AppRoutes._(); + static const splash = '/'; +} + +final appRouter = GoRouter( + initialLocation: AppRoutes.splash, + routes: [ + GoRoute( + path: AppRoutes.splash, + builder: (context, state) => const SplashPage(), + ), + ], +); diff --git a/apps/rider_new/lib/core/config/app_config.dart b/apps/rider_new/lib/core/config/app_config.dart new file mode 100644 index 0000000..69ee220 --- /dev/null +++ b/apps/rider_new/lib/core/config/app_config.dart @@ -0,0 +1,36 @@ +/// إعداد البناء — كل قيمة هنا `const` تُمرَّر عبر `--dart-define` عند البناء. +/// +/// هذا هو أساس نموذج lite/pro/max (docs/37 §6.25): بناء مولَّد بأعلام ثابتة، +/// لا فروع كود. القيم الافتراضية تشير للسيرفر التجريبي. +class AppConfig { + const AppConfig._(); + + /// أصل الـAPI **مع** `/api` — كما في docs/38. + static const String apiBaseUrl = String.fromEnvironment( + 'API_BASE_URL', + defaultValue: 'https://tripz-api.intaleqapp.com/api', + ); + + /// أصل الـWebSocket — بلا `/api` (docs/38 §9). + static const String wsBaseUrl = String.fromEnvironment( + 'WS_BASE_URL', + defaultValue: 'https://tripz-api.intaleqapp.com', + ); + + /// **slug** المستأجر لا الـUUID — مصيدة docs/38 §12.9. + static const String tenantSlug = String.fromEnvironment( + 'TENANT_SLUG', + defaultValue: 'siro', + ); + + /// يحدّد هوية المستخدم على الخادم: نفس الرقم بدورين = حسابان منفصلان + /// (docs/38 §1). **يُثبَّت عند البناء ولا يتغيّر في وقت التشغيل أبداً.** + static const String appRole = 'rider'; + + /// هامش التجديد الاستباقي. عمر التوكن 15 دقيقة فقط (docs/38 §2)، فالانتظار + /// حتى 401 يعني فشل طلب في منتصف رحلة. + static const Duration tokenRefreshLeeway = Duration(seconds: 60); + + static const Duration connectTimeout = Duration(seconds: 20); + static const Duration receiveTimeout = Duration(seconds: 30); +} diff --git a/apps/rider_new/lib/core/di/injector.dart b/apps/rider_new/lib/core/di/injector.dart new file mode 100644 index 0000000..257480c --- /dev/null +++ b/apps/rider_new/lib/core/di/injector.dart @@ -0,0 +1,31 @@ +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; +import 'package:get_it/get_it.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +import '../network/api_client.dart'; +import '../storage/token_store.dart'; + +final sl = GetIt.instance; + +/// يُنادى مرة واحدة قبل `runApp`. +Future setupInjector() async { + sl.registerSingleton( + await SharedPreferences.getInstance(), + ); + + const secure = FlutterSecureStorage( + iOptions: IOSOptions(accessibility: KeychainAccessibility.first_unlock), + ); + + final tokens = TokenStore(secure); + await tokens.load(); + sl.registerSingleton(tokens); + + sl.registerSingleton( + ApiClient.create( + tokens: tokens, + // يُربط بالتوجيه في م3 (إخراج للمستخدم عند انتهاء الجلسة). + onSessionExpired: () async {}, + ), + ); +} diff --git a/apps/rider_new/lib/core/network/api_client.dart b/apps/rider_new/lib/core/network/api_client.dart new file mode 100644 index 0000000..7b96ded --- /dev/null +++ b/apps/rider_new/lib/core/network/api_client.dart @@ -0,0 +1,55 @@ +import 'package:dio/dio.dart'; + +import '../config/app_config.dart'; +import '../storage/token_store.dart'; +import 'api_exception.dart'; +import 'auth_interceptor.dart'; + +/// الواجهة الوحيدة للخادم. لا تُنشأ `Dio` في أي مكان آخر. +class ApiClient { + ApiClient._(this._dio); + + final Dio _dio; + + factory ApiClient.create({ + required TokenStore tokens, + required Future Function() onSessionExpired, + }) { + final options = BaseOptions( + baseUrl: AppConfig.apiBaseUrl, + connectTimeout: AppConfig.connectTimeout, + receiveTimeout: AppConfig.receiveTimeout, + contentType: Headers.jsonContentType, + // نتولّى كل ما ليس 2xx بأنفسنا في ApiException. + validateStatus: (s) => s != null && s >= 200 && s < 300, + ); + + final dio = Dio(options); + dio.interceptors.add(AuthInterceptor( + tokens: tokens, + refreshClient: Dio(options), + onSessionExpired: onSessionExpired, + )); + return ApiClient._(dio); + } + + Future get(String path, {Map? query}) => + _send(() => _dio.get(path, queryParameters: query)); + + Future post(String path, {Object? body}) => + _send(() => _dio.post(path, data: body)); + + Future patch(String path, {Object? body}) => + _send(() => _dio.patch(path, data: body)); + + Future delete(String path) => _send(() => _dio.delete(path)); + + Future _send(Future> Function() call) async { + try { + final res = await call(); + return res.data as T; + } on DioException catch (e) { + throw ApiException.from(e); + } + } +} diff --git a/apps/rider_new/lib/core/network/api_exception.dart b/apps/rider_new/lib/core/network/api_exception.dart new file mode 100644 index 0000000..6514cc1 --- /dev/null +++ b/apps/rider_new/lib/core/network/api_exception.dart @@ -0,0 +1,65 @@ +import 'package:dio/dio.dart'; + +/// خطأ موحّد تراه طبقة الميزات — لا `DioException` يتسرّب فوق طبقة الشبكة. +class ApiException implements Exception { + const ApiException({ + required this.message, + this.statusCode, + this.kind = ApiErrorKind.unknown, + }); + + final String message; + final int? statusCode; + final ApiErrorKind kind; + + bool get isUnauthorized => statusCode == 401; + bool get isForbidden => statusCode == 403; + + /// حدّ المعدّل — `send-otp` ثلاث مرات كل خمس دقائق (docs/38 §2). الواجهة + /// تعرض عدّاداً تنازلياً بدل رسالة خطأ عامة. + bool get isRateLimited => statusCode == 429; + + factory ApiException.from(DioException e) { + switch (e.type) { + case DioExceptionType.connectionTimeout: + case DioExceptionType.sendTimeout: + case DioExceptionType.receiveTimeout: + return const ApiException( + message: 'انتهت مهلة الاتصال', + kind: ApiErrorKind.timeout, + ); + case DioExceptionType.connectionError: + return const ApiException( + message: 'تعذّر الاتصال بالخادم', + kind: ApiErrorKind.network, + ); + case DioExceptionType.cancel: + return const ApiException( + message: 'أُلغي الطلب', + kind: ApiErrorKind.cancelled, + ); + default: + final code = e.response?.statusCode; + return ApiException( + message: _messageOf(e.response?.data) ?? 'حدث خطأ غير متوقّع', + statusCode: code, + kind: ApiErrorKind.server, + ); + } + } + + /// NestJS يرجّع `message` نصاً أو مصفوفة نصوص (أخطاء التحقق). + static String? _messageOf(dynamic data) { + if (data is Map) { + final m = data['message']; + if (m is String && m.isNotEmpty) return m; + if (m is List && m.isNotEmpty) return m.join('\n'); + } + return null; + } + + @override + String toString() => 'ApiException($statusCode): $message'; +} + +enum ApiErrorKind { network, timeout, server, cancelled, unknown } diff --git a/apps/rider_new/lib/core/network/auth_interceptor.dart b/apps/rider_new/lib/core/network/auth_interceptor.dart new file mode 100644 index 0000000..7ee3f2e --- /dev/null +++ b/apps/rider_new/lib/core/network/auth_interceptor.dart @@ -0,0 +1,125 @@ +import 'dart:async'; + +import 'package:dio/dio.dart'; + +import '../config/app_config.dart'; +import '../storage/token_store.dart'; + +/// يثبّت ترويسات كل طلب، ويجدّد التوكن **استباقياً** قبل انتهائه. +/// +/// عمر `access_token` خمس عشرة دقيقة فقط (docs/38 §2). لذلك لا ننتظر 401: +/// نجدّد قبل الإرسال إن قاربت الصلاحية. الـ401 يبقى شبكة أمان لا الآلية. +/// +/// التجديد **بطلقة واحدة**: عشرة طلبات متزامنة بتوكن منتهٍ تُنتج نداء تجديد +/// واحداً لا عشرة — وإلا أبطل الخادم رمز التحديث تحت أقدامنا. +class AuthInterceptor extends Interceptor { + AuthInterceptor({ + required TokenStore tokens, + required Dio refreshClient, + required Future Function() onSessionExpired, + }) : _tokens = tokens, + _refreshClient = refreshClient, + _onSessionExpired = onSessionExpired; + + final TokenStore _tokens; + + /// عميل منفصل بلا هذا الـinterceptor — وإلا استدعى التجديدُ نفسَه. + final Dio _refreshClient; + + final Future Function() _onSessionExpired; + + Future? _inFlight; + + @override + Future onRequest( + RequestOptions options, + RequestInterceptorHandler handler, + ) async { + options.headers['x-tenant-id'] = AppConfig.tenantSlug; + options.headers['x-app-role'] = AppConfig.appRole; + + final deviceId = await _tokens.deviceId(); + if (deviceId != null) options.headers['x-device-id'] = deviceId; + + // نقاط المصادقة لا تحمل توكناً ولا تُشغّل تجديداً. + if (!_needsAuth(options.path)) return handler.next(options); + + if (_tokens.isLoggedIn && + _tokens.isAccessExpired(AppConfig.tokenRefreshLeeway)) { + await _refresh(); + } + + final access = _tokens.accessToken; + if (access != null && access.isNotEmpty) { + options.headers['Authorization'] = 'Bearer $access'; + } + handler.next(options); + } + + @override + Future onError( + DioException err, + ErrorInterceptorHandler handler, + ) async { + final options = err.requestOptions; + final retried = options.extra['__retried'] == true; + + if (err.response?.statusCode != 401 || + retried || + !_needsAuth(options.path) || + !_tokens.isLoggedIn) { + return handler.next(err); + } + + if (!await _refresh()) return handler.next(err); + + options.extra['__retried'] = true; + options.headers['Authorization'] = 'Bearer ${_tokens.accessToken}'; + try { + handler.resolve(await _refreshClient.fetch(options)); + } on DioException catch (e) { + handler.next(e); + } + } + + static bool _needsAuth(String path) => + !path.startsWith('/auth/') && + !path.startsWith('/maps/') && + !path.startsWith('/tenant/config'); + + Future _refresh() { + return _inFlight ??= _doRefresh().whenComplete(() => _inFlight = null); + } + + Future _doRefresh() async { + final refresh = _tokens.refreshToken; + if (refresh == null || refresh.isEmpty) return false; + try { + final deviceId = await _tokens.deviceId(); + final res = await _refreshClient.post>( + '/auth/refresh', + data: {'refresh_token': refresh}, + options: Options(headers: { + 'x-tenant-id': AppConfig.tenantSlug, + 'x-app-role': AppConfig.appRole, + 'x-device-id': ?deviceId, + }), + ); + final body = res.data; + final access = body?['access_token'] as String?; + if (access == null || access.isEmpty) return false; + await _tokens.save( + accessToken: access, + // الخادم قد لا يدوّر رمز التحديث — نحتفظ بالقديم حينها. + refreshToken: (body?['refresh_token'] as String?) ?? refresh, + signingKey: body?['signing_key'] as String?, + ); + return true; + } on DioException { + // رمز تحديث ميّت = جلسة منتهية. لا معنى للمحاولة مجدداً. + await _tokens.clear(); + await _onSessionExpired(); + return false; + } + } +} diff --git a/apps/rider_new/lib/core/storage/token_store.dart b/apps/rider_new/lib/core/storage/token_store.dart new file mode 100644 index 0000000..9e37f68 --- /dev/null +++ b/apps/rider_new/lib/core/storage/token_store.dart @@ -0,0 +1,86 @@ +import 'dart:convert'; + +import 'package:flutter_secure_storage/flutter_secure_storage.dart'; + +/// مخزن الرموز — التخزين الآمن وحده. لا يُكتب توكن في `SharedPreferences`. +class TokenStore { + TokenStore(this._storage); + + final FlutterSecureStorage _storage; + + static const _kAccess = 'access_token'; + static const _kRefresh = 'refresh_token'; + static const _kSigning = 'signing_key'; + static const _kDeviceId = 'device_id'; + + // نسخة في الذاكرة: الـinterceptor يقرأ التوكن عند كل طلب، وقراءة Keychain + // في كل مرة عمل ثقيل على المسار الساخن. + String? _access; + String? _refresh; + + Future load() async { + _access = await _storage.read(key: _kAccess); + _refresh = await _storage.read(key: _kRefresh); + } + + String? get accessToken => _access; + String? get refreshToken => _refresh; + bool get isLoggedIn => _refresh != null && _refresh!.isNotEmpty; + + Future save({ + required String accessToken, + required String refreshToken, + String? signingKey, + }) async { + _access = accessToken; + _refresh = refreshToken; + await _storage.write(key: _kAccess, value: accessToken); + await _storage.write(key: _kRefresh, value: refreshToken); + if (signingKey != null) { + await _storage.write(key: _kSigning, value: signingKey); + } + } + + Future clear() async { + _access = null; + _refresh = null; + await _storage.delete(key: _kAccess); + await _storage.delete(key: _kRefresh); + await _storage.delete(key: _kSigning); + // مُعرّف الجهاز لا يُمسح عند الخروج — هو بصمة الجهاز لا بصمة الجلسة. + } + + /// مفتاح توقيع الطلبات — يعود مع رد الدخول (docs/38 §8). يُستهلك في م3. + Future signingKey() => _storage.read(key: _kSigning); + + Future deviceId() => _storage.read(key: _kDeviceId); + Future setDeviceId(String id) => + _storage.write(key: _kDeviceId, value: id); + + /// هل انتهت صلاحية التوكن (أو ستنتهي خلال [leeway])؟ + /// + /// قراءة محليّة لحقل `exp` — بلا حزمة خارجية. أي عطب في التوكن يُعامل + /// كمنتهٍ: الأسوأ تجديد زائد، لا طلب فاشل. + bool isAccessExpired(Duration leeway) { + final token = _access; + if (token == null || token.isEmpty) return true; + final exp = _expiryOf(token); + if (exp == null) return true; + return DateTime.now().add(leeway).isAfter(exp); + } + + static DateTime? _expiryOf(String jwt) { + try { + final parts = jwt.split('.'); + if (parts.length != 3) return null; + final payload = json.decode( + utf8.decode(base64Url.decode(base64Url.normalize(parts[1]))), + ) as Map; + final exp = payload['exp']; + if (exp is! int) return null; + return DateTime.fromMillisecondsSinceEpoch(exp * 1000); + } catch (_) { + return null; + } + } +} diff --git a/apps/rider_new/lib/core/theme/app_theme.dart b/apps/rider_new/lib/core/theme/app_theme.dart new file mode 100644 index 0000000..e082d46 --- /dev/null +++ b/apps/rider_new/lib/core/theme/app_theme.dart @@ -0,0 +1,26 @@ +import 'package:flutter/material.dart'; + +/// سمة مبدئية — تُستبدل بنظام التصميم الكامل في م2 (docs/26). +/// الغرض الآن: تثبيت الخطوط وأن يقلع التطبيق بشكل صحيح، لا أكثر. +class AppTheme { + const AppTheme._(); + + static const seed = Color(0xFF1F6FEB); + static const arabicFont = 'IBMPlexSansArabic'; + + static ThemeData light() => _base(Brightness.light); + static ThemeData dark() => _base(Brightness.dark); + + static ThemeData _base(Brightness brightness) { + final scheme = ColorScheme.fromSeed( + seedColor: seed, + brightness: brightness, + ); + return ThemeData( + useMaterial3: true, + colorScheme: scheme, + fontFamily: arabicFont, + scaffoldBackgroundColor: scheme.surface, + ); + } +} diff --git a/apps/rider_new/lib/features/splash/splash_page.dart b/apps/rider_new/lib/features/splash/splash_page.dart new file mode 100644 index 0000000..9854908 --- /dev/null +++ b/apps/rider_new/lib/features/splash/splash_page.dart @@ -0,0 +1,50 @@ +import 'package:flutter/material.dart'; + +import '../../core/config/app_config.dart'; + +/// شاشة الإقلاع. في م3 تتولّى استعادة الجلسة والتوجيه؛ الآن تثبت فقط أن +/// السقالة والأصول والخطوط تعمل (بوابة م1). +class SplashPage extends StatelessWidget { + const SplashPage({super.key}); + + @override + Widget build(BuildContext context) { + final scheme = Theme.of(context).colorScheme; + return Scaffold( + body: Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Image.asset( + 'assets/images/logo.png', + width: 140, + height: 140, + fit: BoxFit.contain, + ), + const SizedBox(height: 24), + Text( + 'Tripz', + style: Theme.of(context).textTheme.headlineMedium?.copyWith( + fontWeight: FontWeight.w700, + color: scheme.primary, + ), + ), + const SizedBox(height: 8), + Text( + AppConfig.appRole == 'driver' ? 'تطبيق السائق' : 'تطبيق الراكب', + style: Theme.of(context).textTheme.bodyMedium?.copyWith( + color: scheme.onSurfaceVariant, + ), + ), + const SizedBox(height: 32), + const SizedBox( + width: 28, + height: 28, + child: CircularProgressIndicator(strokeWidth: 2.5), + ), + ], + ), + ), + ); + } +} diff --git a/apps/rider_new/lib/main.dart b/apps/rider_new/lib/main.dart new file mode 100644 index 0000000..b5a5ff8 --- /dev/null +++ b/apps/rider_new/lib/main.dart @@ -0,0 +1,10 @@ +import 'package:flutter/material.dart'; + +import 'app/app.dart'; +import 'core/di/injector.dart'; + +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + await setupInjector(); + runApp(const TripzApp()); +} diff --git a/apps/rider_new/pubspec.lock b/apps/rider_new/pubspec.lock new file mode 100644 index 0000000..f21bfbd --- /dev/null +++ b/apps/rider_new/pubspec.lock @@ -0,0 +1,647 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + args: + dependency: transitive + description: + name: args + sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 + url: "https://pub.dev" + source: hosted + version: "2.7.0" + async: + dependency: transitive + description: + name: async + sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37 + url: "https://pub.dev" + source: hosted + version: "2.13.1" + bloc: + dependency: transitive + description: + name: bloc + sha256: e03b235924e4f509c27b5d6b2f949200e0a91149a9818b4f65eeb56662b75413 + url: "https://pub.dev" + source: hosted + version: "9.2.1" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + characters: + dependency: transitive + description: + name: characters + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b + url: "https://pub.dev" + source: hosted + version: "1.4.1" + clock: + dependency: transitive + description: + name: clock + sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b + url: "https://pub.dev" + source: hosted + version: "1.1.2" + code_assets: + dependency: transitive + description: + name: code_assets + sha256: bf394f466ba9205f1812a0433b392d6af280f155f56651eda7c18cc32ed493b8 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + collection: + dependency: transitive + description: + name: collection + sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" + url: "https://pub.dev" + source: hosted + version: "1.19.1" + crypto: + dependency: transitive + description: + name: crypto + sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf + url: "https://pub.dev" + source: hosted + version: "3.0.7" + cupertino_icons: + dependency: "direct main" + description: + name: cupertino_icons + sha256: "41e005c33bd814be4d3096aff55b1908d419fde52ca656c8c47719ec745873cd" + url: "https://pub.dev" + source: hosted + version: "1.0.9" + dio: + dependency: "direct main" + description: + name: dio + sha256: "0df44ebba85e503958eb75d07eedd3c86275a58c1d3eda2f2ce8f0a2c3abbb3c" + url: "https://pub.dev" + source: hosted + version: "5.11.0" + dio_web_adapter: + dependency: transitive + description: + name: dio_web_adapter + sha256: "0786d0b7295a373de356fc0af4f6f1d0ab2844ed31b19dfc5e7556b70e24212c" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + equatable: + dependency: "direct main" + description: + name: equatable + sha256: "3bce007a596ff8b3119c45d68aaef631272537c03d30e5d4534dd24bf4c5eaa2" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" + url: "https://pub.dev" + source: hosted + version: "1.3.3" + ffi: + dependency: transitive + description: + name: ffi + sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + ffi_leak_tracker: + dependency: transitive + description: + name: ffi_leak_tracker + sha256: "4093d4ef9ca06ffe2786e73bfb25e22aa92112b9bb4ec941f11e3e6b61489a97" + url: "https://pub.dev" + source: hosted + version: "0.1.2" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_bloc: + dependency: "direct main" + description: + name: flutter_bloc + sha256: cf51747952201a455a1c840f8171d273be009b932c75093020f9af64f2123e38 + url: "https://pub.dev" + source: hosted + version: "9.1.1" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1" + url: "https://pub.dev" + source: hosted + version: "6.0.0" + flutter_localizations: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_secure_storage: + dependency: "direct main" + description: + name: flutter_secure_storage + sha256: "7686b1d6a29985dcbb808c59518226e603e3bfa7c0ddfd1a0d00e4cda77c868e" + url: "https://pub.dev" + source: hosted + version: "10.3.1" + flutter_secure_storage_darwin: + dependency: transitive + description: + name: flutter_secure_storage_darwin + sha256: "82329fa5cdf343773b1b6897dea959105a29f092454259edff92f9f6637e8149" + url: "https://pub.dev" + source: hosted + version: "0.3.2" + flutter_secure_storage_linux: + dependency: transitive + description: + name: flutter_secure_storage_linux + sha256: a5f35ddab43cf5c8215d2feb4ce1957851f28c5c37e6f04335066a0602087bf5 + url: "https://pub.dev" + source: hosted + version: "3.0.1" + flutter_secure_storage_platform_interface: + dependency: transitive + description: + name: flutter_secure_storage_platform_interface + sha256: "06686df417f34fe9f963ed217b7fdce250e2f637ddd6c374d7eb054549770633" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + flutter_secure_storage_web: + dependency: transitive + description: + name: flutter_secure_storage_web + sha256: "073a62b3aeb866ab4ce795f960413948e51e5a42a9b0c8333b6daf5bb3208a1c" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + flutter_secure_storage_windows: + dependency: transitive + description: + name: flutter_secure_storage_windows + sha256: "471951813a97006d899db4948acc654a4f28c440083ea08178935ce20b173ec1" + url: "https://pub.dev" + source: hosted + version: "4.2.2" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + get_it: + dependency: "direct main" + description: + name: get_it + sha256: ae78de7c3f2304b8d81f2bb6e320833e5e81de942188542328f074978cc0efa9 + url: "https://pub.dev" + source: hosted + version: "8.3.0" + go_router: + dependency: "direct main" + description: + name: go_router + sha256: f02fd7d2a4dc512fec615529824fdd217fecb3a3d3de68360293a551f21634b3 + url: "https://pub.dev" + source: hosted + version: "14.8.1" + hooks: + dependency: transitive + description: + name: hooks + sha256: "9a62a50b50b769a737bc0a8ff381f333529df3ab746b2f6b02e83760231455ba" + url: "https://pub.dev" + source: hosted + version: "2.0.2" + http_parser: + dependency: transitive + description: + name: http_parser + sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" + url: "https://pub.dev" + source: hosted + version: "4.1.2" + intl: + dependency: transitive + description: + name: intl + sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" + url: "https://pub.dev" + source: hosted + version: "0.20.2" + jni: + dependency: transitive + description: + name: jni + sha256: f038e58b4dc2c9037f50e233175086337e0b305e356d28211bf55f21c504cbd3 + url: "https://pub.dev" + source: hosted + version: "1.0.3" + jni_flutter: + dependency: transitive + description: + name: jni_flutter + sha256: "7b717011ea40d04fd47c2731d3d1d36eb99eba3435c2753d62489e8c3c9991d5" + url: "https://pub.dev" + source: hosted + version: "1.0.2" + jni_util: + dependency: transitive + description: + name: jni_util + sha256: "1ba86da04a5f2bf18fde2edb235587e70c5b0fc5bd4ba955f46b00942c3fc35f" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" + url: "https://pub.dev" + source: hosted + version: "11.0.2" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + url: "https://pub.dev" + source: hosted + version: "3.0.10" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + url: "https://pub.dev" + source: hosted + version: "3.0.2" + lints: + dependency: transitive + description: + name: lints + sha256: "12f842a479589fea194fe5c5a3095abc7be0c1f2ddfa9a0e76aed1dbd26a87df" + url: "https://pub.dev" + source: hosted + version: "6.1.0" + logging: + dependency: transitive + description: + name: logging + sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61 + url: "https://pub.dev" + source: hosted + version: "1.3.0" + matcher: + dependency: transitive + description: + name: matcher + sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6" + url: "https://pub.dev" + source: hosted + version: "0.12.18" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" + url: "https://pub.dev" + source: hosted + version: "0.13.0" + meta: + dependency: transitive + description: + name: meta + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" + url: "https://pub.dev" + source: hosted + version: "1.17.0" + mime: + dependency: transitive + description: + name: mime + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" + url: "https://pub.dev" + source: hosted + version: "2.0.0" + nested: + dependency: transitive + description: + name: nested + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" + source: hosted + version: "1.0.0" + objective_c: + dependency: transitive + description: + name: objective_c + sha256: b7fb95a6d9a4f009edd63dc5ac69f07420b23a16161c6dd8660290b59c602e8e + url: "https://pub.dev" + source: hosted + version: "9.5.0" + package_config: + dependency: transitive + description: + name: package_config + sha256: ffcf4cf3d6c0b74ac43708d9f56625506e8a68aa935abe9d267a7330f320eb5d + url: "https://pub.dev" + source: hosted + version: "3.0.0" + path: + dependency: transitive + description: + name: path + sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" + url: "https://pub.dev" + source: hosted + version: "1.9.1" + path_provider: + dependency: transitive + description: + name: path_provider + sha256: a7f4874f987173da295a61c181b8ee71dab59b332a486b391babf26a1b884825 + url: "https://pub.dev" + source: hosted + version: "2.1.6" + path_provider_android: + dependency: transitive + description: + name: path_provider_android + sha256: "69cbd515a62b94d32a7944f086b2f82b4ac40a1d45bebfc00813a430ab2dabcd" + url: "https://pub.dev" + source: hosted + version: "2.3.1" + path_provider_foundation: + dependency: transitive + description: + name: path_provider_foundation + sha256: "2a376b7d6392d80cd3705782d2caa734ca4727776db0b6ec36ef3f1855197699" + url: "https://pub.dev" + source: hosted + version: "2.6.0" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: "58c2005f147315b11e9b4a7bc889cd5203e250cba8e3f012dae259b4972b5c16" + url: "https://pub.dev" + source: hosted + version: "2.2.2" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "484838772624c3a4b94f1e44a3e19897fee738f2d5c4ce448443b0417f7c9dda" + url: "https://pub.dev" + source: hosted + version: "2.1.3" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 + url: "https://pub.dev" + source: hosted + version: "2.3.0" + platform: + dependency: transitive + description: + name: platform + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + url: "https://pub.dev" + source: hosted + version: "3.1.6" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + provider: + dependency: transitive + description: + name: provider + sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272" + url: "https://pub.dev" + source: hosted + version: "6.1.5+1" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + record_use: + dependency: transitive + description: + name: record_use + sha256: "2551bd8eecfe95d14ae75f6021ad0248be5c27f138c2ec12fcb52b500b3ba1ed" + url: "https://pub.dev" + source: hosted + version: "0.6.0" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: c3025c5534b01739267eb7d76959bbc25a6d10f6988e1c2a3036940133dd10bf + url: "https://pub.dev" + source: hosted + version: "2.5.5" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: e8d4762b1e2e8578fc4d0fd548cebf24afd24f49719c08974df92834565e2c53 + url: "https://pub.dev" + source: hosted + version: "2.4.23" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f" + url: "https://pub.dev" + source: hosted + version: "2.5.6" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "649dc798a33931919ea356c4305c2d1f81619ea6e92244070b520187b5140ef9" + url: "https://pub.dev" + source: hosted + version: "2.4.2" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 + url: "https://pub.dev" + source: hosted + version: "2.4.3" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + source_span: + dependency: transitive + description: + name: source_span + sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab" + url: "https://pub.dev" + source: hosted + version: "1.10.2" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" + url: "https://pub.dev" + source: hosted + version: "1.12.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" + url: "https://pub.dev" + source: hosted + version: "1.4.1" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" + url: "https://pub.dev" + source: hosted + version: "1.2.2" + test_api: + dependency: transitive + description: + name: test_api + sha256: "93167629bfc610f71560ab9312acdda4959de4df6fac7492c89ff0d3886f6636" + url: "https://pub.dev" + source: hosted + version: "0.7.9" + typed_data: + dependency: transitive + description: + name: typed_data + sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 + url: "https://pub.dev" + source: hosted + version: "1.4.0" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + url: "https://pub.dev" + source: hosted + version: "2.2.0" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360" + url: "https://pub.dev" + source: hosted + version: "15.2.0" + web: + dependency: transitive + description: + name: web + sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + win32: + dependency: transitive + description: + name: win32 + sha256: ba6f4bba816c8d7e3c1580e170f3786d216951cc6b94babc3b814c08d2cb2738 + url: "https://pub.dev" + source: hosted + version: "6.3.0" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + yaml: + dependency: transitive + description: + name: yaml + sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce + url: "https://pub.dev" + source: hosted + version: "3.1.3" +sdks: + dart: ">=3.11.0 <4.0.0" + flutter: ">=3.38.4" diff --git a/apps/rider_new/pubspec.yaml b/apps/rider_new/pubspec.yaml new file mode 100644 index 0000000..8b4920f --- /dev/null +++ b/apps/rider_new/pubspec.yaml @@ -0,0 +1,78 @@ +name: rider_new +description: "تطبيق الراكب — Tripz. مبنيّ من الصفر على Bloc/Cubit وباك إند NestJS (docs/37)." +publish_to: "none" + +# يطابق هوية النشر في android/app/build.gradle — لا يُغيَّر إلا مع رفع إصدار +# حقيقي في المتجر (docs/37 §2.ج). +version: 2.0.135+135 + +environment: + sdk: ^3.11.0 + +dependencies: + flutter: + sdk: flutter + flutter_localizations: + sdk: flutter + + # الحالة والتوجيه والحقن — الإصدارات موحّدة حرفياً مع driver_new (docs/23 §9): + # تباعدهما يعني سلوكاً مختلفاً في كود مشترك. + flutter_bloc: ^9.1.1 + equatable: ^2.0.7 + get_it: ^8.0.3 + go_router: ^14.6.2 + + # الشبكة + dio: ^5.9.1 + + # التخزين — الرموز في التخزين الآمن، والتفضيلات في العادي + flutter_secure_storage: ^10.0.0 + shared_preferences: ^2.3.3 + + cupertino_icons: ^1.0.8 + +# باقي الحزم تُضاف في مرحلتها لا قبلها (docs/37 §1.7): +# م3: device_info_plus · crypto (توقيع الطلبات وبصمة الجهاز) +# م4: الخريطة · geolocator · socket_io_client +# م5: التقييم والمحفظة م6: الإشعارات والدردشة + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^6.0.0 + +flutter: + uses-material-design: true + + assets: + - assets/ + - assets/images/ + - shorebird.yaml + + fonts: + # عربية — تايبوغرافيا نظام التصميم (docs/26) + - family: IBMPlexSansArabic + fonts: + - asset: assets/fonts/IBMPlexSansArabic-Regular.ttf + weight: 400 + - asset: assets/fonts/IBMPlexSansArabic-Medium.ttf + weight: 500 + - asset: assets/fonts/IBMPlexSansArabic-SemiBold.ttf + weight: 600 + - asset: assets/fonts/IBMPlexSansArabic-Bold.ttf + weight: 700 + # لاتينية + - family: Inter + fonts: + - asset: assets/fonts/Inter-Regular.ttf + weight: 400 + - asset: assets/fonts/Inter-Medium.ttf + weight: 500 + - asset: assets/fonts/Inter-SemiBold.ttf + weight: 600 + - asset: assets/fonts/Inter-Bold.ttf + weight: 700 + # أرقام العدّادات (الأجرة/المؤقّت) + - family: Digit + fonts: + - asset: assets/fonts/digit.ttf diff --git a/apps/rider_new/shorebird.yaml b/apps/rider_new/shorebird.yaml new file mode 100644 index 0000000..10c3a35 --- /dev/null +++ b/apps/rider_new/shorebird.yaml @@ -0,0 +1,14 @@ +# This file is used to configure the Shorebird updater used by your app. +# Learn more at https://docs.shorebird.dev +# This file does not contain any sensitive information and should be checked into version control. + +# Your app_id is the unique identifier assigned to your app. +# It is used to identify your app when requesting patches from Shorebird's servers. +# It is not a secret and can be shared publicly. +app_id: 496cb3ac-c25c-455d-9d2e-5ebbea13ab03 + +# auto_update controls if Shorebird should automatically update in the background on launch. +# If auto_update: false, you will need to use package:shorebird_code_push to trigger updates. +# https://pub.dev/packages/shorebird_code_push +# Uncomment the following line to disable automatic updates. +# auto_update: false diff --git a/docs/37-newapps-cubit-plan.md b/docs/37-newapps-cubit-plan.md new file mode 100644 index 0000000..7af711f --- /dev/null +++ b/docs/37-newapps-cubit-plan.md @@ -0,0 +1,201 @@ +# 37 — خطة `rider_new` و `driver_new` (Cubit + باك إند NestJS) + +تاريخ: 2026-08-04 · الحالة: مسودّة للموافقة + +## 1. القرار المطلوب ومعناه + +المطلوب: بناء تطبيقين جديدين (`rider_new`, `driver_new`) بـ Bloc/Cubit، +يعملان على **`backend-archive/` (NestJS)**، بأخذ الأصول والحزم من تطبيقات +سيرو، مع الحفاظ على `build.gradle` و`Info.plist` كي لا تنكسر هوية النشر. + +هذا **عكس لقرارين مقفلين**: + +| القرار | التاريخ | المرجع | +|---|---|---| +| الباك إند المعتمد = سيرو PHP، وNestJS مؤرشف | 2026-07-27 | `backend-archive/README-ARCHIVE.md`, `docs/34` | +| التطبيقات = نقل سيرو GetX بدل إعادة بناء Cubit | 2026-07-21 | `docs/30` | + +سبب الأرشفة وقتها كان مكتوباً صراحة: «NestJS مكتمل تقنياً لكن **بلا تطبيقات +تعمل عليه**، وبناء تطبيقات له من الصفر أطول من نقل تطبيقات سيرو». +الخطة الحالية تقول: نعم، سنبني التطبيقات. هذا يحلّ الاعتراض — بشرط قبول أن +شغل نقل PHP يتوقّف مؤقتاً. + +## 2. القاعدة الحاكمة — بناء من الصفر، وسيرو مرجع لا مصدر نسخ + +قرار المالك 2026-08-04، وهو يعلو على أي اقتراح في هذه الوثيقة: + +1. **كل كود دارت يُكتب من الصفر.** لا يُورَّث سطر من + `apps/rider-archive-cubit` (77 ملف) ولا `apps/driver-archive-cubit` + (53 ملف) — السبب: أداؤها وشكلها مرفوضان، ووراثتها تعني وراثة المشكلة. + تبقى للقراءة فقط ثم تُحذف بعد المرحلة 3. +2. **سيرو مرجع بصري وسلوكي، لا مصدر نسخ.** نقرأ منه: كيف بُنيت الشاشة، ما + ترتيب الخطوات، أي حالات حافة عولجت ميدانياً. لا ننسخ منه ملفات دارت. +3. **سقف الجودة = شكل تريبز الحالي أو أفضل.** الهدف ليس المعادلة بل التفوّق: + أداء (60fps، بلا rebuild زائد) وشكل (نظام تصميم واحد متّسق). + +### أ. الشيء الوحيد الذي يُنقل حرفياً: الطبقة الأصلية + +لأن كل شيء آخر يُكتب من جديد، تبقى الطبقة الأصلية (`android/`, `ios/`, +`shorebird.yaml`) هي الوحيدة التي تُنقل كما هي — لأنها هوية النشر ولا يجوز +إعادة اختراعها. مصدرها محسوم في §2.ج. + +### ب. `pubspec` — قائمة تُبنى بالطلب، لا تُنسخ + +`siro_rider/pubspec.yaml` فيه ~60 اعتماد، ومنها `get` و`get_storage` كحزمتين +**محليّتين معدّلتين** (`./packages/get`) — أي أن نسخه يجرّ GetX كاملاً معه، +وكذلك `intaleq_maps` و`secure_string_operations` المربوطة بعقد PHP. + +لذلك `pubspec` الجديد يُكتب من الصفر، وتُضاف الحزمة **فقط عند الحاجة إليها في +مرحلتها** — لا قائمة مسبقة من 60 اعتماداً. سيرو يجيب على سؤال «أي حزمة نجحت +ميدانياً لهذه المهمة»، لا «ما القائمة». + +- ✅ نأخذ منه: الأصول (`assets/`)، والحزم المحليّة غير المرتبطة بـ GetX + (`secure_string_operations`, `trip_overlay_plugin`, `bubble-master`)، + والحزم الأصلية (webrtc · geolocator · location · permission_handler · + firebase · local_auth · image_cropper · live_activities · quick_actions …) + لأن هذي هي القيمة الحقيقية المجرّبة ميدانياً. +- ❌ لا ننسخ: `get`, `get_storage` — تُستبدل بـ `flutter_bloc` + + `hydrated_bloc`/`shared_preferences`. +- ⚠️ نراجع: `intaleq_maps` (قرار الخرائط المباشرة لـ map-saas بمفتاح + `x-api-key` قائم — يبقى)، و`socket_io_client` (NestJS realtime قد يكون + عقده مختلفاً — يُتحقّق من `backend-archive/src/realtime`). + +### ج. خطر هوية النشر — يُحسم قبل أي نسخ + +| التطبيق | applicationId | shorebird app_id | +|---|---|---| +| `Siro/siro_driver` | `com.siro.siro_driver` | `f8e9c087-…0120c` | +| `Tripz/apps/driver` | `com.sefer_driver` | `f8e9c087-…0120c` ← **نفس سيرو** | +| `apps/driver-archive-cubit` | `com.sefer_driver` | `68cc9345-…5836d` | +| `Siro/siro_rider` | `com.siro.rider` | `44245793-…305dd` | +| `Tripz/apps/rider` | `com.mobileapp.store.ride` | `44245793-…305dd` ← **نفس سيرو** | +| `apps/rider-archive-cubit` | `com.mobileapp.store.ride` | `496cb3ac-…a13ac` | + +قرار المالك: **لكل تطبيق تريبز هويته الخاصة**، منفصلة تماماً عن سيرو. لذلك +`apps/driver` و`apps/rider` — اللذان يحملان app_id سيرو نفسه — **أثرُ نسخٍ +خاطئ عند نقل GetX، وليسا مرجع هوية**. باتش شوربيرد منهما قد يُدفع لتطبيق +سيرو المنشور. المرجع الصحيح هو `*-archive-cubit`: + +| | applicationId | shorebird app_id | +|---|---|---| +| `driver_new` | `com.sefer_driver` | `68cc9345-…5836d` | +| `rider_new` | `com.mobileapp.store.ride` | `496cb3ac-…a13ac` | + +القاعدة: **لا يُنسخ أي `build.gradle` أو `shorebird.yaml` أو `Info.plist` من +سيرو.** الطبقة الأصلية تُنقل من `*-archive-cubit` (هي وحدها كودٌ لم يكتبه +النموذج السابق — ملفات إعداد مُولّدة من Flutter ومعدّلة يدوياً)، ويُقرأ من +سيرو ما يلزم من أذونات وخدمات خلفية و entitlements فيُكتب يدوياً سطراً سطراً. + +## 3. الخطة بالترتيب + +### المرحلة 0 — تثبيت الأساس (قبل أي كود) — **نُفّذت 2026-08-04** +1. ✅ عقد NestJS موثّق في **[`docs/38-api-contract.md`](38-api-contract.md)** — + 37 controller + `e2e-test.mjs`، ومعظم الأشكال **مُتحقَّقة حيّاً** من + السيرفر المنشور. المصدر الوحيد للحقيقة لطبقة الشبكة. +2. ⚠️ **جزئي**: الباك إند حيّ ويعمل (`/health` → 200)، والدخول والمستخدم + والمحفظة وأنواع الرحلات والتعرفة والمسار والتقييم المعلّق كلها تحقّقت + حيّاً. لكن **`e2e-test.mjs` الكامل لم يُشغَّل**: يحتاج `OTP_DEV_MODE=true` + وهو مطفأ على المنشور، والـSSH من الماك مرفوض + (`Permission denied (publickey)`). المتبقّي غير المُتحقَّق مذكور في + `docs/38` §13. **بلوكر يحتاج المالك.** +3. ✅ المرجع البصري في **[`docs/39-siro-screens.md`](39-siro-screens.md)** — + 89 شاشة راكب + 113 شاشة سائق، مصنّفة داخل/خارج النطاق، مع ترتيب الخطوات + وحالات الحافة وملاحظات الأداء. **بلا نسخ كود.** + +**ما انحسم في م0** (كان مخاطرة، صار حقيقة): +- `x-app-role` **منفّذ فعلاً**: نفس الرقم أعطى user id مختلفاً للراكب والسائق. + لا عمل باك إند إضافي في م3. +- `access_token` = **15 دقيقة فقط** → تجديد استباقي إجباري في طبقة الشبكة. +- `GET /tenant/config/:slug` يرجّع **خريطة ميزات كاملة** → هي ربط lite/pro/max + بالخادم، لا أعلام مكتوبة في الكود (يعدّل فهم م6.25). +- حسابا مراجعة المتاجر `0790000001`/`0790000002` بالرمز `1234` يعملان **بلا** + `OTP_DEV_MODE` — مدخلنا للاختبار حتى يتوفّر وصول السيرفر. +- ثغرات مؤكَّدة على المنشور: `/maps/geocode` معطوب (قائمة دول فارغة)، + و`/tariff/quote` يفشل صامتاً بقيم `null` عند إرسال المعاملات الخطأ. + +### المرحلة 1 — سقالة `rider_new` و `driver_new` من الصفر — **نُفّذت 2026-08-04، متوقّفة عند البوابة** + +الحالة: الخطوات 4–8 ✅ · الخطوة 9 (البوابة) ⚠️ جزئية — +`flutter analyze` **نظيف في التطبيقين (0 مشاكل)**، لكن البناء الفعلي لم +يُجرَّب: SSH للسيرفر مرفوض (بلوكر م0.2 نفسه). + +قرارات اتُّخذت أثناء التنفيذ ولم تكن في الخطة: +- **الأصول مصدرها `*-archive-cubit` لا سيرو.** أصول الأرشيف **مجموعة أشمل** + من أصول سيرو (كل صور سيرو + `login_hero`/`name_hero`/`onboarding_1..3`/ + `splash_logo`) وخطوطها هي خطوط `docs/26` (IBM Plex Sans Arabic + Inter) + بينما سيرو عليه `mohanad`/`josefin`. النسخ من سيرو كان سيكون **تراجعاً**. + استُكمل السائق بعشرة ملفات ناقصة من سيرو (شعارات مزوّدي الدفع + صوتان). + الأصول ليست كوداً كتبه النموذج السابق، فلا تخالف قاعدة «من الصفر». +- **أُصلح تعارض هوية في iOS للسائق**: هدف `RunnerTests` في + `driver_new` كان يحمل `com.mobileapp.store.ride` (bundle الراكب) — + نُقل إلى `com.sefer.driver.RunnerTests`. +- `flutter_secure_storage` + `shared_preferences` أُضيفتا لقائمة م1 الدنيا: + التوكن لا يُخزَّن إلا في التخزين الآمن، وهذا أساس لا إضافة لاحقة. +4. `flutter create` نظيف لكل تطبيق، ثم **استبدال `android/` و`ios/` و + `shorebird.yaml` بنسخة من `*-archive-cubit`** (الهوية فقط — §2.ج). +5. `lib/` فارغ يُبنى من جديد: `core/` (شبكة · تخزين · أخطاء · توجيه · DI) + ثم `features/` — بلا استيراد أي ملف من الأرشيف. +6. نقل الأصول من سيرو: `assets/` + الخطوط + الأيقونات + ملفات الترجمة. +7. `pubspec` بالحد الأدنى: `flutter_bloc` · `dio` · `go_router` · + `get_it` · `freezed`. الباقي يُضاف في مرحلته. +8. مواءمة الأذونات في `AndroidManifest` و`Info.plist` مع ما تحتاجه كل حزمة + عند إضافتها — بلا لمس المعرّفات. +9. **بوابة**: يبني على السيرفر، يقلع على المحاكي بشاشة splash، + و`flutter analyze` نظيف. + +### المرحلة 2 — نظام التصميم (هنا يُكسب الشكل أو يُخسر) +10. تطبيق `docs/26-flutter-design-system.md` + `docs/23-flutter-conventions.md`: + theme · ألوان · تايبوغرافي · مسافات · حركة · RTL/LTR بأربع لغات. +11. حزمة مشتركة `packages/tripz_ui` يستهلكها التطبيقان (تجنّب ازدواج الشاشات). +12. **ميزانية أداء مكتوبة** تُفحص في كل بوابة بعدها: بلا `setState` فوق شجرة + كبيرة · `BlocSelector`/`buildWhen` افتراضياً · `const` على كل widget ساكن · + قوائم كسولة · بلا عمل ثقيل في `build`. سبب الأداء السيئ سابقاً يُشخّص من + `*-archive-cubit` **مرة واحدة** ويُكتب هنا كقائمة ممنوعات. + +### المرحلة 3 — التسجيل والدخول (OTP) كاملاً +13. طبقة الشبكة: Dio + interceptors + تجديد التوكن + `x-app-role`. +14. شاشات: onboarding → إدخال الهاتف → OTP → إكمال الملف → استعادة الجلسة. +15. مراعاة قرار **هوية الراكب/السائق المنفصلة** (قيد `tenant,phone_bidx,role` + + ترويسة `x-app-role`) — يجب أن يكون موجوداً في NestJS، وإن لم يكن فهو + عمل باك إند إضافي يُحسب في هذه المرحلة. +16. **بوابة**: دخول حقيقي من التطبيقين على NestJS المشتغل + لقطات شاشة تُقارن + بمرجع سيرو، ولا تُقبل إن كانت أدنى منه. + +### المرحلة 4 — الخريطة وطلب الرحلة +17. الخريطة مباشرة لـ map-saas بمفتاح `x-api-key` مقيّد ببصمة التطبيق + (قرار `maps-direct-decision`) — لا تمرير عبر الباك إند. +18. الراكب: اختيار المصدر/الوجهة · التسعير المسبق · تأكيد الطلب · انتظار سائق. +19. السائق: أونلاين/أوفلاين · استقبال العروض · قبول/رفض. +20. الواقع اللحظي (WebSocket) حسب `backend-archive/src/realtime`. +21. **بوابة**: رحلة كاملة من الطلب إلى الإنهاء بين جهازين + الخريطة تتحرّك + بسلاسة أثناء التتبّع (لا اهتزاز، لا إعادة رسم للشاشة كاملة). + +### المرحلة 5 — مسار الرحلة وما بعدها +22. حالات الرحلة · التتبّع الحيّ · الإلغاء · الإنهاء · الأجرة · التقييم. +23. المحفظتان (محفظة الراكب = التزام، محفظة السائق = إيراد — لا تُدمجان). + +### المرحلة 6 — الدراور والإضافات +24. الدراور · الملف الشخصي · الرحلات السابقة · الإشعارات · الدعم · اللغة. +25. الوحدات المدفوعة السبع (`docs/33`) خلف أعلام `const` حسب نموذج + lite/pro/max — بناء مولَّد، لا فروع. + +## 4. مصير المجلدات القائمة + +| المجلد | المصير | +|---|---| +| `apps/rider-archive-cubit`, `driver-archive-cubit` | مصدر الطبقة الأصلية في م1، ومصدر تشخيص الأداء في م2 — ثم **يُحذفان** بعد نجاح بوابة م3 | +| `apps/rider`, `apps/driver` (نقل GetX) | مرجع سلوك ميداني فقط → `apps/*-archive-getx` بعد م3. **ليسا مرجع هوية** (§2.ج) | +| `Siro/siro_rider`, `siro_driver` | مرجع خارجي دائم — لا يُعدَّل ولا يُنسخ منه دارت | +| باك إند PHP (`docs/34`) | يتوقّف العمل عليه — لا يُحذف | + +## 5. المخاطر + +| الخطر | التخفيف | +|---|---| +| تعارض shorebird app_id بين سيرو وتريبز | الهوية من `*-archive-cubit` حصراً (§2.ج)؛ يُفحص قبل أول باتش | +| تكرار الأداء السيئ نفسه | م2.12 ميزانية أداء مكتوبة + بوابة أداء في كل مرحلة | +| «من الصفر» تتحول لنسخ صامت من الأرشيف | ممنوع أي `import` من `*-archive-*`؛ يُفحص بـ grep عند كل بوابة | +| NestJS «جاهز» لكن غير مختبر منذ 2026-07 | بوابة م0.2 قبل أي شغل تطبيق | +| هوية الراكب/السائق المنفصلة غير منفّذة في NestJS | يُتحقّق في م0.1 | +| جرّ GetX بالغلط عبر pubspec | ممنوع `get`/`get_storage` في `*_new` | +| بناء/اختبار على الماك | كل بناء وهجرة على السيرفر | diff --git a/docs/38-api-contract.md b/docs/38-api-contract.md new file mode 100644 index 0000000..4160540 --- /dev/null +++ b/docs/38-api-contract.md @@ -0,0 +1,308 @@ +# 38 — عقد الـ API لتطبيقي `rider_new` و `driver_new` + +المصدر: `backend-archive/` (NestJS) · مُتحقَّق حيّاً على +`https://tripz-api.intaleqapp.com/api` بتاريخ **2026-08-04**. +هذا الملف **المصدر الوحيد للحقيقة** لطبقة الشبكة في التطبيقين (م0.1 من `docs/37`). + +> ✅ = تُحقّق شكله حيّاً من السيرفر · 📄 = مقروء من الكود فقط + +--- + +## 0. حالة السيرفر — تحقّق حيّ + +``` +GET https://tripz-api.intaleqapp.com/api/health +→ 200 {"status":"ok","service":"tripz-api","time":"2026-08-04T17:52:23Z"} +``` + +الباك إند المؤرشف **ما زال منشوراً ويعمل** رغم قرار الأرشفة 2026-07-27. +المستأجر التجريبي `siro` → `efefa0ad-d803-4a81-9627-125945bb079b`. + +--- + +## 1. الترويسات — في كل طلب + +| الترويسة | القيمة | إلزامي | +|---|---|---| +| `x-tenant-id` | **slug** المستأجر (`siro`) لا UUID | نعم — بدونه 401 | +| `x-app-role` | `rider` أو `driver` | نعم عملياً (الافتراض `rider`) | +| `x-device-id` | بصمة الجهاز | عند `verify-otp` و`refresh` | +| `Authorization` | `Bearer ` | لكل ما عدا `auth/*` و`maps/*` و`tenant/config` | + +**`x-app-role` ليس تجميلاً.** ✅ نفس الرقم `0790000001` أعطى: +`rider` → `d3a29299-909b-4267-80f3-887d8e478e04` · +`driver` → `f21875fa-15db-4805-be39-ccefb9f63450`. +هويتان منفصلتان بمحفظتين منفصلتين. **التطبيق يجب أن يثبّت الترويسة على +قيمة واحدة عند البناء ولا يغيّرها أبداً** — تغييرها = مستخدم آخر. + +--- + +## 2. المصادقة — هاتف + OTP، بلا كلمة سر + +### `POST /auth/send-otp` 📄 +`{ phone }` → `{ success: true, message: 'OTP sent' }` +حدّ: **3 طلبات / 5 دقائق**. التطبيق يجب أن يعرض عدّاداً تنازلياً ويمنع الضغط +المتكرر، وإلا صار المستخدم محظوراً بعد ثلاث ضغطات. + +### `POST /auth/verify-otp` ✅ +```jsonc +// الطلب +{ "phone": "0790000001", "code": "1234", "referral_code": "اختياري" } +// الرد 200 +{ + "access_token": "eyJ…", + "refresh_token": "eyJ…", + "signing_key": "598d8044…c2a2", // ← لتوقيع الطلبات (§8) + "user": { + "id": "uuid", "tenant_id": "uuid", + "phone": "962790000001", // مطبّع دولياً — لا كما أُدخل + "phone_bidx": "3f14…", // فهرس أعمى — لا يُعرض + "name": null, "role": "rider", "status": "active", + "language": "ar", "rating": "5.00", + "created_at": "…", "updated_at": "…" + } +} +``` +- **التطبيع**: `0790000001` يُخزَّن `962790000001`. التطبيق يعرض ما أدخله + المستخدم، ويرسل ما شاء — الخادم يطبّع. لا تعتمد على تطابق نصّي. +- **حدّ المحاولات**: 10 محاولات / 5 دقائق شبكياً + عدّاد لكل (مستأجر، رقم) + يُبطل الرمز فوراً عند تجاوزه. رسالة الخطأ: + `401 {"message":"Too many attempts — request a new code"}`. +- الرمز الخاطئ: `401 {"message":"Invalid or expired OTP code"}`. +- **حسابا مراجعة المتاجر** (مقيّدان بمستأجر `siro` فقط): + `0790000001` و`0790000002` بالرمز الثابت `1234` — يعملان **بلا** + `OTP_DEV_MODE`. ✅ هذان مدخلنا للاختبار حتى نحصل على وصول للسيرفر. + +### `POST /auth/refresh` 📄 +`{ refresh_token }` + ترويسة `x-device-id` → توكن جديد. + +### أعمار التوكن ✅ +`access_token` صالح **900 ثانية (15 دقيقة)** — من `iat`/`exp` الفعليين. +معناه للتطبيق: interceptor يجدّد استباقياً قبل انتهاء الصلاحية، ولا ينتظر +401 — 15 دقيقة قصيرة جداً في منتصف رحلة. + +--- + +## 3. المستخدم + +| النقطة | الوصف | +|---|---| +| `GET /users/me` ✅ | نفس شكل `user` أعلاه بالضبط | +| `PATCH /users/me` 📄 | `{ name?, language? }` | + +--- + +## 4. الراكب — دورة الرحلة + +### `POST /trips` — طلب رحلة 📄 +```jsonc +{ + "origin": { "lat": 31.9539, "lng": 35.9106 }, + "destination": { "lat": 31.98, "lng": 35.87 }, + "service_class": "economy", // من /ride-types + "city": "…", // اختياري + "payment_method": "wallet", + "is_round_trip": false, + "stops": [{ "lat": …, "lng": …, "label": "…" }], // محطات وسيطة + "scheduled_at": "ISO", // حجز مسبق + "coupon_code": "…" +} +→ { "trip": { "id", "status": "searching", "quoted_fare": …, … }, + "offeredDrivers": 3 } +``` + +### باقي النقاط + +| النقطة | من | ملاحظة | +|---|---|---| +| `GET /trips/mine` ✅ | راكب | مصفوفة (فارغة `[]` للحساب الجديد) | +| `GET /trips/:id` 📄 | الطرفان | | +| `POST /trips/:id/cancel` 📄 | الطرفان | الفاعل يُستنتج من الدور | +| `GET /trips/available` 📄 | سائق | الطلبات القريبة | +| `POST /trips/:id/accept` 📄 | سائق | قبول ذرّي — أول واحد يفوز | +| `PATCH /trips/:id/status` 📄 | سائق | `{ status }` | + +### آلة الحالات +``` +searching → assigned → driver_arriving → driver_arrived + → in_progress → completed → paid +(+ cancelled · expired/no_drivers) +``` +⚠️ **`expired`/`no_drivers` قد لا يُطلقان أبداً** (ثغرة R1 المسجّلة). +لا يجوز أن ينتظر التطبيق حدثاً قد لا يصل — **لازم مهلة محليّة في +`searching`** تعرض «لا يوجد سائقون» وتتيح الإلغاء. + +### الأجرة +عند الإنهاء: `price_for_passenger` و`price_for_driver` **حقلان منفصلان** +(الفرق = العمولة). لا تعرض حقلاً واحداً للطرفين. + +--- + +## 5. السائق + +| النقطة | الجسم | +|---|---| +| `POST /drivers/apply` | `{ vehicle_make, service_class }` | +| `GET /drivers/me` | ملف السائق | +| `PATCH /drivers/profile` | `gender · national_number · name_arabic · birthdate · address · license_type · license_categories · license_issue · license_expiry` | +| `PATCH /drivers/status` | `{ online: bool }` | +| `POST /drivers/location` | `{ lat, lng, heading?, speed? }` → Redis | +| `GET /credit` | الرصيد التشغيلي. للراكب: `403 "Not a driver"` ✅ | +| `GET /credit/transactions` | كشف الرصيد | + +**الدور يتغيّر بعد `apply`+`approve`** — التوكن القديم يحمل الدور القديم. +لازم إعادة دخول (أو refresh) بعد الاعتماد، وإلا فشلت نقاط السائق بـ403. + +### المركبات +`GET /vehicles/mine` · `POST /vehicles` (`make · model · year · color · +color_hex · plate`) · `PATCH /vehicles/:id/default` · `DELETE /vehicles/:id`. +أول مركبة تصير الافتراضية تلقائياً. + +### الوثائق +`POST /drivers/documents` (رفع) · `GET /drivers/documents/mine` · +`GET /drivers/documents/requirements` (يقود شاشة «الوثائق الناقصة»). + +--- + +## 6. المال + +| النقطة | الرد ✅ | +|---|---| +| `GET /wallet` | `{ id, tenant_id, user_id, balance: "0.000", currency: "JOD", … }` | +| `GET /wallet/transactions` | كشف | +| `POST /wallet/topup` | `{ amount }` | + +⚠️ **`balance` نصّ لا رقم** (`"0.000"`). لا تمرّره لعملية حسابية بلا تحويل. +`currency` من المستأجر (`JOD`/`EGP`/`SYP`) — لا يُثبَّت في التطبيق. + +**السحب — خطوتان**: `POST /payouts/request` (`{ amount, channel }`) يرسل +رمزاً **بلا خصم** → `POST /payouts/:id/confirm` (`{ code }`) يخصم ويحجز. +`GET /payouts/mine` للسجل. شاشة السحب يجب أن تعكس الخطوتين لا خطوة واحدة. + +`POST /payments/charge` · `GET /payments/mine` لبوابات الدفع. + +--- + +## 7. التقييم · التعرفة · الأنواع · الخريطة + +### `GET /trips/rating/pending` ✅ +`{ "pending": null, "count": 0 }` أو +`{ "pending": { "tripId", "role": "rider"|"driver" } }`. +**يُنادى عند كل فتح للتطبيق** — إن وُجدت رحلة معلّقة تُفرض شاشة التقييم. +`POST /trips/:id/rate` `{ stars, comment? }`. التقييم المزدوج → `400`. + +### `GET /ride-types` ✅ +```jsonc +[{ "id","code":"economy","name_ar":"اقتصادي","name_en":"Economy", + "vehicle_kind":"car","women_only":false,"round_trip_supported":true, + "icon":null,"sort":1,"active":true }, …] +``` +شاشة اختيار النوع تُبنى من هنا — لا قائمة مكتوبة في التطبيق. انتبه +لـ`women_only` و`round_trip_supported` و`sort`. + +### `POST /tariff/quote` ✅ +```jsonc +{ "city": "…", "serviceClass": "economy", "distanceKm": 5.2, "durationMin": 14 } +→ { "quote": { "window":"normal_evening","flag","distance","time","waiting", + "weight","bookingFee","subtotal","surgeMultiplier","total", + "currency":"JOD" }, "tariffId", "version" } +``` +⚠️ **الأسماء camelCase هنا، بخلاف بقية الـAPI (snake_case).** وإرسال +`origin/destination` بدل `distanceKm/durationMin` يرجّع 200 بقيم `null` +صامتة — لا خطأ. يعني: احسب المسافة من `/maps/route` أولاً ثم اطلب التسعيرة، +وتحقّق أن `total != null` قبل عرضها. +⚠️ `city` غير معروف → `404 "No active tariff for amman/economy"` ✅ — +قيمة `city` تأتي من إعداد المستأجر لا من نصّ حرّ. + +### الخريطة +| النقطة | الحالة | +|---|---| +| `GET /maps/route?fromLat&fromLng&toLat&toLng&country` | ✅ `{"distanceKm":7.209,"durationMin":11.5,"provider":"antlaq"}` | +| `GET /maps/reverse?lat&lng&country` | ✅ مصفوفة أماكن (`name_ar`, `category`, `distance`, …) | +| `GET /maps/geocode?q&country` | ❌ `400 "country must be one of the following values: "` — **قائمة الدول فارغة على السيرفر المنشور** | +| `POST /maps/voice-search` · `POST /maps/places` | 📄 | + +**تعارض قرار يُحسم قبل م4**: قرار `maps-direct-decision` (2026-07-20) يقول كل +الخرائط مباشرة لـ map-saas بمفتاح `x-api-key`؛ و`docs/01`/الذاكرة الأقدم +تقول geocode/route عبر خادمنا. النقاط أعلاه موجودة وتعمل (عدا geocode). +القرار الأحدث يسود — لكن يُثبَّت صراحةً قبل بناء شاشة الخريطة. +هذه النقاط **بلا `JwtAuthGuard`** — مفتوحة بلا توكن. + +--- + +## 8. الأمان — علمان مُطفآن ينتظران التطبيق + +`signing_key` يعود في رد الدخول، ويوجد `PAYMENTS_REQUIRE_SIGNATURE` و +`AUTH_REQUIRE_DEVICE_BINDING`. القرار: **يُفعَّلان بعد أن يوقّع التطبيق +طلباته ويرسل `x-device-id`**. لذلك يُبنى التوقيع وبصمة الجهاز في طبقة +الشبكة **من م3**، لا يُؤجَّل — تأجيله يعني إعادة كتابة الـinterceptors لاحقاً. + +--- + +## 9. الواقع اللحظي (WebSocket) + +Socket.IO على أصل الـAPI بلا `/api`، المصادقة `auth: { token }`، +`transports: ['websocket']`. + +**يُرسِله الخادم**: `trip:update` · `driver:location` · `trip:offer` · +`trip:offer_taken` · `bus:arrived` +**يستقبله الخادم**: `trip:join` (`{ tripId }`) · `driver:location` · +`call:offer` / `call:answer` / `call:ice` / `call:end` (WebRTC) + +`trip:offer` و`trip:offer_taken` = قلب شاشة السائق: عرض يصل، ثم يختفي إذا +سبقه غيره. لازم انضمام (`trip:join`) **قبل** أي انتقال حالة وإلا فاتت الأحداث. + +--- + +## 10. إعداد المستأجر — يقود واجهة التطبيق + +### `GET /tenant/config/:slug` ✅ (بلا توكن) +```jsonc +{ "slug":"siro","name":"Siro Amman","countryPack":"jo","plan":"brand", + "branding":{}, + "features":{ "dispatch":false,"wallet":true,"payments":true,"chat":true, + "calls":true,"ride_types":true,"market_intel":false,"bots":false, + "ads":false,"transit":false,"api_access":false,"driver_tiers":true, + "marketing_engine":false,"dynamic_pricing":false,"geofence":false, + "negotiator":false,"driver_assurance":false,"coupons":false }, + "limits":{ "drivers_max":500,"cities_max":3 } } +``` +**كل ميزة في التطبيق تُخفى أو تُظهر من `features`**، لا من علم مكتوب في +الكود. هذا هو ربط lite/pro/max بالخادم. يُجلب مرة عند الإقلاع ويُخزَّن. +`GET /tenant/logo/:slug` للشعار. + +--- + +## 11. نقاط أخرى تخصّ التطبيقين + +`POST /notifications/token` `{ token, platform }` — FCM · +`POST /trips/:id/messages` + `GET /trips/:id/messages` — الدردشة · +`GET /geofence/nearby` · `GET /rewards/referrals` · `GET /rewards/coupons` · +`GET /rewards/coupons/preview` · `POST /trips/:id/audio` + `GET .../audio`. + +**نقاط الأدمن ليست للتطبيقين** (`/admin/*`, `/superadmin/*`, `/tenant/billing`, +`/dispatch/*`): محروسة بـ`RolesGuard` وترجع `403` — لا تُستدعى. + +--- + +## 12. مصائد مؤكَّدة — تُقرأ قبل كتابة طبقة الشبكة + +1. `access_token` = 15 دقيقة → تجديد استباقي إجباري. +2. `balance` وكل المبالغ **نصوص** — حوّلها. +3. `x-app-role` يحدّد الهوية — يُثبَّت عند البناء. +4. `/tariff/quote` بـcamelCase وحده، ويفشل صامتاً بقيم `null`. +5. `/auth/send-otp` = 3 طلبات / 5 دقائق — عدّاد تنازلي إجباري في الواجهة. +6. الدور يتغيّر بعد اعتماد السائق → إعادة دخول إجبارية. +7. `expired`/`no_drivers` قد لا يصلان → مهلة محليّة في `searching`. +8. `/maps/geocode` معطوب على المنشور (قائمة دول فارغة). +9. `x-tenant-id` هو **slug** لا UUID. + +--- + +## 13. ما لم يُتحقّق بعد — يحتاج وصول للسيرفر + +`e2e-test.mjs` الكامل يحتاج `OTP_DEV_MODE=true` (أرقام عشوائية)؛ على +المنشور هو **مطفأ**، والـSSH من الماك مرفوض (`Permission denied (publickey)`). +غير مُتحقَّق حيّاً: دورة الرحلة الكاملة · WebSocket · التسوية والعمولة · +السحب بـOTP · حراسة الأدمن. الشكل موثّق أعلاه من الكود (📄) ويُثبَّت عند +توفّر الوصول. diff --git a/docs/39-siro-screens.md b/docs/39-siro-screens.md new file mode 100644 index 0000000..b4f60e6 --- /dev/null +++ b/docs/39-siro-screens.md @@ -0,0 +1,196 @@ +# 39 — جرد شاشات سيرو: المرجع البصري والسلوكي + +الغرض: هذا **ما نبني عليه الشكل والترتيب** في `rider_new` و`driver_new` +(م0.3 من `docs/37`). المصدر: `~/development/App/Siro/siro_rider` و`siro_driver`. + +> **قاعدة الاستخدام**: هذا الملف يجيب على «ما هي الشاشة، وما ترتيب خطواتها، +> وأي حالة حافة عولجت ميدانياً». **لا يُنسخ ملف دارت واحد من سيرو.** +> شكل الواجهة يُعاد بناؤه على `docs/26` بجودة أعلى، والعقد من `docs/38`. + +--- + +## 1. المخزون — الحجم الحقيقي + +| | شاشات/ويدجت | ملاحظة | +|---|---|---| +| `siro_rider/lib/views` | 89 ملف | يشمل الطعام والنقل العام | +| `siro_driver/lib/views` | 113 ملف | يشمل التوصيل والتلعيب والإحصاءات | + +**ليس كله في النطاق.** خارج نطاق `docs/37` تماماً: `food/`, `food_delivery/`, +`transit/`, `gamification/`, `assurance_health_page`, `siro_prime_page`, +`android_bot`. هذي تُقرأ لاحقاً عند وحدات `docs/33` المدفوعة، لا الآن. + +**داخل النطاق** (م1–م6): المصادقة · الخريطة وطلب الرحلة · مسار الرحلة · +المحفظة · الدراور والملف · الإشعارات · التقييم. + +--- + +## 2. المصادقة — مرجع م3 + +### التسلسل في سيرو (متطابق في التطبيقين) + +``` +موافقة الشروط → إذن الموقع → رقم الهاتف → OTP → [تسجيل] → الرئيسية +``` + +بوابتان **قبل** أي حقل إدخال، وكل واحدة شاشة كاملة لا حوار: + +1. **صفحة الموافقة** (`_buildAgreementPage`): نصّ الاتفاقية بـHTML من الخادم، + مربّع اختيار، وزر متابعة **معطّل حتى يُؤشَّر**. تُحفظ + (`BoxName.agreeTerms == 'agreed'`) ولا تتكرر. +2. **صفحة إذن الموقع**: تطلب الإذن، ومعها زر `openAppSettings()` للحالة التي + يرفض فيها المستخدم نهائياً. تطبيق السائق يراقب دورة حياة التطبيق + (`WidgetsBindingObserver` + `didChangeAppLifecycleState`) ليعيد الفحص عند + **العودة من إعدادات النظام** — بلا هذا تبقى الشاشة عالقة. حالة حافة حقيقية + لازم تُنقل. + +### شاشة الهاتف +- `IntlPhoneField` مع مفتاح دولة افتراضي من `BoxName.countryCode`. +- تحقّقات مطبّقة: فارغ · **يبدأ بصفر → رفض** («أدخل بلا الصفر») · أقصر من 10. +- الرقم يُرسل بلا `+`. + +### شاشة الـOTP +- **3 خانات** في سيرو، حقل واحد بتباعد حروف كبير + ثلاث نقاط تقدّم متحرّكة. +- ⚠️ **تريبز يستخدم 4 خانات** (`docs/38`). الشكل يُقلَّد، الطول لا. +- ⚠️ **لا يوجد عدّاد إعادة إرسال ولا زر «إعادة الإرسال» في سيرو.** هذه + **فجوة، لا مرجع**: تريبز يحدّ `send-otp` بـ3 طلبات/5 دقائق، فبلا عدّاد + تنازلي يُحظر المستخدم بثلاث ضغطات. **لازم نضيفها.** + +### شاشة التسجيل +الاسم الأول · الأخير · البريد. ⚠️ عقد تريبز يقبل `{ name, language }` فقط +(`PATCH /users/me`) — حقل اسم واحد. لا تُنقل الحقول كما هي. + +### فروق تطبيق السائق +مسار إضافي بعد الدخول: `registration_view` (تسجيل السائق) → +`pending_driver_page` (شاشة «قيد المراجعة») → `camera_lisence_page` / +`text_scanner` / `passportimage` (تصوير الوثائق) → `cars_inserting_page`. +يقابلها في تريبز: `/drivers/apply` → `/drivers/profile` → +`/drivers/documents` → `/vehicles`، **ثم إعادة دخول إجبارية** لأن الدور +يتغيّر بعد الاعتماد (مصيدة `docs/38` §5). + +### ما لا يُنقل من طبقة مصادقة سيرو +`login_controller.dart` فيه JWT مزدوج (توكن عام + `walletJwt` منفصل)، وقفل +تزامن ساكن، وعدّاد إخفاقات، وفكّ base64 يدوي للـpayload. **هذا تعقيد مفروض +من باك إند PHP**، وتريبز عنده `access_token`/`refresh_token` واحد. لا يُنقل. +المُنقَل هو الفكرة الصالحة: **تجديد واحد متزامن لا يتضاعف عند تعدد الطلبات**. + +--- + +## 3. الخريطة وطلب الرحلة — مرجع م4 + +أنضج جزء في سيرو، وأدقّ ما نأخذه منه. الوحدة: `views/home/route_planner/` +(10 ملفات، 1,928 سطراً) + `views/home/map_widget.dart/`. + +### البنية: خريطة ثابتة + ورقة سفلية بثلاث حالات +1. **مطوية** (`_Collapsed`) — بطاقة «إلى أين؟» فقط. +2. **موسّعة** (`_Expanded`) — المخطّط الكامل. +3. **اختيار من الخريطة** (`RpMapPickOverlay`) — الورقة تنزوي، ودبّوس ثابت في + المنتصف (`rp_center_pin`) والخريطة تتحرك تحته. النمط الصحيح: **المستخدم + يحرّك الخريطة لا الدبّوس.** + +### ترتيب المخطّط الموسّع (من أعلى لأسفل) +ترويسة → **مبدّل نوع الطلب** (لنفسي ⇄ لشخص آخر) → **الخط الزمني للمسار** +(المصدر · محطات وسيطة · الوجهة) → **وصول سريع** (المنزل/العمل) → **متقدّم**. + +- المصدر افتراضياً = الموقع الحالي، وقابل للتغيير من الخريطة. +- عند «لشخص آخر» يتبدّل حقل المصدر فوراً (`rp_sheet.dart:509`). +- **المحطات الوسيطة** صفوف قابلة للإضافة/الحذف — يقابلها `stops[]` في + `POST /trips` (`docs/38` §4). موجودة في الطرفين. +- المفضّلات (`rp_favorites`) والبحث (`rp_search_dialog` + `rp_search_results`). + +### نافذة البحث عن سائق (`searching_captain_window`) +- أنيميشن رادار (دورة ثانيتين) + نصّ الحالة من الكنترولر + مؤشّر دوّار. +- **لا مقبض سحب** — لا تُغلق بالسحب، **فقط بزر «إلغاء البحث»**. قرار تصميمي + صحيح يُنقل: المستخدم لا يزيح شاشة البحث بالخطأ. +- الويدجت «غبي» بلا منطق؛ المؤقّت في الكنترولر هو من يقرر متى يعرض حوار + زيادة الأجرة. **يقابل مباشرةً** مصيدة `docs/38` §4: `expired`/`no_drivers` + قد لا يصلان من الخادم → **المهلة المحليّة إلزامية**. سيرو عالجها؛ نكرّرها. + +### بطاقة الرحلة الجارية (`apply_order_widget`, 871 سطراً) +ترويسة مضغوطة · بطاقة معلومات · **شارة السائق** · **لوحة مركبة مرسومة** · +أيقونة سيارة متحرّكة · صف أزرار · حقل رسالة مخصّصة · مؤشّرا +«وصل السائق وينتظر ن دقيقة» و«الوقت المتبقّي للوصول». +هذي المكوّنات هي ما يجعل الشاشة تبدو احترافية — تُعاد بناؤها في +`packages/tripz_ui`، لا تُنسخ. + +### شاشات مساندة +`payment_method_page` · `cash_confirm_bottom_page` · `cancel_raide_page` +(أسباب الإلغاء) · `ride_begin_passenger` · `car_details_widget_to_go` · +`trip_monitor` + `trip_link_monitor` (مشاركة رابط تتبّع) · +`voice_call_bottom_sheet` (WebRTC — يقابل `call:*` في `docs/38` §9). + +### شاشة السائق (`order_request_page`, 468 سطراً) +خريطة → **كبسولة «الوصول للراكب»** → بطاقة سفلية: +`الراكب + السعر` → `شريط معلومات (المسافة/المدة)` → `العناوين` → `الأزرار`. +- **حالة تحميل صريحة** إن وصل العرض بلا بيانات كاملة — لا شاشة فارغة. +- `order_over_lay.dart` (847 سطراً) = العرض المنبثق فوق أي شاشة. يقابل + `trip:offer` و`trip:offer_taken` في `docs/38` §9. +- ⚠️ شارة `driverEarningsExtra` تعتمد حقولاً من `add_ride.php` (باك إند PHP) + **غير موجودة في عقد NestJS** — تُسقط أو يُضاف لها حقل في الخادم. مثال حيّ + على أن سيرو ليس مطابقاً للعقد. + +--- + +## 4. المحفظة — مرجع م5 + +| الراكب | السائق | +|---|---| +| `passenger_wallet` · `payment_history_passenger_page` · `cliq_payment_sheet` · `payment_screen_cliq/mtn/sham` | `walet_captain` · `pay_out_screen` · `weekly_payment_page` · `transfer_budget_page` · `points_captain` · `ecash` · `bank_account_egypt` | + +محفظة السائق مقسّمة لويدجت جاهزة (`balance_card` · +`financial_summary_card` · `quick_actions` · `transaction_preview_item`) — +تفكيك جيد يُحتذى. + +⚠️ **مصيدتان**: +1. سيرو يخلط محفظة الراكب والسائق في تصميم واحد. تريبز يفصلهما (التزام مقابل + إيراد) — لا تُوحَّد الشاشة. +2. `pay_out_screen` في سيرو **خطوة واحدة**؛ تريبز **خطوتان** مع OTP + (`docs/38` §6). الشاشة تُعاد تصميمها لا تُقلَّد. + +--- + +## 5. الدراور والملف والإشعارات — مرجع م6 + +**الراكب**: `drawer_menu_page` · `passenger_profile_page` · `order_history` · +`setting_page` · `languages` · `about_page` · `contact_us` · +`frequentlyQuestionsPage` · `share_app_page` · `complaint_page` · +`promos_passenger_page` · `taarif_page` · `notification_page` · +`rate_captain` + `rating_driver_bottom`. + +**السائق**: `drawer_captain` · `bottom_bar` (تنقّل سفلي — الراكب بلا) · +`profile_captain` · `captains_cars` · `history_captain` + +`history_details_page` · `settings_captain` · `behavior_page` · +`feed_back_page` · `help_captain` + `help_details_replay_page` · +`available_rides_page` · `statistics_dashboard` (+6 ويدجت رسوم) · +`rate_passenger` · `ride_calculate_driver` · `sos_connect` (استغاثة). + +**شاشة التقييم مهمة معمارياً**: تُفرض عند فتح التطبيق عبر +`GET /trips/rating/pending` (`docs/38` §7) — تُبنى في م5 لا م6. + +--- + +## 6. الويدجت المشتركة — مدخل `packages/tripz_ui` + +الملفات نفسها **مكرّرة حرفياً** في التطبيقين: +`circle_container` · `elevated_btn` · `error_snakbar` · `icon_widget_menu` · +`my_circular_indicator_timer` · `my_scafold` · `my_textField` · `mycircular` · +`mydialoug` · `voice_call_bottom_sheet`. + +**هذا بالضبط ما تحلّه `packages/tripz_ui`** (م2.11): ازدواج مؤكَّد في سيرو، +لا يتكرر عندنا. + +--- + +## 7. ملاحظات أداء — مادة قائمة الممنوعات (م2.12) + +من قراءة سيرو، هذي أنماط تُتجنّب في `*_new`: +- `Get.put()` داخل `build()` (`login_page.dart:27`) — حقن عند كل إعادة بناء. +- ملفات ويدجت تتجاوز 800 سطر (`apply_order_widget` 871 · + `order_over_lay` 847 · `home_captin` 840) — تفكّك. +- `GetBuilder` يلفّ الشاشة كاملة → إعادة بناء الشجرة كلها عند أي تحديث. + البديل: `BlocSelector`/`buildWhen` على أصغر جزء. +- منطق داخل الويدجت. النمط الصحيح موجود في سيرو نفسه + (`searching_captain_window` «غبي» والمؤقّت في الكنترولر) — يُعمَّم. + +> قائمة الممنوعات النهائية تُستكمل في م2 بعد تشخيص `*-archive-cubit` نفسه — +> فسبب الأداء المرفوض هناك، لا هنا.