From bccff22866dc6834dbea9c415aa788aa3c21d8c8 Mon Sep 17 00:00:00 2001 From: jay-tux Date: Wed, 19 Feb 2025 09:27:21 +0100 Subject: [PATCH] Initial --- .gitignore | 20 ++ README.md | 11 + build.gradle.kts | 7 + composeApp/build.gradle.kts | 51 ++++ .../gradle/wrapper/gradle-wrapper.properties | 6 + .../drawable/compose-multiplatform.xml | 36 +++ .../kotlin/com/jaytux/grader/App.kt | 23 ++ .../kotlin/com/jaytux/grader/data/DSL.kt | 86 ++++++ .../kotlin/com/jaytux/grader/data/Database.kt | 22 ++ .../kotlin/com/jaytux/grader/data/Entities.kt | 85 ++++++ .../kotlin/com/jaytux/grader/main.kt | 18 ++ .../kotlin/com/jaytux/grader/ui/Courses.kt | 95 +++++++ .../com/jaytux/grader/viewmodel/DbState.kt | 43 +++ gradle.properties | 6 + gradle/libs.versions.toml | 29 ++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43504 bytes gradle/wrapper/gradle-wrapper.properties | 7 + gradlew | 252 ++++++++++++++++++ gradlew.bat | 94 +++++++ settings.gradle.kts | 31 +++ 20 files changed, 922 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 build.gradle.kts create mode 100644 composeApp/build.gradle.kts create mode 100644 composeApp/gradle/wrapper/gradle-wrapper.properties create mode 100644 composeApp/src/commonMain/composeResources/drawable/compose-multiplatform.xml create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/App.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/DSL.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/Database.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/Entities.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/main.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Courses.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/DbState.kt create mode 100644 gradle.properties create mode 100644 gradle/libs.versions.toml create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle.kts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a5ee101 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +*.iml +.kotlin +.gradle +**/build/ +xcuserdata +!src/**/build/ +local.properties +.idea +.fleet +.DS_Store +captures +.externalNativeBuild +.cxx +*.xcodeproj/* +!*.xcodeproj/project.pbxproj +!*.xcodeproj/xcshareddata/ +!*.xcodeproj/project.xcworkspace/ +!*.xcworkspace/contents.xcworkspacedata +**/xcshareddata/WorkspaceSettings.xcsettings +**/grader.db \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..ce5734e --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +This is a Kotlin Multiplatform project targeting Desktop. + +* `/composeApp` is for code that will be shared across your Compose Multiplatform applications. + It contains several subfolders: + - `commonMain` is for code that’s common for all targets. + - Other folders are for Kotlin code that will be compiled for only the platform indicated in the folder name. + For example, if you want to use Apple’s CoreCrypto for the iOS part of your Kotlin app, + `iosMain` would be the right folder for such calls. + + +Learn more about [Kotlin Multiplatform](https://www.jetbrains.com/help/kotlin-multiplatform-dev/get-started.html)… \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..7d61caf --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + // this is necessary to avoid the plugins to be loaded multiple times + // in each subproject's classloader + alias(libs.plugins.composeMultiplatform) apply false + alias(libs.plugins.composeCompiler) apply false + alias(libs.plugins.kotlinMultiplatform) apply false +} \ No newline at end of file diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts new file mode 100644 index 0000000..a6573c5 --- /dev/null +++ b/composeApp/build.gradle.kts @@ -0,0 +1,51 @@ +import org.jetbrains.compose.desktop.application.dsl.TargetFormat + +plugins { + alias(libs.plugins.kotlinMultiplatform) + alias(libs.plugins.composeMultiplatform) + alias(libs.plugins.composeCompiler) +} + +kotlin { + jvm("desktop") + + sourceSets { + val desktopMain by getting + + commonMain.dependencies { + implementation(compose.runtime) + implementation(compose.foundation) + implementation(compose.material) + implementation(compose.ui) + implementation(compose.components.resources) + implementation(compose.components.uiToolingPreview) + implementation(libs.androidx.lifecycle.viewmodel) + implementation(libs.androidx.lifecycle.runtime.compose) + implementation(libs.material3.core) + implementation(libs.sl4j) + } + desktopMain.dependencies { + implementation(compose.desktop.currentOs) + implementation(libs.kotlinx.coroutines.swing) + implementation(libs.exposed.core) + implementation(libs.exposed.jdbc) + implementation(libs.exposed.dao) + implementation(libs.exposed.kotlin.datetime) + implementation(libs.sqlite) + implementation(libs.material3.desktop) + } + } +} + + +compose.desktop { + application { + mainClass = "com.jaytux.grader.MainKt" + + nativeDistributions { + targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) + packageName = "com.jaytux.grader" + packageVersion = "1.0.0" + } + } +} diff --git a/composeApp/gradle/wrapper/gradle-wrapper.properties b/composeApp/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..1fd731f --- /dev/null +++ b/composeApp/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Tue Feb 18 19:10:58 CET 2025 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/composeApp/src/commonMain/composeResources/drawable/compose-multiplatform.xml b/composeApp/src/commonMain/composeResources/drawable/compose-multiplatform.xml new file mode 100644 index 0000000..c0bcfb2 --- /dev/null +++ b/composeApp/src/commonMain/composeResources/drawable/compose-multiplatform.xml @@ -0,0 +1,36 @@ + + + + + + + + \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/App.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/App.kt new file mode 100644 index 0000000..94b3725 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/App.kt @@ -0,0 +1,23 @@ +package com.jaytux.grader + +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.runtime.* +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import com.jaytux.grader.ui.CoursesView +import com.jaytux.grader.viewmodel.CourseListState +import org.jetbrains.compose.ui.tooling.preview.Preview + +@Composable +@Preview +fun App() { + MaterialTheme { + val courseList = CourseListState() + Surface(Modifier.fillMaxSize().padding(10.dp)) { + CoursesView(courseList) + } + } +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/DSL.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/DSL.kt new file mode 100644 index 0000000..ac4e2fe --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/DSL.kt @@ -0,0 +1,86 @@ +package com.jaytux.grader.data + +import org.jetbrains.exposed.dao.id.CompositeIdTable +import org.jetbrains.exposed.dao.id.UUIDTable +import org.jetbrains.exposed.sql.Table + +object Courses : UUIDTable("courses") { + val name = varchar("name", 50).uniqueIndex() +} + +object Editions : UUIDTable("editions") { + val courseId = reference("course_id", Courses.id) + val name = varchar("name", 50) + + init { + uniqueIndex(courseId, name) + } +} + +object Groups : UUIDTable("groups") { + val editionId = reference("edition_id", Editions.id) + val name = varchar("name", 50) + + init { + uniqueIndex(editionId, name) + } +} + +object Students : UUIDTable("students") { + val name = varchar("name", 50) + val note = text("note") +} + +object GroupStudents : Table("grpStudents") { + val groupId = reference("group_id", Groups.id) + val studentId = reference("student_id", Students.id) + + override val primaryKey = PrimaryKey(groupId, studentId) +} + +object SoloStudents : Table("soloStudents") { + val editionId = reference("edition_id", Editions.id) + val studentId = reference("student_id", Students.id) + + override val primaryKey = PrimaryKey(studentId) +} + +object GroupAssignments : UUIDTable("grpAssgmts") { + val editionId = reference("edition_id_", Editions.id) + val name = varchar("name_", 50) + val assignment = text("assignment_") +} + +object SoloAssignments : UUIDTable("soloAssgmts") { + val editionId = GroupAssignments.reference("edition_id", Editions.id) + val name = GroupAssignments.varchar("name", 50) + val assignment = GroupAssignments.text("assignment") +} + +object GroupFeedbacks : CompositeIdTable("grpFdbks") { + val groupAssignmentId = reference("group_assignment_id", GroupAssignments.id) + val groupId = reference("group_id", Groups.id) + val feedback = text("feedback") + val grade = varchar("grade", 32) + + override val primaryKey = PrimaryKey(groupAssignmentId, groupId) +} + +object IndividualFeedbacks : CompositeIdTable("indivFdbks") { + val groupAssignmentId = reference("group_assignment_id", GroupAssignments.id) + val groupId = reference("group_id", Groups.id) + val studentId = reference("student_id", Students.id) + val feedback = text("feedback") + val grade = varchar("grade", 32) + + override val primaryKey = PrimaryKey(groupAssignmentId, studentId) +} + +object SoloFeedbacks : CompositeIdTable("soloFdbks") { + val soloAssignmentId = reference("solo_assignment_id", SoloAssignments.id) + val studentId = reference("student_id", Students.id) + val feedback = text("feedback") + val grade = varchar("grade", 32) + + override val primaryKey = PrimaryKey(soloAssignmentId, studentId) +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/Database.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/Database.kt new file mode 100644 index 0000000..2e825bd --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/Database.kt @@ -0,0 +1,22 @@ +package com.jaytux.grader.data + +import org.jetbrains.exposed.sql.Database +import org.jetbrains.exposed.sql.SchemaUtils +import org.jetbrains.exposed.sql.transactions.transaction + +object Database { + val db by lazy { + val actual = Database.connect("jdbc:sqlite:file:./grader.db", "org.sqlite.JDBC") + transaction { + SchemaUtils.create( + Courses, Editions, Groups, + Students, GroupStudents, SoloStudents, + GroupAssignments, SoloAssignments, + GroupFeedbacks, IndividualFeedbacks, SoloFeedbacks + ) + } + actual + } + + fun init() { db } +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/Entities.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/Entities.kt new file mode 100644 index 0000000..32cee68 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/Entities.kt @@ -0,0 +1,85 @@ +package com.jaytux.grader.data + +import org.jetbrains.exposed.dao.Entity +import org.jetbrains.exposed.dao.EntityClass +import org.jetbrains.exposed.dao.id.CompositeID +import org.jetbrains.exposed.dao.id.EntityID +import org.jetbrains.exposed.sql.transactions.transaction +import java.util.UUID + +class Course(id: EntityID) : Entity(id) { + companion object : EntityClass(Courses) + + fun loadEditions() = transaction { Edition.find { Editions.courseId eq this@Course.id }.toList() } + + var name by Courses.name +} + +class Edition(id: EntityID) : Entity(id) { + companion object : EntityClass(Editions) + + var course by Course referencedOn Editions.courseId + var name by Editions.name + val groups by Group referrersOn Groups.editionId + val soloStudents by Student via SoloStudents +} + +class Group(id: EntityID) : Entity(id) { + companion object : EntityClass(Groups) + + var edition by Edition referencedOn Groups.editionId + var name by Groups.name + val students by Student via GroupStudents +} + +class Student(id: EntityID) : Entity(id) { + companion object : EntityClass(Students) + + var name by Students.name + var note by Students.note + val groups by Group via GroupStudents + val soloCourses by Edition via SoloStudents +} + +class GroupAssignment(id: EntityID) : Entity(id) { + companion object : EntityClass(GroupAssignments) + + var edition by Edition referencedOn GroupAssignments.editionId + var name by GroupAssignments.name + var assignment by GroupAssignments.assignment +} + +class SoloAssignment(id: EntityID) : Entity(id) { + companion object : EntityClass(SoloAssignments) + + var edition by Edition referencedOn SoloAssignments.editionId + var name by SoloAssignments.name + var assignment by SoloAssignments.assignment +} + +class GroupFeedback(id: EntityID) : Entity(id) { + companion object : EntityClass(GroupFeedbacks) + + var group by Group referencedOn GroupFeedbacks.groupId + var assignment by GroupAssignment referencedOn GroupFeedbacks.groupAssignmentId + var feedback by GroupFeedbacks.feedback + var grade by GroupFeedbacks.grade +} + +class IndividualFeedback(id: EntityID) : Entity(id) { + companion object : EntityClass(IndividualFeedbacks) + + var student by Student referencedOn IndividualFeedbacks.studentId + var assignment by SoloAssignment referencedOn IndividualFeedbacks.groupAssignmentId + var feedback by IndividualFeedbacks.feedback + var grade by IndividualFeedbacks.grade +} + +class SoloFeedback(id: EntityID) : Entity(id) { + companion object : EntityClass(SoloFeedbacks) + + var student by Student referencedOn SoloFeedbacks.studentId + var assignment by SoloAssignment referencedOn SoloFeedbacks.soloAssignmentId + var feedback by SoloFeedbacks.feedback + var grade by SoloFeedbacks.grade +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/main.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/main.kt new file mode 100644 index 0000000..44df480 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/main.kt @@ -0,0 +1,18 @@ +package com.jaytux.grader + +import androidx.compose.ui.window.Window +import androidx.compose.ui.window.application +import com.jaytux.grader.App +import com.jaytux.grader.data.Database + +fun main(){ + Database.init() + application { + Window( + onCloseRequest = ::exitApplication, + title = "Grader", + ) { + App() + } + } +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Courses.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Courses.kt new file mode 100644 index 0000000..98f849b --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Courses.kt @@ -0,0 +1,95 @@ +package com.jaytux.grader.ui + +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material.Icon +import androidx.compose.material.IconButton +import androidx.compose.material.OutlinedTextField +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Delete +import androidx.compose.material.icons.filled.Edit +import androidx.compose.material.icons.filled.PlayArrow +import androidx.compose.material3.Button +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.unit.DpSize +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.* +import com.jaytux.grader.data.Course +import com.jaytux.grader.viewmodel.CourseListState + +@Composable +fun CoursesView(state: CourseListState) { + val data by state.courses.entities + var showDialog by remember { mutableStateOf(false) } + + if(data.isEmpty()) { + Box(Modifier.fillMaxSize()) { + Column(Modifier.align(Alignment.Center)) { + Text("You have no courses yet.", Modifier.align(Alignment.CenterHorizontally)) + Button({ showDialog = true }, Modifier.align(Alignment.CenterHorizontally)) { + Text("Add a course") + } + } + } + } + else { + LazyColumn(Modifier.fillMaxSize()) { + items(data) { CourseWidget(it) { state.delete(it) } } + + item { + Button({ showDialog = true }, Modifier.fillMaxWidth()) { + Text("Add course") + } + } + } + } + + if(showDialog) AddCourseDialog(data.map { it.name }, { showDialog = false }) { state.new(it) } +} + +@Composable +fun AddCourseDialog(taken: List, onClose: () -> Unit, onSave: (String) -> Unit) = DialogWindow( + onCloseRequest = onClose, + state = rememberDialogState(size = DpSize(400.dp, 300.dp), position = WindowPosition(Alignment.Center)) +) { + Surface(Modifier.fillMaxSize().padding(10.dp)) { + Box(Modifier.fillMaxSize()) { + var name by remember { mutableStateOf("") } + Column(Modifier.align(Alignment.Center)) { + OutlinedTextField(name, { name = it }, Modifier.fillMaxWidth(), label = { Text("Course name") }, isError = name in taken) + Row { + Button({ onClose() }, Modifier.weight(0.45f)) { Text("Cancel") } + Spacer(Modifier.weight(0.1f)) + Button({ onSave(name); onClose() }, Modifier.weight(0.45f)) { Text("Save") } + } + } + } + } +} + +@Composable +fun CourseWidget(course: Course, onDelete: () -> Unit) { + val editions = remember(course) { course.loadEditions().size } + Surface(Modifier.fillMaxWidth().padding(horizontal = 5.dp, vertical = 10.dp), shape = MaterialTheme.shapes.medium, tonalElevation = 2.dp, shadowElevation = 2.dp) { + Row { + Column(Modifier.weight(1f)) { + Text(course.name, Modifier.padding(5.dp), style = MaterialTheme.typography.headlineMedium) + Row { + Spacer(Modifier.width(15.dp)) + Text("$editions editions", fontStyle = FontStyle.Italic) + } + } + Column { + IconButton({ onDelete() }) { Icon(Icons.Default.Delete, "Remove") } + IconButton({ TODO() }) { Icon(Icons.Default.Edit, "Edit") } + } + } + } +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/DbState.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/DbState.kt new file mode 100644 index 0000000..f2eac2d --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/DbState.kt @@ -0,0 +1,43 @@ +package com.jaytux.grader.viewmodel + +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.State +import androidx.compose.runtime.mutableStateOf +import com.jaytux.grader.data.Course +import com.jaytux.grader.data.Edition +import com.jaytux.grader.data.Editions +import org.jetbrains.exposed.dao.Entity +import org.jetbrains.exposed.sql.Transaction +import org.jetbrains.exposed.sql.transactions.transaction +import java.util.* + +class RawDbState>(private val loader: (Transaction.() -> List)) { + private fun MutableState.immutable(): State = this@immutable + + private val rawEntities by lazy { + mutableStateOf(transaction { loader() }) + } + val entities = rawEntities.immutable() + + fun refresh() { + rawEntities.value = transaction { loader() } + } +} + +class CourseListState { + val courses = RawDbState { Course.all().toList() } + + fun new(name: String) { + transaction { Course.new { this.name = name } } + courses.refresh() + } + + fun delete(course: Course) { + transaction { course.delete() } + courses.refresh() + } +} + +class EditionListState(private val course: Course) { + val editions = RawDbState { Edition.find { Editions.courseId eq course.id }.toList() } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..ddad6aa --- /dev/null +++ b/gradle.properties @@ -0,0 +1,6 @@ +#Kotlin +kotlin.code.style=official +kotlin.daemon.jvmargs=-Xmx2048M + +#Gradle +org.gradle.jvmargs=-Xmx2048M -Dfile.encoding=UTF-8 \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..bebc6e6 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,29 @@ +[versions] +androidx-lifecycle = "2.8.4" +compose-multiplatform = "1.7.0" +junit = "4.13.2" +kotlin = "2.1.0" +kotlinx-coroutines = "1.10.1" +exposed = "0.59.0" +material3 = "1.7.3" + +[libraries] +kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } +kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version.ref = "kotlin" } +junit = { group = "junit", name = "junit", version.ref = "junit" } +androidx-lifecycle-viewmodel = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-viewmodel", version.ref = "androidx-lifecycle" } +androidx-lifecycle-runtime-compose = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-runtime-compose", version.ref = "androidx-lifecycle" } +kotlinx-coroutines-swing = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-swing", version.ref = "kotlinx-coroutines" } +exposed-core = { group = "org.jetbrains.exposed", name = "exposed-core", version.ref = "exposed" } +exposed-dao = { group = "org.jetbrains.exposed", name = "exposed-dao", version.ref = "exposed" } +exposed-jdbc = { group = "org.jetbrains.exposed", name = "exposed-jdbc", version.ref = "exposed" } +exposed-kotlin-datetime = { group = "org.jetbrains.exposed", name = "exposed-kotlin-datetime", version.ref = "exposed" } +sqlite = { group = "org.xerial", name = "sqlite-jdbc", version = "3.34.0" } +sl4j = { group = "org.slf4j", name = "slf4j-simple", version = "2.0.12" } +material3-core = { group = "org.jetbrains.compose.material3", name = "material3", version.ref = "material3" } +material3-desktop = { group = "org.jetbrains.compose.material3", name = "material3-desktop", version.ref = "material3" } + +[plugins] +composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "compose-multiplatform" } +composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } +kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" } \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..2c3521197d7c4586c843d1d3e9090525f1898cde GIT binary patch literal 43504 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 PP-GC|Wnefl2gCyaq>Ln) literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..09523c0 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..f5feea6 --- /dev/null +++ b/gradlew @@ -0,0 +1,252 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..9b42019 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,94 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..5afcfde --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,31 @@ +rootProject.name = "KotlinProject" +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") + +pluginManagement { + repositories { + google { + mavenContent { + includeGroupAndSubgroups("androidx") + includeGroupAndSubgroups("com.android") + includeGroupAndSubgroups("com.google") + } + } + mavenCentral() + gradlePluginPortal() + } +} + +dependencyResolutionManagement { + repositories { + google { + mavenContent { + includeGroupAndSubgroups("androidx") + includeGroupAndSubgroups("com.android") + includeGroupAndSubgroups("com.google") + } + } + mavenCentral() + } +} + +include(":composeApp") \ No newline at end of file