diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..13d83f6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,7 @@ +[*.{kt,kts}] +ktlint_code_style = ktlint_official + +ktlint_standard_multiline-if-else = disabled +ktlint_standard_property-naming = disabled +ktlint_standard_function_naming_ignore_when_annotated_with = Composable +ktlint_function_naming_ignore_when_annotated_with = Composable \ No newline at end of file diff --git a/calf-core/build.gradle.kts b/calf-core/build.gradle.kts new file mode 100644 index 0000000..95e9bde --- /dev/null +++ b/calf-core/build.gradle.kts @@ -0,0 +1,55 @@ +import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi + +plugins { + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.composeMultiplatform) + alias(libs.plugins.androidLibrary) + id("module.publication") +} + +kotlin { + @OptIn(ExperimentalKotlinGradlePluginApi::class) + applyDefaultHierarchyTemplate { + common { + group("nonAndroid") { + withJvm() + withIos() + withJs() + } + } + } + androidTarget { + publishLibraryVariants("release") + compilations.all { + kotlinOptions { + jvmTarget = "11" + } + } + } + jvm("desktop") { + jvmToolchain(11) + } + js(IR) { + browser() + } + iosX64() + iosArm64() + iosSimulatorArm64() + + sourceSets.commonMain.dependencies { + implementation(compose.runtime) + implementation(compose.foundation) + } +} + +android { + namespace = "com.mohamedrejeb.calf.core" + compileSdk = libs.versions.android.compileSdk.get().toInt() + defaultConfig { + minSdk = libs.versions.android.minSdk.get().toInt() + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } +} diff --git a/calf-core/src/androidMain/kotlin/com.mohamedrejeb.calf/core/LocalPlatformContext.android.kt b/calf-core/src/androidMain/kotlin/com.mohamedrejeb.calf/core/LocalPlatformContext.android.kt new file mode 100644 index 0000000..91ddc11 --- /dev/null +++ b/calf-core/src/androidMain/kotlin/com.mohamedrejeb.calf/core/LocalPlatformContext.android.kt @@ -0,0 +1,5 @@ +package com.mohamedrejeb.calf.core + +import androidx.compose.ui.platform.LocalContext + +actual val LocalPlatformContext get() = LocalContext diff --git a/calf-core/src/androidMain/kotlin/com.mohamedrejeb.calf/core/PlatformContext.android.kt b/calf-core/src/androidMain/kotlin/com.mohamedrejeb.calf/core/PlatformContext.android.kt new file mode 100644 index 0000000..6d24d8a --- /dev/null +++ b/calf-core/src/androidMain/kotlin/com.mohamedrejeb.calf/core/PlatformContext.android.kt @@ -0,0 +1,5 @@ +package com.mohamedrejeb.calf.core + +import android.content.Context + +actual typealias PlatformContext = Context diff --git a/calf-core/src/commonMain/kotlin/com.mohamedrejeb.calf/core/LocalPlatformContext.kt b/calf-core/src/commonMain/kotlin/com.mohamedrejeb.calf/core/LocalPlatformContext.kt new file mode 100644 index 0000000..d17c9e3 --- /dev/null +++ b/calf-core/src/commonMain/kotlin/com.mohamedrejeb.calf/core/LocalPlatformContext.kt @@ -0,0 +1,5 @@ +package com.mohamedrejeb.calf.core + +import androidx.compose.runtime.ProvidableCompositionLocal + +expect val LocalPlatformContext: ProvidableCompositionLocal diff --git a/calf-core/src/commonMain/kotlin/com.mohamedrejeb.calf/core/PlatformContext.kt b/calf-core/src/commonMain/kotlin/com.mohamedrejeb.calf/core/PlatformContext.kt new file mode 100644 index 0000000..8b5636c --- /dev/null +++ b/calf-core/src/commonMain/kotlin/com.mohamedrejeb.calf/core/PlatformContext.kt @@ -0,0 +1,3 @@ +package com.mohamedrejeb.calf.core + +expect abstract class PlatformContext diff --git a/calf-core/src/nonAndroidMain/kotlin/com.mohamedrejeb.calf/core/LocalPlatformContext.nonAndroid.kt b/calf-core/src/nonAndroidMain/kotlin/com.mohamedrejeb.calf/core/LocalPlatformContext.nonAndroid.kt new file mode 100644 index 0000000..209b1a8 --- /dev/null +++ b/calf-core/src/nonAndroidMain/kotlin/com.mohamedrejeb.calf/core/LocalPlatformContext.nonAndroid.kt @@ -0,0 +1,8 @@ +package com.mohamedrejeb.calf.core + +import androidx.compose.runtime.staticCompositionLocalOf + +actual val LocalPlatformContext = + staticCompositionLocalOf { + PlatformContext.INSTANCE + } diff --git a/calf-core/src/nonAndroidMain/kotlin/com.mohamedrejeb.calf/core/PlatformContext.nonAndroid.kt b/calf-core/src/nonAndroidMain/kotlin/com.mohamedrejeb.calf/core/PlatformContext.nonAndroid.kt new file mode 100644 index 0000000..481f53a --- /dev/null +++ b/calf-core/src/nonAndroidMain/kotlin/com.mohamedrejeb.calf/core/PlatformContext.nonAndroid.kt @@ -0,0 +1,10 @@ +package com.mohamedrejeb.calf.core + +import kotlin.jvm.JvmField + +actual abstract class PlatformContext private constructor() { + companion object { + @JvmField + val INSTANCE = object : PlatformContext() {} + } +} diff --git a/calf-file-picker/build.gradle.kts b/calf-file-picker/build.gradle.kts index a8f3325..a589980 100644 --- a/calf-file-picker/build.gradle.kts +++ b/calf-file-picker/build.gradle.kts @@ -1,5 +1,3 @@ -import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi - plugins { alias(libs.plugins.kotlinMultiplatform) alias(libs.plugins.composeMultiplatform) @@ -28,21 +26,17 @@ kotlin { iosSimulatorArm64() sourceSets.commonMain.get().dependencies { + api(projects.calfIo) + implementation(compose.runtime) implementation(compose.foundation) - implementation(compose.material) - api(project(":calf-io")) } sourceSets.commonTest.get().dependencies { implementation(libs.kotlin.test) } - sourceSets { - val androidMain by getting { - dependencies { - implementation(libs.activity.compose) - } - } + sourceSets.androidMain.dependencies { + implementation(libs.activity.compose) } } diff --git a/calf-file-picker/src/androidMain/kotlin/com/mohamedrejeb/calf/picker/FilePickerLauncher.android.kt b/calf-file-picker/src/androidMain/kotlin/com/mohamedrejeb/calf/picker/FilePickerLauncher.android.kt index 3bc6d1d..9a1b6e0 100644 --- a/calf-file-picker/src/androidMain/kotlin/com/mohamedrejeb/calf/picker/FilePickerLauncher.android.kt +++ b/calf-file-picker/src/androidMain/kotlin/com/mohamedrejeb/calf/picker/FilePickerLauncher.android.kt @@ -1,14 +1,11 @@ package com.mohamedrejeb.calf.picker -import android.content.Intent import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.PickVisualMediaRequest import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.runtime.Composable import androidx.compose.runtime.remember -import androidx.compose.ui.platform.LocalContext import com.mohamedrejeb.calf.io.KmpFile -import java.io.File @Composable actual fun rememberFilePickerLauncher( @@ -22,19 +19,16 @@ actual fun rememberFilePickerLauncher( FilePickerFileType.Image, FilePickerFileType.Video, FilePickerFileType.ImageVideo -> pickSingleVisualMedia( type = type, - selectionMode = selectionMode, onResult = onResult, ) FilePickerFileType.Folder -> pickFolder( type = type, - selectionMode = selectionMode, onResult = onResult, ) else -> pickSingleFile( type = type, - selectionMode = selectionMode, onResult = onResult, ) } @@ -44,19 +38,16 @@ actual fun rememberFilePickerLauncher( FilePickerFileType.Image, FilePickerFileType.Video, FilePickerFileType.ImageVideo -> pickMultipleVisualMedia( type = type, - selectionMode = selectionMode, onResult = onResult, ) FilePickerFileType.Folder -> pickFolder( type = type, - selectionMode = selectionMode, onResult = onResult, ) else -> pickMultipleFiles( type = type, - selectionMode = selectionMode, onResult = onResult, ) } @@ -67,28 +58,25 @@ actual fun rememberFilePickerLauncher( @Composable private fun pickSingleVisualMedia( type: FilePickerFileType, - selectionMode: FilePickerSelectionMode, onResult: (List) -> Unit, ): FilePickerLauncher { - val context = LocalContext.current - - val singlePhotoPickerLauncher = rememberLauncherForActivityResult( - contract = ActivityResultContracts.PickVisualMedia(), - onResult = { uri -> - val file = URIPathHelper.getPath(context, uri)?.let { File(it) } - file?.let { onResult(listOf(it)) } ?: onResult(emptyList()) - } - ) + val singlePhotoPickerLauncher = + rememberLauncherForActivityResult( + contract = ActivityResultContracts.PickVisualMedia(), + onResult = { uri -> + onResult(uri?.let { listOf(KmpFile(it)) } ?: emptyList()) + }, + ) return remember { FilePickerLauncher( type = type, - selectionMode = selectionMode, + selectionMode = FilePickerSelectionMode.Single, onLaunch = { singlePhotoPickerLauncher.launch( - type.toPickVisualMediaRequest() + type.toPickVisualMediaRequest(), ) - } + }, ) } } @@ -96,30 +84,29 @@ private fun pickSingleVisualMedia( @Composable fun pickMultipleVisualMedia( type: FilePickerFileType, - selectionMode: FilePickerSelectionMode, onResult: (List) -> Unit, ): FilePickerLauncher { - val context = LocalContext.current - - val singlePhotoPickerLauncher = rememberLauncherForActivityResult( - contract = ActivityResultContracts.PickMultipleVisualMedia(), - onResult = { uriList -> - val fileList = uriList.mapNotNull { uri -> - URIPathHelper.getPath(context, uri)?.let { File(it) } - } - onResult(fileList) - } - ) + val singlePhotoPickerLauncher = + rememberLauncherForActivityResult( + contract = ActivityResultContracts.PickMultipleVisualMedia(), + onResult = { uriList -> + val fileList = + uriList.map { uri -> + KmpFile(uri) + } + onResult(fileList) + }, + ) return remember { FilePickerLauncher( type = type, - selectionMode = selectionMode, + selectionMode = FilePickerSelectionMode.Multiple, onLaunch = { singlePhotoPickerLauncher.launch( - type.toPickVisualMediaRequest() + type.toPickVisualMediaRequest(), ) - } + }, ) } } @@ -127,28 +114,25 @@ fun pickMultipleVisualMedia( @Composable private fun pickSingleFile( type: FilePickerFileType, - selectionMode: FilePickerSelectionMode, onResult: (List) -> Unit, ): FilePickerLauncher { - val context = LocalContext.current - - val singlePhotoPickerLauncher = rememberLauncherForActivityResult( - contract = ActivityResultContracts.GetContent(), - onResult = { uri -> - val file = URIPathHelper.getPath(context, uri)?.let { File(it) } - file?.let { onResult(listOf(it)) } ?: onResult(emptyList()) - } - ) + val singlePhotoPickerLauncher = + rememberLauncherForActivityResult( + contract = ActivityResultContracts.OpenDocument(), + onResult = { uri -> + onResult(uri?.let { listOf(KmpFile(it)) } ?: emptyList()) + }, + ) return remember { FilePickerLauncher( type = type, - selectionMode = selectionMode, + selectionMode = FilePickerSelectionMode.Single, onLaunch = { singlePhotoPickerLauncher.launch( - type.value.first() + type.value.toList().toTypedArray(), ) - } + }, ) } } @@ -156,30 +140,29 @@ private fun pickSingleFile( @Composable private fun pickMultipleFiles( type: FilePickerFileType, - selectionMode: FilePickerSelectionMode, onResult: (List) -> Unit, ): FilePickerLauncher { - val context = LocalContext.current - - val singlePhotoPickerLauncher = rememberLauncherForActivityResult( - contract = ActivityResultContracts.GetMultipleContents(), - onResult = { uriList -> - val fileList = uriList.mapNotNull { uri -> - URIPathHelper.getPath(context, uri)?.let { File(it) } - } - onResult(fileList) - } - ) + val singlePhotoPickerLauncher = + rememberLauncherForActivityResult( + contract = ActivityResultContracts.OpenMultipleDocuments(), + onResult = { uriList -> + val fileList = + uriList.map { uri -> + KmpFile(uri) + } + onResult(fileList) + }, + ) return remember { FilePickerLauncher( type = type, - selectionMode = selectionMode, + selectionMode = FilePickerSelectionMode.Multiple, onLaunch = { singlePhotoPickerLauncher.launch( - type.value.first() + type.value.toList().toTypedArray(), ) - } + }, ) } } @@ -187,32 +170,23 @@ private fun pickMultipleFiles( @Composable private fun pickFolder( type: FilePickerFileType, - selectionMode: FilePickerSelectionMode, onResult: (List) -> Unit, ): FilePickerLauncher { - val context = LocalContext.current - - val singlePhotoPickerLauncher = rememberLauncherForActivityResult( - contract = ActivityResultContracts.OpenDocumentTree(), - onResult = { uri -> - uri?.let { uri -> - context.contentResolver.takePersistableUriPermission( - uri, - Intent.FLAG_GRANT_READ_URI_PERMISSION - ) - val file = URIPathHelper.getPath(context, uri)?.let { File(it) } - file?.let { onResult(listOf(it)) } ?: onResult(emptyList()) - } - } - ) + val singlePhotoPickerLauncher = + rememberLauncherForActivityResult( + contract = ActivityResultContracts.OpenDocumentTree(), + onResult = { uri -> + onResult(uri?.let { listOf(KmpFile(it)) } ?: emptyList()) + }, + ) return remember { FilePickerLauncher( type = type, - selectionMode = selectionMode, + selectionMode = FilePickerSelectionMode.Single, onLaunch = { singlePhotoPickerLauncher.launch(null) - } + }, ) } } diff --git a/calf-file-picker/src/androidMain/kotlin/com/mohamedrejeb/calf/picker/UriHelper.kt b/calf-file-picker/src/androidMain/kotlin/com/mohamedrejeb/calf/picker/UriHelper.kt index e4128fd..3c28bc6 100644 --- a/calf-file-picker/src/androidMain/kotlin/com/mohamedrejeb/calf/picker/UriHelper.kt +++ b/calf-file-picker/src/androidMain/kotlin/com/mohamedrejeb/calf/picker/UriHelper.kt @@ -9,7 +9,10 @@ import android.provider.DocumentsContract import android.provider.MediaStore internal object URIPathHelper { - fun getPath(context: Context, uri: Uri?): String? { + fun getPath( + context: Context, + uri: Uri?, + ): String? { if (uri == null) return null // DocumentProvider @@ -22,19 +25,22 @@ internal object URIPathHelper { if ("primary".equals(type, ignoreCase = true)) { return Environment.getExternalStorageDirectory().toString() + "/" + split[1] } - } else if (isDownloadsDocument(uri)) { val id = DocumentsContract.getDocumentId(uri) - val contentUri = ContentUris.withAppendedId( - Uri.parse("content://downloads/public_downloads"), - java.lang.Long.valueOf(id) - ) + val contentUri = + ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), + java.lang.Long.valueOf(id), + ) return getDataColumn(context, contentUri, null, null) } else if (isMediaDocument(uri)) { val docId = DocumentsContract.getDocumentId(uri) val split = docId.split(":".toRegex()).toTypedArray() val type = split[0] var contentUri: Uri? = null + println("docId: $docId") + println("type: $type") + when (type) { "image" -> { contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI @@ -48,7 +54,10 @@ internal object URIPathHelper { } val selection = "_id=?" val selectionArgs = arrayOf(split[1]) + println("contentUri: $contentUri") + println("selectionArgs: $selectionArgs") return getDataColumn(context, contentUri, selection, selectionArgs) + ?: getDataColumn(context, uri, null, null) } } else if (isExternalStorageDocument(uri)) { if (uri.pathSegments.size > 1) { @@ -60,6 +69,7 @@ internal object URIPathHelper { } } } else if ("content".equals(uri.scheme, ignoreCase = true)) { + println("content") return getDataColumn(context, uri, null, null) } else if ("file".equals(uri.scheme, ignoreCase = true)) { return uri.path @@ -67,7 +77,12 @@ internal object URIPathHelper { return null } - private fun getDataColumn(context: Context, uri: Uri?, selection: String?, selectionArgs: Array?): String? { + private fun getDataColumn( + context: Context, + uri: Uri?, + selection: String?, + selectionArgs: Array?, + ): String? { var cursor: Cursor? = null val column = "_data" val projection = arrayOf(column) @@ -94,4 +109,4 @@ internal object URIPathHelper { private fun isMediaDocument(uri: Uri): Boolean { return "com.android.providers.media.documents" == uri.authority } -} \ No newline at end of file +} diff --git a/calf-file-picker/src/desktopMain/kotlin/com/mohamedrejeb/calf/picker/FilePickerLauncher.desktop.kt b/calf-file-picker/src/desktopMain/kotlin/com/mohamedrejeb/calf/picker/FilePickerLauncher.desktop.kt index b3824b7..8eeed75 100644 --- a/calf-file-picker/src/desktopMain/kotlin/com/mohamedrejeb/calf/picker/FilePickerLauncher.desktop.kt +++ b/calf-file-picker/src/desktopMain/kotlin/com/mohamedrejeb/calf/picker/FilePickerLauncher.desktop.kt @@ -1,14 +1,17 @@ package com.mohamedrejeb.calf.picker -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.window.AwtWindow import com.mohamedrejeb.calf.io.KmpFile import java.awt.FileDialog import java.awt.Frame import java.io.File import java.net.URLConnection -import java.nio.file.Files @Composable actual fun rememberFilePickerLauncher( @@ -22,34 +25,37 @@ actual fun rememberFilePickerLauncher( AwtWindow( create = { val frame: Frame? = null - val fileDialog = object : FileDialog( - frame, - "Select ${if (type == FilePickerFileType.Folder) "Folder" else "File"}", - if (type == FilePickerFileType.Folder) SAVE else LOAD - ) { - override fun setVisible(value: Boolean) { - super.setVisible(value) - if (value) { - onResult(files?.toList() ?: emptyList()) - fileDialogVisible = false + val fileDialog = + object : FileDialog( + frame, + "Select ${if (type == FilePickerFileType.Folder) "Folder" else "File"}", + if (type == FilePickerFileType.Folder) SAVE else LOAD, + ) { + override fun setVisible(value: Boolean) { + super.setVisible(value) + if (value) { + onResult(files.orEmpty().map { KmpFile(it) }) + fileDialogVisible = false + } } } - } fileDialog.isMultipleMode = selectionMode == FilePickerSelectionMode.Multiple - val mimeType = when (type) { - FilePickerFileType.Folder -> listOf("folder") - FilePickerFileType.All -> emptyList() - else -> type.value.map { - it - .removeSuffix("/*") - .removeSuffix("/") - .removeSuffix("*") - }.filter { - it.isNotEmpty() + val mimeType = + when (type) { + FilePickerFileType.Folder -> listOf("folder") + FilePickerFileType.All -> emptyList() + else -> + type.value.map { + it + .removeSuffix("/*") + .removeSuffix("/") + .removeSuffix("*") + }.filter { + it.isNotEmpty() + } } - } fileDialog.setFilenameFilter { file, name -> if (mimeType.isEmpty()) { true @@ -67,7 +73,7 @@ actual fun rememberFilePickerLauncher( }, dispose = { it.dispose() - } + }, ) } @@ -77,7 +83,7 @@ actual fun rememberFilePickerLauncher( selectionMode = selectionMode, onLaunch = { fileDialogVisible = true - } + }, ) } } @@ -93,4 +99,4 @@ actual class FilePickerLauncher actual constructor( } val File.extension: String - get() = name.substringAfterLast(".") \ No newline at end of file + get() = name.substringAfterLast(".") diff --git a/calf-file-picker/src/jsMain/kotlin/com.mohamedrejeb.calf.picker/FilePickerLauncher.js.kt b/calf-file-picker/src/jsMain/kotlin/com.mohamedrejeb.calf.picker/FilePickerLauncher.js.kt index be5f67d..fa1c821 100644 --- a/calf-file-picker/src/jsMain/kotlin/com.mohamedrejeb.calf.picker/FilePickerLauncher.js.kt +++ b/calf-file-picker/src/jsMain/kotlin/com.mohamedrejeb.calf.picker/FilePickerLauncher.js.kt @@ -1,8 +1,14 @@ package com.mohamedrejeb.calf.picker -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import com.mohamedrejeb.calf.io.KmpFile +import kotlinx.browser.document + @Composable actual fun rememberFilePickerLauncher( type: FilePickerFileType, @@ -11,14 +17,18 @@ actual fun rememberFilePickerLauncher( ): FilePickerLauncher { var fileDialogVisible by rememberSaveable { mutableStateOf(false) } - return remember { FilePickerLauncher( type = type, selectionMode = selectionMode, onLaunch = { - fileDialogVisible = true - } + val fileInputElement = document.createElement("input") + fileInputElement.setAttribute("style", "display='none'") + fileInputElement.setAttribute("type", "file") + fileInputElement.setAttribute("name", "file") + js("fileInputElement.click();") + Unit + }, ) } } @@ -31,4 +41,4 @@ actual class FilePickerLauncher actual constructor( actual fun launch() { onLaunch() } -} \ No newline at end of file +} diff --git a/calf-io/build.gradle.kts b/calf-io/build.gradle.kts index 2b029d9..1d0b738 100644 --- a/calf-io/build.gradle.kts +++ b/calf-io/build.gradle.kts @@ -24,7 +24,11 @@ kotlin { iosArm64() iosSimulatorArm64() - sourceSets.commonMain.get().dependencies {} + sourceSets.commonMain.dependencies { + api(projects.calfCore) + + implementation(libs.documentfile) + } } android { diff --git a/calf-io/src/androidMain/kotlin/com/mohamedrejeb/calf/io/KmpFile.android.kt b/calf-io/src/androidMain/kotlin/com/mohamedrejeb/calf/io/KmpFile.android.kt index b4dc479..3cc1721 100644 --- a/calf-io/src/androidMain/kotlin/com/mohamedrejeb/calf/io/KmpFile.android.kt +++ b/calf-io/src/androidMain/kotlin/com/mohamedrejeb/calf/io/KmpFile.android.kt @@ -1,23 +1,55 @@ package com.mohamedrejeb.calf.io -import java.io.File +import android.net.Uri +import androidx.documentfile.provider.DocumentFile +import com.mohamedrejeb.calf.core.PlatformContext +import java.io.FileNotFoundException /** * An typealias representing a file in the platform specific implementation */ -actual typealias KmpFile = File +actual class KmpFile( + val uri: Uri, +) -actual fun createKmpFile(path: String): KmpFile? = File(path) +actual fun KmpFile.exists(context: PlatformContext): Boolean = + try { + val inputStream = context.contentResolver.openInputStream(uri)!! + inputStream.close() -actual fun KmpFile.exists() = this.exists() + true + } catch (e: Exception) { + false + } -actual fun KmpFile.readByteArray(): ByteArray = this.readBytes() +/** + * Reads the content of the file as a byte array + * + * @param context the context to use to open the file + * @throws FileNotFoundException if the file is not found + * @return the content of the file as a byte array + */ +@Throws(FileNotFoundException::class) +actual fun KmpFile.readByteArray(context: PlatformContext): ByteArray { + val inputStream = + context.contentResolver.openInputStream(uri) + ?: throw FileNotFoundException("File not found") + + return inputStream.readBytes().also { + inputStream.close() + } +} + +actual fun KmpFile.getName(context: PlatformContext): String? { + val documentFile = DocumentFile.fromSingleUri(context, uri) + + return documentFile?.name +} -actual val KmpFile.name: String? - get() = this.name +actual fun KmpFile.getPath(context: PlatformContext): String? = uri.toString() -actual val KmpFile.path: String? - get() = this.path +actual fun KmpFile.isDirectory(context: PlatformContext): Boolean { + val documentFile = DocumentFile.fromSingleUri(context, uri) -actual val KmpFile.isDirectory: Boolean - get() = this.isDirectory \ No newline at end of file + return documentFile?.isDirectory == true +} diff --git a/calf-io/src/commonMain/kotlin/com.mohamedrejeb.calf/io/KmpFile.kt b/calf-io/src/commonMain/kotlin/com.mohamedrejeb.calf/io/KmpFile.kt index b87543f..d657bb6 100644 --- a/calf-io/src/commonMain/kotlin/com.mohamedrejeb.calf/io/KmpFile.kt +++ b/calf-io/src/commonMain/kotlin/com.mohamedrejeb.calf/io/KmpFile.kt @@ -1,21 +1,48 @@ package com.mohamedrejeb.calf.io +import com.mohamedrejeb.calf.core.PlatformContext + /** - * An typealias representing a file in the platform specific implementation + * Represents a file in a platform-agnostic way. */ expect class KmpFile -expect fun createKmpFile(path: String): KmpFile? - -expect fun KmpFile.exists(): Boolean - -expect fun KmpFile.readByteArray(): ByteArray +/** + * Checks if the KmpFile exists in the specified platform context. + * + * @param context The platform context in which to check the existence of the file. + * @return True if the file exists, false otherwise. + */ +expect fun KmpFile.exists(context: PlatformContext): Boolean -expect val KmpFile.name: String? +/** + * Reads the content of the KmpFile as a byte array. + * + * @param context The platform context. + * @return The content of the file as a byte array. + */ +expect fun KmpFile.readByteArray(context: PlatformContext): ByteArray -expect val KmpFile.path: String? +/** + * Reads the name of the KmpFile. + * + * @param context The platform context. + * @return The name of the file as a string. + */ +expect fun KmpFile.getName(context: PlatformContext): String? -expect val KmpFile.isDirectory: Boolean +/** + * Reads the path of the KmpFile. + * + * @param context The platform context. + * @return The path of the file as a string. + */ +expect fun KmpFile.getPath(context: PlatformContext): String? -val KmpFile.isFile: Boolean - get() = !this.isDirectory \ No newline at end of file +/** + * Checks if the KmpFile is a directory. + * + * @param context The platform context. + * @return True if the file is a directory, false otherwise. + */ +expect fun KmpFile.isDirectory(context: PlatformContext): Boolean diff --git a/calf-io/src/desktopMain/kotlin/com/mohamedrejeb/calf/io/KmpFile.desktop.kt b/calf-io/src/desktopMain/kotlin/com/mohamedrejeb/calf/io/KmpFile.desktop.kt index b4dc479..3c35789 100644 --- a/calf-io/src/desktopMain/kotlin/com/mohamedrejeb/calf/io/KmpFile.desktop.kt +++ b/calf-io/src/desktopMain/kotlin/com/mohamedrejeb/calf/io/KmpFile.desktop.kt @@ -1,23 +1,21 @@ package com.mohamedrejeb.calf.io +import com.mohamedrejeb.calf.core.PlatformContext import java.io.File /** * An typealias representing a file in the platform specific implementation */ -actual typealias KmpFile = File +actual class KmpFile( + val file: File, +) -actual fun createKmpFile(path: String): KmpFile? = File(path) +actual fun KmpFile.exists(context: PlatformContext) = file.exists() -actual fun KmpFile.exists() = this.exists() +actual fun KmpFile.readByteArray(context: PlatformContext): ByteArray = file.readBytes() -actual fun KmpFile.readByteArray(): ByteArray = this.readBytes() +actual fun KmpFile.getName(context: PlatformContext): String? = file.name -actual val KmpFile.name: String? - get() = this.name +actual fun KmpFile.getPath(context: PlatformContext): String? = file.path -actual val KmpFile.path: String? - get() = this.path - -actual val KmpFile.isDirectory: Boolean - get() = this.isDirectory \ No newline at end of file +actual fun KmpFile.isDirectory(context: PlatformContext): Boolean = file.isDirectory diff --git a/calf-io/src/iosMain/kotlin/com.mohamedrejeb.calf/io/KmpFile.ios.kt b/calf-io/src/iosMain/kotlin/com.mohamedrejeb.calf/io/KmpFile.ios.kt index 6b4e8cd..c8d9575 100644 --- a/calf-io/src/iosMain/kotlin/com.mohamedrejeb.calf/io/KmpFile.ios.kt +++ b/calf-io/src/iosMain/kotlin/com.mohamedrejeb.calf/io/KmpFile.ios.kt @@ -1,5 +1,6 @@ package com.mohamedrejeb.calf.io +import com.mohamedrejeb.calf.core.PlatformContext import kotlinx.cinterop.ExperimentalForeignApi import kotlinx.cinterop.addressOf import kotlinx.cinterop.usePinned @@ -13,19 +14,18 @@ import platform.posix.memcpy /** * A typealias representing a file in the platform specific implementation */ -@Suppress("CONFLICTING_OVERLOADS") -actual typealias KmpFile = NSURL +actual class KmpFile( + val url: NSURL, +) -actual fun createKmpFile(path: String): KmpFile? = NSURL(fileURLWithPath = path) - -actual fun KmpFile.exists(): Boolean { - return NSFileManager.defaultManager.fileExistsAtPath(this.path ?: return false) +actual fun KmpFile.exists(context: PlatformContext): Boolean { + return NSFileManager.defaultManager.fileExistsAtPath(url.path ?: return false) } @OptIn(ExperimentalForeignApi::class) -actual fun KmpFile.readByteArray(): ByteArray { - val data = NSData.dataWithContentsOfURL(this) ?: return ByteArray(0) - val byteArraySize: Int = if (data.length > Int.MAX_VALUE.toUInt()) Int.MAX_VALUE else data.length .toInt() +actual fun KmpFile.readByteArray(context: PlatformContext): ByteArray { + val data = NSData.dataWithContentsOfURL(url) ?: return ByteArray(0) + val byteArraySize: Int = if (data.length > Int.MAX_VALUE.toUInt()) Int.MAX_VALUE else data.length.toInt() return ByteArray(byteArraySize).apply { usePinned { memcpy(it.addressOf(0), data.bytes, data.length) @@ -33,11 +33,8 @@ actual fun KmpFile.readByteArray(): ByteArray { } } -actual val KmpFile.name: String? - get() = this.lastPathComponent +actual fun KmpFile.getName(context: PlatformContext): String? = url.lastPathComponent -actual val KmpFile.path: String? - get() = this.path +actual fun KmpFile.getPath(context: PlatformContext): String? = url.path -actual val KmpFile.isDirectory: Boolean - get() = !this.path.orEmpty().contains(".") \ No newline at end of file +actual fun KmpFile.isDirectory(context: PlatformContext): Boolean = !url.path.orEmpty().contains(".") diff --git a/calf-io/src/jsMain/kotlin/com.mohamedrejeb.calf/io/KmpFile.js.kt b/calf-io/src/jsMain/kotlin/com.mohamedrejeb.calf/io/KmpFile.js.kt index 419ee59..e8687cb 100644 --- a/calf-io/src/jsMain/kotlin/com.mohamedrejeb.calf/io/KmpFile.js.kt +++ b/calf-io/src/jsMain/kotlin/com.mohamedrejeb.calf/io/KmpFile.js.kt @@ -1,19 +1,19 @@ package com.mohamedrejeb.calf.io -import org.khronos.webgl.ArrayBuffer +import com.mohamedrejeb.calf.core.PlatformContext import org.w3c.files.File import org.w3c.files.FileReader /** * A typealias representing a file in the platform specific implementation */ -actual typealias KmpFile = File +actual class KmpFile( + val file: File, +) -actual fun createKmpFile(path: String): KmpFile? = null +actual fun KmpFile.exists(context: PlatformContext) = true -actual fun KmpFile.exists() = true - -actual fun KmpFile.readByteArray(): ByteArray { +actual fun KmpFile.readByteArray(context: PlatformContext): ByteArray { val fileReader = FileReader() fileReader.onload = { val arrayBuffer = it.target.asDynamic().result as String @@ -21,15 +21,12 @@ actual fun KmpFile.readByteArray(): ByteArray { arrayBuffer[index].code.toByte() } } - fileReader.readAsText(this) + fileReader.readAsText(file) return fileReader.result as ByteArray } -actual val KmpFile.name: String? - get() = this.name +actual fun KmpFile.getName(context: PlatformContext): String? = file.name -actual val KmpFile.path: String? - get() = this.name +actual fun KmpFile.getPath(context: PlatformContext): String? = file.name -actual val KmpFile.isDirectory: Boolean - get() = !this.name.contains(".") \ No newline at end of file +actual fun KmpFile.isDirectory(context: PlatformContext): Boolean = !file.name.contains(".") diff --git a/calf-ui/build.gradle.kts b/calf-ui/build.gradle.kts index 693012c..d9941b0 100644 --- a/calf-ui/build.gradle.kts +++ b/calf-ui/build.gradle.kts @@ -1,4 +1,5 @@ import org.gradle.internal.os.OperatingSystem +import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi plugins { alias(libs.plugins.kotlinMultiplatform) @@ -11,6 +12,8 @@ val os: OperatingSystem = OperatingSystem.current() val arch: String = System.getProperty("os.arch") val isAarch64: Boolean = arch.contains("aarch64") +println("arch: $arch") + val platform = when { os.isWindows -> "win" os.isMacOsX -> "mac" @@ -18,7 +21,17 @@ val platform = when { } + if (isAarch64) "-aarch64" else "" kotlin { - kotlin.applyDefaultHierarchyTemplate() + @OptIn(ExperimentalKotlinGradlePluginApi::class) + applyDefaultHierarchyTemplate { + common { + group("material") { + withAndroidTarget() + withJvm() + withJs() + } + } + } + androidTarget { publishLibraryVariants("release") compilations.all { @@ -44,33 +57,19 @@ kotlin { implementation(libs.kotlinx.coroutines.core) } - sourceSets { - val commonMain by getting - - val androidMain by getting { - dependencies { - implementation(libs.activity.compose) - implementation(libs.kotlinx.coroutines.android) - } - } - - val desktopMain by getting { - dependencies { - implementation("org.openjfx:javafx-base:19:$platform") - implementation("org.openjfx:javafx-graphics:19:$platform") - implementation("org.openjfx:javafx-controls:19:$platform") - implementation("org.openjfx:javafx-media:19:$platform") - implementation("org.openjfx:javafx-web:19:$platform") - implementation("org.openjfx:javafx-swing:19:$platform") - implementation(libs.kotlinx.coroutines.javafx) - } - } + sourceSets.androidMain.dependencies { + implementation(libs.activity.compose) + implementation(libs.kotlinx.coroutines.android) + } - // Group for Material3 targets - val materialMain by creating - androidMain.dependsOn(materialMain) - desktopMain.dependsOn(materialMain) - materialMain.dependsOn(commonMain) + sourceSets.named("desktopMain").dependencies { + implementation("org.openjfx:javafx-base:19:$platform") + implementation("org.openjfx:javafx-graphics:19:$platform") + implementation("org.openjfx:javafx-controls:19:$platform") + implementation("org.openjfx:javafx-media:19:$platform") + implementation("org.openjfx:javafx-web:19:$platform") + implementation("org.openjfx:javafx-swing:19:$platform") + implementation(libs.kotlinx.coroutines.javafx) } } diff --git a/calf-ui/src/androidMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePickerState.android.kt b/calf-ui/src/androidMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePickerState.android.kt new file mode 100644 index 0000000..fb6def5 --- /dev/null +++ b/calf-ui/src/androidMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePickerState.android.kt @@ -0,0 +1,6 @@ +package com.mohamedrejeb.calf.ui.datepicker + +import androidx.compose.material3.CalendarLocale + +internal actual fun getCalendarLocalDefault(): CalendarLocale = + CalendarLocale.getDefault() diff --git a/calf-ui/src/androidMain/kotlin/com/mohamedrejeb/calf/ui/web/WebView.android.kt b/calf-ui/src/androidMain/kotlin/com.mohamedrejeb.calf.ui/web/WebView.android.kt similarity index 100% rename from calf-ui/src/androidMain/kotlin/com/mohamedrejeb/calf/ui/web/WebView.android.kt rename to calf-ui/src/androidMain/kotlin/com.mohamedrejeb.calf.ui/web/WebView.android.kt diff --git a/calf-ui/src/commonMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePicker.kt b/calf-ui/src/commonMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePicker.kt index a50e58a..d137c97 100644 --- a/calf-ui/src/commonMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePicker.kt +++ b/calf-ui/src/commonMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePicker.kt @@ -15,7 +15,7 @@ import androidx.compose.ui.unit.dp expect fun AdaptiveDatePicker( state: AdaptiveDatePickerState, modifier: Modifier = Modifier, - dateFormatter: DatePickerFormatter = remember { DatePickerFormatter() }, + dateFormatter: DatePickerFormatter = remember { DatePickerDefaults.dateFormatter() }, title: (@Composable () -> Unit)? = null, headline: (@Composable () -> Unit)? = null, showModeToggle: Boolean = true, diff --git a/calf-ui/src/commonMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePickerState.kt b/calf-ui/src/commonMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePickerState.kt index 07f48ed..ce2781b 100644 --- a/calf-ui/src/commonMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePickerState.kt +++ b/calf-ui/src/commonMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePickerState.kt @@ -13,21 +13,22 @@ fun rememberAdaptiveDatePickerState( yearRange: IntRange = DatePickerDefaults.YearRange, initialMaterialDisplayMode: DisplayMode = DisplayMode.Picker, initialUIKitDisplayMode: UIKitDisplayMode = UIKitDisplayMode.Picker, -): AdaptiveDatePickerState = rememberSaveable( - saver = AdaptiveDatePickerState.Saver() -) { - AdaptiveDatePickerState( - initialSelectedDateMillis = initialSelectedDateMillis, - initialDisplayedMonthMillis = initialDisplayedMonthMillis, - yearRange = yearRange, - initialMaterialDisplayMode = initialMaterialDisplayMode, - initialUIKitDisplayMode = initialUIKitDisplayMode - ) -} +): AdaptiveDatePickerState = + rememberSaveable( + saver = AdaptiveDatePickerState.Saver(), + ) { + AdaptiveDatePickerState( + initialSelectedDateMillis = initialSelectedDateMillis, + initialDisplayedMonthMillis = initialDisplayedMonthMillis, + yearRange = yearRange, + initialMaterialDisplayMode = initialMaterialDisplayMode, + initialUIKitDisplayMode = initialUIKitDisplayMode, + ) + } /** * A state object that can be hoisted to observe the date picker state. See - * [rememberDatePickerState]. + * [rememberAdaptiveDatePickerState]. * * The state's [selectedDateMillis] will provide a timestamp that represents the _start_ of the day. * @@ -42,7 +43,7 @@ fun rememberAdaptiveDatePickerState( * @param yearRange an [IntRange] that holds the year range that the date picker will be limited * to * @param initialMaterialDisplayMode an initial [DisplayMode] that this state will hold - * @see rememberDatePickerState + * @see rememberAdaptiveDatePickerState * @throws [IllegalArgumentException] if the initial selected date or displayed month represent * a year that is out of the year range. */ @@ -55,7 +56,6 @@ expect class AdaptiveDatePickerState( initialMaterialDisplayMode: DisplayMode, initialUIKitDisplayMode: UIKitDisplayMode, ) { - /** * A timestamp that represents the _start_ of the day of the selected date in _UTC_ milliseconds * from the epoch. @@ -64,7 +64,7 @@ expect class AdaptiveDatePickerState( * * @see [setSelection] */ - val selectedDateMillis: Long? + var selectedDateMillis: Long? /** * Sets the selected date. @@ -75,6 +75,10 @@ expect class AdaptiveDatePickerState( * @throws IllegalArgumentException in case the given timestamps do not fall within the year * range this state was created with. */ + @Deprecated( + message = "Use selectedDateMillis property instead", + replaceWith = ReplaceWith("selectedDateMillis = dateMillis"), + ) fun setSelection(dateMillis: Long?) /** @@ -93,19 +97,25 @@ expect class AdaptiveDatePickerState( @OptIn(ExperimentalMaterial3Api::class) internal val DisplayMode.value: Int - get() = when (this) { - DisplayMode.Picker -> 0 - DisplayMode.Input -> 1 - else -> -1 - } + get() = + when (this) { + DisplayMode.Picker -> 0 + DisplayMode.Input -> 1 + else -> -1 + } @OptIn(ExperimentalMaterial3Api::class) -internal fun displayModeFromValue(value: Int) = when (value) { - 0 -> DisplayMode.Picker - else -> DisplayMode.Input -} +internal fun displayModeFromValue(value: Int) = + when (value) { + 0 -> DisplayMode.Picker + else -> DisplayMode.Input + } -internal fun uiKitDisplayModeFromValue(value: Int) = when (value) { - 0 -> UIKitDisplayMode.Picker - else -> UIKitDisplayMode.Wheels -} \ No newline at end of file +internal fun uiKitDisplayModeFromValue(value: Int) = + when (value) { + 0 -> UIKitDisplayMode.Picker + else -> UIKitDisplayMode.Wheels + } + +@OptIn(ExperimentalMaterial3Api::class) +internal expect fun getCalendarLocalDefault(): CalendarLocale diff --git a/calf-ui/src/commonMain/kotlin/com.mohamedrejeb.calf.ui/toggle/CupertinoSwitch.kt b/calf-ui/src/commonMain/kotlin/com.mohamedrejeb.calf.ui/toggle/CupertinoSwitch.kt index b47dad0..1467aab 100644 --- a/calf-ui/src/commonMain/kotlin/com.mohamedrejeb.calf.ui/toggle/CupertinoSwitch.kt +++ b/calf-ui/src/commonMain/kotlin/com.mohamedrejeb.calf.ui/toggle/CupertinoSwitch.kt @@ -1,5 +1,3 @@ -@file:Suppress("INVISIBLE_MEMBER") - package com.mohamedrejeb.calf.ui.toggle import androidx.compose.animation.animateColorAsState @@ -19,12 +17,14 @@ import androidx.compose.foundation.shape.CircleShape import androidx.compose.material3.SwitchColors import androidx.compose.material3.SwitchDefaults import androidx.compose.runtime.Composable +import androidx.compose.runtime.Stable import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.BiasAlignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color import androidx.compose.ui.semantics.Role import androidx.compose.ui.unit.dp @@ -41,7 +41,7 @@ fun CupertinoSwitch( val isPressed by interactionSource.collectIsPressedAsState() val animatedAspectRatio by animateFloatAsState(if (isPressed) 1.25f else 1f) - val animatedBackground by animateColorAsState(colors.trackColor(enabled, checked).value) + val animatedBackground by animateColorAsState(colors.trackColor(enabled, checked)) val animatedAlignment by animateFloatAsState(if (checked) 1f else -1f) Column( @@ -67,10 +67,26 @@ fun CupertinoSwitch( .fillMaxHeight() .clip(CircleShape) .aspectRatio(animatedAspectRatio) - .background(colors.thumbColor(enabled, checked).value) + .background(colors.thumbColor(enabled, checked)) .align(BiasAlignment.Horizontal(animatedAlignment)) ) { thumbContent?.invoke() } } -} \ No newline at end of file +} + +@Stable +internal fun SwitchColors.trackColor(enabled: Boolean, checked: Boolean): Color = + if (enabled) { + if (checked) checkedTrackColor else uncheckedTrackColor + } else { + if (checked) disabledCheckedTrackColor else disabledUncheckedTrackColor + } + +@Stable +internal fun SwitchColors.thumbColor(enabled: Boolean, checked: Boolean): Color = + if (enabled) { + if (checked) checkedThumbColor else uncheckedThumbColor + } else { + if (checked) disabledCheckedThumbColor else disabledUncheckedThumbColor + } \ No newline at end of file diff --git a/calf-ui/src/desktopMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePickerState.desktop.kt b/calf-ui/src/desktopMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePickerState.desktop.kt new file mode 100644 index 0000000..573ec8d --- /dev/null +++ b/calf-ui/src/desktopMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePickerState.desktop.kt @@ -0,0 +1,6 @@ +package com.mohamedrejeb.calf.ui.datepicker + +import androidx.compose.material3.CalendarLocale + +internal actual fun getCalendarLocalDefault(): CalendarLocale = + CalendarLocale.getDefault() \ No newline at end of file diff --git a/calf-ui/src/desktopMain/kotlin/com/mohamedrejeb/calf/ui/web/WebView.desktop.kt b/calf-ui/src/desktopMain/kotlin/com.mohamedrejeb.calf.ui/web/WebView.desktop.kt similarity index 100% rename from calf-ui/src/desktopMain/kotlin/com/mohamedrejeb/calf/ui/web/WebView.desktop.kt rename to calf-ui/src/desktopMain/kotlin/com.mohamedrejeb.calf.ui/web/WebView.desktop.kt diff --git a/calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/datepicker/AdaptiveDatePicker.ios.kt b/calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePicker.ios.kt similarity index 96% rename from calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/datepicker/AdaptiveDatePicker.ios.kt rename to calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePicker.ios.kt index 888ddbd..85060fb 100644 --- a/calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/datepicker/AdaptiveDatePicker.ios.kt +++ b/calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePicker.ios.kt @@ -32,7 +32,7 @@ actual fun AdaptiveDatePicker( datePicker = datePicker, displayMode = state.initialUIKitDisplayMode, onSelectionChanged = { dateMillis -> - state.setSelection(dateMillis = dateMillis) + state.selectedDateMillis = dateMillis } ) } diff --git a/calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/datepicker/AdaptiveDatePickerState.ios.kt b/calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePickerState.ios.kt similarity index 56% rename from calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/datepicker/AdaptiveDatePickerState.ios.kt rename to calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePickerState.ios.kt index 2970c81..93b0912 100644 --- a/calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/datepicker/AdaptiveDatePickerState.ios.kt +++ b/calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePickerState.ios.kt @@ -3,10 +3,11 @@ package com.mohamedrejeb.calf.ui.datepicker import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.runtime.saveable.Saver +import platform.Foundation.currentLocale /** * A state object that can be hoisted to observe the date picker state. See - * [rememberDatePickerState]. + * [rememberAdaptiveDatePickerState]. * * The state's [selectedDateMillis] will provide a timestamp that represents the _start_ of the day. * @@ -21,21 +22,19 @@ import androidx.compose.runtime.saveable.Saver * @param yearRange an [IntRange] that holds the year range that the date picker will be limited * to * @param initialMaterialDisplayMode an initial [DisplayMode] that this state will hold - * @see rememberDatePickerState + * @see rememberAdaptiveDatePickerState * @throws [IllegalArgumentException] if the initial selected date or displayed month represent * a year that is out of the year range. */ @OptIn(ExperimentalMaterial3Api::class) @Stable actual class AdaptiveDatePickerState actual constructor( - private val initialSelectedDateMillis: Long?, - private val initialDisplayedMonthMillis: Long?, - private val yearRange: IntRange, - private val initialMaterialDisplayMode: DisplayMode, - internal val initialUIKitDisplayMode: UIKitDisplayMode + val initialSelectedDateMillis: Long?, + val initialDisplayedMonthMillis: Long?, + val yearRange: IntRange, + val initialMaterialDisplayMode: DisplayMode, + val initialUIKitDisplayMode: UIKitDisplayMode, ) { - internal var selectedDateMillisState by mutableStateOf(initialSelectedDateMillis) - /** * A timestamp that represents the _start_ of the day of the selected date in _UTC_ milliseconds * from the epoch. @@ -44,8 +43,7 @@ actual class AdaptiveDatePickerState actual constructor( * * @see [setSelection] */ - actual val selectedDateMillis: Long? - get() = selectedDateMillisState + actual var selectedDateMillis by mutableStateOf(initialSelectedDateMillis) /** * Sets the selected date. @@ -56,8 +54,15 @@ actual class AdaptiveDatePickerState actual constructor( * @throws IllegalArgumentException in case the given timestamps do not fall within the year * range this state was created with. */ - actual fun setSelection(@Suppress("AutoBoxing") dateMillis: Long?) { - selectedDateMillisState = dateMillis + @Deprecated( + message = "Use selectedDateMillis property instead", + replaceWith = ReplaceWith("selectedDateMillis = dateMillis"), + level = DeprecationLevel.ERROR, + ) + actual fun setSelection( + @Suppress("AutoBoxing") dateMillis: Long?, + ) { + selectedDateMillis = dateMillis } /** @@ -70,25 +75,28 @@ actual class AdaptiveDatePickerState actual constructor( /** * The default [Saver] implementation for [DatePickerState]. */ - actual fun Saver(): Saver = Saver( - save = { - listOf( - it.selectedDateMillis, - it.yearRange.first, - it.yearRange.last, - it.displayMode.value, - it.initialUIKitDisplayMode.value, - ) - }, - restore = { value -> - AdaptiveDatePickerState( - initialSelectedDateMillis = value[0] as Long?, - initialDisplayedMonthMillis = value[0] as Long?, - yearRange = IntRange(value[1] as Int, value[2] as Int), - initialMaterialDisplayMode = displayModeFromValue(value[3] as Int), - initialUIKitDisplayMode = uiKitDisplayModeFromValue(value[4] as Int), - ) - } - ) + actual fun Saver(): Saver = + Saver( + save = { + listOf( + it.selectedDateMillis, + it.yearRange.first, + it.yearRange.last, + it.displayMode.value, + it.initialUIKitDisplayMode.value, + ) + }, + restore = { value -> + AdaptiveDatePickerState( + initialSelectedDateMillis = value[0] as Long?, + initialDisplayedMonthMillis = value[0] as Long?, + yearRange = IntRange(value[1] as Int, value[2] as Int), + initialMaterialDisplayMode = displayModeFromValue(value[3] as Int), + initialUIKitDisplayMode = uiKitDisplayModeFromValue(value[4] as Int), + ) + }, + ) } -} \ No newline at end of file +} + +internal actual fun getCalendarLocalDefault(): CalendarLocale = CalendarLocale.currentLocale diff --git a/calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/datepicker/DatePickerManager.kt b/calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/DatePickerManager.kt similarity index 100% rename from calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/datepicker/DatePickerManager.kt rename to calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/DatePickerManager.kt diff --git a/calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/dialog/AdaptiveAlertDialog.ios.kt b/calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/dialog/AdaptiveAlertDialog.ios.kt similarity index 100% rename from calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/dialog/AdaptiveAlertDialog.ios.kt rename to calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/dialog/AdaptiveAlertDialog.ios.kt diff --git a/calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/dialog/AlertDialogManager.kt b/calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/dialog/AlertDialogManager.kt similarity index 100% rename from calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/dialog/AlertDialogManager.kt rename to calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/dialog/AlertDialogManager.kt diff --git a/calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/dropdown/AdaptiveDropDownMenu.ios.kt b/calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/dropdown/AdaptiveDropDownMenu.ios.kt similarity index 100% rename from calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/dropdown/AdaptiveDropDownMenu.ios.kt rename to calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/dropdown/AdaptiveDropDownMenu.ios.kt diff --git a/calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/progress/AdaptiveCircularProgressIndicator.ios.kt b/calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/progress/AdaptiveCircularProgressIndicator.ios.kt similarity index 100% rename from calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/progress/AdaptiveCircularProgressIndicator.ios.kt rename to calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/progress/AdaptiveCircularProgressIndicator.ios.kt diff --git a/calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/sheet/AdaptiveBottomSheet.ios.kt b/calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/sheet/AdaptiveBottomSheet.ios.kt similarity index 100% rename from calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/sheet/AdaptiveBottomSheet.ios.kt rename to calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/sheet/AdaptiveBottomSheet.ios.kt diff --git a/calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/sheet/BottomSheetManager.kt b/calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/sheet/BottomSheetManager.kt similarity index 100% rename from calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/sheet/BottomSheetManager.kt rename to calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/sheet/BottomSheetManager.kt diff --git a/calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/sheet/SheetState.ios.kt b/calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/sheet/SheetState.ios.kt similarity index 100% rename from calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/sheet/SheetState.ios.kt rename to calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/sheet/SheetState.ios.kt diff --git a/calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/timepicker/AdaptiveTimePicker.ios.kt b/calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/timepicker/AdaptiveTimePicker.ios.kt similarity index 100% rename from calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/timepicker/AdaptiveTimePicker.ios.kt rename to calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/timepicker/AdaptiveTimePicker.ios.kt diff --git a/calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/timepicker/AdaptiveTimePickerState.ios.kt b/calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/timepicker/AdaptiveTimePickerState.ios.kt similarity index 100% rename from calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/timepicker/AdaptiveTimePickerState.ios.kt rename to calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/timepicker/AdaptiveTimePickerState.ios.kt diff --git a/calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/timepicker/TimePickerManager.kt b/calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/timepicker/TimePickerManager.kt similarity index 100% rename from calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/timepicker/TimePickerManager.kt rename to calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/timepicker/TimePickerManager.kt diff --git a/calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/toggle/AdaptiveSwitch.ios.kt b/calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/toggle/AdaptiveSwitch.ios.kt similarity index 100% rename from calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/toggle/AdaptiveSwitch.ios.kt rename to calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/toggle/AdaptiveSwitch.ios.kt diff --git a/calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/utils/ColorHelper.kt b/calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/utils/ColorHelper.kt similarity index 100% rename from calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/utils/ColorHelper.kt rename to calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/utils/ColorHelper.kt diff --git a/calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/web/WebView.ios.kt b/calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/web/WebView.ios.kt similarity index 100% rename from calf-ui/src/iosMain/kotlin/com/mohamedrejeb/calf/ui/web/WebView.ios.kt rename to calf-ui/src/iosMain/kotlin/com.mohamedrejeb.calf.ui/web/WebView.ios.kt diff --git a/calf-ui/src/jsMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePickerState.js.kt b/calf-ui/src/jsMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePickerState.js.kt new file mode 100644 index 0000000..7985fb8 --- /dev/null +++ b/calf-ui/src/jsMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePickerState.js.kt @@ -0,0 +1,6 @@ +package com.mohamedrejeb.calf.ui.datepicker + +import androidx.compose.material3.CalendarLocale + +internal actual fun getCalendarLocalDefault(): CalendarLocale = + CalendarLocale.current \ No newline at end of file diff --git a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/web/WebView.js.kt b/calf-ui/src/jsMain/kotlin/com.mohamedrejeb.calf.ui/web/WebView.js.kt similarity index 100% rename from calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/web/WebView.js.kt rename to calf-ui/src/jsMain/kotlin/com.mohamedrejeb.calf.ui/web/WebView.js.kt diff --git a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/datepicker/AdaptiveDatePicker.js.kt b/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/datepicker/AdaptiveDatePicker.js.kt deleted file mode 100644 index b9db883..0000000 --- a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/datepicker/AdaptiveDatePicker.js.kt +++ /dev/null @@ -1,19 +0,0 @@ -package com.mohamedrejeb.calf.ui.datepicker - -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -actual fun AdaptiveDatePicker( - state: AdaptiveDatePickerState, - modifier: Modifier, - dateFormatter: DatePickerFormatter, - title: @Composable() (() -> Unit)?, - headline: @Composable() (() -> Unit)?, - showModeToggle: Boolean, - colors: DatePickerColors -) { - -} \ No newline at end of file diff --git a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/datepicker/AdaptiveDatePickerState.desktop.kt b/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/datepicker/AdaptiveDatePickerState.desktop.kt deleted file mode 100644 index 5e49e77..0000000 --- a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/datepicker/AdaptiveDatePickerState.desktop.kt +++ /dev/null @@ -1,100 +0,0 @@ -package com.mohamedrejeb.calf.ui.datepicker - -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.runtime.saveable.Saver - -/** - * A state object that can be hoisted to observe the date picker state. See - * [rememberDatePickerState]. - * - * The state's [selectedDateMillis] will provide a timestamp that represents the _start_ of the day. - * - * @param initialSelectedDateMillis timestamp in _UTC_ milliseconds from the epoch that - * represents an initial selection of a date. Provide a `null` to indicate no selection. Note - * that the state's - * [selectedDateMillis] will provide a timestamp that represents the _start_ of the day, which - * may be different than the provided initialSelectedDateMillis. - * @param initialDisplayedMonthMillis timestamp in _UTC_ milliseconds from the epoch that - * represents an initial selection of a month to be displayed to the user. In case `null` is - * provided, the displayed month would be the current one. - * @param yearRange an [IntRange] that holds the year range that the date picker will be limited - * to - * @param initialMaterialDisplayMode an initial [DisplayMode] that this state will hold - * @see rememberDatePickerState - * @throws [IllegalArgumentException] if the initial selected date or displayed month represent - * a year that is out of the year range. - */ -@OptIn(ExperimentalMaterial3Api::class) -@Stable -actual class AdaptiveDatePickerState actual constructor( - private val initialSelectedDateMillis: Long?, - private val initialDisplayedMonthMillis: Long?, - private val yearRange: IntRange, - private val initialMaterialDisplayMode: DisplayMode, - private val initialUIKitDisplayMode: UIKitDisplayMode -) { - - internal var selectedDateMillisState by mutableStateOf(initialSelectedDateMillis) - private set - - /** - * A timestamp that represents the _start_ of the day of the selected date in _UTC_ milliseconds - * from the epoch. - * - * In case no date was selected or provided, the state will hold a `null` value. - * - * @see [setSelection] - */ - actual val selectedDateMillis: Long? - get() = selectedDateMillisState - - /** - * Sets the selected date. - * - * @param dateMillis timestamp in _UTC_ milliseconds from the epoch that represents the date - * selection, or `null` to indicate no selection. - * - * @throws IllegalArgumentException in case the given timestamps do not fall within the year - * range this state was created with. - */ - actual fun setSelection(@Suppress("AutoBoxing") dateMillis: Long?) { - selectedDateMillisState = dateMillis - } - - /** - * A mutable state of [DisplayMode] that represents the current display mode of the UI - * (i.e. picker or input). - */ - actual var displayMode: DisplayMode - get() = initialMaterialDisplayMode - set(value) { - - } - - actual companion object { - /** - * The default [Saver] implementation for [DatePickerState]. - */ - actual fun Saver(): Saver = Saver( - save = { - listOf( - it.selectedDateMillis, - it.yearRange.first, - it.yearRange.last, - it.displayMode.value, - it.initialUIKitDisplayMode.value, - ) - }, - restore = { value -> - AdaptiveDatePickerState( - initialSelectedDateMillis = value[0] as Long?, - initialDisplayedMonthMillis = value[0] as Long?, - yearRange = IntRange(value[1] as Int, value[2] as Int), - initialMaterialDisplayMode = displayModeFromValue(value[3] as Int), - initialUIKitDisplayMode = uiKitDisplayModeFromValue(value[4] as Int), - ) - } - ) - } -} \ No newline at end of file diff --git a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/dialog/AdaptiveAlertDialog.js.kt b/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/dialog/AdaptiveAlertDialog.js.kt deleted file mode 100644 index 05c7d76..0000000 --- a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/dialog/AdaptiveAlertDialog.js.kt +++ /dev/null @@ -1,17 +0,0 @@ -package com.mohamedrejeb.calf.ui.dialog - -import androidx.compose.runtime.Composable -import androidx.compose.ui.window.DialogProperties - -@Composable -actual fun AdaptiveAlertDialog( - onConfirm: () -> Unit, - onDismiss: () -> Unit, - confirmText: String, - dismissText: String, - title: String, - text: String, - properties: DialogProperties -) { - -} \ No newline at end of file diff --git a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/dropdown/AdaptiveDropDownMenu.js.kt b/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/dropdown/AdaptiveDropDownMenu.js.kt deleted file mode 100644 index d55ab1f..0000000 --- a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/dropdown/AdaptiveDropDownMenu.js.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.mohamedrejeb.calf.ui.dropdown - -import androidx.compose.foundation.layout.BoxScope -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier - -@Composable -actual fun BoxScope.AdaptiveDropdownMenu( - expanded: Boolean, - onDismissRequest: () -> Unit, - modifier: Modifier -) { - -} \ No newline at end of file diff --git a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/progress/AdaptiveCircularProgressIndicator.js.kt b/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/progress/AdaptiveCircularProgressIndicator.js.kt deleted file mode 100644 index 9ec6d0d..0000000 --- a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/progress/AdaptiveCircularProgressIndicator.js.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.mohamedrejeb.calf.ui.progress - -import androidx.compose.material3.CircularProgressIndicator -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.StrokeCap -import androidx.compose.ui.unit.Dp - -@Composable -actual fun AdaptiveCircularProgressIndicator( - modifier: Modifier, - color: Color, - strokeWidth: Dp, - trackColor: Color, - strokeCap: StrokeCap, -) { - CircularProgressIndicator( - modifier = modifier, - color = color, - strokeWidth = strokeWidth, - trackColor = trackColor, - strokeCap = strokeCap, - ) -} \ No newline at end of file diff --git a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/sheet/AdaptiveBottomSheet.js.kt b/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/sheet/AdaptiveBottomSheet.js.kt deleted file mode 100644 index 465bf49..0000000 --- a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/sheet/AdaptiveBottomSheet.js.kt +++ /dev/null @@ -1,26 +0,0 @@ -package com.mohamedrejeb.calf.ui.sheet - -import androidx.compose.foundation.layout.ColumnScope -import androidx.compose.foundation.layout.WindowInsets -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.Shape -import androidx.compose.ui.unit.Dp - -@Composable -actual fun AdaptiveBottomSheet( - onDismissRequest: () -> Unit, - modifier: Modifier, - adaptiveSheetState: AdaptiveSheetState, - shape: Shape, - containerColor: Color, - contentColor: Color, - tonalElevation: Dp, - scrimColor: Color, - dragHandle: @Composable() (() -> Unit)?, - windowInsets: WindowInsets, - content: @Composable() (ColumnScope.() -> Unit) -) { - -} \ No newline at end of file diff --git a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/sheet/AdaptiveSheetState.js.kt b/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/sheet/AdaptiveSheetState.js.kt deleted file mode 100644 index 532bda1..0000000 --- a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/sheet/AdaptiveSheetState.js.kt +++ /dev/null @@ -1,70 +0,0 @@ -package com.mohamedrejeb.calf.ui.sheet - -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.SheetValue -import androidx.compose.runtime.Stable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.saveable.Saver -import androidx.compose.runtime.setValue -import kotlinx.coroutines.CancellationException - -@OptIn(ExperimentalMaterial3Api::class) -@Stable -actual class AdaptiveSheetState actual constructor( - skipPartiallyExpanded: Boolean, - initialValue: SheetValue, - confirmValueChange: (SheetValue) -> Boolean, - skipHiddenState: Boolean, -) { - init { - if (skipPartiallyExpanded) { - require(initialValue != SheetValue.PartiallyExpanded) { - "The initial value must not be set to PartiallyExpanded if skipPartiallyExpanded " + - "is set to true." - } - } - if (skipHiddenState) { - require(initialValue != SheetValue.Hidden) { - "The initial value must not be set to Hidden if skipHiddenState is set to true." - } - } - } - - var sheetValue by mutableStateOf(initialValue) - actual val currentValue: SheetValue get() = sheetValue - actual val isVisible get() = currentValue != SheetValue.Hidden - - /** - * Expand the bottom sheet with animation and suspend until it is [PartiallyExpanded] if defined - * else [Expanded]. - * @throws [CancellationException] if the animation is interrupted - */ - actual suspend fun show() { - sheetValue = SheetValue.Expanded - } - - /** - * Hide the bottom sheet with animation and suspend until it is fully hidden or animation has - * been cancelled. - * @throws [CancellationException] if the animation is interrupted - */ - actual suspend fun hide() { - sheetValue = SheetValue.Hidden - } - - actual companion object { - /** - * The default [Saver] implementation for [AdaptiveSheetState]. - */ - actual fun Saver( - skipPartiallyExpanded: Boolean, - confirmValueChange: (SheetValue) -> Boolean - ) = Saver( - save = { it.currentValue }, - restore = { savedValue -> - AdaptiveSheetState(skipPartiallyExpanded, savedValue, confirmValueChange, false) - } - ) - } -} \ No newline at end of file diff --git a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/timepicker/AdaptiveTimePicker.js.kt b/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/timepicker/AdaptiveTimePicker.js.kt deleted file mode 100644 index be3c44a..0000000 --- a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/timepicker/AdaptiveTimePicker.js.kt +++ /dev/null @@ -1,16 +0,0 @@ -package com.mohamedrejeb.calf.ui.timepicker - -import androidx.compose.material3.* -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -actual fun AdaptiveTimePicker( - state: AdaptiveTimePickerState, - modifier: Modifier, - colors: TimePickerColors, - layoutType: TimePickerLayoutType, -) { - -} \ No newline at end of file diff --git a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/timepicker/AdaptiveTimePickerState.js.kt b/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/timepicker/AdaptiveTimePickerState.js.kt deleted file mode 100644 index 3f58338..0000000 --- a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/timepicker/AdaptiveTimePickerState.js.kt +++ /dev/null @@ -1,67 +0,0 @@ -package com.mohamedrejeb.calf.ui.timepicker - -import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.TimePickerState -import androidx.compose.runtime.Stable -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.saveable.Saver -import androidx.compose.runtime.setValue - - -/** - * A class to handle state changes in a [TimePicker] - * - * @sample androidx.compose.material3.samples.TimePickerSample - * - * @param initialHour - * starting hour for this state, will be displayed in the time picker when launched - * Ranges from 0 to 23 - * @param initialMinute - * starting minute for this state, will be displayed in the time picker when launched. - * Ranges from 0 to 59 - * @param is24Hour The format for this time picker `false` for 12 hour format with an AM/PM toggle - * or `true` for 24 hour format without toggle. - */ -@Stable -actual class AdaptiveTimePickerState actual constructor( - initialHour: Int, - initialMinute: Int, - is24Hour: Boolean, -) { - init { - require(initialHour in 0..23) { "initialHour should in [0..23] range" } - require(initialHour in 0..59) { "initialMinute should be in [0..59] range" } - } - - internal var minuteState by mutableStateOf(initialMinute) - private set - internal var hourState by mutableStateOf(initialMinute) - private set - - actual val minute: Int get() = minuteState - actual val hour: Int get() = hourState - actual val is24hour: Boolean get() = is24hour - - actual companion object { - /** - * The default [Saver] implementation for [TimePickerState]. - */ - actual fun Saver(): Saver = Saver( - save = { - listOf( - it.hour, - it.minute, - it.is24hour - ) - }, - restore = { value -> - AdaptiveTimePickerState( - initialHour = value[0] as Int, - initialMinute = value[1] as Int, - is24Hour = value[2] as Boolean - ) - } - ) - } -} \ No newline at end of file diff --git a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/toggle/AdaptiveSwitch.js.kt b/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/toggle/AdaptiveSwitch.js.kt deleted file mode 100644 index 8ac8451..0000000 --- a/calf-ui/src/jsMain/kotlin/com/mohamedrejeb/calf/ui/toggle/AdaptiveSwitch.js.kt +++ /dev/null @@ -1,28 +0,0 @@ -package com.mohamedrejeb.calf.ui.toggle - -import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.material3.Switch -import androidx.compose.material3.SwitchColors -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier - -@Composable -actual fun AdaptiveSwitch( - checked: Boolean, - onCheckedChange: ((Boolean) -> Unit)?, - modifier: Modifier, - thumbContent: (@Composable () -> Unit)?, - enabled: Boolean, - colors: SwitchColors, - interactionSource: MutableInteractionSource, -) { - Switch( - checked = checked, - onCheckedChange = onCheckedChange, - modifier = modifier, - thumbContent = thumbContent, - enabled = enabled, - colors = colors, - interactionSource = interactionSource, - ) -} \ No newline at end of file diff --git a/calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/datepicker/AdaptiveDatePicker.material.kt b/calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePicker.material.kt similarity index 100% rename from calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/datepicker/AdaptiveDatePicker.material.kt rename to calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePicker.material.kt diff --git a/calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/datepicker/AdaptiveDatePickerState.material.kt b/calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePickerState.material.kt similarity index 52% rename from calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/datepicker/AdaptiveDatePickerState.material.kt rename to calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePickerState.material.kt index 88f9e40..0475c17 100644 --- a/calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/datepicker/AdaptiveDatePickerState.material.kt +++ b/calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/datepicker/AdaptiveDatePickerState.material.kt @@ -1,12 +1,14 @@ package com.mohamedrejeb.calf.ui.datepicker -import androidx.compose.material3.* -import androidx.compose.runtime.* +import androidx.compose.material3.DatePickerState +import androidx.compose.material3.DisplayMode +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.runtime.Stable import androidx.compose.runtime.saveable.Saver /** * A state object that can be hoisted to observe the date picker state. See - * [rememberDatePickerState]. + * [rememberAdaptiveDatePickerState]. * * The state's [selectedDateMillis] will provide a timestamp that represents the _start_ of the day. * @@ -21,29 +23,30 @@ import androidx.compose.runtime.saveable.Saver * @param yearRange an [IntRange] that holds the year range that the date picker will be limited * to * @param initialMaterialDisplayMode an initial [DisplayMode] that this state will hold - * @see rememberDatePickerState + * @see rememberAdaptiveDatePickerState * @throws [IllegalArgumentException] if the initial selected date or displayed month represent - * a year that is out of the year range. + * a year out of the year range. */ @OptIn(ExperimentalMaterial3Api::class) @Stable actual class AdaptiveDatePickerState actual constructor( - private val initialSelectedDateMillis: Long?, - private val initialDisplayedMonthMillis: Long?, - private val yearRange: IntRange, - private val initialMaterialDisplayMode: DisplayMode, - private val initialUIKitDisplayMode: UIKitDisplayMode + val initialSelectedDateMillis: Long?, + val initialDisplayedMonthMillis: Long?, + val yearRange: IntRange, + val initialMaterialDisplayMode: DisplayMode, + val initialUIKitDisplayMode: UIKitDisplayMode, ) { - /** * The date picker state that this state holds. */ - val datePickerState: DatePickerState = DatePickerState( - initialSelectedDateMillis = initialSelectedDateMillis, - initialDisplayedMonthMillis = initialDisplayedMonthMillis, - yearRange = yearRange, - initialDisplayMode = initialMaterialDisplayMode - ) + val datePickerState: DatePickerState = + DatePickerState( + locale = getCalendarLocalDefault(), + initialSelectedDateMillis = initialSelectedDateMillis, + initialDisplayedMonthMillis = initialDisplayedMonthMillis, + yearRange = yearRange, + initialDisplayMode = initialMaterialDisplayMode, + ) /** * A timestamp that represents the _start_ of the day of the selected date in _UTC_ milliseconds @@ -53,8 +56,11 @@ actual class AdaptiveDatePickerState actual constructor( * * @see [setSelection] */ - actual val selectedDateMillis: Long? + actual var selectedDateMillis: Long? get() = datePickerState.selectedDateMillis + set(value) { + datePickerState.selectedDateMillis = value + } /** * Sets the selected date. @@ -65,8 +71,15 @@ actual class AdaptiveDatePickerState actual constructor( * @throws IllegalArgumentException in case the given timestamps do not fall within the year * range this state was created with. */ - actual fun setSelection(@Suppress("AutoBoxing") dateMillis: Long?) = - datePickerState.setSelection(dateMillis) + @Deprecated( + message = "Use selectedDateMillis property instead", + replaceWith = ReplaceWith("selectedDateMillis = dateMillis"), + ) + actual fun setSelection( + @Suppress("AutoBoxing") dateMillis: Long?, + ) { + datePickerState.selectedDateMillis = dateMillis + } /** * A mutable state of [DisplayMode] that represents the current display mode of the UI @@ -82,25 +95,26 @@ actual class AdaptiveDatePickerState actual constructor( /** * The default [Saver] implementation for [DatePickerState]. */ - actual fun Saver(): Saver = Saver( - save = { - listOf( - it.selectedDateMillis, - it.yearRange.first, - it.yearRange.last, - it.displayMode.value, - it.initialUIKitDisplayMode.value, - ) - }, - restore = { value -> - AdaptiveDatePickerState( - initialSelectedDateMillis = value[0] as Long?, - initialDisplayedMonthMillis = value[0] as Long?, - yearRange = IntRange(value[1] as Int, value[2] as Int), - initialMaterialDisplayMode = displayModeFromValue(value[3] as Int), - initialUIKitDisplayMode = uiKitDisplayModeFromValue(value[4] as Int), - ) - } - ) + actual fun Saver(): Saver = + Saver( + save = { + listOf( + it.selectedDateMillis, + it.yearRange.first, + it.yearRange.last, + it.displayMode.value, + it.initialUIKitDisplayMode.value, + ) + }, + restore = { value -> + AdaptiveDatePickerState( + initialSelectedDateMillis = value[0] as Long?, + initialDisplayedMonthMillis = value[0] as Long?, + yearRange = IntRange(value[1] as Int, value[2] as Int), + initialMaterialDisplayMode = displayModeFromValue(value[3] as Int), + initialUIKitDisplayMode = uiKitDisplayModeFromValue(value[4] as Int), + ) + }, + ) } -} \ No newline at end of file +} diff --git a/calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/dialog/AdaptiveAlertDialog.material.kt b/calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/dialog/AdaptiveAlertDialog.material.kt similarity index 100% rename from calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/dialog/AdaptiveAlertDialog.material.kt rename to calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/dialog/AdaptiveAlertDialog.material.kt diff --git a/calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/dropdown/AdaptiveDropDownMenu.material.kt b/calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/dropdown/AdaptiveDropDownMenu.material.kt similarity index 100% rename from calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/dropdown/AdaptiveDropDownMenu.material.kt rename to calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/dropdown/AdaptiveDropDownMenu.material.kt diff --git a/calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/progress/AdaptiveCircularProgressIndicator.material.kt b/calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/progress/AdaptiveCircularProgressIndicator.material.kt similarity index 100% rename from calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/progress/AdaptiveCircularProgressIndicator.material.kt rename to calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/progress/AdaptiveCircularProgressIndicator.material.kt diff --git a/calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/sheet/AdaptiveBottomSheet.material.kt b/calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/sheet/AdaptiveBottomSheet.material.kt similarity index 87% rename from calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/sheet/AdaptiveBottomSheet.material.kt rename to calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/sheet/AdaptiveBottomSheet.material.kt index 86875bb..56c24ea 100644 --- a/calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/sheet/AdaptiveBottomSheet.material.kt +++ b/calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/sheet/AdaptiveBottomSheet.material.kt @@ -4,7 +4,7 @@ import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.WindowInsets import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ModalBottomSheet -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Shape @@ -21,9 +21,13 @@ actual fun AdaptiveBottomSheet( contentColor: Color, tonalElevation: Dp, scrimColor: Color, - dragHandle: @Composable() (() -> Unit)?, + dragHandle: + @Composable() + (() -> Unit)?, windowInsets: WindowInsets, - content: @Composable() (ColumnScope.() -> Unit) + content: + @Composable() + (ColumnScope.() -> Unit), ) { ModalBottomSheet( onDismissRequest = onDismissRequest, @@ -38,4 +42,4 @@ actual fun AdaptiveBottomSheet( windowInsets = windowInsets, content = content, ) -} \ No newline at end of file +} diff --git a/calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/sheet/AdaptiveSheetState.material.kt b/calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/sheet/AdaptiveSheetState.material.kt similarity index 100% rename from calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/sheet/AdaptiveSheetState.material.kt rename to calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/sheet/AdaptiveSheetState.material.kt diff --git a/calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/timepicker/AdaptiveTimePicker.material.kt b/calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/timepicker/AdaptiveTimePicker.material.kt similarity index 100% rename from calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/timepicker/AdaptiveTimePicker.material.kt rename to calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/timepicker/AdaptiveTimePicker.material.kt diff --git a/calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/timepicker/AdaptiveTimePickerState.material.kt b/calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/timepicker/AdaptiveTimePickerState.material.kt similarity index 100% rename from calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/timepicker/AdaptiveTimePickerState.material.kt rename to calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/timepicker/AdaptiveTimePickerState.material.kt diff --git a/calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/toggle/AdaptiveSwitch.material.kt b/calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/toggle/AdaptiveSwitch.material.kt similarity index 100% rename from calf-ui/src/materialMain/kotlin/com/mohamedrejeb/calf/ui/toggle/AdaptiveSwitch.material.kt rename to calf-ui/src/materialMain/kotlin/com.mohamedrejeb.calf.ui/toggle/AdaptiveSwitch.material.kt diff --git a/convention-plugins/build.gradle.kts b/convention-plugins/build.gradle.kts index 5e77211..08d502d 100644 --- a/convention-plugins/build.gradle.kts +++ b/convention-plugins/build.gradle.kts @@ -1,7 +1,20 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + plugins { `kotlin-dsl` } +java { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 +} + +tasks.withType { + kotlinOptions { + jvmTarget = "11" + } +} + dependencies { implementation(libs.nexus.publish) -} \ No newline at end of file +} diff --git a/convention-plugins/settings.gradle.kts b/convention-plugins/settings.gradle.kts index ffb42e8..7953214 100644 --- a/convention-plugins/settings.gradle.kts +++ b/convention-plugins/settings.gradle.kts @@ -1,3 +1,5 @@ +rootProject.name = "convention-plugins" + pluginManagement { repositories { google() @@ -7,6 +9,7 @@ pluginManagement { } dependencyResolutionManagement { + @Suppress("UnstableApiUsage") repositories { google() gradlePluginPortal() @@ -18,4 +21,4 @@ dependencyResolutionManagement { from(files("../gradle/libs.versions.toml")) } } -} \ No newline at end of file +} diff --git a/gradle.properties b/gradle.properties index 8d145a5..5dd79c4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ #Gradle org.gradle.jvmargs=-Xmx4048M -Dfile.encoding=UTF-8 -Dkotlin.daemon.jvm.options\="-Xmx4048M" -#org.gradle.caching=true -#org.gradle.configuration-cache=true +org.gradle.caching=true +org.gradle.parallel=true kotlin.code.style=official diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index eb8219a..9886250 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,20 +1,21 @@ [versions] -agp = "8.1.0" -kotlin = "1.9.21" -compose = "1.5.11" +agp = "8.2.2" +kotlin = "1.9.22" +compose = "1.6.0" kotlinx-serialization-json = "1.6.2" nexus-publish = "2.0.0-rc-1" +documentfile = "1.0.1" # For sample compose-compiler = "1.5.4" -activity-compose = "1.8.1" -navigation-compose = "2.7.5" +activity-compose = "1.8.2" +navigation-compose = "2.7.7" android-minSdk = "24" android-compileSdk = "34" -kotlinx-coroutines = "1.7.3" +kotlinx-coroutines = "1.8.0" appcompat = "1.6.1" android-lifecycle = "2.2.0" -play-services-location = "21.0.1" +play-services-location = "21.1.0" [libraries] kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } @@ -27,6 +28,9 @@ kotlinx-coroutines-javafx = { module = "org.jetbrains.kotlinx:kotlinx-coroutines kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization-json" } nexus-publish = { module = "io.github.gradle-nexus.publish-plugin:io.github.gradle-nexus.publish-plugin.gradle.plugin", version.ref = "nexus-publish" } +# Android +documentfile = { module = "androidx.documentfile:documentfile", version.ref = "documentfile" } + # For sample activity-compose = { module = "androidx.activity:activity-compose", version.ref = "activity-compose" } navigation-compose = { module = "androidx.navigation:navigation-compose", version.ref = "navigation-compose" } diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock index 51b7613..199de55 100644 --- a/kotlin-js-store/yarn.lock +++ b/kotlin-js-store/yarn.lock @@ -57,11 +57,51 @@ "@jridgewell/resolve-uri" "3.1.0" "@jridgewell/sourcemap-codec" "1.4.14" +"@js-joda/core@3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@js-joda/core/-/core-3.2.0.tgz#3e61e21b7b2b8a6be746df1335cf91d70db2a273" + integrity sha512-PMqgJ0sw5B7FKb2d5bWYIoxjri+QlW/Pys7+Rw82jSH0QN3rB05jZ/VrrsUdh1w4+i2kw9JOejXGq/KhDOX7Kg== + +"@leichtgewicht/ip-codec@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" + integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== + "@socket.io/component-emitter@~3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz#96116f2a912e0c02817345b3c10751069920d553" integrity sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg== +"@types/body-parser@*": + version "1.19.5" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" + integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bonjour@^3.5.9": + version "3.5.13" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.13.tgz#adf90ce1a105e81dd1f9c61fdc5afda1bfb92956" + integrity sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ== + dependencies: + "@types/node" "*" + +"@types/connect-history-api-fallback@^1.3.5": + version "1.5.4" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz#7de71645a103056b48ac3ce07b3520b819c1d5b3" + integrity sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.38" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== + dependencies: + "@types/node" "*" + "@types/cookie@^0.4.1": version "0.4.1" resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d" @@ -95,16 +135,123 @@ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194" integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA== +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": + version "4.17.43" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.43.tgz#10d8444be560cb789c4735aea5eac6e5af45df54" + integrity sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + +"@types/express@*", "@types/express@^4.17.13": + version "4.17.21" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" + integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/http-errors@*": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" + integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== + +"@types/http-proxy@^1.17.8": + version "1.17.14" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.14.tgz#57f8ccaa1c1c3780644f8a94f9c6b5000b5e2eec" + integrity sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w== + dependencies: + "@types/node" "*" + "@types/json-schema@*", "@types/json-schema@^7.0.8": version "7.0.12" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== +"@types/json-schema@^7.0.9": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + +"@types/mime@*": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.4.tgz#2198ac274de6017b44d941e00261d5bc6a0e0a45" + integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== + +"@types/mime@^1": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" + integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== + +"@types/node-forge@^1.3.0": + version "1.3.11" + resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.11.tgz#0972ea538ddb0f4d9c2fa0ec5db5724773a604da" + integrity sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ== + dependencies: + "@types/node" "*" + "@types/node@*", "@types/node@>=10.0.0": version "20.4.4" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.4.tgz#c79c7cc22c9d0e97a7944954c9e663bcbd92b0cb" integrity sha512-CukZhumInROvLq3+b5gLev+vgpsIqC2D0deQr/yS1WnxvmYLlJXZpaQrQiseMY+6xusl79E04UjWoqyr+t1/Ew== +"@types/qs@*": + version "6.9.12" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.12.tgz#afa96b383a3a6fdc859453a1892d41b607fc7756" + integrity sha512-bZcOkJ6uWrL0Qb2NAWKa7TBU+mJHPzhx9jjLL1KHF+XpzEcR7EXHvjbHlGtR/IsP1vyPrehuS6XqkmaePy//mg== + +"@types/range-parser@*": + version "1.2.7" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" + integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== + +"@types/retry@0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" + integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== + +"@types/send@*": + version "0.17.4" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" + integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + +"@types/serve-index@^1.9.1": + version "1.9.4" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.4.tgz#e6ae13d5053cb06ed36392110b4f9a49ac4ec898" + integrity sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug== + dependencies: + "@types/express" "*" + +"@types/serve-static@*", "@types/serve-static@^1.13.10": + version "1.15.5" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.5.tgz#15e67500ec40789a1e8c9defc2d32a896f05b033" + integrity sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ== + dependencies: + "@types/http-errors" "*" + "@types/mime" "*" + "@types/node" "*" + +"@types/sockjs@^0.3.33": + version "0.3.36" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.36.tgz#ce322cf07bcc119d4cbf7f88954f3a3bd0f67535" + integrity sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q== + dependencies: + "@types/node" "*" + +"@types/ws@^8.5.1": + version "8.5.10" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.10.tgz#4acfb517970853fa6574a3a6886791d04a396787" + integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== + dependencies: + "@types/node" "*" + "@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": version "1.11.6" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" @@ -256,7 +403,7 @@ abab@^2.0.6: resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== -accepts@~1.3.4: +accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: version "1.3.8" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== @@ -274,11 +421,25 @@ acorn@^8.7.1, acorn@^8.8.2: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== +ajv-keywords@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -289,11 +450,26 @@ ajv@^6.12.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^8.0.0, ajv@^8.9.0: + version "8.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + ansi-colors@4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== +ansi-html-community@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" @@ -319,6 +495,11 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" @@ -329,12 +510,17 @@ base64id@2.0.0, base64id@~2.0.0: resolved "https://registry.yarnpkg.com/base64id/-/base64id-2.0.0.tgz#2770ac6bc47d312af97a8bf9a634342e0cd25cb6" integrity sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog== +batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== + binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -body-parser@^1.19.0: +body-parser@1.20.2, body-parser@^1.19.0: version "1.20.2" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== @@ -352,6 +538,14 @@ body-parser@^1.19.0: type-is "~1.6.18" unpipe "1.0.0" +bonjour-service@^1.0.11: + version "1.2.1" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.2.1.tgz#eb41b3085183df3321da1264719fbada12478d02" + integrity sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw== + dependencies: + fast-deep-equal "^3.1.3" + multicast-dns "^7.2.5" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -394,6 +588,11 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== + bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" @@ -440,6 +639,21 @@ chokidar@3.5.3, chokidar@^3.5.1: optionalDependencies: fsevents "~2.3.2" +chokidar@^3.5.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" + integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + chrome-trace-event@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" @@ -475,7 +689,7 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -colorette@^2.0.14: +colorette@^2.0.10, colorette@^2.0.14: version "2.0.20" resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== @@ -490,11 +704,36 @@ commander@^2.20.0: resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== +compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + +compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +connect-history-api-fallback@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" + integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== + connect@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" @@ -505,16 +744,38 @@ connect@^3.7.0: parseurl "~1.3.3" utils-merge "1.0.1" -content-type@~1.0.5: +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-type@~1.0.4, content-type@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + cookie@~0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + cors@~2.8.5: version "2.8.5" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" @@ -549,7 +810,7 @@ debug@2.6.9: dependencies: ms "2.0.0" -debug@4.3.4, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: +debug@4.3.4, debug@^4.1.0, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -561,16 +822,38 @@ decamelize@^4.0.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== +default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" + +define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + depd@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== +depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + destroy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== +detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + di@^0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" @@ -581,6 +864,13 @@ diff@5.0.0: resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== +dns-packet@^5.2.2: + version "5.6.1" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.6.1.tgz#ae888ad425a9d1478a0674256ab866de1012cf2f" + integrity sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw== + dependencies: + "@leichtgewicht/ip-codec" "^2.0.1" + dom-serialize@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b" @@ -695,6 +985,11 @@ estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + eventemitter3@^4.0.0: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" @@ -705,12 +1000,64 @@ events@^3.2.0: resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +express@^4.17.3: + version "4.18.3" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.3.tgz#6870746f3ff904dee1819b82e4b51509afffb0d4" + integrity sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.2" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + extend@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -fast-deep-equal@^3.1.1: +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== @@ -725,6 +1072,13 @@ fastest-levenshtein@^1.0.12: resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== +faye-websocket@^0.11.3: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + fill-range@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" @@ -745,6 +1099,19 @@ finalhandler@1.1.2: statuses "~1.5.0" unpipe "~1.0.0" +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + find-up@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" @@ -781,6 +1148,16 @@ format-util@^1.0.5: resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg== +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" @@ -790,6 +1167,11 @@ fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" +fs-monkey@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.5.tgz#fe450175f0db0d7ea758102e1d84096acb925788" + integrity sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew== + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -820,6 +1202,11 @@ get-intrinsic@^1.0.2: has-proto "^1.0.1" has-symbols "^1.0.3" +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -861,6 +1248,11 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.10, resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== +handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + has-flag@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" @@ -888,6 +1280,26 @@ he@1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^2.3.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.4.0.tgz#edd0cee70402584c8c76cc2c0556db09d1f45061" + integrity sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ== + +http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== + http-errors@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" @@ -899,6 +1311,32 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" +http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-parser-js@>=0.5.1: + version "0.5.8" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" + integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== + +http-proxy-middleware@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== + dependencies: + "@types/http-proxy" "^1.17.8" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + http-proxy@^1.18.1: version "1.18.1" resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" @@ -908,6 +1346,11 @@ http-proxy@^1.18.1: follow-redirects "^1.0.0" requires-port "^1.0.0" +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -938,16 +1381,31 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + interpret@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4" integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ== +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +ipaddr.js@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.1.0.tgz#2119bc447ff8c257753b196fc5f1ce08a4cdf39f" + integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== + is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -962,6 +1420,11 @@ is-core-module@^2.13.0: dependencies: has "^1.0.3" +is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -989,6 +1452,11 @@ is-plain-obj@^2.1.0: resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -996,11 +1464,28 @@ is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + is-unicode-supported@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + isbinaryfile@^4.0.8: version "4.0.10" resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3" @@ -1042,6 +1527,11 @@ json-schema-traverse@^0.4.1: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -1114,6 +1604,14 @@ kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== +launch-editor@^2.6.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.6.1.tgz#f259c9ef95cbc9425620bbbd14b468fcdb4ffe3c" + integrity sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw== + dependencies: + picocolors "^1.0.0" + shell-quote "^1.8.1" + loader-runner@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" @@ -1162,28 +1660,68 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== +memfs@^3.4.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" + integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== + dependencies: + fs-monkey "^1.0.4" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -mime-db@1.52.0: +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + +micromatch@^4.0.2: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.27, mime-types@~2.1.24, mime-types@~2.1.34: +mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + mime@^2.5.2: version "2.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimalistic-assert@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + minimatch@5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" @@ -1252,6 +1790,14 @@ ms@2.1.3: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +multicast-dns@^7.2.5: + version "7.2.5" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" + integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== + dependencies: + dns-packet "^5.2.2" + thunky "^1.0.2" + nanoid@3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" @@ -1267,6 +1813,11 @@ neo-async@^2.6.2: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +node-forge@^1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + node-releases@^2.0.12: version "2.0.13" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" @@ -1277,6 +1828,13 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + object-assign@^4: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -1287,6 +1845,11 @@ object-inspect@^1.9.0: resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== +obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + on-finished@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" @@ -1301,6 +1864,11 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" +on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -1308,6 +1876,22 @@ once@^1.3.0: dependencies: wrappy "1" +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +open@^8.0.9: + version "8.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" + integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + p-limit@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" @@ -1336,12 +1920,20 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +p-retry@^4.5.0: + version "4.6.2" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" + integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== + dependencies: + "@types/retry" "0.12.0" + retry "^0.13.1" + p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -parseurl@~1.3.3: +parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== @@ -1356,7 +1948,7 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== -path-key@^3.1.0: +path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== @@ -1366,12 +1958,17 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== -picomatch@^2.0.4, picomatch@^2.2.1: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -1383,6 +1980,19 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + punycode@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" @@ -1407,7 +2017,7 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" -range-parser@^1.2.1: +range-parser@^1.2.1, range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== @@ -1422,6 +2032,28 @@ raw-body@2.5.2: iconv-lite "0.4.24" unpipe "1.0.0" +readable-stream@^2.0.1: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@^3.0.6: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -1441,6 +2073,11 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + requires-port@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" @@ -1467,6 +2104,11 @@ resolve@^1.20.0: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + rfdc@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" @@ -1479,7 +2121,12 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" -safe-buffer@^5.1.0: +safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -1498,6 +2145,48 @@ schema-utils@^3.1.1, schema-utils@^3.1.2: ajv "^6.12.5" ajv-keywords "^3.5.2" +schema-utils@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.2.0.tgz#70d7c93e153a273a805801882ebd3bff20d89c8b" + integrity sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.9.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.1.0" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== + +selfsigned@^2.1.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" + integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== + dependencies: + "@types/node-forge" "^1.3.0" + node-forge "^1" + +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + serialize-javascript@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -1512,6 +2201,34 @@ serialize-javascript@^6.0.1: dependencies: randombytes "^2.1.0" +serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + setprototypeof@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" @@ -1536,6 +2253,11 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +shell-quote@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" + integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== + side-channel@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -1545,6 +2267,11 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" +signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + socket.io-adapter@~2.5.2: version "2.5.2" resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz#5de9477c9182fdc171cd8c8364b9a8894ec75d12" @@ -1573,6 +2300,15 @@ socket.io@^4.4.1: socket.io-adapter "~2.5.2" socket.io-parser "~4.2.4" +sockjs@^0.3.24: + version "0.3.24" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== + dependencies: + faye-websocket "^0.11.3" + uuid "^8.3.2" + websocket-driver "^0.7.4" + source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" @@ -1600,12 +2336,35 @@ source-map@^0.6.0, source-map@^0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + +spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + statuses@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== -statuses@~1.5.0: +"statuses@>= 1.4.0 < 2", statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== @@ -1628,6 +2387,20 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -1635,6 +2408,11 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + strip-json-comments@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" @@ -1685,6 +2463,11 @@ terser@^5.16.8: commander "^2.20.0" source-map-support "~0.5.20" +thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + tmp@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" @@ -1747,12 +2530,22 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== -vary@^1: +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== @@ -1770,6 +2563,13 @@ watchpack@^2.4.0: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" +wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + webpack-cli@5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.1.0.tgz#abc4b1f44b50250f2632d8b8b536cfe2f6257891" @@ -1789,6 +2589,53 @@ webpack-cli@5.1.0: rechoir "^0.8.0" webpack-merge "^5.7.3" +webpack-dev-middleware@^5.3.1: + version "5.3.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" + integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== + dependencies: + colorette "^2.0.10" + memfs "^3.4.3" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-server@4.15.0: + version "4.15.0" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.15.0.tgz#87ba9006eca53c551607ea0d663f4ae88be7af21" + integrity sha512-HmNB5QeSl1KpulTBQ8UT4FPrByYyaLxpJoQ0+s7EvUrMc16m0ZS1sgb1XGqzmgCPk0c9y+aaXxn11tbLzuM7NQ== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" + "@types/serve-index" "^1.9.1" + "@types/serve-static" "^1.13.10" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.5.1" + ansi-html-community "^0.0.8" + bonjour-service "^1.0.11" + chokidar "^3.5.3" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^2.0.0" + default-gateway "^6.0.3" + express "^4.17.3" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.3" + ipaddr.js "^2.0.1" + launch-editor "^2.6.0" + open "^8.0.9" + p-retry "^4.5.0" + rimraf "^3.0.2" + schema-utils "^4.0.0" + selfsigned "^2.1.1" + serve-index "^1.9.1" + sockjs "^0.3.24" + spdy "^4.0.2" + webpack-dev-middleware "^5.3.1" + ws "^8.13.0" + webpack-merge@^4.1.5: version "4.2.2" resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d" @@ -1839,6 +2686,20 @@ webpack@5.82.0: watchpack "^2.4.0" webpack-sources "^3.2.3" +websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + which@^1.2.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -1877,6 +2738,11 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== +ws@^8.13.0: + version "8.16.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.16.0.tgz#d1cd774f36fbc07165066a60e40323eab6446fd4" + integrity sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ== + ws@~8.11.0: version "8.11.0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143" diff --git a/sample/android/src/main/AndroidManifest.xml b/sample/android/src/main/AndroidManifest.xml index 9e9f123..a4b94ef 100644 --- a/sample/android/src/main/AndroidManifest.xml +++ b/sample/android/src/main/AndroidManifest.xml @@ -25,7 +25,10 @@ + android:enableOnBackInvokedCallback="true" + android:theme="@style/Theme.AppCompat.Light.NoActionBar" + tools:targetApi="tiramisu" + > iosTarget.binaries.framework { baseName = "Common" @@ -34,41 +34,20 @@ kotlin { } } - sourceSets { - all { - languageSettings { - optIn("org.jetbrains.compose.resources.ExperimentalResourceApi") - } - } - - val commonMain by getting { - dependencies { - api(compose.runtime) - api(compose.foundation) - api(compose.material) - api(compose.material3) - implementation(compose.materialIconsExtended) - @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class) - implementation(compose.components.resources) + sourceSets.commonMain.dependencies { + api(compose.runtime) + api(compose.foundation) + api(compose.material) + api(compose.material3) + implementation(compose.materialIconsExtended) - // Calf - // This is possible thanks to `enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")` in `settings.gradle.kts - api(projects.calfUi) - implementation(projects.calfFilePicker) - implementation(projects.calfPermissions) - implementation(projects.calfNavigation) - } - } - - val androidMain by getting - - val desktopMain by getting - -// val jsMain by getting { -// dependencies {} -// } - - val iosMain by getting + // Calf + // This is possible thanks to `enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")` + // in `settings.gradle.kts + api(projects.calfUi) + implementation(projects.calfFilePicker) + implementation(projects.calfPermissions) + implementation(projects.calfNavigation) } } @@ -85,4 +64,4 @@ android { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } -} \ No newline at end of file +} diff --git a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/App.kt b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/App.kt index 17d7fb0..bd4e13e 100644 --- a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/App.kt +++ b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/App.kt @@ -3,7 +3,7 @@ package com.mohamedrejeb.calf.sample import androidx.compose.runtime.* import com.mohamedrejeb.calf.navigation.rememberNavController import com.mohamedrejeb.calf.sample.navigation.AppNavGraph -import com.mohamedrejeb.calf.sample.ui.theme.CalfTheme +import com.mohamedrejeb.calf.sample.screens.theme.CalfTheme @Composable fun App() = CalfTheme { diff --git a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/navigation/AppNavGraph.kt b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/navigation/AppNavGraph.kt index 1b60f3d..ce4d574 100644 --- a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/navigation/AppNavGraph.kt +++ b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/navigation/AppNavGraph.kt @@ -3,19 +3,19 @@ package com.mohamedrejeb.calf.sample.navigation import androidx.compose.runtime.Composable import com.mohamedrejeb.calf.navigation.AdaptiveNavHost import com.mohamedrejeb.calf.navigation.AdaptiveNavHostController -import com.mohamedrejeb.calf.sample.ui.AlertDialogScreen -import com.mohamedrejeb.calf.sample.ui.BottomSheetScreen -import com.mohamedrejeb.calf.sample.ui.DatePickerScreen -import com.mohamedrejeb.calf.sample.ui.DropDownMenuScreen -import com.mohamedrejeb.calf.sample.ui.FilePickerScreen -import com.mohamedrejeb.calf.sample.ui.HomeScreen -import com.mohamedrejeb.calf.sample.ui.ImagePickerScreen -import com.mohamedrejeb.calf.sample.ui.MapScreen -import com.mohamedrejeb.calf.sample.ui.PermissionScreen -import com.mohamedrejeb.calf.sample.ui.ProgressBarScreen -import com.mohamedrejeb.calf.sample.ui.SwitchScreen -import com.mohamedrejeb.calf.sample.ui.TimePickerScreen -import com.mohamedrejeb.calf.sample.ui.WebViewScreen +import com.mohamedrejeb.calf.sample.screens.AlertDialogScreen +import com.mohamedrejeb.calf.sample.screens.BottomSheetScreen +import com.mohamedrejeb.calf.sample.screens.DatePickerScreen +import com.mohamedrejeb.calf.sample.screens.DropDownMenuScreen +import com.mohamedrejeb.calf.sample.screens.FilePickerScreen +import com.mohamedrejeb.calf.sample.screens.HomeScreen +import com.mohamedrejeb.calf.sample.screens.ImagePickerScreen +import com.mohamedrejeb.calf.sample.screens.MapScreen +import com.mohamedrejeb.calf.sample.screens.PermissionScreen +import com.mohamedrejeb.calf.sample.screens.ProgressBarScreen +import com.mohamedrejeb.calf.sample.screens.SwitchScreen +import com.mohamedrejeb.calf.sample.screens.TimePickerScreen +import com.mohamedrejeb.calf.sample.screens.WebViewScreen @Composable fun AppNavGraph( diff --git a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/AlertDialogScreen.kt b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/AlertDialogScreen.kt similarity index 76% rename from sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/AlertDialogScreen.kt rename to sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/AlertDialogScreen.kt index 7a577b1..912799d 100644 --- a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/AlertDialogScreen.kt +++ b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/AlertDialogScreen.kt @@ -1,9 +1,7 @@ -package com.mohamedrejeb.calf.sample.ui +package com.mohamedrejeb.calf.sample.screens import androidx.compose.foundation.background -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* import androidx.compose.material3.* @@ -11,14 +9,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.mohamedrejeb.calf.ui.cupertino.CupertinoActivityIndicator -import com.mohamedrejeb.calf.ui.datepicker.AdaptiveDatePicker import com.mohamedrejeb.calf.ui.dialog.AdaptiveAlertDialog -import com.mohamedrejeb.calf.ui.progress.AdaptiveCircularProgressIndicator -import com.mohamedrejeb.calf.ui.sheet.AdaptiveBottomSheet -import com.mohamedrejeb.calf.ui.timepicker.AdaptiveTimePicker -import com.mohamedrejeb.calf.ui.timepicker.rememberAdaptiveTimePickerState -import kotlinx.coroutines.launch @Composable fun AlertDialogScreen( diff --git a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/BottomSheetScreen.kt b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/BottomSheetScreen.kt similarity index 86% rename from sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/BottomSheetScreen.kt rename to sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/BottomSheetScreen.kt index f9a225d..2692759 100644 --- a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/BottomSheetScreen.kt +++ b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/BottomSheetScreen.kt @@ -1,7 +1,6 @@ -package com.mohamedrejeb.calf.sample.ui +package com.mohamedrejeb.calf.sample.screens import androidx.compose.foundation.background -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material.icons.Icons @@ -11,14 +10,8 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.mohamedrejeb.calf.ui.cupertino.CupertinoActivityIndicator -import com.mohamedrejeb.calf.ui.datepicker.AdaptiveDatePicker -import com.mohamedrejeb.calf.ui.dialog.AdaptiveAlertDialog -import com.mohamedrejeb.calf.ui.progress.AdaptiveCircularProgressIndicator import com.mohamedrejeb.calf.ui.sheet.AdaptiveBottomSheet import com.mohamedrejeb.calf.ui.sheet.rememberAdaptiveSheetState -import com.mohamedrejeb.calf.ui.timepicker.AdaptiveTimePicker -import com.mohamedrejeb.calf.ui.timepicker.rememberAdaptiveTimePickerState import kotlinx.coroutines.launch @OptIn(ExperimentalMaterial3Api::class) diff --git a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/DatePickerScreen.kt b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/DatePickerScreen.kt similarity index 77% rename from sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/DatePickerScreen.kt rename to sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/DatePickerScreen.kt index 77e73f0..fc77a51 100644 --- a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/DatePickerScreen.kt +++ b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/DatePickerScreen.kt @@ -1,11 +1,9 @@ -package com.mohamedrejeb.calf.sample.ui +package com.mohamedrejeb.calf.sample.screens import androidx.compose.foundation.background -import androidx.compose.foundation.clickable import androidx.compose.foundation.gestures.Orientation import androidx.compose.foundation.gestures.scrollable import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.rememberScrollState import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* @@ -14,16 +12,8 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.mohamedrejeb.calf.ui.cupertino.CupertinoActivityIndicator import com.mohamedrejeb.calf.ui.datepicker.AdaptiveDatePicker import com.mohamedrejeb.calf.ui.datepicker.rememberAdaptiveDatePickerState -import com.mohamedrejeb.calf.ui.dialog.AdaptiveAlertDialog -import com.mohamedrejeb.calf.ui.progress.AdaptiveCircularProgressIndicator -import com.mohamedrejeb.calf.ui.sheet.AdaptiveBottomSheet -import com.mohamedrejeb.calf.ui.sheet.rememberAdaptiveSheetState -import com.mohamedrejeb.calf.ui.timepicker.AdaptiveTimePicker -import com.mohamedrejeb.calf.ui.timepicker.rememberAdaptiveTimePickerState -import kotlinx.coroutines.launch @OptIn(ExperimentalMaterial3Api::class) @Composable diff --git a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/DropDownMenuScreen.kt b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/DropDownMenuScreen.kt similarity index 97% rename from sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/DropDownMenuScreen.kt rename to sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/DropDownMenuScreen.kt index c34cc72..3e2d456 100644 --- a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/DropDownMenuScreen.kt +++ b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/DropDownMenuScreen.kt @@ -1,4 +1,4 @@ -package com.mohamedrejeb.calf.sample.ui +package com.mohamedrejeb.calf.sample.screens import androidx.compose.foundation.background import androidx.compose.foundation.layout.* diff --git a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/FilePickerScreen.kt b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/FilePickerScreen.kt similarity index 60% rename from sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/FilePickerScreen.kt rename to sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/FilePickerScreen.kt index eaaaddf..7360488 100644 --- a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/FilePickerScreen.kt +++ b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/FilePickerScreen.kt @@ -1,4 +1,4 @@ -package com.mohamedrejeb.calf.sample.ui +package com.mohamedrejeb.calf.sample.screens import androidx.compose.foundation.background import androidx.compose.foundation.layout.Column @@ -28,49 +28,57 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.mohamedrejeb.calf.io.name +import com.mohamedrejeb.calf.core.LocalPlatformContext +import com.mohamedrejeb.calf.io.getName import com.mohamedrejeb.calf.picker.FilePickerFileType import com.mohamedrejeb.calf.picker.FilePickerSelectionMode import com.mohamedrejeb.calf.picker.rememberFilePickerLauncher import com.mohamedrejeb.calf.ui.toggle.AdaptiveSwitch @Composable -fun FilePickerScreen( - navigateBack: () -> Unit -) { +fun FilePickerScreen(navigateBack: () -> Unit) { + val context = LocalPlatformContext.current + var fileNames by remember { mutableStateOf>(emptyList()) } + var isMultiple by remember { mutableStateOf(false) } - val singlePickerLauncher = rememberFilePickerLauncher( - type = FilePickerFileType.All, - selectionMode = FilePickerSelectionMode.Single, - onResult = { files -> - fileNames = files.map { it.name.orEmpty() } - }, - ) - val multiplePickerLauncher = rememberFilePickerLauncher( - type = FilePickerFileType.All, - selectionMode = FilePickerSelectionMode.Multiple, - onResult = { files -> - fileNames = files.map { it.name.orEmpty() } - }, - ) + + val singlePickerLauncher = + rememberFilePickerLauncher( + type = FilePickerFileType.All, + selectionMode = FilePickerSelectionMode.Single, + onResult = { files -> + fileNames = files.map { it.getName(context).orEmpty() } + }, + ) + + val multiplePickerLauncher = + rememberFilePickerLauncher( + type = FilePickerFileType.All, + selectionMode = FilePickerSelectionMode.Multiple, + onResult = { files -> + fileNames = files.map { it.getName(context).orEmpty() } + }, + ) Column( - modifier = Modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.background) - .windowInsetsPadding(WindowInsets.systemBars) - .windowInsetsPadding(WindowInsets.ime) - .verticalScroll(rememberScrollState()) + modifier = + Modifier + .fillMaxSize() + .background(MaterialTheme.colorScheme.background) + .windowInsetsPadding(WindowInsets.systemBars) + .windowInsetsPadding(WindowInsets.ime) + .verticalScroll(rememberScrollState()), ) { IconButton( onClick = { navigateBack() }, - modifier = Modifier - .padding(16.dp) + modifier = + Modifier + .padding(16.dp), ) { Icon( Icons.Filled.ArrowBackIosNew, @@ -79,11 +87,20 @@ fun FilePickerScreen( ) } - Row(Modifier.padding(16.dp)) { - Text("Select multiple files?", Modifier.weight(1f)) - AdaptiveSwitch(isMultiple, onCheckedChange = { checked -> - isMultiple = checked - }) + Row( + modifier = Modifier.padding(16.dp), + ) { + Text( + text = "Select multiple files?", + modifier = Modifier.weight(1f), + ) + + AdaptiveSwitch( + checked = isMultiple, + onCheckedChange = { checked -> + isMultiple = checked + }, + ) } Button( @@ -94,7 +111,7 @@ fun FilePickerScreen( singlePickerLauncher.launch() } }, - modifier = Modifier.padding(16.dp) + modifier = Modifier.padding(16.dp), ) { Text("Pick Files") } @@ -102,9 +119,11 @@ fun FilePickerScreen( Text( text = "Files picked:", style = MaterialTheme.typography.titleLarge, - modifier = Modifier.padding(16.dp) + modifier = Modifier.padding(16.dp), ) + Spacer(Modifier.height(8.dp)) + fileNames.forEach { Text( text = "- $it", @@ -112,4 +131,4 @@ fun FilePickerScreen( ) } } -} \ No newline at end of file +} diff --git a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/HomeScreen.kt b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/HomeScreen.kt similarity index 99% rename from sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/HomeScreen.kt rename to sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/HomeScreen.kt index 027a80b..eab1c08 100644 --- a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/HomeScreen.kt +++ b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/HomeScreen.kt @@ -1,4 +1,4 @@ -package com.mohamedrejeb.calf.sample.ui +package com.mohamedrejeb.calf.sample.screens import androidx.compose.foundation.background import androidx.compose.foundation.clickable diff --git a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/ImagePickerScreen.kt b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/ImagePickerScreen.kt new file mode 100644 index 0000000..34017e3 --- /dev/null +++ b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/ImagePickerScreen.kt @@ -0,0 +1,158 @@ +package com.mohamedrejeb.calf.sample.screens + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.ime +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBars +import androidx.compose.foundation.layout.windowInsetsPadding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.ArrowBackIosNew +import androidx.compose.material3.Button +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.unit.dp +import com.mohamedrejeb.calf.core.LocalPlatformContext +import com.mohamedrejeb.calf.io.readByteArray +import com.mohamedrejeb.calf.picker.FilePickerFileType +import com.mohamedrejeb.calf.picker.FilePickerSelectionMode +import com.mohamedrejeb.calf.picker.rememberFilePickerLauncher +import com.mohamedrejeb.calf.picker.toImageBitmap +import com.mohamedrejeb.calf.ui.toggle.AdaptiveSwitch + +@Composable +fun ImagePickerScreen(navigateBack: () -> Unit) { + val context = LocalPlatformContext.current + + var imageBitmaps by remember { + mutableStateOf>(emptyList()) + } + var isMultiple by remember { mutableStateOf(false) } + + val singlePickerLauncher = + rememberFilePickerLauncher( + type = FilePickerFileType.Image, + selectionMode = FilePickerSelectionMode.Single, + onResult = { files -> + imageBitmaps = + files.mapNotNull { + try { + it.readByteArray(context).toImageBitmap() + } catch (e: Exception) { + e.printStackTrace() + null + } + } + }, + ) + + val multiplePickerLauncher = + rememberFilePickerLauncher( + type = FilePickerFileType.Image, + selectionMode = FilePickerSelectionMode.Multiple, + onResult = { files -> + imageBitmaps = + files.mapNotNull { + try { + it.readByteArray(context).toImageBitmap() + } catch (e: Exception) { + e.printStackTrace() + null + } + } + }, + ) + + Column( + modifier = + Modifier + .fillMaxSize() + .background(MaterialTheme.colorScheme.background) + .windowInsetsPadding(WindowInsets.systemBars) + .windowInsetsPadding(WindowInsets.ime) + .verticalScroll(rememberScrollState()), + ) { + IconButton( + onClick = { + navigateBack() + }, + modifier = + Modifier + .padding(16.dp), + ) { + Icon( + Icons.Filled.ArrowBackIosNew, + contentDescription = "Back", + tint = MaterialTheme.colorScheme.onBackground, + ) + } + + Row( + modifier = Modifier.padding(16.dp), + ) { + Text( + text = "Select multiple images?", + modifier = Modifier.weight(1f), + ) + + AdaptiveSwitch( + checked = isMultiple, + onCheckedChange = { checked -> + isMultiple = checked + }, + ) + } + + Button( + onClick = { + if (isMultiple) { + multiplePickerLauncher.launch() + } else { + singlePickerLauncher.launch() + } + }, + modifier = Modifier.padding(16.dp), + ) { + Text( + text = "Pick image", + ) + } + + Text( + text = "Image picked:", + style = MaterialTheme.typography.titleLarge, + modifier = Modifier.padding(16.dp), + ) + + imageBitmaps.forEach { + Image( + bitmap = it, + contentDescription = "Image", + contentScale = ContentScale.FillWidth, + modifier = + Modifier + .fillMaxWidth() + .padding(16.dp) + .clip(MaterialTheme.shapes.medium), + ) + } + } +} diff --git a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/MapScreen.kt b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/MapScreen.kt similarity index 79% rename from sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/MapScreen.kt rename to sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/MapScreen.kt index 07033e0..ed282e0 100644 --- a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/MapScreen.kt +++ b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/MapScreen.kt @@ -1,9 +1,6 @@ -package com.mohamedrejeb.calf.sample.ui +package com.mohamedrejeb.calf.sample.screens -import androidx.compose.foundation.Image import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.gestures.detectDragGestures import androidx.compose.foundation.layout.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* @@ -11,21 +8,11 @@ import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.drawBehind -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.graphics.Canvas -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.ImageBitmap -import androidx.compose.ui.graphics.Paint -import androidx.compose.ui.graphics.drawscope.drawIntoCanvas -import androidx.compose.ui.graphics.nativeCanvas -import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.unit.dp import com.mohamedrejeb.calf.permissions.ExperimentalPermissionsApi import com.mohamedrejeb.calf.permissions.Permission import com.mohamedrejeb.calf.permissions.isGranted import com.mohamedrejeb.calf.permissions.rememberPermissionState -import kotlin.random.Random @OptIn(ExperimentalPermissionsApi::class) @Composable diff --git a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/PermissionsScreen.kt b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/PermissionsScreen.kt similarity index 76% rename from sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/PermissionsScreen.kt rename to sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/PermissionsScreen.kt index 9649c6f..109fe1c 100644 --- a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/PermissionsScreen.kt +++ b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/PermissionsScreen.kt @@ -1,7 +1,6 @@ -package com.mohamedrejeb.calf.sample.ui +package com.mohamedrejeb.calf.sample.screens import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets @@ -33,27 +32,40 @@ import com.mohamedrejeb.calf.permissions.isGranted import com.mohamedrejeb.calf.permissions.rememberPermissionState @Composable -fun PermissionScreen( - navigateBack: () -> Unit -) { +fun PermissionScreen(navigateBack: () -> Unit) { Box( - modifier = Modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.background) - .windowInsetsPadding(WindowInsets.systemBars) - .windowInsetsPadding(WindowInsets.ime) + modifier = + Modifier + .fillMaxSize() + .background(MaterialTheme.colorScheme.background) + .windowInsetsPadding(WindowInsets.systemBars) + .windowInsetsPadding(WindowInsets.ime), ) { + LazyColumn( + horizontalAlignment = Alignment.CenterHorizontally, + modifier = + Modifier + .fillMaxSize() + .padding(16.dp), + ) { + items(Permission.entries) { permission -> + PermissionItem(permission = permission) + } + } + IconButton( onClick = { navigateBack() }, - colors = IconButtonDefaults.iconButtonColors( - contentColor = MaterialTheme.colorScheme.onBackground, - containerColor = MaterialTheme.colorScheme.surface, - ), - modifier = Modifier - .align(Alignment.TopStart) - .padding(16.dp) + colors = + IconButtonDefaults.iconButtonColors( + contentColor = MaterialTheme.colorScheme.onBackground, + containerColor = MaterialTheme.colorScheme.surface, + ), + modifier = + Modifier + .align(Alignment.TopStart) + .padding(16.dp), ) { Icon( Icons.Filled.ArrowBackIosNew, @@ -61,17 +73,6 @@ fun PermissionScreen( tint = MaterialTheme.colorScheme.onBackground, ) } - - LazyColumn( - horizontalAlignment = Alignment.CenterHorizontally, - modifier = Modifier - .fillMaxSize() - .padding(16.dp), - ) { - items(Permission.entries) { permission -> - PermissionItem(permission = permission) - } - } } } @@ -89,4 +90,4 @@ private fun LazyItemScope.PermissionItem(permission: Permission) { } Spacer(modifier = Modifier.height(16.dp)) Divider() -} \ No newline at end of file +} diff --git a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/ProgressBarScreen.kt b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/ProgressBarScreen.kt similarity index 72% rename from sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/ProgressBarScreen.kt rename to sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/ProgressBarScreen.kt index 16c0f25..6deb0b4 100644 --- a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/ProgressBarScreen.kt +++ b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/ProgressBarScreen.kt @@ -1,9 +1,7 @@ -package com.mohamedrejeb.calf.sample.ui +package com.mohamedrejeb.calf.sample.screens import androidx.compose.foundation.background -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* import androidx.compose.material3.* @@ -11,15 +9,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.mohamedrejeb.calf.ui.cupertino.CupertinoActivityIndicator -import com.mohamedrejeb.calf.ui.datepicker.AdaptiveDatePicker -import com.mohamedrejeb.calf.ui.dialog.AdaptiveAlertDialog import com.mohamedrejeb.calf.ui.progress.AdaptiveCircularProgressIndicator -import com.mohamedrejeb.calf.ui.sheet.AdaptiveBottomSheet -import com.mohamedrejeb.calf.ui.sheet.rememberAdaptiveSheetState -import com.mohamedrejeb.calf.ui.timepicker.AdaptiveTimePicker -import com.mohamedrejeb.calf.ui.timepicker.rememberAdaptiveTimePickerState -import kotlinx.coroutines.launch @Composable fun ProgressBarScreen( diff --git a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/SwitchScreen.kt b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/SwitchScreen.kt similarity index 72% rename from sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/SwitchScreen.kt rename to sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/SwitchScreen.kt index 9dee21a..63c227e 100644 --- a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/SwitchScreen.kt +++ b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/SwitchScreen.kt @@ -1,9 +1,7 @@ -package com.mohamedrejeb.calf.sample.ui +package com.mohamedrejeb.calf.sample.screens import androidx.compose.foundation.background -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* import androidx.compose.material3.* @@ -11,17 +9,7 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.mohamedrejeb.calf.ui.cupertino.CupertinoActivityIndicator -import com.mohamedrejeb.calf.ui.datepicker.AdaptiveDatePicker -import com.mohamedrejeb.calf.ui.dialog.AdaptiveAlertDialog -import com.mohamedrejeb.calf.ui.progress.AdaptiveCircularProgressIndicator -import com.mohamedrejeb.calf.ui.sheet.AdaptiveBottomSheet -import com.mohamedrejeb.calf.ui.sheet.rememberAdaptiveSheetState -import com.mohamedrejeb.calf.ui.timepicker.AdaptiveTimePicker -import com.mohamedrejeb.calf.ui.timepicker.rememberAdaptiveTimePickerState import com.mohamedrejeb.calf.ui.toggle.AdaptiveSwitch -import com.mohamedrejeb.calf.ui.toggle.CupertinoSwitch -import kotlinx.coroutines.launch @OptIn(ExperimentalMaterial3Api::class) @Composable diff --git a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/TimePickerScreen.kt b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/TimePickerScreen.kt similarity index 74% rename from sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/TimePickerScreen.kt rename to sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/TimePickerScreen.kt index f61273f..64b00f1 100644 --- a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/TimePickerScreen.kt +++ b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/TimePickerScreen.kt @@ -1,9 +1,7 @@ -package com.mohamedrejeb.calf.sample.ui +package com.mohamedrejeb.calf.sample.screens import androidx.compose.foundation.background -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.* import androidx.compose.material3.* @@ -11,16 +9,8 @@ import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp -import com.mohamedrejeb.calf.ui.cupertino.CupertinoActivityIndicator -import com.mohamedrejeb.calf.ui.datepicker.AdaptiveDatePicker -import com.mohamedrejeb.calf.ui.datepicker.rememberAdaptiveDatePickerState -import com.mohamedrejeb.calf.ui.dialog.AdaptiveAlertDialog -import com.mohamedrejeb.calf.ui.progress.AdaptiveCircularProgressIndicator -import com.mohamedrejeb.calf.ui.sheet.AdaptiveBottomSheet -import com.mohamedrejeb.calf.ui.sheet.rememberAdaptiveSheetState import com.mohamedrejeb.calf.ui.timepicker.AdaptiveTimePicker import com.mohamedrejeb.calf.ui.timepicker.rememberAdaptiveTimePickerState -import kotlinx.coroutines.launch @OptIn(ExperimentalMaterial3Api::class) @Composable diff --git a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/WebViewScreen.kt b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/WebViewScreen.kt similarity index 98% rename from sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/WebViewScreen.kt rename to sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/WebViewScreen.kt index 7142a37..30424db 100644 --- a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/WebViewScreen.kt +++ b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/screens/WebViewScreen.kt @@ -1,4 +1,4 @@ -package com.mohamedrejeb.calf.sample.ui +package com.mohamedrejeb.calf.sample.screens import androidx.compose.foundation.background import androidx.compose.foundation.layout.* diff --git a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui.theme/Color.kt b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui.theme/Color.kt index e8f127c..5ace6d2 100644 --- a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui.theme/Color.kt +++ b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui.theme/Color.kt @@ -1,4 +1,4 @@ -package com.mohamedrejeb.calf.sample.ui.theme +package com.mohamedrejeb.calf.sample.screens.theme import androidx.compose.ui.graphics.Color diff --git a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui.theme/Theme.kt b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui.theme/Theme.kt index 54ce588..cf4ba1d 100644 --- a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui.theme/Theme.kt +++ b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui.theme/Theme.kt @@ -1,4 +1,4 @@ -package com.mohamedrejeb.calf.sample.ui.theme +package com.mohamedrejeb.calf.sample.screens.theme import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.material3.MaterialTheme diff --git a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui.theme/Typography.kt b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui.theme/Typography.kt index 0e64806..a2c7feb 100644 --- a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui.theme/Typography.kt +++ b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui.theme/Typography.kt @@ -1,4 +1,4 @@ -package com.mohamedrejeb.calf.sample.ui.theme +package com.mohamedrejeb.calf.sample.screens.theme import androidx.compose.material3.Typography diff --git a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/ImagePickerScreen.kt b/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/ImagePickerScreen.kt deleted file mode 100644 index d19fdac..0000000 --- a/sample/common/src/commonMain/kotlin/com.mohamedrejeb.calf.sample/ui/ImagePickerScreen.kt +++ /dev/null @@ -1,121 +0,0 @@ -package com.mohamedrejeb.calf.sample.ui - -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.ImageBitmap -import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.unit.dp -import com.mohamedrejeb.calf.io.readByteArray -import com.mohamedrejeb.calf.picker.FilePickerSelectionMode -import com.mohamedrejeb.calf.picker.FilePickerFileType -import com.mohamedrejeb.calf.picker.rememberFilePickerLauncher -import com.mohamedrejeb.calf.picker.toImageBitmap -import com.mohamedrejeb.calf.ui.toggle.AdaptiveSwitch - -@Composable -fun ImagePickerScreen( - navigateBack: () -> Unit -) { - var imageBitmaps by remember { - mutableStateOf>(emptyList()) - } - var isMultiple by remember { mutableStateOf(false) } - val singlePickerLauncher = rememberFilePickerLauncher( - type = FilePickerFileType.Image, - selectionMode = FilePickerSelectionMode.Single, - onResult = { files -> - imageBitmaps = files.mapNotNull { - try { - it.readByteArray().toImageBitmap() - } catch (e: Exception) { - e.printStackTrace() - null - } - } - }, - ) - val multiplePickerLauncher = rememberFilePickerLauncher( - type = FilePickerFileType.Image, - selectionMode = FilePickerSelectionMode.Multiple, - onResult = { files -> - imageBitmaps = files.mapNotNull { - try { - it.readByteArray().toImageBitmap() - } catch (e: Exception) { - e.printStackTrace() - null - } - } - }, - ) - - Column( - modifier = Modifier - .fillMaxSize() - .background(MaterialTheme.colorScheme.background) - .windowInsetsPadding(WindowInsets.systemBars) - .windowInsetsPadding(WindowInsets.ime) - .verticalScroll(rememberScrollState()) - ) { - IconButton( - onClick = { - navigateBack() - }, - modifier = Modifier - .padding(16.dp) - ) { - Icon( - Icons.Filled.ArrowBackIosNew, - contentDescription = "Back", - tint = MaterialTheme.colorScheme.onBackground, - ) - } - - Row(Modifier.padding(16.dp)) { - Text("Select multiple images?", Modifier.weight(1f)) - AdaptiveSwitch(isMultiple, onCheckedChange = { checked -> - isMultiple = checked - }) - } - - Button( - onClick = { - if (isMultiple) { - multiplePickerLauncher.launch() - } else { - singlePickerLauncher.launch() - } - }, - modifier = Modifier.padding(16.dp) - ) { - Text("Pick image") - } - - Text( - text = "Image picked:", - style = MaterialTheme.typography.titleLarge, - modifier = Modifier.padding(16.dp) - ) - - imageBitmaps.forEach { - Image( - bitmap = it, - contentDescription = "Image", - contentScale = ContentScale.FillWidth, - modifier = Modifier - .fillMaxWidth() - .padding(16.dp) - .clip(MaterialTheme.shapes.medium) - ) - } - } -} \ No newline at end of file diff --git a/sample/web/build.gradle.kts b/sample/web/build.gradle.kts index 3c61133..fb119f3 100644 --- a/sample/web/build.gradle.kts +++ b/sample/web/build.gradle.kts @@ -8,16 +8,15 @@ kotlin { browser() binaries.executable() } - sourceSets { - val jsMain by getting { - dependencies { - implementation(compose.ui) - implementation(project(":sample:common")) - } - } + + sourceSets.jsMain.dependencies { + implementation(projects.sample.common) + + implementation(compose.ui) + implementation(compose.html.core) } } compose.experimental { web.application {} -} \ No newline at end of file +} diff --git a/sample/web/src/jsMain/kotlin/Main.kt b/sample/web/src/jsMain/kotlin/Main.kt index 1af6a8d..1ac5dd8 100644 --- a/sample/web/src/jsMain/kotlin/Main.kt +++ b/sample/web/src/jsMain/kotlin/Main.kt @@ -1,16 +1,23 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier -import androidx.compose.ui.window.Window +import androidx.compose.ui.window.CanvasBasedWindow import com.mohamedrejeb.calf.sample.App import org.jetbrains.skiko.wasm.onWasmReady +@OptIn(ExperimentalComposeUiApi::class) fun main() { onWasmReady { - Window("Calf") { - Box(Modifier.fillMaxSize()) { + CanvasBasedWindow( + title = "Calf", + canvasElementId = "ComposeTarget", + ) { + Box( + modifier = Modifier.fillMaxSize(), + ) { App() } } } -} \ No newline at end of file +} diff --git a/sample/web/src/jsMain/resources/index.html b/sample/web/src/jsMain/resources/index.html index d34c6fd..56add1a 100644 --- a/sample/web/src/jsMain/resources/index.html +++ b/sample/web/src/jsMain/resources/index.html @@ -2,23 +2,11 @@ - Compose Rich Editor - + Calf + - - - + \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index ea49013..c15c016 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,3 +1,5 @@ +rootProject.name = "Calf" + pluginManagement { includeBuild("convention-plugins") repositories { @@ -13,6 +15,7 @@ pluginManagement { } dependencyResolutionManagement { + @Suppress("UnstableApiUsage") repositories { google() mavenCentral() @@ -20,8 +23,9 @@ dependencyResolutionManagement { } } -rootProject.name = "Calf" include( + // Artifact modules + ":calf-core", ":calf-ui", ":calf-sf-symbols", ":calf-navigation", @@ -30,11 +34,11 @@ include( ":calf-permissions", ":calf-geo", ":calf-maps", - + // Sample modules ":sample:android", ":sample:desktop", -// ":sample:web", + ":sample:web", ":sample:common", ) -enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") \ No newline at end of file +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")