this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

android support-ish (iOS soon)

+1901
+19
mobile/.fleet/receipt.json
··· 1 + // Project generated by Kotlin Multiplatform Wizard 2 + { 3 + "spec": { 4 + "template_id": "kmt", 5 + "targets": { 6 + "android": { 7 + "ui": [ 8 + "compose" 9 + ] 10 + }, 11 + "ios": { 12 + "ui": [ 13 + "compose" 14 + ] 15 + } 16 + } 17 + }, 18 + "timestamp": "2025-03-15T18:00:33.935977603Z" 19 + }
+18
mobile/.gitignore
··· 1 + *.iml 2 + .kotlin 3 + .gradle 4 + **/build/ 5 + xcuserdata 6 + !src/**/build/ 7 + local.properties 8 + .idea 9 + .DS_Store 10 + captures 11 + .externalNativeBuild 12 + .cxx 13 + *.xcodeproj/* 14 + !*.xcodeproj/project.pbxproj 15 + !*.xcodeproj/xcshareddata/ 16 + !*.xcodeproj/project.xcworkspace/ 17 + !*.xcworkspace/contents.xcworkspacedata 18 + **/xcshareddata/WorkspaceSettings.xcsettings
+14
mobile/README.md
··· 1 + This is a Kotlin Multiplatform project targeting Android, iOS. 2 + 3 + * `/composeApp` is for code that will be shared across your Compose Multiplatform applications. 4 + It contains several subfolders: 5 + - `commonMain` is for code that’s common for all targets. 6 + - Other folders are for Kotlin code that will be compiled for only the platform indicated in the folder name. 7 + For example, if you want to use Apple’s CoreCrypto for the iOS part of your Kotlin app, 8 + `iosMain` would be the right folder for such calls. 9 + 10 + * `/iosApp` contains iOS applications. Even if you’re sharing your UI with Compose Multiplatform, 11 + you need this entry point for your iOS app. This is also where you should add SwiftUI code for your project. 12 + 13 + 14 + Learn more about [Kotlin Multiplatform](https://www.jetbrains.com/help/kotlin-multiplatform-dev/get-started.html)…
+9
mobile/build.gradle.kts
··· 1 + plugins { 2 + // this is necessary to avoid the plugins to be loaded multiple times 3 + // in each subproject's classloader 4 + alias(libs.plugins.androidApplication) apply false 5 + alias(libs.plugins.androidLibrary) apply false 6 + alias(libs.plugins.composeMultiplatform) apply false 7 + alias(libs.plugins.composeCompiler) apply false 8 + alias(libs.plugins.kotlinMultiplatform) apply false 9 + }
+83
mobile/composeApp/build.gradle.kts
··· 1 + import org.jetbrains.compose.desktop.application.dsl.TargetFormat 2 + import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi 3 + import org.jetbrains.kotlin.gradle.dsl.JvmTarget 4 + 5 + plugins { 6 + alias(libs.plugins.kotlinMultiplatform) 7 + alias(libs.plugins.androidApplication) 8 + alias(libs.plugins.composeMultiplatform) 9 + alias(libs.plugins.composeCompiler) 10 + } 11 + 12 + kotlin { 13 + androidTarget { 14 + @OptIn(ExperimentalKotlinGradlePluginApi::class) 15 + compilerOptions { 16 + jvmTarget.set(JvmTarget.JVM_11) 17 + } 18 + } 19 + 20 + listOf( 21 + iosX64(), 22 + iosArm64(), 23 + iosSimulatorArm64() 24 + ).forEach { iosTarget -> 25 + iosTarget.binaries.framework { 26 + baseName = "ComposeApp" 27 + isStatic = true 28 + } 29 + } 30 + 31 + sourceSets { 32 + 33 + androidMain.dependencies { 34 + implementation(compose.preview) 35 + implementation(libs.androidx.activity.compose) 36 + implementation(libs.face.detection) 37 + } 38 + commonMain.dependencies { 39 + implementation(compose.runtime) 40 + implementation(compose.foundation) 41 + implementation(compose.material) 42 + implementation(compose.ui) 43 + implementation(compose.components.resources) 44 + implementation(compose.components.uiToolingPreview) 45 + implementation(libs.androidx.lifecycle.viewmodel) 46 + implementation(libs.androidx.lifecycle.runtime.compose) 47 + implementation(libs.camerak) 48 + implementation(libs.androidx.graphics.shapes) 49 + } 50 + } 51 + } 52 + 53 + android { 54 + namespace = "com.paytondeveloper.myrus_mobile" 55 + compileSdk = libs.versions.android.compileSdk.get().toInt() 56 + 57 + defaultConfig { 58 + applicationId = "com.paytondeveloper.myrus_mobile" 59 + minSdk = libs.versions.android.minSdk.get().toInt() 60 + targetSdk = libs.versions.android.targetSdk.get().toInt() 61 + versionCode = 1 62 + versionName = "1.0" 63 + } 64 + packaging { 65 + resources { 66 + excludes += "/META-INF/{AL2.0,LGPL2.1}" 67 + } 68 + } 69 + buildTypes { 70 + getByName("release") { 71 + isMinifyEnabled = false 72 + } 73 + } 74 + compileOptions { 75 + sourceCompatibility = JavaVersion.VERSION_11 76 + targetCompatibility = JavaVersion.VERSION_11 77 + } 78 + } 79 + 80 + dependencies { 81 + debugImplementation(compose.uiTooling) 82 + } 83 +
+33
mobile/composeApp/src/androidMain/AndroidManifest.xml
··· 1 + <?xml version="1.0" encoding="utf-8"?> 2 + <manifest xmlns:android="http://schemas.android.com/apk/res/android"> 3 + 4 + <uses-feature 5 + android:name="android.hardware.camera" 6 + android:required="false" /> 7 + 8 + <uses-permission android:name="android.permission.CAMERA" /> 9 + <uses-permission 10 + android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 11 + <meta-data 12 + android:name="com.google.mlkit.vision.DEPENDENCIES" 13 + android:value="face"/> 14 + <application 15 + android:allowBackup="true" 16 + android:icon="@mipmap/ic_launcher" 17 + android:label="@string/app_name" 18 + android:roundIcon="@mipmap/ic_launcher_round" 19 + android:supportsRtl="true" 20 + android:theme="@android:style/Theme.Material.Light.NoActionBar"> 21 + <activity 22 + android:exported="true" 23 + android:configChanges="orientation|screenSize|screenLayout|keyboardHidden|mnc|colorMode|density|fontScale|fontWeightAdjustment|keyboard|layoutDirection|locale|mcc|navigation|smallestScreenSize|touchscreen|uiMode" 24 + android:name=".MainActivity"> 25 + <intent-filter> 26 + <action android:name="android.intent.action.MAIN" /> 27 + 28 + <category android:name="android.intent.category.LAUNCHER" /> 29 + </intent-filter> 30 + </activity> 31 + </application> 32 + 33 + </manifest>
+189
mobile/composeApp/src/androidMain/kotlin/com/paytondeveloper/myrus_mobile/MLFace.android.kt
··· 1 + package com.paytondeveloper.myrus_mobile 2 + 3 + import android.app.Activity 4 + import android.content.ContentValues 5 + import android.content.Context 6 + import android.content.Context.CAMERA_SERVICE 7 + import android.graphics.Bitmap 8 + import android.graphics.BitmapFactory 9 + import android.hardware.camera2.CameraAccessException 10 + import android.hardware.camera2.CameraCharacteristics 11 + import android.hardware.camera2.CameraManager 12 + import android.net.Uri 13 + import android.os.Build 14 + import android.os.Environment 15 + import android.provider.MediaStore 16 + import android.util.Log 17 + import android.util.SparseIntArray 18 + import android.view.Surface 19 + import androidx.annotation.RequiresApi 20 + import androidx.camera.core.Camera 21 + import androidx.camera.core.CameraSelector 22 + import androidx.camera.core.ImageCapture 23 + import androidx.camera.core.impl.CameraInternal 24 + import androidx.camera.core.impl.Config 25 + import com.google.mlkit.vision.common.InputImage 26 + import com.google.mlkit.vision.face.FaceDetection 27 + import com.google.mlkit.vision.face.FaceDetector 28 + import com.google.mlkit.vision.face.FaceDetectorOptions 29 + import com.google.mlkit.vision.face.FaceDetectorOptions.LandmarkMode 30 + import com.kashif.cameraK.builder.CameraControllerBuilder 31 + import com.kashif.cameraK.controller.CameraController 32 + import com.kashif.cameraK.enums.Directory 33 + import com.kashif.cameraK.utils.getActivityOrNull 34 + import org.slf4j.MDC.put 35 + import java.io.FileOutputStream 36 + import java.io.IOException 37 + 38 + actual fun CameraController.getResolution(): Size? { 39 + val field = this::class.java.getDeclaredField("imageCapture") 40 + field.isAccessible = true 41 + val imgCapture = field.get(this) as ImageCapture? 42 + val res = imgCapture?.resolutionInfo?.resolution 43 + return if (res != null) Size(width = res.width.toFloat(), height = res.height.toFloat()) else null 44 + 45 + } 46 + 47 + actual fun analyzeImage(img: ByteArray, callback: (Rect, Size) -> Unit) { 48 + // println("res2: ${saveByteArrayToMediaStore(AppInfo.app.applicationContext, img)}") 49 + try { 50 + 51 + val rotationDegrees = rotationDegrees(AppInfo.activity, isFrontFacing = true) 52 + // val img = InputImage.fromByteArray(img, options.outWidth, options.outHeight, rotationDegrees, InputImage.IMAGE_FORMAT_NV21) 53 + val bitmap = BitmapFactory.decodeByteArray(img, 0, img.size) 54 + val img = InputImage.fromBitmap(bitmap, 0) 55 + val detector = FaceDetection.getClient() 56 + if (AppInfo.canDetectFace) { 57 + AppInfo.canDetectFace = false 58 + val res = detector.process(img) 59 + res.addOnCompleteListener { 60 + println("ml completed: ${it.isSuccessful} ${it.exception} ${res.result.count()}") 61 + AppInfo.canDetectFace = true 62 + res.result.forEach { 63 + println("FACE @ ${it.boundingBox.top}") 64 + 65 + callback(Rect(it.boundingBox.top.toFloat(), it.boundingBox.left.toFloat(), it.boundingBox.bottom.toFloat(), it.boundingBox.right.toFloat()), Size(width = bitmap.width.toFloat(), height = bitmap.height.toFloat())) 66 + } 67 + } 68 + } 69 + 70 + } catch (e: Exception) { 71 + println("error: ${e}") 72 + } 73 + } 74 + 75 + 76 + 77 + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) 78 + @Throws(CameraAccessException::class) 79 + fun rotationDegrees(activity: Activity, isFrontFacing: Boolean): Int { 80 + val ORIENTATIONS = SparseIntArray() 81 + ORIENTATIONS.append(Surface.ROTATION_0, 0) 82 + ORIENTATIONS.append(Surface.ROTATION_90, 90) 83 + ORIENTATIONS.append(Surface.ROTATION_180, 180) 84 + ORIENTATIONS.append(Surface.ROTATION_270, 270) 85 + 86 + /** 87 + * Get the angle by which an image must be rotated given the device's current 88 + * orientation. 89 + */ 90 + 91 + // Get the device's current rotation relative to its "native" orientation. 92 + // Then, from the ORIENTATIONS table, look up the angle the image must be 93 + // rotated to compensate for the device's rotation. 94 + val deviceRotation = activity.windowManager.defaultDisplay.rotation 95 + var rotationCompensation = ORIENTATIONS.get(deviceRotation) 96 + 97 + // Get the device's sensor orientation. 98 + val cameraManager = activity.getSystemService(CAMERA_SERVICE) as CameraManager 99 + var cameraId = "" 100 + cameraManager.cameraIdList.forEach { 101 + if (cameraManager.getCameraCharacteristics(it).get(CameraCharacteristics.LENS_FACING) == CameraCharacteristics.LENS_FACING_FRONT) cameraId = it 102 + } 103 + val sensorOrientation = cameraManager 104 + .getCameraCharacteristics(cameraId) 105 + .get(CameraCharacteristics.SENSOR_ORIENTATION)!! 106 + 107 + if (isFrontFacing) { 108 + rotationCompensation = (sensorOrientation + rotationCompensation) % 360 109 + } else { // back-facing 110 + rotationCompensation = (sensorOrientation - rotationCompensation + 360) % 360 111 + } 112 + return rotationCompensation 113 + } 114 + 115 + //DEBUG ONLY 116 + 117 + fun saveByteArrayToMediaStore( 118 + context: Context, 119 + byteArray: ByteArray, 120 + filename: String = "image_${System.currentTimeMillis()}.jpg", 121 + mimeType: String = "image/png", 122 + quality: Int = 100 123 + ): Uri? { 124 + // First decode the image to get its dimensions 125 + val options = BitmapFactory.Options().apply { 126 + inJustDecodeBounds = true // This option decodes only the dimensions without loading the full bitmap 127 + } 128 + 129 + BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size, options) 130 + 131 + // Check if we could decode the image dimensions 132 + if (options.outWidth <= 0 || options.outHeight <= 0) { 133 + return null // Invalid image data 134 + } 135 + 136 + // Now decode the actual bitmap 137 + val bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.size) 138 + ?: return null // Failed to decode 139 + 140 + // Set up the MediaStore ContentValues 141 + val contentValues = ContentValues().apply { 142 + put(MediaStore.Images.Media.DISPLAY_NAME, filename) 143 + put(MediaStore.Images.Media.MIME_TYPE, mimeType) 144 + put(MediaStore.Images.Media.WIDTH, bitmap.width) 145 + put(MediaStore.Images.Media.HEIGHT, bitmap.height) 146 + 147 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { 148 + put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES) 149 + put(MediaStore.Images.Media.IS_PENDING, 1) 150 + } 151 + } 152 + 153 + // Insert and get the URI 154 + val contentResolver = context.contentResolver 155 + val uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues) 156 + 157 + uri?.let { 158 + try { 159 + contentResolver.openOutputStream(it)?.use { outputStream -> 160 + bitmap.compress( 161 + when (mimeType) { 162 + "image/png" -> Bitmap.CompressFormat.PNG 163 + "image/webp" -> if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { 164 + Bitmap.CompressFormat.WEBP_LOSSLESS 165 + } else { 166 + @Suppress("DEPRECATION") 167 + Bitmap.CompressFormat.WEBP 168 + } 169 + else -> Bitmap.CompressFormat.JPEG 170 + }, 171 + quality, 172 + outputStream 173 + ) 174 + } 175 + 176 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { 177 + contentValues.clear() 178 + contentValues.put(MediaStore.Images.Media.IS_PENDING, 0) 179 + contentResolver.update(it, contentValues, null, null) 180 + } 181 + } catch (e: IOException) { 182 + contentResolver.delete(it, null, null) 183 + return null 184 + } 185 + } 186 + 187 + bitmap.recycle() 188 + return uri 189 + }
+34
mobile/composeApp/src/androidMain/kotlin/com/paytondeveloper/myrus_mobile/MainActivity.kt
··· 1 + package com.paytondeveloper.myrus_mobile 2 + 3 + import android.app.Activity 4 + import android.app.Application 5 + import android.os.Bundle 6 + import androidx.activity.ComponentActivity 7 + import androidx.activity.compose.setContent 8 + import androidx.activity.enableEdgeToEdge 9 + import androidx.compose.runtime.Composable 10 + import androidx.compose.ui.tooling.preview.Preview 11 + 12 + class MainActivity : ComponentActivity() { 13 + override fun onCreate(savedInstanceState: Bundle?) { 14 + super.onCreate(savedInstanceState) 15 + AppInfo.app = this.application 16 + AppInfo.activity = this 17 + enableEdgeToEdge() 18 + setContent { 19 + App() 20 + } 21 + } 22 + } 23 + 24 + @Preview 25 + @Composable 26 + fun AppAndroidPreview() { 27 + App() 28 + } 29 + 30 + object AppInfo { 31 + lateinit var app: Application 32 + lateinit var activity: Activity 33 + var canDetectFace: Boolean = true 34 + }
+12
mobile/composeApp/src/androidMain/kotlin/com/paytondeveloper/myrus_mobile/Platform.android.kt
··· 1 + package com.paytondeveloper.myrus_mobile 2 + 3 + import android.os.Build 4 + import com.kashif.cameraK.controller.CameraController 5 + 6 + class AndroidPlatform : Platform { 7 + override val name: String = "Android ${Build.VERSION.SDK_INT}" 8 + } 9 + 10 + actual fun getPlatform(): Platform = AndroidPlatform() 11 + 12 +
+30
mobile/composeApp/src/androidMain/res/drawable-v24/ic_launcher_foreground.xml
··· 1 + <vector xmlns:android="http://schemas.android.com/apk/res/android" 2 + xmlns:aapt="http://schemas.android.com/aapt" 3 + android:width="108dp" 4 + android:height="108dp" 5 + android:viewportWidth="108" 6 + android:viewportHeight="108"> 7 + <path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z"> 8 + <aapt:attr name="android:fillColor"> 9 + <gradient 10 + android:endX="85.84757" 11 + android:endY="92.4963" 12 + android:startX="42.9492" 13 + android:startY="49.59793" 14 + android:type="linear"> 15 + <item 16 + android:color="#44000000" 17 + android:offset="0.0" /> 18 + <item 19 + android:color="#00000000" 20 + android:offset="1.0" /> 21 + </gradient> 22 + </aapt:attr> 23 + </path> 24 + <path 25 + android:fillColor="#FFFFFF" 26 + android:fillType="nonZero" 27 + android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z" 28 + android:strokeWidth="1" 29 + android:strokeColor="#00000000" /> 30 + </vector>
+170
mobile/composeApp/src/androidMain/res/drawable/ic_launcher_background.xml
··· 1 + <?xml version="1.0" encoding="utf-8"?> 2 + <vector xmlns:android="http://schemas.android.com/apk/res/android" 3 + android:width="108dp" 4 + android:height="108dp" 5 + android:viewportWidth="108" 6 + android:viewportHeight="108"> 7 + <path 8 + android:fillColor="#3DDC84" 9 + android:pathData="M0,0h108v108h-108z" /> 10 + <path 11 + android:fillColor="#00000000" 12 + android:pathData="M9,0L9,108" 13 + android:strokeWidth="0.8" 14 + android:strokeColor="#33FFFFFF" /> 15 + <path 16 + android:fillColor="#00000000" 17 + android:pathData="M19,0L19,108" 18 + android:strokeWidth="0.8" 19 + android:strokeColor="#33FFFFFF" /> 20 + <path 21 + android:fillColor="#00000000" 22 + android:pathData="M29,0L29,108" 23 + android:strokeWidth="0.8" 24 + android:strokeColor="#33FFFFFF" /> 25 + <path 26 + android:fillColor="#00000000" 27 + android:pathData="M39,0L39,108" 28 + android:strokeWidth="0.8" 29 + android:strokeColor="#33FFFFFF" /> 30 + <path 31 + android:fillColor="#00000000" 32 + android:pathData="M49,0L49,108" 33 + android:strokeWidth="0.8" 34 + android:strokeColor="#33FFFFFF" /> 35 + <path 36 + android:fillColor="#00000000" 37 + android:pathData="M59,0L59,108" 38 + android:strokeWidth="0.8" 39 + android:strokeColor="#33FFFFFF" /> 40 + <path 41 + android:fillColor="#00000000" 42 + android:pathData="M69,0L69,108" 43 + android:strokeWidth="0.8" 44 + android:strokeColor="#33FFFFFF" /> 45 + <path 46 + android:fillColor="#00000000" 47 + android:pathData="M79,0L79,108" 48 + android:strokeWidth="0.8" 49 + android:strokeColor="#33FFFFFF" /> 50 + <path 51 + android:fillColor="#00000000" 52 + android:pathData="M89,0L89,108" 53 + android:strokeWidth="0.8" 54 + android:strokeColor="#33FFFFFF" /> 55 + <path 56 + android:fillColor="#00000000" 57 + android:pathData="M99,0L99,108" 58 + android:strokeWidth="0.8" 59 + android:strokeColor="#33FFFFFF" /> 60 + <path 61 + android:fillColor="#00000000" 62 + android:pathData="M0,9L108,9" 63 + android:strokeWidth="0.8" 64 + android:strokeColor="#33FFFFFF" /> 65 + <path 66 + android:fillColor="#00000000" 67 + android:pathData="M0,19L108,19" 68 + android:strokeWidth="0.8" 69 + android:strokeColor="#33FFFFFF" /> 70 + <path 71 + android:fillColor="#00000000" 72 + android:pathData="M0,29L108,29" 73 + android:strokeWidth="0.8" 74 + android:strokeColor="#33FFFFFF" /> 75 + <path 76 + android:fillColor="#00000000" 77 + android:pathData="M0,39L108,39" 78 + android:strokeWidth="0.8" 79 + android:strokeColor="#33FFFFFF" /> 80 + <path 81 + android:fillColor="#00000000" 82 + android:pathData="M0,49L108,49" 83 + android:strokeWidth="0.8" 84 + android:strokeColor="#33FFFFFF" /> 85 + <path 86 + android:fillColor="#00000000" 87 + android:pathData="M0,59L108,59" 88 + android:strokeWidth="0.8" 89 + android:strokeColor="#33FFFFFF" /> 90 + <path 91 + android:fillColor="#00000000" 92 + android:pathData="M0,69L108,69" 93 + android:strokeWidth="0.8" 94 + android:strokeColor="#33FFFFFF" /> 95 + <path 96 + android:fillColor="#00000000" 97 + android:pathData="M0,79L108,79" 98 + android:strokeWidth="0.8" 99 + android:strokeColor="#33FFFFFF" /> 100 + <path 101 + android:fillColor="#00000000" 102 + android:pathData="M0,89L108,89" 103 + android:strokeWidth="0.8" 104 + android:strokeColor="#33FFFFFF" /> 105 + <path 106 + android:fillColor="#00000000" 107 + android:pathData="M0,99L108,99" 108 + android:strokeWidth="0.8" 109 + android:strokeColor="#33FFFFFF" /> 110 + <path 111 + android:fillColor="#00000000" 112 + android:pathData="M19,29L89,29" 113 + android:strokeWidth="0.8" 114 + android:strokeColor="#33FFFFFF" /> 115 + <path 116 + android:fillColor="#00000000" 117 + android:pathData="M19,39L89,39" 118 + android:strokeWidth="0.8" 119 + android:strokeColor="#33FFFFFF" /> 120 + <path 121 + android:fillColor="#00000000" 122 + android:pathData="M19,49L89,49" 123 + android:strokeWidth="0.8" 124 + android:strokeColor="#33FFFFFF" /> 125 + <path 126 + android:fillColor="#00000000" 127 + android:pathData="M19,59L89,59" 128 + android:strokeWidth="0.8" 129 + android:strokeColor="#33FFFFFF" /> 130 + <path 131 + android:fillColor="#00000000" 132 + android:pathData="M19,69L89,69" 133 + android:strokeWidth="0.8" 134 + android:strokeColor="#33FFFFFF" /> 135 + <path 136 + android:fillColor="#00000000" 137 + android:pathData="M19,79L89,79" 138 + android:strokeWidth="0.8" 139 + android:strokeColor="#33FFFFFF" /> 140 + <path 141 + android:fillColor="#00000000" 142 + android:pathData="M29,19L29,89" 143 + android:strokeWidth="0.8" 144 + android:strokeColor="#33FFFFFF" /> 145 + <path 146 + android:fillColor="#00000000" 147 + android:pathData="M39,19L39,89" 148 + android:strokeWidth="0.8" 149 + android:strokeColor="#33FFFFFF" /> 150 + <path 151 + android:fillColor="#00000000" 152 + android:pathData="M49,19L49,89" 153 + android:strokeWidth="0.8" 154 + android:strokeColor="#33FFFFFF" /> 155 + <path 156 + android:fillColor="#00000000" 157 + android:pathData="M59,19L59,89" 158 + android:strokeWidth="0.8" 159 + android:strokeColor="#33FFFFFF" /> 160 + <path 161 + android:fillColor="#00000000" 162 + android:pathData="M69,19L69,89" 163 + android:strokeWidth="0.8" 164 + android:strokeColor="#33FFFFFF" /> 165 + <path 166 + android:fillColor="#00000000" 167 + android:pathData="M79,19L79,89" 168 + android:strokeWidth="0.8" 169 + android:strokeColor="#33FFFFFF" /> 170 + </vector>
+5
mobile/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher.xml
··· 1 + <?xml version="1.0" encoding="utf-8"?> 2 + <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> 3 + <background android:drawable="@drawable/ic_launcher_background" /> 4 + <foreground android:drawable="@drawable/ic_launcher_foreground" /> 5 + </adaptive-icon>
+5
mobile/composeApp/src/androidMain/res/mipmap-anydpi-v26/ic_launcher_round.xml
··· 1 + <?xml version="1.0" encoding="utf-8"?> 2 + <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> 3 + <background android:drawable="@drawable/ic_launcher_background" /> 4 + <foreground android:drawable="@drawable/ic_launcher_foreground" /> 5 + </adaptive-icon>
mobile/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher.png

This is a binary file and will not be displayed.

mobile/composeApp/src/androidMain/res/mipmap-hdpi/ic_launcher_round.png

This is a binary file and will not be displayed.

mobile/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher.png

This is a binary file and will not be displayed.

mobile/composeApp/src/androidMain/res/mipmap-mdpi/ic_launcher_round.png

This is a binary file and will not be displayed.

mobile/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher.png

This is a binary file and will not be displayed.

mobile/composeApp/src/androidMain/res/mipmap-xhdpi/ic_launcher_round.png

This is a binary file and will not be displayed.

mobile/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher.png

This is a binary file and will not be displayed.

mobile/composeApp/src/androidMain/res/mipmap-xxhdpi/ic_launcher_round.png

This is a binary file and will not be displayed.

mobile/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher.png

This is a binary file and will not be displayed.

mobile/composeApp/src/androidMain/res/mipmap-xxxhdpi/ic_launcher_round.png

This is a binary file and will not be displayed.

+3
mobile/composeApp/src/androidMain/res/values/strings.xml
··· 1 + <resources> 2 + <string name="app_name">myrus-mobile</string> 3 + </resources>
+36
mobile/composeApp/src/commonMain/composeResources/drawable/compose-multiplatform.xml
··· 1 + <vector xmlns:android="http://schemas.android.com/apk/res/android" 2 + android:width="600dp" 3 + android:height="600dp" 4 + android:viewportWidth="600" 5 + android:viewportHeight="600"> 6 + <path 7 + android:pathData="M301.21,418.53C300.97,418.54 300.73,418.56 300.49,418.56C297.09,418.59 293.74,417.72 290.79,416.05L222.6,377.54C220.63,376.43 219,374.82 217.85,372.88C216.7,370.94 216.09,368.73 216.07,366.47L216.07,288.16C216.06,287.32 216.09,286.49 216.17,285.67C216.38,283.54 216.91,281.5 217.71,279.6L199.29,268.27L177.74,256.19C175.72,260.43 174.73,265.23 174.78,270.22L174.79,387.05C174.85,393.89 178.57,400.2 184.53,403.56L286.26,461.02C290.67,463.51 295.66,464.8 300.73,464.76C300.91,464.76 301.09,464.74 301.27,464.74C301.24,449.84 301.22,439.23 301.22,439.23L301.21,418.53Z" 8 + android:fillColor="#041619" 9 + android:fillType="nonZero"/> 10 + <path 11 + android:pathData="M409.45,242.91L312.64,188.23C303.64,183.15 292.58,183.26 283.68,188.51L187.92,245C183.31,247.73 179.93,251.62 177.75,256.17L177.74,256.19L199.29,268.27L217.71,279.6C217.83,279.32 217.92,279.02 218.05,278.74C218.24,278.36 218.43,277.98 218.64,277.62C219.06,276.88 219.52,276.18 220.04,275.51C221.37,273.8 223.01,272.35 224.87,271.25L289.06,233.39C290.42,232.59 291.87,231.96 293.39,231.51C295.53,230.87 297.77,230.6 300,230.72C302.98,230.88 305.88,231.73 308.47,233.2L373.37,269.85C375.54,271.08 377.49,272.68 379.13,274.57C379.68,275.19 380.18,275.85 380.65,276.53C380.86,276.84 381.05,277.15 381.24,277.47L397.79,266.39L420.34,252.93L420.31,252.88C417.55,248.8 413.77,245.35 409.45,242.91Z" 12 + android:fillColor="#37BF6E" 13 + android:fillType="nonZero"/> 14 + <path 15 + android:pathData="M381.24,277.47C381.51,277.92 381.77,278.38 382.01,278.84C382.21,279.24 382.39,279.65 382.57,280.06C382.91,280.88 383.19,281.73 383.41,282.59C383.74,283.88 383.92,285.21 383.93,286.57L383.93,361.1C383.96,363.95 383.35,366.77 382.16,369.36C381.93,369.86 381.69,370.35 381.42,370.83C379.75,373.79 377.32,376.27 374.39,378L310.2,415.87C307.47,417.48 304.38,418.39 301.21,418.53L301.22,439.23C301.22,439.23 301.24,449.84 301.27,464.74C306.1,464.61 310.91,463.3 315.21,460.75L410.98,404.25C419.88,399 425.31,389.37 425.22,379.03L425.22,267.85C425.17,262.48 423.34,257.34 420.34,252.93L397.79,266.39L381.24,277.47Z" 16 + android:fillColor="#3870B2" 17 + android:fillType="nonZero"/> 18 + <path 19 + android:pathData="M177.75,256.17C179.93,251.62 183.31,247.73 187.92,245L283.68,188.51C292.58,183.26 303.64,183.15 312.64,188.23L409.45,242.91C413.77,245.35 417.55,248.8 420.31,252.88L420.34,252.93L498.59,206.19C494.03,199.46 487.79,193.78 480.67,189.75L320.86,99.49C306.01,91.1 287.75,91.27 273.07,99.95L114.99,193.2C107.39,197.69 101.81,204.11 98.21,211.63L177.74,256.19L177.75,256.17ZM301.27,464.74C301.09,464.74 300.91,464.76 300.73,464.76C295.66,464.8 290.67,463.51 286.26,461.02L184.53,403.56C178.57,400.2 174.85,393.89 174.79,387.05L174.78,270.22C174.73,265.23 175.72,260.43 177.74,256.19L98.21,211.63C94.86,218.63 93.23,226.58 93.31,234.82L93.31,427.67C93.42,438.97 99.54,449.37 109.4,454.92L277.31,549.77C284.6,553.88 292.84,556.01 301.2,555.94L301.2,555.8C301.39,543.78 301.33,495.26 301.27,464.74Z" 20 + android:strokeWidth="10" 21 + android:fillColor="#00000000" 22 + android:strokeColor="#083042" 23 + android:fillType="nonZero"/> 24 + <path 25 + android:pathData="M498.59,206.19L420.34,252.93C423.34,257.34 425.17,262.48 425.22,267.85L425.22,379.03C425.31,389.37 419.88,399 410.98,404.25L315.21,460.75C310.91,463.3 306.1,464.61 301.27,464.74C301.33,495.26 301.39,543.78 301.2,555.8L301.2,555.94C309.48,555.87 317.74,553.68 325.11,549.32L483.18,456.06C497.87,447.39 506.85,431.49 506.69,414.43L506.69,230.91C506.6,222.02 503.57,213.5 498.59,206.19Z" 26 + android:strokeWidth="10" 27 + android:fillColor="#00000000" 28 + android:strokeColor="#083042" 29 + android:fillType="nonZero"/> 30 + <path 31 + android:pathData="M301.2,555.94C292.84,556.01 284.6,553.88 277.31,549.76L109.4,454.92C99.54,449.37 93.42,438.97 93.31,427.67L93.31,234.82C93.23,226.58 94.86,218.63 98.21,211.63C101.81,204.11 107.39,197.69 114.99,193.2L273.07,99.95C287.75,91.27 306.01,91.1 320.86,99.49L480.67,189.75C487.79,193.78 494.03,199.46 498.59,206.19C503.57,213.5 506.6,222.02 506.69,230.91L506.69,414.43C506.85,431.49 497.87,447.39 483.18,456.06L325.11,549.32C317.74,553.68 309.48,555.87 301.2,555.94Z" 32 + android:strokeWidth="10" 33 + android:fillColor="#00000000" 34 + android:strokeColor="#083042" 35 + android:fillType="nonZero"/> 36 + </vector>
+150
mobile/composeApp/src/commonMain/kotlin/com/paytondeveloper/myrus_mobile/App.kt
··· 1 + package com.paytondeveloper.myrus_mobile 2 + 3 + import androidx.compose.animation.AnimatedVisibility 4 + import androidx.compose.foundation.Image 5 + import androidx.compose.foundation.layout.Box 6 + import androidx.compose.foundation.layout.Column 7 + import androidx.compose.foundation.layout.fillMaxSize 8 + import androidx.compose.foundation.layout.fillMaxWidth 9 + import androidx.compose.foundation.layout.offset 10 + import androidx.compose.material.Button 11 + import androidx.compose.material.MaterialTheme 12 + import androidx.compose.material.Text 13 + import androidx.compose.runtime.* 14 + import androidx.compose.ui.Alignment 15 + import androidx.compose.ui.Modifier 16 + import androidx.compose.ui.draw.drawWithCache 17 + import androidx.compose.ui.geometry.Offset 18 + import androidx.compose.ui.graphics.Color 19 + import androidx.compose.ui.graphics.RectangleShape 20 + import androidx.compose.ui.layout.onSizeChanged 21 + import androidx.compose.ui.platform.LocalDensity 22 + import androidx.compose.ui.platform.LocalViewConfiguration 23 + import androidx.compose.ui.unit.dp 24 + import androidx.graphics.shapes.RoundedPolygon 25 + import com.kashif.cameraK.builder.CameraControllerBuilder 26 + import com.kashif.cameraK.controller.CameraController 27 + import com.kashif.cameraK.enums.CameraLens 28 + import com.kashif.cameraK.enums.Directory 29 + import com.kashif.cameraK.enums.ImageFormat 30 + import com.kashif.cameraK.permissions.providePermissions 31 + import com.kashif.cameraK.result.ImageCaptureResult 32 + import com.kashif.cameraK.ui.CameraPreview 33 + import io.ktor.util.Identity.encode 34 + import kotlinx.coroutines.delay 35 + import org.jetbrains.compose.resources.painterResource 36 + import org.jetbrains.compose.ui.tooling.preview.Preview 37 + 38 + import myrus_mobile.composeapp.generated.resources.Res 39 + import myrus_mobile.composeapp.generated.resources.compose_multiplatform 40 + 41 + expect fun analyzeImage(img: ByteArray, callback: (Rect, Size) -> Unit) 42 + 43 + data class Size(val width: Float, val height: Float) 44 + data class Rect(val top: Float, val left: Float, val bottom: Float, val right: Float) 45 + data class FaceData(val boundingBox: Rect) 46 + 47 + 48 + expect fun CameraController.getResolution(): Size? 49 + 50 + @Composable 51 + @Preview 52 + fun App() { 53 + MaterialTheme { 54 + val permissions = providePermissions() 55 + val camPermission = remember { mutableStateOf(permissions.hasCameraPermission()) } 56 + if (!camPermission.value) { 57 + permissions.RequestCameraPermission( { 58 + camPermission.value = true 59 + }, onDenied = { 60 + camPermission.value = false 61 + }) 62 + } 63 + 64 + 65 + 66 + if (camPermission.value) { 67 + var camController by remember { mutableStateOf<CameraController?>(null) } 68 + var camSize by remember { mutableStateOf<Size?>(null) } 69 + var currentThingy by remember { mutableStateOf<Rect?>(Rect(0f,0f,0f,0f)) } 70 + LaunchedEffect(Unit) { 71 + //not proud of this. 72 + suspend fun runloop() { 73 + 74 + val res = camController?.takePicture() 75 + res?.let { 76 + when (it) { 77 + is ImageCaptureResult.Error -> { 78 + println("error taking pic. skipping frame: ${it.exception}") 79 + } 80 + is ImageCaptureResult.Success -> { 81 + analyzeImage(it.byteArray, { it, size -> 82 + // println("offset: ${it.top} ${it.left}") 83 + val factorY = it.top.toFloat() / size.height.toFloat() 84 + val factorX = it.left.toFloat() / size.width.toFloat() 85 + 86 + val newY = factorY * camSize!!.height.toFloat() 87 + val newX = factorX * camSize!!.width.toFloat() 88 + 89 + currentThingy = it.copy(top = newY, left = newX) 90 + }) 91 + } 92 + } 93 + } 94 + delay(1000) 95 + runloop() 96 + } 97 + runloop() 98 + } 99 + Box(modifier = Modifier/*.drawWithCache { 100 + if (currentThingy != null) { 101 + val roundedPolygon = RoundedPolygon( 102 + numVertices = 6, 103 + radius = (currentThingy!!.right - currentThingy!!.left).toFloat(), 104 + centerX = currentThingy!!.left.toFloat(), 105 + centerY = currentThingy!!.top.toFloat() 106 + ) 107 + val roundedPolygonPath = roundedPolygon 108 + onDrawBehind { 109 + // drawPath(roundedPolygonPath, color = Color.Blue) 110 + drawRect( 111 + color = Color.Red, 112 + topLeft = Offset(currentThingy!!.left.toFloat(), currentThingy!!.top.toFloat()), 113 + size = androidx.compose.ui.geometry.Size(width = (currentThingy!!.right - currentThingy!!.left).toFloat(), height = (currentThingy!!.bottom - currentThingy!!.top).toFloat()) 114 + ) 115 + } 116 + 117 + } else { 118 + onDrawBehind { } 119 + } 120 + }*/) { 121 + val topPx = with(LocalDensity.current) { 122 + currentThingy!!.top.toDp() 123 + } 124 + val leftPx = with(LocalDensity.current) { 125 + currentThingy!!.left.toDp() 126 + } 127 + println("offset (dp) ${topPx} ${leftPx}") 128 + 129 + CameraPreview(modifier = Modifier.fillMaxSize().onSizeChanged { 130 + camSize = Size( 131 + width = it.width.toFloat(), 132 + height = it.height.toFloat() 133 + ) 134 + println("camsize: ${camSize?.width}x${camSize?.height}") 135 + }, { 136 + setCameraLens(CameraLens.FRONT) 137 + setImageFormat(ImageFormat.PNG) 138 + setDirectory(Directory.PICTURES) 139 + 140 + 141 + }, onCameraControllerReady = { 142 + camController = it 143 + }) 144 + Text("Face", modifier = Modifier.offset(x = leftPx, y = topPx)) 145 + } 146 + } else { 147 + Text("no permissions!! can't do anything :(") 148 + } 149 + } 150 + }
+9
mobile/composeApp/src/commonMain/kotlin/com/paytondeveloper/myrus_mobile/Greeting.kt
··· 1 + package com.paytondeveloper.myrus_mobile 2 + 3 + class Greeting { 4 + private val platform = getPlatform() 5 + 6 + fun greet(): String { 7 + return "Hello, ${platform.name}!" 8 + } 9 + }
+7
mobile/composeApp/src/commonMain/kotlin/com/paytondeveloper/myrus_mobile/Platform.kt
··· 1 + package com.paytondeveloper.myrus_mobile 2 + 3 + interface Platform { 4 + val name: String 5 + } 6 + 7 + expect fun getPlatform(): Platform
+8
mobile/composeApp/src/iosMain/kotlin/com/paytondeveloper/myrus_mobile/MLFace.ios.kt
··· 1 + package com.paytondeveloper.myrus_mobile 2 + 3 + import com.kashif.cameraK.builder.CameraControllerBuilder 4 + import com.kashif.cameraK.controller.CameraController 5 + 6 + actual fun analyzeImage(img: ByteArray, callback:(Rect, Size) -> Unit) {} 7 + 8 + actual fun CameraController.getResolution(): Size? {return null}
+5
mobile/composeApp/src/iosMain/kotlin/com/paytondeveloper/myrus_mobile/MainViewController.kt
··· 1 + package com.paytondeveloper.myrus_mobile 2 + 3 + import androidx.compose.ui.window.ComposeUIViewController 4 + 5 + fun MainViewController() = ComposeUIViewController { App() }
+9
mobile/composeApp/src/iosMain/kotlin/com/paytondeveloper/myrus_mobile/Platform.ios.kt
··· 1 + package com.paytondeveloper.myrus_mobile 2 + 3 + import platform.UIKit.UIDevice 4 + 5 + class IOSPlatform: Platform { 6 + override val name: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion 7 + } 8 + 9 + actual fun getPlatform(): Platform = IOSPlatform()
+10
mobile/gradle.properties
··· 1 + #Kotlin 2 + kotlin.code.style=official 3 + kotlin.daemon.jvmargs=-Xmx2048M 4 + 5 + #Gradle 6 + org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 7 + 8 + #Android 9 + android.nonTransitiveRClass=true 10 + android.useAndroidX=true
+43
mobile/gradle/libs.versions.toml
··· 1 + [versions] 2 + agp = "8.5.2" 3 + android-compileSdk = "34" 4 + android-minSdk = "24" 5 + android-targetSdk = "34" 6 + androidx-activityCompose = "1.9.3" 7 + androidx-appcompat = "1.7.0" 8 + androidx-constraintlayout = "2.2.0" 9 + androidx-core-ktx = "1.15.0" 10 + androidx-espresso-core = "3.6.1" 11 + androidx-lifecycle = "2.8.4" 12 + androidx-material = "1.12.0" 13 + androidx-test-junit = "1.2.1" 14 + camerak = "0.0.10" 15 + compose-multiplatform = "1.7.0" 16 + faceDetection = "16.1.7" 17 + graphicsShapes = "1.0.1" 18 + junit = "4.13.2" 19 + kotlin = "2.1.0" 20 + 21 + [libraries] 22 + androidx-graphics-shapes = { module = "androidx.graphics:graphics-shapes", version.ref = "graphicsShapes" } 23 + camerak = { module = "io.github.kashif-mehmood-km:camerak", version.ref = "camerak" } 24 + face-detection = { module = "com.google.mlkit:face-detection", version.ref = "faceDetection" } 25 + kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } 26 + kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" } 27 + junit = { group = "junit", name = "junit", version.ref = "junit" } 28 + androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "androidx-core-ktx" } 29 + androidx-test-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx-test-junit" } 30 + androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "androidx-espresso-core" } 31 + androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "androidx-appcompat" } 32 + androidx-material = { group = "com.google.android.material", name = "material", version.ref = "androidx-material" } 33 + androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "androidx-constraintlayout" } 34 + androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activityCompose" } 35 + androidx-lifecycle-viewmodel = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-viewmodel", version.ref = "androidx-lifecycle" } 36 + androidx-lifecycle-runtime-compose = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "androidx-lifecycle" } 37 + 38 + [plugins] 39 + androidApplication = { id = "com.android.application", version.ref = "agp" } 40 + androidLibrary = { id = "com.android.library", version.ref = "agp" } 41 + composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "compose-multiplatform" } 42 + composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } 43 + kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
mobile/gradle/wrapper/gradle-wrapper.jar

This is a binary file and will not be displayed.

+7
mobile/gradle/wrapper/gradle-wrapper.properties
··· 1 + distributionBase=GRADLE_USER_HOME 2 + distributionPath=wrapper/dists 3 + distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip 4 + networkTimeout=10000 5 + validateDistributionUrl=true 6 + zipStoreBase=GRADLE_USER_HOME 7 + zipStorePath=wrapper/dists
+252
mobile/gradlew
··· 1 + #!/bin/sh 2 + 3 + # 4 + # Copyright © 2015-2021 the original authors. 5 + # 6 + # Licensed under the Apache License, Version 2.0 (the "License"); 7 + # you may not use this file except in compliance with the License. 8 + # You may obtain a copy of the License at 9 + # 10 + # https://www.apache.org/licenses/LICENSE-2.0 11 + # 12 + # Unless required by applicable law or agreed to in writing, software 13 + # distributed under the License is distributed on an "AS IS" BASIS, 14 + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 + # See the License for the specific language governing permissions and 16 + # limitations under the License. 17 + # 18 + # SPDX-License-Identifier: Apache-2.0 19 + # 20 + 21 + ############################################################################## 22 + # 23 + # Gradle start up script for POSIX generated by Gradle. 24 + # 25 + # Important for running: 26 + # 27 + # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 28 + # noncompliant, but you have some other compliant shell such as ksh or 29 + # bash, then to run this script, type that shell name before the whole 30 + # command line, like: 31 + # 32 + # ksh Gradle 33 + # 34 + # Busybox and similar reduced shells will NOT work, because this script 35 + # requires all of these POSIX shell features: 36 + # * functions; 37 + # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 38 + # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 39 + # * compound commands having a testable exit status, especially «case»; 40 + # * various built-in commands including «command», «set», and «ulimit». 41 + # 42 + # Important for patching: 43 + # 44 + # (2) This script targets any POSIX shell, so it avoids extensions provided 45 + # by Bash, Ksh, etc; in particular arrays are avoided. 46 + # 47 + # The "traditional" practice of packing multiple parameters into a 48 + # space-separated string is a well documented source of bugs and security 49 + # problems, so this is (mostly) avoided, by progressively accumulating 50 + # options in "$@", and eventually passing that to Java. 51 + # 52 + # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 53 + # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 54 + # see the in-line comments for details. 55 + # 56 + # There are tweaks for specific operating systems such as AIX, CygWin, 57 + # Darwin, MinGW, and NonStop. 58 + # 59 + # (3) This script is generated from the Groovy template 60 + # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 61 + # within the Gradle project. 62 + # 63 + # You can find Gradle at https://github.com/gradle/gradle/. 64 + # 65 + ############################################################################## 66 + 67 + # Attempt to set APP_HOME 68 + 69 + # Resolve links: $0 may be a link 70 + app_path=$0 71 + 72 + # Need this for daisy-chained symlinks. 73 + while 74 + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 75 + [ -h "$app_path" ] 76 + do 77 + ls=$( ls -ld "$app_path" ) 78 + link=${ls#*' -> '} 79 + case $link in #( 80 + /*) app_path=$link ;; #( 81 + *) app_path=$APP_HOME$link ;; 82 + esac 83 + done 84 + 85 + # This is normally unused 86 + # shellcheck disable=SC2034 87 + APP_BASE_NAME=${0##*/} 88 + # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) 89 + APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s 90 + ' "$PWD" ) || exit 91 + 92 + # Use the maximum available, or set MAX_FD != -1 to use that value. 93 + MAX_FD=maximum 94 + 95 + warn () { 96 + echo "$*" 97 + } >&2 98 + 99 + die () { 100 + echo 101 + echo "$*" 102 + echo 103 + exit 1 104 + } >&2 105 + 106 + # OS specific support (must be 'true' or 'false'). 107 + cygwin=false 108 + msys=false 109 + darwin=false 110 + nonstop=false 111 + case "$( uname )" in #( 112 + CYGWIN* ) cygwin=true ;; #( 113 + Darwin* ) darwin=true ;; #( 114 + MSYS* | MINGW* ) msys=true ;; #( 115 + NONSTOP* ) nonstop=true ;; 116 + esac 117 + 118 + CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 119 + 120 + 121 + # Determine the Java command to use to start the JVM. 122 + if [ -n "$JAVA_HOME" ] ; then 123 + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 124 + # IBM's JDK on AIX uses strange locations for the executables 125 + JAVACMD=$JAVA_HOME/jre/sh/java 126 + else 127 + JAVACMD=$JAVA_HOME/bin/java 128 + fi 129 + if [ ! -x "$JAVACMD" ] ; then 130 + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 131 + 132 + Please set the JAVA_HOME variable in your environment to match the 133 + location of your Java installation." 134 + fi 135 + else 136 + JAVACMD=java 137 + if ! command -v java >/dev/null 2>&1 138 + then 139 + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 140 + 141 + Please set the JAVA_HOME variable in your environment to match the 142 + location of your Java installation." 143 + fi 144 + fi 145 + 146 + # Increase the maximum file descriptors if we can. 147 + if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 148 + case $MAX_FD in #( 149 + max*) 150 + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 151 + # shellcheck disable=SC2039,SC3045 152 + MAX_FD=$( ulimit -H -n ) || 153 + warn "Could not query maximum file descriptor limit" 154 + esac 155 + case $MAX_FD in #( 156 + '' | soft) :;; #( 157 + *) 158 + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 159 + # shellcheck disable=SC2039,SC3045 160 + ulimit -n "$MAX_FD" || 161 + warn "Could not set maximum file descriptor limit to $MAX_FD" 162 + esac 163 + fi 164 + 165 + # Collect all arguments for the java command, stacking in reverse order: 166 + # * args from the command line 167 + # * the main class name 168 + # * -classpath 169 + # * -D...appname settings 170 + # * --module-path (only if needed) 171 + # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 172 + 173 + # For Cygwin or MSYS, switch paths to Windows format before running java 174 + if "$cygwin" || "$msys" ; then 175 + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 176 + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 177 + 178 + JAVACMD=$( cygpath --unix "$JAVACMD" ) 179 + 180 + # Now convert the arguments - kludge to limit ourselves to /bin/sh 181 + for arg do 182 + if 183 + case $arg in #( 184 + -*) false ;; # don't mess with options #( 185 + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 186 + [ -e "$t" ] ;; #( 187 + *) false ;; 188 + esac 189 + then 190 + arg=$( cygpath --path --ignore --mixed "$arg" ) 191 + fi 192 + # Roll the args list around exactly as many times as the number of 193 + # args, so each arg winds up back in the position where it started, but 194 + # possibly modified. 195 + # 196 + # NB: a `for` loop captures its iteration list before it begins, so 197 + # changing the positional parameters here affects neither the number of 198 + # iterations, nor the values presented in `arg`. 199 + shift # remove old arg 200 + set -- "$@" "$arg" # push replacement arg 201 + done 202 + fi 203 + 204 + 205 + # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 206 + DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 207 + 208 + # Collect all arguments for the java command: 209 + # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, 210 + # and any embedded shellness will be escaped. 211 + # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be 212 + # treated as '${Hostname}' itself on the command line. 213 + 214 + set -- \ 215 + "-Dorg.gradle.appname=$APP_BASE_NAME" \ 216 + -classpath "$CLASSPATH" \ 217 + org.gradle.wrapper.GradleWrapperMain \ 218 + "$@" 219 + 220 + # Stop when "xargs" is not available. 221 + if ! command -v xargs >/dev/null 2>&1 222 + then 223 + die "xargs is not available" 224 + fi 225 + 226 + # Use "xargs" to parse quoted args. 227 + # 228 + # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 229 + # 230 + # In Bash we could simply go: 231 + # 232 + # readarray ARGS < <( xargs -n1 <<<"$var" ) && 233 + # set -- "${ARGS[@]}" "$@" 234 + # 235 + # but POSIX shell has neither arrays nor command substitution, so instead we 236 + # post-process each arg (as a line of input to sed) to backslash-escape any 237 + # character that might be a shell metacharacter, then use eval to reverse 238 + # that process (while maintaining the separation between arguments), and wrap 239 + # the whole thing up as a single "set" statement. 240 + # 241 + # This will of course break if any of these variables contains a newline or 242 + # an unmatched quote. 243 + # 244 + 245 + eval "set -- $( 246 + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 247 + xargs -n1 | 248 + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 249 + tr '\n' ' ' 250 + )" '"$@"' 251 + 252 + exec "$JAVACMD" "$@"
+94
mobile/gradlew.bat
··· 1 + @rem 2 + @rem Copyright 2015 the original author or authors. 3 + @rem 4 + @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 + @rem you may not use this file except in compliance with the License. 6 + @rem You may obtain a copy of the License at 7 + @rem 8 + @rem https://www.apache.org/licenses/LICENSE-2.0 9 + @rem 10 + @rem Unless required by applicable law or agreed to in writing, software 11 + @rem distributed under the License is distributed on an "AS IS" BASIS, 12 + @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 + @rem See the License for the specific language governing permissions and 14 + @rem limitations under the License. 15 + @rem 16 + @rem SPDX-License-Identifier: Apache-2.0 17 + @rem 18 + 19 + @if "%DEBUG%"=="" @echo off 20 + @rem ########################################################################## 21 + @rem 22 + @rem Gradle startup script for Windows 23 + @rem 24 + @rem ########################################################################## 25 + 26 + @rem Set local scope for the variables with windows NT shell 27 + if "%OS%"=="Windows_NT" setlocal 28 + 29 + set DIRNAME=%~dp0 30 + if "%DIRNAME%"=="" set DIRNAME=. 31 + @rem This is normally unused 32 + set APP_BASE_NAME=%~n0 33 + set APP_HOME=%DIRNAME% 34 + 35 + @rem Resolve any "." and ".." in APP_HOME to make it shorter. 36 + for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 37 + 38 + @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 39 + set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 40 + 41 + @rem Find java.exe 42 + if defined JAVA_HOME goto findJavaFromJavaHome 43 + 44 + set JAVA_EXE=java.exe 45 + %JAVA_EXE% -version >NUL 2>&1 46 + if %ERRORLEVEL% equ 0 goto execute 47 + 48 + echo. 1>&2 49 + echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 50 + echo. 1>&2 51 + echo Please set the JAVA_HOME variable in your environment to match the 1>&2 52 + echo location of your Java installation. 1>&2 53 + 54 + goto fail 55 + 56 + :findJavaFromJavaHome 57 + set JAVA_HOME=%JAVA_HOME:"=% 58 + set JAVA_EXE=%JAVA_HOME%/bin/java.exe 59 + 60 + if exist "%JAVA_EXE%" goto execute 61 + 62 + echo. 1>&2 63 + echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 64 + echo. 1>&2 65 + echo Please set the JAVA_HOME variable in your environment to match the 1>&2 66 + echo location of your Java installation. 1>&2 67 + 68 + goto fail 69 + 70 + :execute 71 + @rem Setup the command line 72 + 73 + set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 74 + 75 + 76 + @rem Execute Gradle 77 + "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 78 + 79 + :end 80 + @rem End local scope for the variables with windows NT shell 81 + if %ERRORLEVEL% equ 0 goto mainEnd 82 + 83 + :fail 84 + rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 85 + rem the _cmd.exe /c_ return code! 86 + set EXIT_CODE=%ERRORLEVEL% 87 + if %EXIT_CODE% equ 0 set EXIT_CODE=1 88 + if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 89 + exit /b %EXIT_CODE% 90 + 91 + :mainEnd 92 + if "%OS%"=="Windows_NT" endlocal 93 + 94 + :omega
+3
mobile/iosApp/Configuration/Config.xcconfig
··· 1 + TEAM_ID= 2 + BUNDLE_ID=com.paytondeveloper.myrus_mobile.myrus-mobile 3 + APP_NAME=myrus-mobile
+424
mobile/iosApp/iosApp.xcodeproj/project.pbxproj
··· 1 + // !$*UTF8*$! 2 + { 3 + archiveVersion = 1; 4 + classes = { 5 + }; 6 + objectVersion = 56; 7 + objects = { 8 + 9 + /* Begin PBXBuildFile section */ 10 + 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557BA273AAA24004C7B11 /* Assets.xcassets */; }; 11 + 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */; }; 12 + 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2152FB032600AC8F00CF470E /* iOSApp.swift */; }; 13 + 7555FF83242A565900829871 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7555FF82242A565900829871 /* ContentView.swift */; }; 14 + E9B512A52D862B0F00D52AB6 /* MLKitBarcodeScanning in Frameworks */ = {isa = PBXBuildFile; productRef = E9B512A42D862B0F00D52AB6 /* MLKitBarcodeScanning */; }; 15 + E9B512A72D862B0F00D52AB6 /* MLKitFaceDetection in Frameworks */ = {isa = PBXBuildFile; productRef = E9B512A62D862B0F00D52AB6 /* MLKitFaceDetection */; }; 16 + /* End PBXBuildFile section */ 17 + 18 + /* Begin PBXFileReference section */ 19 + 058557BA273AAA24004C7B11 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 20 + 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; }; 21 + 2152FB032600AC8F00CF470E /* iOSApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = iOSApp.swift; sourceTree = "<group>"; }; 22 + 7555FF7B242A565900829871 /* myrus-mobile.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "myrus-mobile.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 23 + 7555FF82242A565900829871 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; }; 24 + 7555FF8C242A565B00829871 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 25 + AB3632DC29227652001CCB65 /* Config.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = "<group>"; }; 26 + /* End PBXFileReference section */ 27 + 28 + /* Begin PBXFrameworksBuildPhase section */ 29 + B92378962B6B1156000C7307 /* Frameworks */ = { 30 + isa = PBXFrameworksBuildPhase; 31 + buildActionMask = 2147483647; 32 + files = ( 33 + E9B512A52D862B0F00D52AB6 /* MLKitBarcodeScanning in Frameworks */, 34 + E9B512A72D862B0F00D52AB6 /* MLKitFaceDetection in Frameworks */, 35 + ); 36 + runOnlyForDeploymentPostprocessing = 0; 37 + }; 38 + /* End PBXFrameworksBuildPhase section */ 39 + 40 + /* Begin PBXGroup section */ 41 + 058557D7273AAEEB004C7B11 /* Preview Content */ = { 42 + isa = PBXGroup; 43 + children = ( 44 + 058557D8273AAEEB004C7B11 /* Preview Assets.xcassets */, 45 + ); 46 + path = "Preview Content"; 47 + sourceTree = "<group>"; 48 + }; 49 + 42799AB246E5F90AF97AA0EF /* Frameworks */ = { 50 + isa = PBXGroup; 51 + children = ( 52 + ); 53 + name = Frameworks; 54 + sourceTree = "<group>"; 55 + }; 56 + 7555FF72242A565900829871 = { 57 + isa = PBXGroup; 58 + children = ( 59 + AB1DB47929225F7C00F7AF9C /* Configuration */, 60 + 7555FF7D242A565900829871 /* iosApp */, 61 + 7555FF7C242A565900829871 /* Products */, 62 + 42799AB246E5F90AF97AA0EF /* Frameworks */, 63 + ); 64 + sourceTree = "<group>"; 65 + }; 66 + 7555FF7C242A565900829871 /* Products */ = { 67 + isa = PBXGroup; 68 + children = ( 69 + 7555FF7B242A565900829871 /* myrus-mobile.app */, 70 + ); 71 + name = Products; 72 + sourceTree = "<group>"; 73 + }; 74 + 7555FF7D242A565900829871 /* iosApp */ = { 75 + isa = PBXGroup; 76 + children = ( 77 + 058557BA273AAA24004C7B11 /* Assets.xcassets */, 78 + 7555FF82242A565900829871 /* ContentView.swift */, 79 + 7555FF8C242A565B00829871 /* Info.plist */, 80 + 2152FB032600AC8F00CF470E /* iOSApp.swift */, 81 + 058557D7273AAEEB004C7B11 /* Preview Content */, 82 + ); 83 + path = iosApp; 84 + sourceTree = "<group>"; 85 + }; 86 + AB1DB47929225F7C00F7AF9C /* Configuration */ = { 87 + isa = PBXGroup; 88 + children = ( 89 + AB3632DC29227652001CCB65 /* Config.xcconfig */, 90 + ); 91 + path = Configuration; 92 + sourceTree = "<group>"; 93 + }; 94 + /* End PBXGroup section */ 95 + 96 + /* Begin PBXNativeTarget section */ 97 + 7555FF7A242A565900829871 /* iosApp */ = { 98 + isa = PBXNativeTarget; 99 + buildConfigurationList = 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */; 100 + buildPhases = ( 101 + F36B1CEB2AD83DDC00CB74D5 /* Compile Kotlin Framework */, 102 + 7555FF77242A565900829871 /* Sources */, 103 + B92378962B6B1156000C7307 /* Frameworks */, 104 + 7555FF79242A565900829871 /* Resources */, 105 + ); 106 + buildRules = ( 107 + ); 108 + dependencies = ( 109 + ); 110 + name = iosApp; 111 + packageProductDependencies = ( 112 + E9B512A42D862B0F00D52AB6 /* MLKitBarcodeScanning */, 113 + E9B512A62D862B0F00D52AB6 /* MLKitFaceDetection */, 114 + ); 115 + productName = iosApp; 116 + productReference = 7555FF7B242A565900829871 /* myrus-mobile.app */; 117 + productType = "com.apple.product-type.application"; 118 + }; 119 + /* End PBXNativeTarget section */ 120 + 121 + /* Begin PBXProject section */ 122 + 7555FF73242A565900829871 /* Project object */ = { 123 + isa = PBXProject; 124 + attributes = { 125 + BuildIndependentTargetsInParallel = YES; 126 + LastSwiftUpdateCheck = 1130; 127 + LastUpgradeCheck = 1540; 128 + ORGANIZATIONNAME = orgName; 129 + TargetAttributes = { 130 + 7555FF7A242A565900829871 = { 131 + CreatedOnToolsVersion = 11.3.1; 132 + }; 133 + }; 134 + }; 135 + buildConfigurationList = 7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */; 136 + compatibilityVersion = "Xcode 14.0"; 137 + developmentRegion = en; 138 + hasScannedForEncodings = 0; 139 + knownRegions = ( 140 + en, 141 + Base, 142 + ); 143 + mainGroup = 7555FF72242A565900829871; 144 + packageReferences = ( 145 + E9B512A32D862B0F00D52AB6 /* XCRemoteSwiftPackageReference "google-mlkit-swiftpm" */, 146 + ); 147 + productRefGroup = 7555FF7C242A565900829871 /* Products */; 148 + projectDirPath = ""; 149 + projectRoot = ""; 150 + targets = ( 151 + 7555FF7A242A565900829871 /* iosApp */, 152 + ); 153 + }; 154 + /* End PBXProject section */ 155 + 156 + /* Begin PBXResourcesBuildPhase section */ 157 + 7555FF79242A565900829871 /* Resources */ = { 158 + isa = PBXResourcesBuildPhase; 159 + buildActionMask = 2147483647; 160 + files = ( 161 + 058557D9273AAEEB004C7B11 /* Preview Assets.xcassets in Resources */, 162 + 058557BB273AAA24004C7B11 /* Assets.xcassets in Resources */, 163 + ); 164 + runOnlyForDeploymentPostprocessing = 0; 165 + }; 166 + /* End PBXResourcesBuildPhase section */ 167 + 168 + /* Begin PBXShellScriptBuildPhase section */ 169 + F36B1CEB2AD83DDC00CB74D5 /* Compile Kotlin Framework */ = { 170 + isa = PBXShellScriptBuildPhase; 171 + buildActionMask = 2147483647; 172 + files = ( 173 + ); 174 + inputFileListPaths = ( 175 + ); 176 + inputPaths = ( 177 + ); 178 + name = "Compile Kotlin Framework"; 179 + outputFileListPaths = ( 180 + ); 181 + outputPaths = ( 182 + ); 183 + runOnlyForDeploymentPostprocessing = 0; 184 + shellPath = /bin/sh; 185 + shellScript = "if [ \"YES\" = \"$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED\" ]; then\n echo \"Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment variable set to \\\"YES\\\"\"\n exit 0\nfi\ncd \"$SRCROOT/..\"\n./gradlew :composeApp:embedAndSignAppleFrameworkForXcode\n"; 186 + }; 187 + /* End PBXShellScriptBuildPhase section */ 188 + 189 + /* Begin PBXSourcesBuildPhase section */ 190 + 7555FF77242A565900829871 /* Sources */ = { 191 + isa = PBXSourcesBuildPhase; 192 + buildActionMask = 2147483647; 193 + files = ( 194 + 2152FB042600AC8F00CF470E /* iOSApp.swift in Sources */, 195 + 7555FF83242A565900829871 /* ContentView.swift in Sources */, 196 + ); 197 + runOnlyForDeploymentPostprocessing = 0; 198 + }; 199 + /* End PBXSourcesBuildPhase section */ 200 + 201 + /* Begin XCBuildConfiguration section */ 202 + 7555FFA3242A565B00829871 /* Debug */ = { 203 + isa = XCBuildConfiguration; 204 + baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */; 205 + buildSettings = { 206 + ALWAYS_SEARCH_USER_PATHS = NO; 207 + CLANG_ANALYZER_NONNULL = YES; 208 + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 209 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 210 + CLANG_CXX_LIBRARY = "libc++"; 211 + CLANG_ENABLE_MODULES = YES; 212 + CLANG_ENABLE_OBJC_ARC = YES; 213 + CLANG_ENABLE_OBJC_WEAK = YES; 214 + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 215 + CLANG_WARN_BOOL_CONVERSION = YES; 216 + CLANG_WARN_COMMA = YES; 217 + CLANG_WARN_CONSTANT_CONVERSION = YES; 218 + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 219 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 220 + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 221 + CLANG_WARN_EMPTY_BODY = YES; 222 + CLANG_WARN_ENUM_CONVERSION = YES; 223 + CLANG_WARN_INFINITE_RECURSION = YES; 224 + CLANG_WARN_INT_CONVERSION = YES; 225 + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 226 + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 227 + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 228 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 229 + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 230 + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 231 + CLANG_WARN_STRICT_PROTOTYPES = YES; 232 + CLANG_WARN_SUSPICIOUS_MOVE = YES; 233 + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 234 + CLANG_WARN_UNREACHABLE_CODE = YES; 235 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 236 + COPY_PHASE_STRIP = NO; 237 + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 238 + ENABLE_STRICT_OBJC_MSGSEND = YES; 239 + ENABLE_TESTABILITY = YES; 240 + ENABLE_USER_SCRIPT_SANDBOXING = NO; 241 + GCC_C_LANGUAGE_STANDARD = gnu11; 242 + GCC_DYNAMIC_NO_PIC = NO; 243 + GCC_NO_COMMON_BLOCKS = YES; 244 + GCC_OPTIMIZATION_LEVEL = 0; 245 + GCC_PREPROCESSOR_DEFINITIONS = ( 246 + "DEBUG=1", 247 + "$(inherited)", 248 + ); 249 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 250 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 251 + GCC_WARN_UNDECLARED_SELECTOR = YES; 252 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 253 + GCC_WARN_UNUSED_FUNCTION = YES; 254 + GCC_WARN_UNUSED_VARIABLE = YES; 255 + IPHONEOS_DEPLOYMENT_TARGET = 15.3; 256 + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 257 + MTL_FAST_MATH = YES; 258 + ONLY_ACTIVE_ARCH = YES; 259 + SDKROOT = iphoneos; 260 + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 261 + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 262 + }; 263 + name = Debug; 264 + }; 265 + 7555FFA4242A565B00829871 /* Release */ = { 266 + isa = XCBuildConfiguration; 267 + baseConfigurationReference = AB3632DC29227652001CCB65 /* Config.xcconfig */; 268 + buildSettings = { 269 + ALWAYS_SEARCH_USER_PATHS = NO; 270 + CLANG_ANALYZER_NONNULL = YES; 271 + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 272 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 273 + CLANG_CXX_LIBRARY = "libc++"; 274 + CLANG_ENABLE_MODULES = YES; 275 + CLANG_ENABLE_OBJC_ARC = YES; 276 + CLANG_ENABLE_OBJC_WEAK = YES; 277 + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 278 + CLANG_WARN_BOOL_CONVERSION = YES; 279 + CLANG_WARN_COMMA = YES; 280 + CLANG_WARN_CONSTANT_CONVERSION = YES; 281 + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 282 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 283 + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 284 + CLANG_WARN_EMPTY_BODY = YES; 285 + CLANG_WARN_ENUM_CONVERSION = YES; 286 + CLANG_WARN_INFINITE_RECURSION = YES; 287 + CLANG_WARN_INT_CONVERSION = YES; 288 + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 289 + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 290 + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 291 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 292 + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 293 + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 294 + CLANG_WARN_STRICT_PROTOTYPES = YES; 295 + CLANG_WARN_SUSPICIOUS_MOVE = YES; 296 + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 297 + CLANG_WARN_UNREACHABLE_CODE = YES; 298 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 299 + COPY_PHASE_STRIP = NO; 300 + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 301 + ENABLE_NS_ASSERTIONS = NO; 302 + ENABLE_STRICT_OBJC_MSGSEND = YES; 303 + ENABLE_USER_SCRIPT_SANDBOXING = NO; 304 + GCC_C_LANGUAGE_STANDARD = gnu11; 305 + GCC_NO_COMMON_BLOCKS = YES; 306 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 307 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 308 + GCC_WARN_UNDECLARED_SELECTOR = YES; 309 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 310 + GCC_WARN_UNUSED_FUNCTION = YES; 311 + GCC_WARN_UNUSED_VARIABLE = YES; 312 + IPHONEOS_DEPLOYMENT_TARGET = 15.3; 313 + MTL_ENABLE_DEBUG_INFO = NO; 314 + MTL_FAST_MATH = YES; 315 + SDKROOT = iphoneos; 316 + SWIFT_COMPILATION_MODE = wholemodule; 317 + SWIFT_OPTIMIZATION_LEVEL = "-O"; 318 + VALIDATE_PRODUCT = YES; 319 + }; 320 + name = Release; 321 + }; 322 + 7555FFA6242A565B00829871 /* Debug */ = { 323 + isa = XCBuildConfiguration; 324 + buildSettings = { 325 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 326 + CODE_SIGN_IDENTITY = "Apple Development"; 327 + CODE_SIGN_STYLE = Automatic; 328 + DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; 329 + DEVELOPMENT_TEAM = "${TEAM_ID}"; 330 + ENABLE_PREVIEWS = YES; 331 + FRAMEWORK_SEARCH_PATHS = ( 332 + "$(inherited)", 333 + "$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\n$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)", 334 + ); 335 + INFOPLIST_FILE = iosApp/Info.plist; 336 + IPHONEOS_DEPLOYMENT_TARGET = 15.3; 337 + LD_RUNPATH_SEARCH_PATHS = ( 338 + "$(inherited)", 339 + "@executable_path/Frameworks", 340 + ); 341 + PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}"; 342 + PRODUCT_NAME = "${APP_NAME}"; 343 + PROVISIONING_PROFILE_SPECIFIER = ""; 344 + SWIFT_VERSION = 5.0; 345 + TARGETED_DEVICE_FAMILY = "1,2"; 346 + }; 347 + name = Debug; 348 + }; 349 + 7555FFA7242A565B00829871 /* Release */ = { 350 + isa = XCBuildConfiguration; 351 + buildSettings = { 352 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 353 + CODE_SIGN_IDENTITY = "Apple Development"; 354 + CODE_SIGN_STYLE = Automatic; 355 + DEVELOPMENT_ASSET_PATHS = "\"iosApp/Preview Content\""; 356 + DEVELOPMENT_TEAM = "${TEAM_ID}"; 357 + ENABLE_PREVIEWS = YES; 358 + FRAMEWORK_SEARCH_PATHS = ( 359 + "$(inherited)", 360 + "$(SRCROOT)/../shared/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)\n$(SRCROOT)/../composeApp/build/xcode-frameworks/$(CONFIGURATION)/$(SDK_NAME)", 361 + ); 362 + INFOPLIST_FILE = iosApp/Info.plist; 363 + IPHONEOS_DEPLOYMENT_TARGET = 15.3; 364 + LD_RUNPATH_SEARCH_PATHS = ( 365 + "$(inherited)", 366 + "@executable_path/Frameworks", 367 + ); 368 + PRODUCT_BUNDLE_IDENTIFIER = "${BUNDLE_ID}${TEAM_ID}"; 369 + PRODUCT_NAME = "${APP_NAME}"; 370 + PROVISIONING_PROFILE_SPECIFIER = ""; 371 + SWIFT_VERSION = 5.0; 372 + TARGETED_DEVICE_FAMILY = "1,2"; 373 + }; 374 + name = Release; 375 + }; 376 + /* End XCBuildConfiguration section */ 377 + 378 + /* Begin XCConfigurationList section */ 379 + 7555FF76242A565900829871 /* Build configuration list for PBXProject "iosApp" */ = { 380 + isa = XCConfigurationList; 381 + buildConfigurations = ( 382 + 7555FFA3242A565B00829871 /* Debug */, 383 + 7555FFA4242A565B00829871 /* Release */, 384 + ); 385 + defaultConfigurationIsVisible = 0; 386 + defaultConfigurationName = Release; 387 + }; 388 + 7555FFA5242A565B00829871 /* Build configuration list for PBXNativeTarget "iosApp" */ = { 389 + isa = XCConfigurationList; 390 + buildConfigurations = ( 391 + 7555FFA6242A565B00829871 /* Debug */, 392 + 7555FFA7242A565B00829871 /* Release */, 393 + ); 394 + defaultConfigurationIsVisible = 0; 395 + defaultConfigurationName = Release; 396 + }; 397 + /* End XCConfigurationList section */ 398 + 399 + /* Begin XCRemoteSwiftPackageReference section */ 400 + E9B512A32D862B0F00D52AB6 /* XCRemoteSwiftPackageReference "google-mlkit-swiftpm" */ = { 401 + isa = XCRemoteSwiftPackageReference; 402 + repositoryURL = "https://github.com/d-date/google-mlkit-swiftpm"; 403 + requirement = { 404 + kind = upToNextMajorVersion; 405 + minimumVersion = 6.0.0; 406 + }; 407 + }; 408 + /* End XCRemoteSwiftPackageReference section */ 409 + 410 + /* Begin XCSwiftPackageProductDependency section */ 411 + E9B512A42D862B0F00D52AB6 /* MLKitBarcodeScanning */ = { 412 + isa = XCSwiftPackageProductDependency; 413 + package = E9B512A32D862B0F00D52AB6 /* XCRemoteSwiftPackageReference "google-mlkit-swiftpm" */; 414 + productName = MLKitBarcodeScanning; 415 + }; 416 + E9B512A62D862B0F00D52AB6 /* MLKitFaceDetection */ = { 417 + isa = XCSwiftPackageProductDependency; 418 + package = E9B512A32D862B0F00D52AB6 /* XCRemoteSwiftPackageReference "google-mlkit-swiftpm" */; 419 + productName = MLKitFaceDetection; 420 + }; 421 + /* End XCSwiftPackageProductDependency section */ 422 + }; 423 + rootObject = 7555FF73242A565900829871 /* Project object */; 424 + }
+7
mobile/iosApp/iosApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata
··· 1 + <?xml version="1.0" encoding="UTF-8"?> 2 + <Workspace 3 + version = "1.0"> 4 + <FileRef 5 + location = "self:"> 6 + </FileRef> 7 + </Workspace>
+60
mobile/iosApp/iosApp.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
··· 1 + { 2 + "originHash" : "891cce1a2e5740e9da5b83f5ae8318d7657deb75e81f6a5d7be479fbdadf82e9", 3 + "pins" : [ 4 + { 5 + "identity" : "google-mlkit-swiftpm", 6 + "kind" : "remoteSourceControl", 7 + "location" : "https://github.com/d-date/google-mlkit-swiftpm", 8 + "state" : { 9 + "revision" : "064418cee64470417fbc5c726e22815dc92c56c9", 10 + "version" : "6.0.0" 11 + } 12 + }, 13 + { 14 + "identity" : "googledatatransport", 15 + "kind" : "remoteSourceControl", 16 + "location" : "https://github.com/google/GoogleDataTransport.git", 17 + "state" : { 18 + "revision" : "a637d318ae7ae246b02d7305121275bc75ed5565", 19 + "version" : "9.4.0" 20 + } 21 + }, 22 + { 23 + "identity" : "googleutilities", 24 + "kind" : "remoteSourceControl", 25 + "location" : "https://github.com/google/GoogleUtilities.git", 26 + "state" : { 27 + "revision" : "8e5d57ed87057cd7b0e4e8f474d9e78f73eb85f7", 28 + "version" : "7.13.2" 29 + } 30 + }, 31 + { 32 + "identity" : "gtm-session-fetcher", 33 + "kind" : "remoteSourceControl", 34 + "location" : "https://github.com/google/gtm-session-fetcher.git", 35 + "state" : { 36 + "revision" : "0382ca27f22fb3494cf657d8dc356dc282cd1193", 37 + "version" : "3.4.1" 38 + } 39 + }, 40 + { 41 + "identity" : "nanopb", 42 + "kind" : "remoteSourceControl", 43 + "location" : "https://github.com/firebase/nanopb.git", 44 + "state" : { 45 + "revision" : "b7e1104502eca3a213b46303391ca4d3bc8ddec1", 46 + "version" : "2.30910.0" 47 + } 48 + }, 49 + { 50 + "identity" : "promises", 51 + "kind" : "remoteSourceControl", 52 + "location" : "https://github.com/google/promises.git", 53 + "state" : { 54 + "revision" : "540318ecedd63d883069ae7f1ed811a2df00b6ac", 55 + "version" : "2.4.0" 56 + } 57 + } 58 + ], 59 + "version" : 3 60 + }
+11
mobile/iosApp/iosApp/Assets.xcassets/AccentColor.colorset/Contents.json
··· 1 + { 2 + "colors" : [ 3 + { 4 + "idiom" : "universal" 5 + } 6 + ], 7 + "info" : { 8 + "author" : "xcode", 9 + "version" : 1 10 + } 11 + }
+14
mobile/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/Contents.json
··· 1 + { 2 + "images" : [ 3 + { 4 + "filename" : "app-icon-1024.png", 5 + "idiom" : "universal", 6 + "platform" : "ios", 7 + "size" : "1024x1024" 8 + } 9 + ], 10 + "info" : { 11 + "author" : "xcode", 12 + "version" : 1 13 + } 14 + }
mobile/iosApp/iosApp/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png

This is a binary file and will not be displayed.

+6
mobile/iosApp/iosApp/Assets.xcassets/Contents.json
··· 1 + { 2 + "info" : { 3 + "author" : "xcode", 4 + "version" : 1 5 + } 6 + }
+21
mobile/iosApp/iosApp/ContentView.swift
··· 1 + import UIKit 2 + import SwiftUI 3 + import ComposeApp 4 + 5 + struct ComposeView: UIViewControllerRepresentable { 6 + func makeUIViewController(context: Context) -> UIViewController { 7 + MainViewControllerKt.MainViewController() 8 + } 9 + 10 + func updateUIViewController(_ uiViewController: UIViewController, context: Context) {} 11 + } 12 + 13 + struct ContentView: View { 14 + var body: some View { 15 + ComposeView() 16 + .ignoresSafeArea(.keyboard) // Compose has own keyboard handler 17 + } 18 + } 19 + 20 + 21 +
+54
mobile/iosApp/iosApp/Info.plist
··· 1 + <?xml version="1.0" encoding="UTF-8"?> 2 + <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 3 + <plist version="1.0"> 4 + <dict> 5 + <key>CFBundleDevelopmentRegion</key> 6 + <string>$(DEVELOPMENT_LANGUAGE)</string> 7 + <key>CFBundleExecutable</key> 8 + <string>$(EXECUTABLE_NAME)</string> 9 + <key>CFBundleIdentifier</key> 10 + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> 11 + <key>CFBundleInfoDictionaryVersion</key> 12 + <string>6.0</string> 13 + <key>CFBundleName</key> 14 + <string>$(PRODUCT_NAME)</string> 15 + <key>CFBundlePackageType</key> 16 + <string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string> 17 + <key>CFBundleShortVersionString</key> 18 + <string>1.0</string> 19 + <key>CFBundleVersion</key> 20 + <string>1</string> 21 + <key>LSRequiresIPhoneOS</key> 22 + <true/> 23 + <key>CADisableMinimumFrameDurationOnPhone</key> 24 + <true/> 25 + <key>UIApplicationSceneManifest</key> 26 + <dict> 27 + <key>UIApplicationSupportsMultipleScenes</key> 28 + <false/> 29 + </dict> 30 + <key>UILaunchScreen</key> 31 + <dict/> 32 + <key>UIRequiredDeviceCapabilities</key> 33 + <array> 34 + <string>armv7</string> 35 + </array> 36 + <key>UISupportedInterfaceOrientations</key> 37 + <array> 38 + <string>UIInterfaceOrientationPortrait</string> 39 + <string>UIInterfaceOrientationLandscapeLeft</string> 40 + <string>UIInterfaceOrientationLandscapeRight</string> 41 + </array> 42 + <key>UISupportedInterfaceOrientations~ipad</key> 43 + <array> 44 + <string>UIInterfaceOrientationPortrait</string> 45 + <string>UIInterfaceOrientationPortraitUpsideDown</string> 46 + <string>UIInterfaceOrientationLandscapeLeft</string> 47 + <string>UIInterfaceOrientationLandscapeRight</string> 48 + </array> 49 + <key>NSCameraUsageDescription</key><string>Camera permission is required for the app to work. 50 + </string><key>NSPhotoLibraryUsageDescription</key><string>Photo Library permission is required for 51 + the app to work. 52 + </string> 53 + </dict> 54 + </plist>
+6
mobile/iosApp/iosApp/Preview Content/Preview Assets.xcassets/Contents.json
··· 1 + { 2 + "info" : { 3 + "author" : "xcode", 4 + "version" : 1 5 + } 6 + }
+10
mobile/iosApp/iosApp/iOSApp.swift
··· 1 + import SwiftUI 2 + 3 + @main 4 + struct iOSApp: App { 5 + var body: some Scene { 6 + WindowGroup { 7 + ContentView() 8 + } 9 + } 10 + }
+31
mobile/settings.gradle.kts
··· 1 + rootProject.name = "myrus-mobile" 2 + enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") 3 + 4 + pluginManagement { 5 + repositories { 6 + google { 7 + mavenContent { 8 + includeGroupAndSubgroups("androidx") 9 + includeGroupAndSubgroups("com.android") 10 + includeGroupAndSubgroups("com.google") 11 + } 12 + } 13 + mavenCentral() 14 + gradlePluginPortal() 15 + } 16 + } 17 + 18 + dependencyResolutionManagement { 19 + repositories { 20 + google { 21 + mavenContent { 22 + includeGroupAndSubgroups("androidx") 23 + includeGroupAndSubgroups("com.android") 24 + includeGroupAndSubgroups("com.google") 25 + } 26 + } 27 + mavenCentral() 28 + } 29 + } 30 + 31 + include(":composeApp")