From 8786cc6072cb7b73e1aa301afe3c02ced1bcc2c8 Mon Sep 17 00:00:00 2001 From: jay-tux Date: Wed, 11 Mar 2026 15:28:18 +0100 Subject: [PATCH] Restructure DB & UI, pt.1 --- .gitignore | 2 +- composeApp/build.gradle.kts | 20 +- composeApp/hs_err_pid2264499.log | 4866 +++++++++++++++++ .../kotlin/com/jaytux/grader/App.kt | 56 +- .../kotlin/com/jaytux/grader/Either.kt | 48 + .../kotlin/com/jaytux/grader/Util.kt | 27 +- .../kotlin/com/jaytux/grader/data/DSL.kt | 145 - .../kotlin/com/jaytux/grader/data/Database.kt | 86 +- .../kotlin/com/jaytux/grader/data/Entities.kt | 139 - .../kotlin/com/jaytux/grader/data/Exporter.kt | 204 +- .../kotlin/com/jaytux/grader/data/v2/DSLv2.kt | 181 + .../com/jaytux/grader/data/v2/Entitiesv2.kt | 190 + .../kotlin/com/jaytux/grader/data/v2/uml.md | 157 + .../com/jaytux/grader/ui/Assignments.kt | 1430 +++-- .../com/jaytux/grader/ui/AssignmentsView.kt | 500 ++ .../kotlin/com/jaytux/grader/ui/Courses.kt | 192 +- .../com/jaytux/grader/ui/EditionView.kt | 100 + .../kotlin/com/jaytux/grader/ui/Editions.kt | 822 ++- .../com/jaytux/grader/ui/GroupsGradingView.kt | 266 + .../kotlin/com/jaytux/grader/ui/GroupsView.kt | 285 + .../kotlin/com/jaytux/grader/ui/HomeView.kt | 147 + .../kotlin/com/jaytux/grader/ui/Icons.kt | 1305 ++++- .../jaytux/grader/ui/PeerEvalsGradingView.kt | 20 + .../kotlin/com/jaytux/grader/ui/RichText.kt | 38 +- .../com/jaytux/grader/ui/SolosGradingView.kt | 20 + .../com/jaytux/grader/ui/StudentsView.kt | 193 + .../kotlin/com/jaytux/grader/ui/Views.kt | 414 +- .../kotlin/com/jaytux/grader/ui/Widgets.kt | 475 +- .../com/jaytux/grader/viewmodel/DbState.kt | 819 +-- .../com/jaytux/grader/viewmodel/EditionVM.kt | 419 ++ .../com/jaytux/grader/viewmodel/Grade.kt | 57 + .../grader/viewmodel/GroupsGradingVM.kt | 174 + .../com/jaytux/grader/viewmodel/HomeVM.kt | 70 + .../com/jaytux/grader/viewmodel/Navigator.kt | 152 + .../grader/viewmodel/PeerEvalsGradingVM.kt | 9 + .../com/jaytux/grader/viewmodel/SnackVM.kt | 28 + .../jaytux/grader/viewmodel/SolosGradingVM.kt | 9 + .../jaytux/grader/viewmodel/UiGradeType.kt | 20 + gradle/libs.versions.toml | 20 +- gradle/wrapper/gradle-wrapper.jar | Bin 43504 -> 46175 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 12 +- gradlew.bat | 3 +- 43 files changed, 11051 insertions(+), 3071 deletions(-) create mode 100644 composeApp/hs_err_pid2264499.log create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/Either.kt delete mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/DSL.kt delete mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/Entities.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/v2/DSLv2.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/v2/Entitiesv2.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/v2/uml.md create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/AssignmentsView.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/EditionView.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/GroupsGradingView.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/GroupsView.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/HomeView.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/PeerEvalsGradingView.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/SolosGradingView.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/StudentsView.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/EditionVM.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/Grade.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/GroupsGradingVM.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/HomeVM.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/Navigator.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/PeerEvalsGradingVM.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/SnackVM.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/SolosGradingVM.kt create mode 100644 composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/UiGradeType.kt diff --git a/.gitignore b/.gitignore index f8113f6..b33d18c 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,4 @@ captures !*.xcworkspace/contents.xcworkspacedata **/xcshareddata/WorkspaceSettings.xcsettings **/grader.db -**/*.backup \ No newline at end of file +**/*.backup diff --git a/composeApp/build.gradle.kts b/composeApp/build.gradle.kts index 68d12ab..98e6288 100644 --- a/composeApp/build.gradle.kts +++ b/composeApp/build.gradle.kts @@ -7,12 +7,17 @@ plugins { } kotlin { - jvm("desktop") + compilerOptions { + freeCompilerArgs.add("-Xcontext-parameters") + } + + jvm("desktop") {} sourceSets { val desktopMain by getting - - commonMain.dependencies { + + desktopMain.dependencies { + implementation(compose.desktop.currentOs) implementation(compose.runtime) implementation(compose.foundation) implementation(compose.material) @@ -22,16 +27,13 @@ kotlin { implementation(libs.androidx.lifecycle.viewmodel) implementation(libs.androidx.lifecycle.runtime.compose) implementation(libs.material3.core) - implementation(libs.material.icons) 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.migration) + implementation(libs.exposed.migration.jdbc) implementation(libs.exposed.kotlin.datetime) implementation(libs.sqlite) implementation(libs.material3.desktop) @@ -40,6 +42,9 @@ kotlin { implementation(libs.filekit.dialogs) implementation(libs.filekit.dialogs.compose) implementation(libs.filekit.coil) + implementation(libs.directories) + implementation(libs.androidx.lifecycle.viewmodel.compose) + implementation(libs.compose.backhandler) } } } @@ -52,6 +57,7 @@ compose.desktop { nativeDistributions { targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb) packageName = "com.jaytux.grader" + mainClass = "com.jaytux.grader.MainKt" packageVersion = "1.0.0" includeAllModules = true diff --git a/composeApp/hs_err_pid2264499.log b/composeApp/hs_err_pid2264499.log new file mode 100644 index 0000000..00f74d2 --- /dev/null +++ b/composeApp/hs_err_pid2264499.log @@ -0,0 +1,4866 @@ +# +# A fatal error has been detected by the Java Runtime Environment: +# +# SIGSEGV (0xb) at pc=0x00007e23d676c491, pid=2264499, tid=2264816 +# +# JRE version: OpenJDK Runtime Environment Corretto-22.0.2.9.1 (22.0.2+9) (build 22.0.2+9-FR) +# Java VM: OpenJDK 64-Bit Server VM Corretto-22.0.2.9.1 (22.0.2+9-FR, mixed mode, sharing, tiered, compressed oops, compressed class ptrs, g1 gc, linux-amd64) +# Problematic frame: +# C [libskiko-linux-x64.so+0x36c491] SkTypeface_fontconfig::onOpenStream(int*) const+0x21 +# +# Core dump will be written. Default location: Core dumps may be processed with "/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h %d %F" (or dumping to /home/jay/kotlin/grader/composeApp/core.2264499) +# +# If you would like to submit a bug report, please visit: +# https://github.com/corretto/corretto-22/issues/ +# The crash happened outside the Java Virtual Machine in native code. +# See problematic frame for where to report the bug. +# + +--------------- S U M M A R Y ------------ + +Command Line: -Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en -Duser.variant com.jaytux.grader.MainKt + +Host: AMD Ryzen 7 8845HS w/ Radeon 780M Graphics, 16 cores, 30G, Arch Linux +Time: Wed Mar 11 12:56:28 2026 CET elapsed time: 4866.509022 seconds (0d 1h 21m 6s) + +--------------- T H R E A D --------------- + +Current thread (0x00007e24dcd721d0): JavaThread "AWT-EventQueue-0" [_thread_in_native, id=2264816, stack(0x00007e2461397000,0x00007e2461497000) (1024K)] + +Stack: [0x00007e2461397000,0x00007e2461497000], sp=0x00007e24614915c0, free space=1001k +Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) +C [libskiko-linux-x64.so+0x36c491] SkTypeface_fontconfig::onOpenStream(int*) const+0x21 +Java frames: (J=compiled Java code, j=interpreted, Vv=VM code) +J 6026 org.jetbrains.skia.paragraph.ParagraphKt._nLayout(JF)V (0 bytes) @ 0x00007e24cc7c83f9 [0x00007e24cc7c83a0+0x0000000000000059] +J 17300 c2 androidx.compose.ui.text.platform.SkiaParagraphIntrinsics.(Ljava/lang/String;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Ljava/util/List;Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;)V (158 bytes) @ 0x00007e24cd062dbc [0x00007e24cd062680+0x000000000000073c] +J 7394 c1 androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt.ActualParagraphIntrinsics(Ljava/lang/String;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Ljava/util/List;Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;)Landroidx/compose/ui/text/ParagraphIntrinsics; (57 bytes) @ 0x00007e24c59229ac [0x00007e24c5921960+0x000000000000104c] +J 7395 c1 androidx.compose.ui.text.ParagraphIntrinsicsKt.ParagraphIntrinsics(Ljava/lang/String;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;Ljava/util/List;)Landroidx/compose/ui/text/ParagraphIntrinsics; (50 bytes) @ 0x00007e24c592bd9c [0x00007e24c592adc0+0x0000000000000fdc] +J 11277 c1 androidx.compose.ui.text.MultiParagraphIntrinsics.(Landroidx/compose/ui/text/AnnotatedString;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;)V (348 bytes) @ 0x00007e24c61f09c4 [0x00007e24c61eeb20+0x0000000000001ea4] +J 10318 c1 androidx.compose.foundation.text.TextDelegate.layoutIntrinsics(Landroidx/compose/ui/unit/LayoutDirection;)V (97 bytes) @ 0x00007e24c5fcc454 [0x00007e24c5fcbf60+0x00000000000004f4] +J 14777 c1 androidx.compose.foundation.text.CoreTextFieldKt$CoreTextField$8$1$1$2.maxIntrinsicWidth(Landroidx/compose/ui/layout/IntrinsicMeasureScope;Ljava/util/List;I)I (40 bytes) @ 0x00007e24c4c7044c [0x00007e24c4c6fdc0+0x000000000000068c] +J 12195 c2 androidx.compose.ui.node.MeasurePassDelegate.maxIntrinsicWidth(I)I (36 bytes) @ 0x00007e24cccc90c4 [0x00007e24cccc8b20+0x00000000000005a4] +J 10358 c2 androidx.compose.ui.layout.DefaultIntrinsicMeasurable.measure-BRTryo0(J)Landroidx/compose/ui/layout/Placeable; (156 bytes) @ 0x00007e24ccadc4d0 [0x00007e24ccadb5a0+0x0000000000000f30] +J 10317 c1 androidx.compose.foundation.text.selection.SimpleLayoutKt$SimpleLayout$1$1.measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Ljava/util/List;J)Landroidx/compose/ui/layout/MeasureResult; (184 bytes) @ 0x00007e24c5fbc874 [0x00007e24c5fbbd60+0x0000000000000b14] +J 9946 c1 androidx.compose.ui.layout.MeasurePolicy.maxIntrinsicWidth(Landroidx/compose/ui/layout/IntrinsicMeasureScope;Ljava/util/List;I)I (191 bytes) @ 0x00007e24c5ec1414 [0x00007e24c5ebfe00+0x0000000000001614] +J 7895 c1 androidx.compose.ui.node.IntrinsicsPolicy.maxIntrinsicWidth(I)I (33 bytes) @ 0x00007e24c5a1b5bc [0x00007e24c5a1b080+0x000000000000053c] +J 7894 c1 androidx.compose.ui.node.LayoutNode.maxIntrinsicWidth(I)I (9 bytes) @ 0x00007e24c5a1a774 [0x00007e24c5a1a6c0+0x00000000000000b4] +J 10130 c2 androidx.compose.ui.node.NodeMeasuringIntrinsics$DefaultIntrinsicMeasurable.measure-BRTryo0(J)Landroidx/compose/ui/layout/Placeable; (156 bytes) @ 0x00007e24ccab5cf0 [0x00007e24ccab4fa0+0x0000000000000d50] +J 10316 c1 androidx.compose.foundation.text.TextFieldSizeKt$textFieldMinSize$1.invoke$lambda$6$lambda$5(Landroidx/compose/foundation/text/TextFieldSize;Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;Landroidx/compose/ui/unit/Constraints;)Landroidx/compose/ui/layout/MeasureResult; (138 bytes) @ 0x00007e24c5fca2fc [0x00007e24c5fc9a80+0x000000000000087c] +J 10315 c1 androidx.compose.foundation.text.TextFieldSizeKt$textFieldMinSize$1$$Lambda+0x00007e24634d9e00.invoke(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; (20 bytes) @ 0x00007e24c5fbb7d4 [0x00007e24c5fbb4c0+0x0000000000000314] +J 11046 c2 androidx.compose.ui.layout.LayoutModifierImpl.measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult; (31 bytes) @ 0x00007e24ccb4f564 [0x00007e24ccb4f4a0+0x00000000000000c4] +J 9845 c1 androidx.compose.ui.node.LayoutModifierNode$maxIntrinsicWidth$1.measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult; (25 bytes) @ 0x00007e24c5e80774 [0x00007e24c5e80120+0x0000000000000654] +J 9844 c1 androidx.compose.ui.node.NodeMeasuringIntrinsics.maxWidth$ui(Landroidx/compose/ui/node/NodeMeasuringIntrinsics$MeasureBlock;Landroidx/compose/ui/layout/IntrinsicMeasureScope;Landroidx/compose/ui/layout/IntrinsicMeasurable;I)I (95 bytes) @ 0x00007e24c5e82534 [0x00007e24c5e81460+0x00000000000010d4] +J 9842 c1 androidx.compose.ui.node.LayoutModifierNode.maxIntrinsicWidth(Landroidx/compose/ui/layout/IntrinsicMeasureScope;Landroidx/compose/ui/layout/IntrinsicMeasurable;I)I (33 bytes) @ 0x00007e24c5e7f504 [0x00007e24c5e7ee40+0x00000000000006c4] +J 12942 c2 androidx.compose.ui.node.LayoutModifierNodeCoordinator.maxIntrinsicWidth(I)I (73 bytes) @ 0x00007e24cc81b494 [0x00007e24cc81b420+0x0000000000000074] +J 14776 c1 androidx.compose.foundation.text.HorizontalScrollLayoutModifier.measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult; (101 bytes) @ 0x00007e24c53e4764 [0x00007e24c53e4100+0x0000000000000664] +J 11183 c1 androidx.compose.ui.node.BackwardsCompatNode.measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult; (45 bytes) @ 0x00007e24c4a75d8c [0x00007e24c4a75400+0x000000000000098c] +J 10116 c2 androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(J)Landroidx/compose/ui/layout/Placeable; (349 bytes) @ 0x00007e24ccab39f8 [0x00007e24ccab3940+0x00000000000000b8] +J 11375 c2 androidx.compose.ui.graphics.SimpleGraphicsLayerModifier.measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult; (47 bytes) @ 0x00007e24ccba728c [0x00007e24ccba7220+0x000000000000006c] +J 10116 c2 androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(J)Landroidx/compose/ui/layout/Placeable; (349 bytes) @ 0x00007e24ccab39f8 [0x00007e24ccab3940+0x00000000000000b8] +J 13043 c2 androidx.compose.foundation.layout.SizeNode.measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult; (351 bytes) @ 0x00007e24ccd509ac [0x00007e24ccd506e0+0x00000000000002cc] +J 10116 c2 androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(J)Landroidx/compose/ui/layout/Placeable; (349 bytes) @ 0x00007e24ccab39f8 [0x00007e24ccab3940+0x00000000000000b8] +J 13043 c2 androidx.compose.foundation.layout.SizeNode.measure-3p2s80s(Landroidx/compose/ui/layout/MeasureScope;Landroidx/compose/ui/layout/Measurable;J)Landroidx/compose/ui/layout/MeasureResult; (351 bytes) @ 0x00007e24ccd509ac [0x00007e24ccd506e0+0x00000000000002cc] +J 10116 c2 androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(J)Landroidx/compose/ui/layout/Placeable; (349 bytes) @ 0x00007e24ccab39f8 [0x00007e24ccab3940+0x00000000000000b8] +J 10626 c2 androidx.compose.ui.node.MeasurePassDelegate$$Lambda+0x00007e24632b3068.invoke()Ljava/lang/Object; (8 bytes) @ 0x00007e24ccb0f2b4 [0x00007e24ccb0f240+0x0000000000000074] +J 8505 c2 androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;)Ljava/lang/Object; (314 bytes) @ 0x00007e24cc949790 [0x00007e24cc948e40+0x0000000000000950] +J 8722 c2 androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(Ljava/lang/Object;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;)V (193 bytes) @ 0x00007e24cc978ed0 [0x00007e24cc9786c0+0x0000000000000810] +J 10420 c2 androidx.compose.ui.node.MeasurePassDelegate.performMeasure-BRTryo0$ui(J)V (96 bytes) @ 0x00007e24ccae8580 [0x00007e24ccae8460+0x0000000000000120] +J 16081 c1 androidx.compose.ui.node.MeasurePassDelegate.remeasure-BRTryo0(J)Z (298 bytes) @ 0x00007e24c5ccc09c [0x00007e24c5ccb5c0+0x0000000000000adc] +J 9594 c1 androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui(Landroidx/compose/ui/unit/Constraints;)Z (34 bytes) @ 0x00007e24c5de0914 [0x00007e24c5de0760+0x00000000000001b4] +J 8298 c1 androidx.compose.ui.node.MeasureAndLayoutDelegate.doRemeasure-sdFAvZA(Landroidx/compose/ui/node/LayoutNode;Landroidx/compose/ui/unit/Constraints;)Z (78 bytes) @ 0x00007e24c5afb1a4 [0x00007e24c5afacc0+0x00000000000004e4] +J 15975 c1 androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureAndRelayoutIfNeeded(Landroidx/compose/ui/node/LayoutNode;ZZ)Z (288 bytes) @ 0x00007e24c4c1ff5c [0x00007e24c4c1e7a0+0x00000000000017bc] +J 16033 c1 androidx.compose.ui.node.MeasureAndLayoutDelegate.measureAndLayout(Lkotlin/jvm/functions/Function0;)Z (507 bytes) @ 0x00007e24c5f52cfc [0x00007e24c5f51240+0x0000000000001abc] +J 16869 c2 androidx.compose.ui.scene.ComposeSceneMediator.onRender(Lorg/jetbrains/skia/Canvas;IIJ)V (64 bytes) @ 0x00007e24ccfcc19c [0x00007e24ccfcb080+0x000000000000111c] +J 16048 c1 org.jetbrains.skiko.SkiaLayer.update$skiko(J)V (344 bytes) @ 0x00007e24c5535814 [0x00007e24c55341c0+0x0000000000001654] +J 8433 c1 org.jetbrains.skiko.redrawer.AWTRedrawer.update(J)V (61 bytes) @ 0x00007e24c5b5472c [0x00007e24c5b54200+0x000000000000052c] +J 16004 c1 org.jetbrains.skiko.redrawer.LinuxOpenGLRedrawer$Companion$frameDispatcher$1.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object; (943 bytes) @ 0x00007e24c4e63384 [0x00007e24c4e61c80+0x0000000000001704] +J 13888 c2 kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(Ljava/lang/Object;)V (124 bytes) @ 0x00007e24cce33144 [0x00007e24cce330e0+0x0000000000000064] +J 7089 c2 kotlinx.coroutines.DispatchedTask.run()V (387 bytes) @ 0x00007e24cc845820 [0x00007e24cc845440+0x00000000000003e0] +J 15861 c2 java.awt.EventQueue.dispatchEventImpl(Ljava/awt/AWTEvent;Ljava/lang/Object;)V java.desktop@22.0.2 (139 bytes) @ 0x00007e24cccf5c1c [0x00007e24cccf5920+0x00000000000002fc] +J 16266 c2 java.awt.EventQueue$4.run()Ljava/lang/Object; java.desktop@22.0.2 (5 bytes) @ 0x00007e24cc973308 [0x00007e24cc9732a0+0x0000000000000068] +J 16244 c2 java.awt.EventQueue.dispatchEvent(Ljava/awt/AWTEvent;)V java.desktop@22.0.2 (80 bytes) @ 0x00007e24ccbb266c [0x00007e24ccbb2340+0x000000000000032c] +J 17032 c2 java.awt.EventDispatchThread.pumpOneEventForFilters(I)V java.desktop@22.0.2 (106 bytes) @ 0x00007e24cca16970 [0x00007e24cca16560+0x0000000000000410] +J 17058 c1 java.awt.EventDispatchThread.pumpEventsForFilter(ILjava/awt/Conditional;Ljava/awt/EventFilter;)V java.desktop@22.0.2 (47 bytes) @ 0x00007e24c549099c [0x00007e24c5490700+0x000000000000029c] +j java.awt.EventDispatchThread.pumpEventsForFilter(Ljava/awt/Conditional;Ljava/awt/EventFilter;)V+4 java.desktop@22.0.2 +j java.awt.WaitDispatchSupport$2.run()V+59 java.desktop@22.0.2 +j java.awt.WaitDispatchSupport$4.run()Ljava/lang/Void;+4 java.desktop@22.0.2 +j java.awt.WaitDispatchSupport$4.run()Ljava/lang/Object;+1 java.desktop@22.0.2 +J 4555 c1 java.security.AccessController.doPrivileged(Ljava/security/PrivilegedAction;)Ljava/lang/Object; java.base@22.0.2 (9 bytes) @ 0x00007e24c5296e54 [0x00007e24c5296ce0+0x0000000000000174] +j java.awt.WaitDispatchSupport.enter()Z+266 java.desktop@22.0.2 +j java.awt.Dialog.show()V+225 java.desktop@22.0.2 +j java.awt.Component.show(Z)V+5 java.desktop@22.0.2 +j java.awt.Component.setVisible(Z)V+2 java.desktop@22.0.2 +j java.awt.Window.setVisible(Z)V+2 java.desktop@22.0.2 +j java.awt.Dialog.setVisible(Z)V+2 java.desktop@22.0.2 +j androidx.compose.ui.awt.AwtWindow_desktopKt$AwtWindow$4$1$showJob$1.invokeSuspend(Ljava/lang/Object;)Ljava/lang/Object;+43 +J 13888 c2 kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(Ljava/lang/Object;)V (124 bytes) @ 0x00007e24cce33144 [0x00007e24cce330e0+0x0000000000000064] +J 7089 c2 kotlinx.coroutines.DispatchedTask.run()V (387 bytes) @ 0x00007e24cc845820 [0x00007e24cc845440+0x00000000000003e0] +J 15861 c2 java.awt.EventQueue.dispatchEventImpl(Ljava/awt/AWTEvent;Ljava/lang/Object;)V java.desktop@22.0.2 (139 bytes) @ 0x00007e24cccf5c1c [0x00007e24cccf5920+0x00000000000002fc] +J 16266 c2 java.awt.EventQueue$4.run()Ljava/lang/Object; java.desktop@22.0.2 (5 bytes) @ 0x00007e24cc973308 [0x00007e24cc9732a0+0x0000000000000068] +J 16244 c2 java.awt.EventQueue.dispatchEvent(Ljava/awt/AWTEvent;)V java.desktop@22.0.2 (80 bytes) @ 0x00007e24ccbb266c [0x00007e24ccbb2340+0x000000000000032c] +J 17032 c2 java.awt.EventDispatchThread.pumpOneEventForFilters(I)V java.desktop@22.0.2 (106 bytes) @ 0x00007e24cca16970 [0x00007e24cca16560+0x0000000000000410] +J 13281% c2 java.awt.EventDispatchThread.pumpEventsForFilter(ILjava/awt/Conditional;Ljava/awt/EventFilter;)V java.desktop@22.0.2 (47 bytes) @ 0x00007e24ccba14cc [0x00007e24ccba1420+0x00000000000000ac] +j java.awt.EventDispatchThread.pumpEventsForHierarchy(ILjava/awt/Conditional;Ljava/awt/Component;)V+11 java.desktop@22.0.2 +j java.awt.EventDispatchThread.pumpEvents(ILjava/awt/Conditional;)V+4 java.desktop@22.0.2 +j java.awt.EventDispatchThread.pumpEvents(Ljava/awt/Conditional;)V+3 java.desktop@22.0.2 +j java.awt.EventDispatchThread.run()V+9 java.desktop@22.0.2 +v ~StubRoutines::call_stub 0x00007e24cbe5fcc6 + +siginfo: si_signo: 11 (SIGSEGV), si_code: 1 (SEGV_MAPERR), si_addr: 0x0000000000000000 + +Registers: +RAX=0x0000000000000000, RBX=0x00007e23d6f22220, RCX=0x00007e23d664d080, RDX=0x00007e246149168c +RSP=0x00007e24614915c0, RBP=0x000000000000001c, RSI=0x0000000000000000, RDI=0x00007e2461491698 +R8 =0x000000004289c4e0, R9 =0x00007e23e233d108, R10=0x00007e23d6f22220, R11=0x00007e23d7e7cbe0 +R12=0x00007e2461491698, R13=0x00007e23e2c34f60, R14=0x00007e235d109660, R15=0x0000000042898669 +RIP=0x00007e23d676c491, EFLAGS=0x0000000000010246, CSGSFS=0x002b000000000033, ERR=0x0000000000000004 + TRAPNO=0x000000000000000e + + +Register to memory mapping: + +RAX=0x0 is null +RBX=0x00007e23d6f22220: in /home/jay/.skiko/466d99514e1c05f31bc8556b637e21363d14da45e8215a739f8d1d8c22184704/libskiko-linux-x64.so at 0x00007e23d6400000 +RCX=0x00007e23d664d080: in /home/jay/.skiko/466d99514e1c05f31bc8556b637e21363d14da45e8215a739f8d1d8c22184704/libskiko-linux-x64.so at 0x00007e23d6400000 +RDX=0x00007e246149168c is pointing into the stack for thread: 0x00007e24dcd721d0 +RSP=0x00007e24614915c0 is pointing into the stack for thread: 0x00007e24dcd721d0 +RBP=0x000000000000001c is an unknown value +RSI=0x0 is null +RDI=0x00007e2461491698 is pointing into the stack for thread: 0x00007e24dcd721d0 +R8 =0x000000004289c4e0 is an unknown value +R9 =0x00007e23e233d108 points into unknown readable memory: 0x00000000e9250490 | 90 04 25 e9 00 00 00 00 +R10=0x00007e23d6f22220: in /home/jay/.skiko/466d99514e1c05f31bc8556b637e21363d14da45e8215a739f8d1d8c22184704/libskiko-linux-x64.so at 0x00007e23d6400000 +R11=0x00007e23d7e7cbe0: in /home/jay/.skiko/466d99514e1c05f31bc8556b637e21363d14da45e8215a739f8d1d8c22184704/libskiko-linux-x64.so at 0x00007e23d6400000 +R12=0x00007e2461491698 is pointing into the stack for thread: 0x00007e24dcd721d0 +R13=0x00007e23e2c34f60 points into unknown readable memory: 0x00007e23d7e51180 | 80 11 e5 d7 23 7e 00 00 +R14=0x00007e235d109660 points into unknown readable memory: 0x0000000100000001 | 01 00 00 00 01 00 00 00 +R15=0x0000000042898669 is an unknown value + +Top of Stack: (sp=0x00007e24614915c0) +0x00007e24614915c0: 0000000000000000 8db8c973edc5b000 +0x00007e24614915d0: 00007e2461491698 00007e23d664e605 +0x00007e24614915e0: 00007e23e2c34f60 8db8c973edc5b000 +0x00007e24614915f0: 000000004289c4e0 00007e23d6f95bb4 +0x00007e2461491600: 00007e235c43cbaf 00007e23e136db50 +0x00007e2461491610: 00007e23e136dbc8 00007e2461491c60 +0x00007e2461491620: 00007e2461491ee0 0000000000000000 +0x00007e2461491630: 00007e24614916a0 00007e2461491ec0 +0x00007e2461491640: 00007e235c43cbb1 0000000000000002 +0x00007e2461491650: 00007e23e31cbf80 00007e23e1ef6fb0 +0x00007e2461491660: 0000000000004289 0000000400000000 +0x00007e2461491670: 0000000000000000 0000000000000000 +0x00007e2461491680: 0000000000000000 0000000000000000 +0x00007e2461491690: 00007e235c43cbb1 0000000000000002 +0x00007e24614916a0: 00007e23d7e7cbe0 00007e23d7e7cc10 +0x00007e24614916b0: 00007e2461491738 00007e235d3dd290 +0x00007e24614916c0: 0000000000000000 0000000000000000 +0x00007e24614916d0: 0000000000000000 0000000000000000 +0x00007e24614916e0: 0000000000000000 0000000000000000 +0x00007e24614916f0: 0000000000000000 0000000000000000 +0x00007e2461491700: 0000000000000000 0000000000000000 +0x00007e2461491710: 0000000000000000 0000000000000000 +0x00007e2461491720: 0000000000000000 0000000100000000 +0x00007e2461491730: 00007e2461491770 8db8c973edc5b000 +0x00007e2461491740: 0000000000000000 000000000000000b +0x00007e2461491750: 00007e23e0ee4540 00007e23d7e73540 +0x00007e2461491760: 00007e23d7e73540 00007e23d7e73540 +0x00007e2461491770: 00007e24614917b0 00007e24e3895814 +0x00007e2461491780: 00007e24614917c0 8db8c973edc5b000 +0x00007e2461491790: 00007e23e36d5cc0 000000000000000b +0x00007e24614917a0: 0000000000000002 8db8c973edc5b000 +0x00007e24614917b0: 6861cd3208088b1f 31782d7265740300 + +Instructions: (pc=0x00007e23d676c491) +0x00007e23d676c391: c0 eb 9c e8 27 77 da ff 0f 1f 80 00 00 00 00 f3 +0x00007e23d676c3a1: 0f 1e fa 48 81 ec d8 00 00 00 49 89 fa 48 89 74 +0x00007e23d676c3b1: 24 28 48 89 54 24 30 48 89 4c 24 38 4c 89 44 24 +0x00007e23d676c3c1: 40 4c 89 4c 24 48 84 c0 74 37 0f 29 44 24 50 0f +0x00007e23d676c3d1: 29 4c 24 60 0f 29 54 24 70 0f 29 9c 24 80 00 00 +0x00007e23d676c3e1: 00 0f 29 a4 24 90 00 00 00 0f 29 ac 24 a0 00 00 +0x00007e23d676c3f1: 00 0f 29 b4 24 b0 00 00 00 0f 29 bc 24 c0 00 00 +0x00007e23d676c401: 00 64 48 8b 04 25 28 00 00 00 48 89 44 24 18 31 +0x00007e23d676c411: c0 48 8d 84 24 e0 00 00 00 48 89 e1 4c 89 d2 48 +0x00007e23d676c421: 89 44 24 08 48 8d 44 24 20 be 01 00 00 00 48 89 +0x00007e23d676c431: 44 24 10 48 8b 05 cd 55 70 01 c7 04 24 08 00 00 +0x00007e23d676c441: 00 48 8b 38 c7 44 24 04 30 00 00 00 e8 4e 54 da +0x00007e23d676c451: ff 48 8b 44 24 18 64 48 33 04 25 28 00 00 00 75 +0x00007e23d676c461: 08 48 81 c4 d8 00 00 00 c3 e8 51 76 da ff 90 f3 +0x00007e23d676c471: 0f 1e fa 41 54 49 89 fc 48 83 ec 10 48 8b 76 40 +0x00007e23d676c481: 64 48 8b 04 25 28 00 00 00 48 89 44 24 08 31 c0 +0x00007e23d676c491: 48 8b 06 ff 50 58 48 8b 44 24 08 64 48 33 04 25 +0x00007e23d676c4a1: 28 00 00 00 75 0a 48 83 c4 10 4c 89 e0 41 5c c3 +0x00007e23d676c4b1: e8 0a 76 da ff 66 2e 0f 1f 84 00 00 00 00 00 f3 +0x00007e23d676c4c1: 0f 1e fa 41 54 49 89 fc 48 83 ec 10 48 8b 76 40 +0x00007e23d676c4d1: 64 48 8b 04 25 28 00 00 00 48 89 44 24 08 31 c0 +0x00007e23d676c4e1: 48 8b 06 ff 50 20 48 8b 44 24 08 64 48 33 04 25 +0x00007e23d676c4f1: 28 00 00 00 75 0a 48 83 c4 10 4c 89 e0 41 5c c3 +0x00007e23d676c501: e8 ba 75 da ff 66 2e 0f 1f 84 00 00 00 00 00 f3 +0x00007e23d676c511: 0f 1e fa 48 8b 7f 40 48 8b 07 ff 60 50 66 90 f3 +0x00007e23d676c521: 0f 1e fa 48 8b 7f 40 48 8b 07 ff a0 a0 00 00 00 +0x00007e23d676c531: 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 f3 +0x00007e23d676c541: 0f 1e fa 48 8b 7f 40 48 8b 07 ff 60 48 66 90 f3 +0x00007e23d676c551: 0f 1e fa 48 8b 7f 40 48 8b 07 ff 60 70 66 90 f3 +0x00007e23d676c561: 0f 1e fa 48 8b 7f 40 48 8b 07 ff 60 78 66 90 f3 +0x00007e23d676c571: 0f 1e fa 41 54 49 89 fc 48 83 ec 10 48 8b b6 80 +0x00007e23d676c581: 00 00 00 64 48 8b 04 25 28 00 00 00 48 89 44 24 + + +Stack slot to memory mapping: + +stack at sp + 0 slots: 0x0 is null +stack at sp + 1 slots: 0x8db8c973edc5b000 is an unknown value +stack at sp + 2 slots: 0x00007e2461491698 is pointing into the stack for thread: 0x00007e24dcd721d0 +stack at sp + 3 slots: 0x00007e23d664e605: in /home/jay/.skiko/466d99514e1c05f31bc8556b637e21363d14da45e8215a739f8d1d8c22184704/libskiko-linux-x64.so at 0x00007e23d6400000 +stack at sp + 4 slots: 0x00007e23e2c34f60 points into unknown readable memory: 0x00007e23d7e51180 | 80 11 e5 d7 23 7e 00 00 +stack at sp + 5 slots: 0x8db8c973edc5b000 is an unknown value +stack at sp + 6 slots: 0x000000004289c4e0 is an unknown value +stack at sp + 7 slots: 0x00007e23d6f95bb4: in /home/jay/.skiko/466d99514e1c05f31bc8556b637e21363d14da45e8215a739f8d1d8c22184704/libskiko-linux-x64.so at 0x00007e23d6400000 + + +Compiled method (n/a) 4866516 6026 n 0 org.jetbrains.skia.paragraph.ParagraphKt::_nLayout (native) + total in heap [0x00007e24cc7c8210,0x00007e24cc7c8588] = 888 + relocation [0x00007e24cc7c8360,0x00007e24cc7c8398] = 56 + main code [0x00007e24cc7c83a0,0x00007e24cc7c857c] = 476 + stub code [0x00007e24cc7c857c,0x00007e24cc7c8580] = 4 + oops [0x00007e24cc7c8580,0x00007e24cc7c8588] = 8 + +[Constant Pool (empty)] + +[MachCode] +[Entry Point] + # {method} {0x00007e2459ce39b8} '_nLayout' '(JF)V' in 'org/jetbrains/skia/paragraph/ParagraphKt' + # parm0: rsi:rsi = long + # parm1: xmm0 = float + # [sp+0x50] (sp of caller) + 0x00007e24cc7c83a0: 448b 5608 | 49bb 0000 | 0062 247e | 0000 4d03 | d349 3bc2 | 0f84 0600 + + 0x00007e24cc7c83b8: ; {runtime_call ic_miss_stub} + 0x00007e24cc7c83b8: 0000 e9c1 | 4e6e ff90 +[Verified Entry Point] + 0x00007e24cc7c83c0: 8984 2400 | c0fe ff55 | 488b ec48 | 83ec 4090 | 4181 7f20 | 0d00 0000 + + 0x00007e24cc7c83d8: ; {runtime_call StubRoutines (final stubs)} + 0x00007e24cc7c83d8: 7405 e881 | e06c ff48 + + 0x00007e24cc7c83e0: ; {oop(a 'java/lang/Class'{0x0000000616c72b08} = 'org/jetbrains/skia/paragraph/ParagraphKt')} + 0x00007e24cc7c83e0: 8bd6 49be | 082b c716 | 0600 0000 | 4c89 7424 | 304c 8d74 | 2430 498b | f6c5 f877 + + 0x00007e24cc7c83fc: ; {internal_word} + 0x00007e24cc7c83fc: 49ba f983 | 7ccc 247e | 0000 4d89 | 97a8 0300 | 0049 89a7 | a003 0000 + + 0x00007e24cc7c8414: ; {external_word} + 0x00007e24cc7c8414: 803d 924a | f516 000f | 8444 0000 | 0056 5248 | 83ec 10c5 | fb11 0424 + + 0x00007e24cc7c842c: ; {metadata({method} {0x00007e2459ce39b8} '_nLayout' '(JF)V' in 'org/jetbrains/skia/paragraph/ParagraphKt')} + 0x00007e24cc7c842c: 48be b839 | ce59 247e | 0000 498b | ff40 f6c4 | 0f0f 8412 | 0000 0048 + + 0x00007e24cc7c8444: ; {runtime_call SharedRuntime::dtrace_method_entry(JavaThread*, Method*)} + 0x00007e24cc7c8444: 83ec 08e8 | 145c 8016 | 4883 c408 | e905 0000 + + 0x00007e24cc7c8454: ; {runtime_call SharedRuntime::dtrace_method_entry(JavaThread*, Method*)} + 0x00007e24cc7c8454: 00e8 065c | 8016 c5fb | 1004 2448 | 83c4 105a | 5e49 8dbf | c003 0000 | 41c7 8754 | 0400 0004 + 0x00007e24cc7c8474: ; {runtime_call Java_org_jetbrains_skia_paragraph_ParagraphKt__1nLayout} + 0x00007e24cc7c8474: 0000 0048 | b830 cf52 | d623 7e00 | 00ff d0c5 | f877 41c7 | 8754 0400 | 0005 0000 | 00f0 8344 + 0x00007e24cc7c8494: 24c0 0049 | 3baf 5804 | 0000 0f87 | 0e00 0000 | 4183 bf50 | 0400 0000 | 0f84 1c00 | 0000 c5f8 + 0x00007e24cc7c84b4: 7749 8bff | 4c8b e448 | 83ec 0048 + + 0x00007e24cc7c84c0: ; {runtime_call JavaThread::check_special_condition_for_native_trans(JavaThread*)} + 0x00007e24cc7c84c0: 83e4 f0e8 | 4896 3616 | 498b e44d | 33e4 41c7 | 8754 0400 | 0008 0000 | 0041 83bf | d004 0000 + 0x00007e24cc7c84e0: 020f 8477 + + 0x00007e24cc7c84e4: ; {external_word} + 0x00007e24cc7c84e4: 0000 0080 | 3dbf 49f5 | 1600 0f84 | 2e00 0000 + + 0x00007e24cc7c84f4: ; {metadata({method} {0x00007e2459ce39b8} '_nLayout' '(JF)V' in 'org/jetbrains/skia/paragraph/ParagraphKt')} + 0x00007e24cc7c84f4: 48be b839 | ce59 247e | 0000 498b | ff40 f6c4 | 0f0f 8412 | 0000 0048 + + 0x00007e24cc7c850c: ; {runtime_call SharedRuntime::dtrace_method_exit(JavaThread*, Method*)} + 0x00007e24cc7c850c: 83ec 08e8 | 5c5b 8016 | 4883 c408 | e905 0000 + + 0x00007e24cc7c851c: ; {runtime_call SharedRuntime::dtrace_method_exit(JavaThread*, Method*)} + 0x00007e24cc7c851c: 00e8 4e5b | 8016 49c7 | 87a0 0300 | 0000 0000 | 0049 c787 | a803 0000 | 0000 0000 | c5f8 7749 + 0x00007e24cc7c853c: 8b8f 3004 | 0000 c781 | 0001 0000 | 0000 0000 | c949 837f | 0800 0f85 | 0100 0000 + + 0x00007e24cc7c8558: ; {runtime_call StubRoutines (initial stubs)} + 0x00007e24cc7c8558: c3e9 a276 | 69ff c5f8 | 774c 8be4 | 4883 ec00 | 4883 e4f0 + + 0x00007e24cc7c856c: ; {runtime_call SharedRuntime::reguard_yellow_pages()} + 0x00007e24cc7c856c: e89f 6980 | 1649 8be4 | 4d33 e4e9 | 6bff ffff +[Stub Code] + 0x00007e24cc7c857c: f4f4 f4f4 +[/MachCode] + + +Compiled method (c2) 4866523 17300 4 androidx.compose.ui.text.platform.SkiaParagraphIntrinsics:: (158 bytes) + total in heap [0x00007e24cd062290,0x00007e24cd065b98] = 14600 + relocation [0x00007e24cd0623e0,0x00007e24cd062648] = 616 + constants [0x00007e24cd062660,0x00007e24cd062680] = 32 + main code [0x00007e24cd062680,0x00007e24cd0644b0] = 7728 + stub code [0x00007e24cd0644b0,0x00007e24cd064598] = 232 + oops [0x00007e24cd064598,0x00007e24cd064620] = 136 + metadata [0x00007e24cd064620,0x00007e24cd0647a8] = 392 + scopes data [0x00007e24cd0647a8,0x00007e24cd0654e8] = 3392 + scopes pcs [0x00007e24cd0654e8,0x00007e24cd065968] = 1152 + dependencies [0x00007e24cd065968,0x00007e24cd065980] = 24 + handler table [0x00007e24cd065980,0x00007e24cd065b48] = 456 + nul chk table [0x00007e24cd065b48,0x00007e24cd065b98] = 80 + + +[Constant Pool] + Address hex4 hex8 + 0x00007e24cd062660: 0x7f800000 0x3727c5ac7f800000 + 0x00007e24cd062664: 0x3727c5ac + 0x00007e24cd062668: 0xf4f4f4f4 0xf4f4f4f4f4f4f4f4 + 0x00007e24cd06266c: 0xf4f4f4f4 + 0x00007e24cd062670: 0xf4f4f4f4 0xf4f4f4f4f4f4f4f4 + 0x00007e24cd062674: 0xf4f4f4f4 + 0x00007e24cd062678: 0xf4f4f4f4 0xf4f4f4f4f4f4f4f4 + 0x00007e24cd06267c: 0xf4f4f4f4 + +[MachCode] +[Entry Point] + # {method} {0x00007e2459c758b8} '' '(Ljava/lang/String;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Ljava/util/List;Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;)V' in 'androidx/compose/ui/text/platform/SkiaParagraphIntrinsics' + # this: rsi:rsi = 'androidx/compose/ui/text/platform/SkiaParagraphIntrinsics' + # parm0: rdx:rdx = 'java/lang/String' + # parm1: rcx:rcx = 'androidx/compose/ui/text/TextStyle' + # parm2: r8:r8 = 'java/util/List' + # parm3: r9:r9 = 'java/util/List' + # parm4: rdi:rdi = 'androidx/compose/ui/unit/Density' + # parm5: [sp+0x60] = 'androidx/compose/ui/text/font/FontFamily$Resolver' (sp of caller) + 0x00007e24cd062680: ; {no_reloc} + 0x00007e24cd062680: 448b 5608 | 49bb 0000 | 0062 247e | 0000 4d03 | d349 3bc2 + + 0x00007e24cd062694: ; {runtime_call ic_miss_stub} + 0x00007e24cd062694: 0f85 e6ab | e4fe 6690 | 0f1f 4000 +[Verified Entry Point] + 0x00007e24cd0626a0: 8984 2400 | c0fe ff55 | 4883 ec50 | 4181 7f20 | 0d00 0000 | 0f85 ea1d | 0000 4c8b | d648 85d2 + 0x00007e24cd0626c0: 0f84 4f16 | 0000 4c8b | d948 85c9 | 0f84 7216 | 0000 4d85 | c00f 8499 | 1600 004d | 85c9 0f84 + 0x00007e24cd0626e0: c016 0000 | 488b ef48 | 85ff 0f84 | e416 0000 | 488b 4c24 | 6048 85c9 | 0f84 0217 | 0000 4180 + 0x00007e24cd062700: 7f38 000f | 8555 0d00 | 0048 8bde | 488b cb4c | 8bd2 49c1 | ea03 4489 | 5314 4d8b | eb49 c1ed + 0x00007e24cd062720: 034d 8bf0 | 49c1 ee03 | 4d8b d149 | c1ea 0344 | 8954 2408 | 4c8b d549 | c1ea 0344 | 8954 240c + 0x00007e24cd062740: 4c8b 5424 | 6049 c1ea | 0344 8954 | 2410 4c8b | d24c 33d1 | 49c1 ea16 | 4d85 d274 | 1a48 c1e9 + 0x00007e24cd062760: 0948 bf00 | 00a0 c024 | 7e00 0048 | 03f9 803f | 020f 851f | 0d00 0041 | 807f 3800 | 0f85 5f0b + 0x00007e24cd062780: 0000 4489 | 6b18 4d8b | d34c 8bdb | 4d33 d349 + + 0x00007e24cd062790: ; {no_reloc} + 0x00007e24cd062790: c1ea 164d | 85d2 741a | 49c1 eb09 | 48bf 0000 | a0c0 247e | 0000 4903 | fb80 3f02 | 0f85 cd0d + 0x00007e24cd0627b0: 0000 4180 | 7f38 000f | 85c5 0b00 | 0044 8973 | 1c4d 8bd0 | 4c8b db4d | 33d3 49c1 | ea16 4d85 + 0x00007e24cd0627d0: d274 1a49 | c1eb 0948 | bf00 00a0 | c024 7e00 | 0049 03fb | 803f 020f | 8508 0e00 | 0041 807f + 0x00007e24cd0627f0: 3800 0f85 | c10b 0000 | 448b 5424 | 0844 8953 | 204d 8bd1 | 4c8b db4d | 33d3 49c1 | ea16 4d85 + 0x00007e24cd062810: d274 1a49 | c1eb 0948 | bf00 00a0 | c024 7e00 | 0049 03fb | 803f 020f | 8522 0e00 | 0041 807f + 0x00007e24cd062830: 3800 0f85 | b80b 0000 | 448b 5c24 | 0c44 895b | 244c 8bd5 | 4c8b db4d | 33d3 49c1 | ea16 4d85 + 0x00007e24cd062850: d274 1a49 | c1eb 0948 | bf00 00a0 | c024 7e00 | 0049 03fb | 803f 020f | 8530 0e00 | 0041 807f + 0x00007e24cd062870: 3800 0f85 | af0b 0000 | 448b 5424 | 1044 8953 | 284c 8b54 | 2460 4c8b | db4d 33d3 | 49c1 ea16 + 0x00007e24cd062890: ; {no_reloc} + 0x00007e24cd062890: 4d85 d274 | 1a49 c1eb | 0948 bf00 | 00a0 c024 | 7e00 0049 | 03fb 803f | 020f 853c | 0e00 0044 + 0x00007e24cd0628b0: 8b5b 1847 | 8b44 dc10 + + 0x00007e24cd0628b8: ; implicit exception: dispatches to 0x00007e24cd0643d8 + 0x00007e24cd0628b8: 478b 54c4 | 1847 8b5c | dc0c 478b | 5cdc 4444 | 8b4b 1445 | 85c9 0f84 | 5815 0000 | 4183 fa01 + 0x00007e24cd0628d8: 0f84 b603 | 0000 4183 | fa02 0f84 | 6c15 0000 | 4183 fa03 | 0f84 8215 | 0000 4181 | fa00 0000 + 0x00007e24cd0628f8: 800f 85a1 | 1500 0049 | ba9c 7e73 | e324 7e00 | 0045 8b02 | 4585 c00f | 85bb 1500 | 0049 8b8f + 0x00007e24cd062918: b801 0000 | 4c8b d149 | 83c2 284d | 3b97 c801 | 0000 0f83 | 2011 0000 | 4d89 97b8 | 0100 004c + 0x00007e24cd062938: 8bc1 4983 | c010 48c7 | 0101 0000 | 0041 0f18 | 8200 0100 + + 0x00007e24cd06294c: ; {metadata('androidx/compose/ui/text/CharHelpers_skikoKt$codePointsOutsideDirectionalIsolate$1')} + 0x00007e24cd06294c: 00c7 4108 | 3888 4d01 | 4489 610c | c5fd efc0 | 41ba 0700 | 0000 c4c1 | 7892 fa62 | d1fe 2f7f + 0x00007e24cd06296c: 0044 8949 | 24c7 4110 | 0200 0000 | 498b 87b8 | 0100 004c | 8bd0 4983 | c220 4d3b | 97c8 0100 + 0x00007e24cd06298c: 000f 83f6 | 1000 004d | 8997 b801 | 0000 410f | 1882 0001 | 0000 48c7 | 0001 0000 | 004c 8bd0 + 0x00007e24cd0629ac: 4983 c210 + + 0x00007e24cd0629b0: ; {metadata('kotlin/sequences/SequenceBuilderIterator')} + 0x00007e24cd0629b0: c740 0810 | f038 0144 | 8960 0cc5 | fdef c062 | d1fe 087f | 0248 895c | 2460 4489 | 5c24 1848 + 0x00007e24cd0629d0: 890c 2448 | 8be8 488b | 3424 488b | d548 8bcd + + 0x00007e24cd0629e0: ; {optimized virtual_call} + 0x00007e24cd0629e0: 6666 90e8 + + 0x00007e24cd0629e4: ; ImmutableOopMap {rbp=Oop [24]=NarrowOop [96]=Oop } + ;*invokevirtual create {reexecute=0 rethrow=0 return_oop=1} + ; - kotlin.coroutines.intrinsics.IntrinsicsKt__IntrinsicsJvmKt::createCoroutineUnintercepted@30 (line 163) + ; - kotlin.sequences.SequencesKt__SequenceBuilderKt::iterator@21 (line 38) + ; - kotlin.sequences.SequencesKt__SequenceBuilderKt$sequence$$inlined$Sequence$1::iterator@6 (line 731) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@10 (line 84) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd0629e4: f8d1 b1f7 + + 0x00007e24cd0629e8: ; {other} + 0x00007e24cd0629e8: 0f1f 8400 | 5807 0000 | 488b d841 | 807f 3800 | 0f85 7e0e | 0000 4889 | 6c24 104c | 8bdb 49c1 + 0x00007e24cd062a08: eb03 4c8b | 5424 1045 | 895a 184c | 8bdb 4d33 | da49 c1eb | 164d 85db | 741f 4885 | db74 1a49 + 0x00007e24cd062a28: c1ea 0948 | bf00 00a0 | c024 7e00 | 0049 03fa | 803f 020f | 85ae 0e00 | 0049 be00 | 00a0 c024 + 0x00007e24cd062a48: 7e00 0045 | 33ed 4c8b | 5424 1045 | 8b5a 0c45 | 85db 756d | 41c7 420c | 0500 0000 | 418b 6a18 + 0x00007e24cd062a68: 85ed 0f84 | c015 0000 | 4180 7f38 | 000f 853d | 0e00 0044 | 896c 2408 | 4c89 3424 | 4c8b 5424 + 0x00007e24cd062a88: 1045 8962 | 1849 8d34 + + 0x00007e24cd062a90: ; {oop(a 'kotlin/Unit'{0x000000061602c928})} + 0x00007e24cd062a90: ec48 ba28 | c902 1606 | 0000 0066 | 9048 b838 | 884d 6324 + + 0x00007e24cd062aa4: ; {virtual_call} + 0x00007e24cd062aa4: 7e00 00e8 + + 0x00007e24cd062aa8: ; ImmutableOopMap {[16]=Oop [24]=NarrowOop [96]=Oop } + ;*invokeinterface resumeWith {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.sequences.SequenceBuilderIterator::hasNext@117 (line 129) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@17 (line 84) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd062aa8: 3406 ddff + + 0x00007e24cd062aac: ; {other} + 0x00007e24cd062aac: 0f1f 8400 | 1c08 0001 | 4d8b 9760 + + 0x00007e24cd062ab8: ; ImmutableOopMap {[16]=Oop [24]=NarrowOop [96]=Oop } + ;*goto {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.sequences.SequenceBuilderIterator::hasNext@122 (line 129) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@17 (line 84) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + ; {poll} + 0x00007e24cd062ab8: 0400 0041 | 8502 4c8b | 3424 448b | 6c24 08eb | 8541 83fb | 030f 85a4 | 0100 0041 | 807f 3800 + 0x00007e24cd062ad8: 0f85 ed0e | 0000 4c8b | 5424 1045 | 8962 0c41 | 8b6a 1045 | 8962 1045 | 8b54 ec08 + + 0x00007e24cd062af4: ; {metadata('java/lang/Integer')} + 0x00007e24cd062af4: 4181 faa0 | fe01 000f | 8527 1800 | 004d 8d14 | ec45 8b5a | 0c41 8beb | c1ed 0885 | ed0f 8585 + 0x00007e24cd062b14: 1500 0041 | 0fb7 eb81 | fd00 0100 | 000f 8341 + + 0x00007e24cd062b24: ; {oop([I{0x0000000616017100})} + 0x00007e24cd062b24: 1400 0049 | ba00 7101 | 1606 0000 | 0045 8b54 | aa10 41c1 | ea1b 4183 | e20f 4183 | fa0f 0f84 + 0x00007e24cd062b44: cd15 0000 + + 0x00007e24cd062b48: ; {oop(a 'kotlin/SynchronizedLazyImpl'{0x0000000616a7a148})} + 0x00007e24cd062b48: 49bb 48a1 | a716 0600 | 0000 458b + + 0x00007e24cd062b54: ; {oop(a 'kotlin/UNINITIALIZED_VALUE'{0x000000061601b230})} + 0x00007e24cd062b54: 4310 4181 | f846 36c0 | c20f 8482 | 0500 0045 | 85c0 0f84 | ad14 0000 | 498b d848 | c1e3 0344 + 0x00007e24cd062b74: ; {metadata('java/util/LinkedHashMap')} + 0x00007e24cd062b74: 8b43 0841 | 81f8 f83b | 0d00 0f85 | c017 0000 | 4c8b db45 | 8b4b 2443 | 8b6c cc0c | 85ed 0f86 + 0x00007e24cd062b94: 3015 0000 | 4f8d 04cc | ffcd 4123 | ea45 8b44 | a810 478b + + 0x00007e24cd062ba8: ; {oop(a 'java/lang/Integer'[256] {0x0000000616401160})} + 0x00007e24cd062ba8: 4cc4 0c48 | b960 1140 | 1606 0000 | 0042 8bac | 9110 0200 | 0045 3bca | 0f85 7604 | 0000 478b + 0x00007e24cd062bc8: 4cc4 1044 | 3bcd 7450 + + 0x00007e24cd062bd0: ; implicit exception: dispatches to 0x00007e24cd062bea + 0x00007e24cd062bd0: 438b 4ccc + + 0x00007e24cd062bd4: ; {metadata('java/lang/Integer')} + 0x00007e24cd062bd4: 0881 f9a0 | fe01 0075 | 0d49 c1e1 | 0341 8b49 | 0c44 3bd1 | 7436 be45 | ffff ff4c | 8b4c 2410 + 0x00007e24cd062bf4: 4c89 4c24 | 088b 4c24 | 1889 4c24 | 104c 895c | 2418 4489 | 4424 2044 | 8954 2424 + + 0x00007e24cd062c10: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd062c10: 6666 90e8 + + 0x00007e24cd062c14: ; ImmutableOopMap {rbp=NarrowOop [8]=Oop [16]=NarrowOop [24]=Oop [32]=NarrowOop [96]=Oop } + ;*ifeq {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) java.util.HashMap::getNode@66 (line 578) + ; - java.util.LinkedHashMap::get@2 (line 536) + ; - kotlin.text.CharDirectionality$Companion::valueOf@8 (line 121) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@7 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd062c14: 6839 e5fe + + 0x00007e24cd062c18: ; {other} + 0x00007e24cd062c18: 0f1f 8400 | 8809 0003 | 4b8d 0cc4 | 450f b64b | 3045 85c9 | 0f85 d00d | 0000 8b69 | 1445 8b44 + 0x00007e24cd062c38: ; {metadata('kotlin/text/CharDirectionality')} + 0x00007e24cd062c38: ec08 4181 | f8b8 8f4d | 010f 8525 | 1700 004d | 8d14 ec41 | 8b6a 0c83 | fd14 0f83 | 2c13 0000 + 0x00007e24cd062c58: ; {oop([I{0x0000000616a7a6e8})} + 0x00007e24cd062c58: 49ba e8a6 | a716 0600 | 0000 418b | 6caa 1083 | fd01 0f85 | 8613 0000 | 488b 5c24 | 60eb 2a41 + 0x00007e24cd062c78: 83fb 040f | 851f 1300 | 00be 45ff + + 0x00007e24cd062c84: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd062c84: ffff 90e8 + + 0x00007e24cd062c88: ; ImmutableOopMap {[24]=NarrowOop [96]=Oop } + ;*ifeq {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@22 (line 84) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd062c88: f438 e5fe + + 0x00007e24cd062c8c: ; {other} + 0x00007e24cd062c8c: 0f1f 8400 | fc09 0004 | 49be 0000 | a0c0 247e | 0000 4533 | ed41 807f | 3800 0f85 | 8d0a 0000 + 0x00007e24cd062cac: ; {oop(a 'androidx/compose/ui/text/style/ResolvedTextDirection'{0x0000000616b29178})} + 0x00007e24cd062cac: c743 2c2f | 52d6 c24c + + 0x00007e24cd062cb4: ; {oop(a 'androidx/compose/ui/text/style/ResolvedTextDirection'{0x0000000616b29178})} + 0x00007e24cd062cb4: 8bd3 49bb | 7891 b216 | 0600 0000 | 4d33 da49 | c1eb 164d | 85db 741a | 49c1 ea09 | 48bf 0000 + 0x00007e24cd062cd4: a0c0 247e | 0000 4903 | fa80 3f02 | 0f85 d70a | 0000 4489 | 6c24 084c | 8934 2448 | 895c 2460 + 0x00007e24cd062cf4: ; {optimized virtual_call} + 0x00007e24cd062cf4: 488b f3e8 + + 0x00007e24cd062cf8: ; ImmutableOopMap {[96]=Oop } + ;*invokespecial newLayouter {reexecute=0 rethrow=0 return_oop=1} + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@106 (line 56) + 0x00007e24cd062cf8: 8469 bfff + + 0x00007e24cd062cfc: ; {other} + 0x00007e24cd062cfc: 0f1f 8400 | 6c0a 0005 | 488b d841 | 807f 3800 | 0f85 6f0a | 0000 4c8b | d349 c1ea | 034c 8b5c + 0x00007e24cd062d1c: 2460 4589 | 5330 4d8b | d34c 8bdb | 4d33 da49 | c1eb 164d | 85db 0f84 | 380a 0000 | 4885 db0f + 0x00007e24cd062d3c: 8425 0b00 | 0049 c1ea | 0948 bf00 | 00a0 c024 | 7e00 0049 | 03fa 803f | 020f 85b0 | 0a00 0044 + 0x00007e24cd062d5c: 8b53 1c8b | 6b18 4585 | d20f 85a9 | 0000 0085 | ed0f 84e1 | 1100 0048 | 895c 2408 | 498d 34ec + 0x00007e24cd062d7c: ; {optimized virtual_call} + 0x00007e24cd062d7c: 6666 90e8 + + 0x00007e24cd062d80: ; ImmutableOopMap {[8]=Oop [96]=Oop } + ;*invokevirtual build {reexecute=0 rethrow=0 return_oop=1} + ; - androidx.compose.ui.text.platform.ParagraphLayouter::layoutParagraph@74 (line 213) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@123 (line 80) + 0x00007e24cd062d80: 9c74 b8ff + + 0x00007e24cd062d84: ; {other} + 0x00007e24cd062d84: 0f1f 8400 | f40a 0006 + + 0x00007e24cd062d8c: ; implicit exception: dispatches to 0x00007e24cd064400 + 0x00007e24cd062d8c: 488b 7010 + + 0x00007e24cd062d90: ; {oop(a 'java/lang/Class'{0x00000006169bdd58} = 'org/jetbrains/skia/impl/Stats')} + 0x00007e24cd062d90: 49ba 58dd | 9b16 0600 | 0000 410f | b6aa 8000 | 0000 85ed | 0f85 cf12 | 0000 488b + + 0x00007e24cd062dac: ; {section_word} + 0x00007e24cd062dac: e8c5 fa10 | 05ab f8ff + + 0x00007e24cd062db4: ; {static_call} + 0x00007e24cd062db4: ff66 90e8 + + 0x00007e24cd062db8: ; ImmutableOopMap {rbp=Oop [8]=Oop [96]=Oop } + ;*invokestatic _nLayout {reexecute=0 rethrow=0 return_oop=0} + ; - org.jetbrains.skia.paragraph.ParagraphKt::access$_nLayout@2 (line 1) + ; - org.jetbrains.skia.paragraph.Paragraph::layout@11 (line 84) + ; - androidx.compose.ui.text.platform.ParagraphLayouter::layoutParagraph@80 (line 214) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@123 (line 80) + 0x00007e24cd062db8: 0456 76ff + + 0x00007e24cd062dbc: ; {other} + 0x00007e24cd062dbc: 0f1f 8400 | 2c0b 0007 | 4180 7f38 | 000f 856e | 0b00 0048 | 8b5c 2408 | 4c8b d34c | 8bdd 49c1 + 0x00007e24cd062ddc: eb03 4489 | 5b1c 4c8b | dd4d 33da | 49c1 eb16 | 4d85 db74 | 1549 c1ea | 094c 8b04 | 244d 03c2 + 0x00007e24cd062dfc: 4180 3802 | 0f85 730b | 0000 4488 | 6310 4889 | 6c24 08e9 | 9100 0000 | 440f b643 | 104f 8d0c + 0x00007e24cd062e1c: d445 85c0 | 0f85 2401 | 0000 448b | 4424 08c5 | fa10 430c + + 0x00007e24cd062e30: ; {section_word} + 0x00007e24cd062e30: c5fa 5c0d | 28f8 ffff + + 0x00007e24cd062e38: ; {section_word} + 0x00007e24cd062e38: c5fa 1005 | 24f8 ffff + + 0x00007e24cd062e40: ; {external_word} + 0x00007e24cd062e40: c5f0 5415 | 58d0 dffe | c5f8 2ec2 | 7607 4585 | c075 09eb | 4bc7 430c | 0000 807f + + 0x00007e24cd062e5c: ; {oop(a 'java/lang/Class'{0x00000006169bdd58} = 'org/jetbrains/skia/impl/Stats')} + 0x00007e24cd062e5c: 49bb 58dd | 9b16 0600 | 0000 410f | b6ab 8000 | 0000 85ed | 0f85 ce11 | 0000 4b8b + + 0x00007e24cd062e78: ; {section_word} + 0x00007e24cd062e78: 74d4 10c5 | fa10 05dd | f7ff ff4c | 890c 244c | 894c 2408 + + 0x00007e24cd062e8c: ; {static_call} + 0x00007e24cd062e8c: 6666 90e8 + + 0x00007e24cd062e90: ; ImmutableOopMap {[0]=Oop [8]=Oop [96]=Oop } + ;*invokestatic _nLayout {reexecute=0 rethrow=0 return_oop=0} + ; - org.jetbrains.skia.paragraph.ParagraphKt::access$_nLayout@2 (line 1) + ; - org.jetbrains.skia.paragraph.Paragraph::layout@11 (line 84) + ; - androidx.compose.ui.text.platform.ParagraphLayouter::layoutParagraph@62 (line 209) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@123 (line 80) + 0x00007e24cd062e90: ecb2 e4fe + + 0x00007e24cd062e94: ; {other} + 0x00007e24cd062e94: 0f1f 8400 | 040c 0008 | 4c8b 0c24 | 4c89 4c24 + + 0x00007e24cd062ea4: ; {oop(a 'java/lang/Class'{0x00000006169bdd58} = 'org/jetbrains/skia/impl/Stats')} + 0x00007e24cd062ea4: 0849 ba58 | dd9b 1606 | 0000 0041 | 0fb6 aa80 | 0000 0085 | ed0f 856b | 1000 004c | 8b54 2408 + 0x00007e24cd062ec4: 498b 7210 + + 0x00007e24cd062ec8: ; {static_call} + 0x00007e24cd062ec8: 6666 90e8 + + 0x00007e24cd062ecc: ; ImmutableOopMap {[8]=Oop [96]=Oop } + ;*invokestatic _nGetMinIntrinsicWidth {reexecute=0 rethrow=0 return_oop=0} + ; - org.jetbrains.skia.paragraph.ParagraphKt::access$_nGetMinIntrinsicWidth@1 (line 1) + ; - org.jetbrains.skia.paragraph.Paragraph::getMinIntrinsicWidth@11 (line 40) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@131 (line 81) + 0x00007e24cd062ecc: 7023 80ff + + 0x00007e24cd062ed0: ; {other} + 0x00007e24cd062ed0: 0f1f 8400 | 400c 0009 + + 0x00007e24cd062ed8: ; {oop(a 'java/lang/Class'{0x00000006169bdd58} = 'org/jetbrains/skia/impl/Stats')} + 0x00007e24cd062ed8: 49ba 58dd | 9b16 0600 | 0000 450f | b682 8000 | 0000 c5fa | 5ac0 c4e3 | 790b c002 | c5fb 5ac0 + 0x00007e24cd062ef8: 488b 6c24 | 60c5 fa11 | 450c 4585 | c00f 8531 | 1000 004c | 8b54 2408 | 498b 7210 + + 0x00007e24cd062f14: ; {static_call} + 0x00007e24cd062f14: 6666 90e8 + + 0x00007e24cd062f18: ; ImmutableOopMap {rbp=Oop [8]=Oop } + ;*invokestatic _nGetMaxIntrinsicWidth {reexecute=0 rethrow=0 return_oop=0} + ; - org.jetbrains.skia.paragraph.ParagraphKt::access$_nGetMaxIntrinsicWidth@1 (line 1) + ; - org.jetbrains.skia.paragraph.Paragraph::getMaxIntrinsicWidth@11 (line 47) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@145 (line 82) + 0x00007e24cd062f18: 2427 80ff + + 0x00007e24cd062f1c: ; {other} + 0x00007e24cd062f1c: 0f1f 8400 | 8c0c 000a | c5fa 5ac0 | c4e3 790b | c002 c5f3 | 5ac8 c5fa | 114d 1048 | 83c4 505d + 0x00007e24cd062f3c: ; {poll_return} + 0x00007e24cd062f3c: 493b a758 | 0400 000f | 8745 1500 | 00c3 85ed | 0f84 da11 | 0000 4c89 | 4c24 1044 | 8954 240c + 0x00007e24cd062f5c: 4889 1c24 | 4d8d 14ec | 4c89 5424 | 1849 8bf2 + + 0x00007e24cd062f6c: ; {optimized virtual_call} + 0x00007e24cd062f6c: 6666 90e8 + + 0x00007e24cd062f70: ; ImmutableOopMap {rbp=NarrowOop [0]=Oop [12]=NarrowOop [16]=Oop [24]=Oop [96]=Oop } + ;*invokespecial prepareDefaultStyle {reexecute=0 rethrow=0 return_oop=0} + ; - androidx.compose.ui.text.platform.ParagraphBuilder::updateForegroundPaint@6 (line 296) + ; - androidx.compose.ui.text.platform.ParagraphLayouter::layoutParagraph@23 (line 196) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@123 (line 80) + 0x00007e24cd062f70: 0ca8 e4fe + + 0x00007e24cd062f74: ; {other} + 0x00007e24cd062f74: 0f1f 8400 | e40c 000b | 458b 54ec | 4045 85d2 | 0f84 ba11 | 0000 4b8d + + 0x00007e24cd062f8c: ; {optimized virtual_call} + 0x00007e24cd062f8c: 34d4 90e8 + + 0x00007e24cd062f90: ; ImmutableOopMap {rbp=NarrowOop [0]=Oop [12]=NarrowOop [16]=Oop [24]=Oop [96]=Oop } + ;*invokevirtual getForegroundPaint {reexecute=0 rethrow=0 return_oop=1} + ; - androidx.compose.ui.text.platform.ParagraphBuilder::updateForegroundPaint@13 (line 297) + ; - androidx.compose.ui.text.platform.ParagraphLayouter::layoutParagraph@23 (line 196) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@123 (line 80) + 0x00007e24cd062f90: eca7 e4fe + + 0x00007e24cd062f94: ; {other} + 0x00007e24cd062f94: 0f1f 8400 | 040d 000c | 4889 4424 | 1845 8b5c | ec20 4585 | db0f 84a9 | 1100 004b | 8d34 dc48 + 0x00007e24cd062fb4: 8b6c 2460 + + 0x00007e24cd062fb8: ; {optimized virtual_call} + 0x00007e24cd062fb8: 6666 90e8 + + 0x00007e24cd062fbc: ; ImmutableOopMap {rbp=Oop [0]=Oop [12]=NarrowOop [16]=Oop [24]=Oop [96]=Oop } + ;*invokevirtual length {reexecute=0 rethrow=0 return_oop=0} + ; - androidx.compose.ui.text.platform.ParagraphBuilder::updateForegroundPaint@23 (line 298) + ; - androidx.compose.ui.text.platform.ParagraphLayouter::layoutParagraph@23 (line 196) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@123 (line 80) + 0x00007e24cd062fbc: c0a7 e4fe + + 0x00007e24cd062fc0: ; {other} + 0x00007e24cd062fc0: 0f1f 8400 | 300d 000d | 488b 7424 | 108b 5424 | 088b c84c | 8b44 2418 + + 0x00007e24cd062fd8: ; {optimized virtual_call} + 0x00007e24cd062fd8: 6666 90e8 + + 0x00007e24cd062fdc: ; ImmutableOopMap {rbp=Oop [0]=Oop [12]=NarrowOop [16]=Oop [96]=Oop } + ;*invokevirtual updateForegroundPaint {reexecute=0 rethrow=0 return_oop=1} + ; - androidx.compose.ui.text.platform.ParagraphBuilder::updateForegroundPaint@27 (line 298) + ; - androidx.compose.ui.text.platform.ParagraphLayouter::layoutParagraph@23 (line 196) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@123 (line 80) + 0x00007e24cd062fdc: a0a7 e4fe + + 0x00007e24cd062fe0: ; {other} + 0x00007e24cd062fe0: 0f1f 8400 | 500d 000e | 4c8b 1424 | 4588 6210 + + 0x00007e24cd062ff0: ; {oop(a 'org/jetbrains/skia/impl/Stats'{0x00000006169bde20})} + 0x00007e24cd062ff0: 48be 20de | 9b16 0600 + + 0x00007e24cd062ff8: ; {optimized virtual_call} + 0x00007e24cd062ff8: 0000 90e8 + + 0x00007e24cd062ffc: ; ImmutableOopMap {rbp=Oop [0]=Oop [12]=NarrowOop [16]=Oop [96]=Oop } + ;*invokevirtual onNativeCall {reexecute=0 rethrow=0 return_oop=0} + ; - org.jetbrains.skia.paragraph.Paragraph::markDirty@3 (line 178) + ; - androidx.compose.ui.text.platform.ParagraphLayouter::layoutParagraph@32 (line 201) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@123 (line 80) + 0x00007e24cd062ffc: 80a7 e4fe + + 0x00007e24cd063000: ; {other} + 0x00007e24cd063000: 0f1f 8400 | 700d 000f | 448b 5424 | 0c4b 8b74 + + 0x00007e24cd063010: ; {static_call} + 0x00007e24cd063010: d410 90e8 + + 0x00007e24cd063014: ; ImmutableOopMap {rbp=Oop [0]=Oop [12]=NarrowOop [16]=Oop [96]=Oop } + ;*invokestatic _nMarkDirty {reexecute=0 rethrow=0 return_oop=0} + ; - org.jetbrains.skia.paragraph.ParagraphKt::access$_nMarkDirty@1 (line 1) + ; - org.jetbrains.skia.paragraph.Paragraph::markDirty@10 (line 179) + ; - androidx.compose.ui.text.platform.ParagraphLayouter::layoutParagraph@32 (line 201) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@123 (line 80) + 0x00007e24cd063014: 68b1 e4fe + + 0x00007e24cd063018: ; {other} + 0x00007e24cd063018: 0f1f 8400 | 880d 0010 | 41b8 0100 | 0000 488b | 1c24 448b | 5424 0c4c | 8b5c 2410 | 4d8b cbe9 + 0x00007e24cd063038: effd ffff | 478b 4cc4 | 1845 85c9 | 0f84 2211 | 0000 438b + + 0x00007e24cd06304c: ; {metadata('java/util/HashMap$TreeNode')} + 0x00007e24cd06304c: 4cc4 0881 | f9b0 6216 | 000f 8429 | 1100 004b | 8d0c cc44 | 8b49 0c45 | 3bca 741a | 498b bf60 + 0x00007e24cd06306c: 0400 008b + + 0x00007e24cd063070: ; ImmutableOopMap {r11=Oop rcx=NarrowOop rbp=NarrowOop [16]=Oop [24]=NarrowOop [96]=Oop } + ;*ifnonnull {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) java.util.HashMap::getNode@145 (line 587) + ; - java.util.LinkedHashMap::get@2 (line 536) + ; - kotlin.text.CharDirectionality$Companion::valueOf@8 (line 121) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@7 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + ; {poll} + 0x00007e24cd063070: 4918 8507 | 85c9 0f84 | f010 0000 | 48c1 e103 | ebdd 448b | 4110 443b | c50f 8495 | fbff ff48 + 0x00007e24cd063090: 894c 2428 | 4c89 5c24 | 2044 8954 | 241c 4489 | 6c24 084c | 8934 2449 | 8bd0 48c1 | e203 498d + 0x00007e24cd0630b0: ; {optimized virtual_call} + 0x00007e24cd0630b0: 34ec 90e8 + + 0x00007e24cd0630b4: ; ImmutableOopMap {rbp=NarrowOop [16]=Oop [24]=NarrowOop [32]=Oop [40]=Oop [96]=Oop } + ;*invokevirtual equals {reexecute=0 rethrow=0 return_oop=0} + ; - java.util.HashMap::getNode@128 (line 585) + ; - java.util.LinkedHashMap::get@2 (line 536) + ; - kotlin.text.CharDirectionality$Companion::valueOf@8 (line 121) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@7 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd0630b4: c8a6 e4fe + + 0x00007e24cd0630b8: ; {other} + 0x00007e24cd0630b8: 0f1f 8400 | 280e 0012 | 85c0 0f84 | 8e11 0000 | 4c8b 3424 | 448b 6c24 | 0844 8b54 | 241c 4c8b + 0x00007e24cd0630d8: 5c24 2048 | 8b4c 2428 | e93f fbff | ff45 8b5b | 1445 85db | 0f84 ca10 | 0000 4f8d | 0cdc 488d + 0x00007e24cd0630f8: 5c24 4049 | 8b01 a802 | 0f85 2300 | 0000 4883 | c801 4889 | 03f0 490f | b119 0f84 | 3700 0000 + 0x00007e24cd063118: 482b c448 | 2507 f0ff | ff48 8903 | e924 0000 | 004c 8bc0 | 4833 c0f0 | 4d0f b178 | 3e48 c703 + 0x00007e24cd063138: 0300 0000 | 7411 4c3b | f875 1549 | ff80 8600 | 0000 4833 | c075 0949 | ff87 5805 | 0000 33c0 + 0x00007e24cd063158: 0f85 7610 + + 0x00007e24cd06315c: ; {oop(a 'kotlin/SynchronizedLazyImpl'{0x0000000616a7a148})} + 0x00007e24cd06315c: 0000 49b8 | 48a1 a716 | 0600 0000 | 418b 6810 + + 0x00007e24cd06316c: ; {oop(a 'kotlin/UNINITIALIZED_VALUE'{0x000000061601b230})} + 0x00007e24cd06316c: 81fd 4636 | c0c2 0f85 | 4e11 0000 | 418b 680c | 85ed 0f84 | 7411 0000 | 4c89 4c24 | 2044 895c + 0x00007e24cd06318c: 241c 4489 | 5424 0c44 | 896c 2408 | 4c89 3424 | 498d 34ec | 9048 b8ff | ffff ffff + + 0x00007e24cd0631a8: ; {virtual_call} + 0x00007e24cd0631a8: ffff ffe8 + + 0x00007e24cd0631ac: ; ImmutableOopMap {[16]=Oop [24]=NarrowOop [28]=NarrowOop [32]=Oop [96]=Oop } + ;*invokeinterface invoke {reexecute=0 rethrow=0 return_oop=1} + ; - kotlin.SynchronizedLazyImpl::getValue@51 (line 86) + ; - kotlin.text.CharDirectionality$Companion::getDirectionalityMap@5 (line 118) + ; - kotlin.text.CharDirectionality$Companion::valueOf@1 (line 121) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@7 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd0631ac: d0aa e4fe + + 0x00007e24cd0631b0: ; {other} + 0x00007e24cd0631b0: 0f1f 8400 | 200f 0013 | 488b d841 | 807f 3800 | 0f85 f308 | 0000 4c8b | db49 c1eb + + 0x00007e24cd0631cc: ; {oop(a 'kotlin/SynchronizedLazyImpl'{0x0000000616a7a148})} + 0x00007e24cd0631cc: 0349 ba48 | a1a7 1606 | 0000 0045 | 895a 104c | 8bdb 4d33 | da49 c1eb | 164d 85db | 741f 4885 + 0x00007e24cd0631ec: db74 1a49 | c1ea 0948 | bf00 00a0 | c024 7e00 | 0049 03fa | 803f 020f | 8532 0900 | 00f0 8344 + 0x00007e24cd06320c: 24c0 0041 | 807f 3800 | 0f85 e008 + + 0x00007e24cd063218: ; {oop(a 'kotlin/SynchronizedLazyImpl'{0x0000000616a7a148})} + 0x00007e24cd063218: 0000 49ba | 48a1 a716 | 0600 0000 | 4589 620c | 4c8b 5c24 | 2048 8d44 | 2440 4883 | 3800 0f84 + 0x00007e24cd063238: 7900 0000 | 4d8b 1341 | f6c2 020f | 8462 0000 | 0049 83ba | 8600 0000 | 0074 0949 | ff8a 8600 + 0x00007e24cd063258: 0000 eb4b | 498b 8296 | 0000 0049 | 0b82 8e00 | 0000 750a | 49c7 423e | 0000 0000 | eb3d 4983 + 0x00007e24cd063278: ba9e 0000 | 0000 7422 | 4833 c049 | c742 3e00 | 0000 00f0 | 8304 2400 | 4983 ba9e | 0000 0000 + 0x00007e24cd063298: 750d f04d | 0fb1 7a3e | 7505 83c8 | 01eb 0ca8 | 00eb 084c | 8b10 f04d | 0fb1 1375 | 0a49 ff8f + 0x00007e24cd0632b8: 5805 0000 | 4533 d20f | 856c 0f00 | 0048 85db | 0f84 460d | 0000 4c8b | 3424 448b | 6c24 0844 + 0x00007e24cd0632d8: 8b54 240c | e992 f8ff | ff8b 4b18 | 85c9 0f84 | 96f4 ffff | 4d8b 5728 | 488b f948 | c1e7 034d + 0x00007e24cd0632f8: 85d2 0f84 | 8c09 0000 | 4889 4424 | f88b 4424 | 1089 4424 | 2048 8b44 | 24f8 4889 | 4424 f88b + 0x00007e24cd063318: ; {no_reloc} + 0x00007e24cd063318: 4424 0c89 | 4424 1c48 | 8b44 24f8 | 4889 4424 | f88b 4424 | 0889 4424 | 1848 8b44 | 24f8 498b + 0x00007e24cd063338: 4f30 4a89 | 7c11 f849 | 83c2 f84d | 8957 2848 | 8944 24f8 | 8b44 2418 | 8944 2408 | 488b 4424 + 0x00007e24cd063358: f848 8944 | 24f8 8b44 | 241c 8944 | 240c 488b | 4424 f848 | 8944 24f8 | 8b44 2420 | 8944 2410 + 0x00007e24cd063378: 488b 4424 | f8e9 00f4 | ffff 448b | 531c 4585 | d20f 842e | f4ff ff4d | 8b5f 2849 | 8bfa 48c1 + 0x00007e24cd063398: e703 4d85 | db0f 84e6 | 0700 004d | 8b57 304b | 897c 1af8 | 4983 c3f8 | 4d89 5f28 | e904 f4ff + 0x00007e24cd0633b8: ff44 8b5b | 2045 85db | 0f84 32f4 | ffff 4d8b | 5728 498b | fb48 c1e7 | 034d 85d2 | 0f84 f407 + 0x00007e24cd0633d8: 0000 4d8b | 5f30 4b89 | 7c13 f849 | 83c2 f84d | 8957 28e9 | 08f4 ffff | 448b 5b24 | 4585 db0f + 0x00007e24cd0633f8: 843b f4ff | ff4d 8b57 | 2849 8bfb | 48c1 e703 | 4d85 d20f | 84e6 0700 | 004d 8b5f | 304b 897c + 0x00007e24cd063418: ; {no_reloc} + 0x00007e24cd063418: 13f8 4983 | c2f8 4d89 | 5728 e911 | f4ff ff44 | 8b5b 2845 | 85db 0f84 | 44f4 ffff | 4d8b 5728 + 0x00007e24cd063438: 498b fb48 | c1e7 034d | 85d2 0f84 | cc07 0000 | 4d8b 5f30 | 4b89 7c13 | f849 83c2 | f84d 8957 + 0x00007e24cd063458: 28e9 1af4 | ffff 488b | de8b 4e14 | 85c9 0f84 | a0f2 ffff | 4d8b 5728 | 488b f948 | c1e7 034d + 0x00007e24cd063478: 85d2 0f84 | b107 0000 | 498b 4f30 | 4a89 7c11 | f849 83c2 | f84d 8957 | 28e9 76f2 | ffff 4889 + 0x00007e24cd063498: 4424 f88b | 4424 1089 | 4424 2048 | 8b44 24f8 | 4889 4424 | f88b 4424 | 0c89 4424 | 1c48 8b44 + 0x00007e24cd0634b8: 24f8 4889 | 4424 f88b | 4424 0889 | 4424 1848 | 8b44 24f8 | 4d8b 5740 | 498b 4f48 | f083 4424 + 0x00007e24cd0634d8: c000 803f | 0074 6544 | 8827 4d85 | d274 0f4a | 897c 11f8 | 4983 c2f8 | 4d89 5740 | eb4e 4c8b + 0x00007e24cd0634f8: 5424 604c | 8954 2410 | 4889 6c24 | 084c 890c | 244c 8944 | 2460 498b | eb49 8bf7 + + 0x00007e24cd063514: ; {no_reloc} + 0x00007e24cd063514: 49ba 10da | 9be2 247e | 0000 41ff + + 0x00007e24cd063520: ; {other} + 0x00007e24cd063520: d20f 1f84 | 0000 0000 | 004c 8bdd | 4c8b 4424 | 604c 8b0c | 2448 8b6c | 2408 4c8b | 5424 104c + 0x00007e24cd063540: 8954 2460 | 4889 4424 | f88b 4424 | 1889 4424 | 0848 8b44 | 24f8 4889 | 4424 f88b | 4424 1c89 + 0x00007e24cd063560: 4424 0c48 | 8b44 24f8 | 4889 4424 | f88b 4424 | 2089 4424 | 1048 8b44 | 24f8 e9f8 | f1ff ff4d + 0x00007e24cd063580: 8b57 404d | 8b5f 48f0 | 8344 24c0 | 0080 3f00 | 0f84 1cf2 | ffff 4488 | 274d 85d2 | 7545 4c8b + 0x00007e24cd0635a0: 5424 604c | 8914 2448 | 896c 2460 | 4d8b e949 | 8be8 498b | f749 ba10 | da9b e224 | 7e00 0041 + 0x00007e24cd0635c0: ; {other} + 0x00007e24cd0635c0: ffd2 0f1f | 8400 0000 | 0000 4c8b | c54d 8bcd | 488b 6c24 | 604c 8b14 | 244c 8954 | 2460 e9cf + 0x00007e24cd0635e0: f1ff ff4b | 897c 13f8 | 4983 c2f8 | 4d89 5740 | e9bd f1ff | ff4d 8b57 | 404d 8b5f | 48f0 8344 + 0x00007e24cd063600: 24c0 0080 | 3f00 0f84 | e1f1 ffff | 4488 274d | 85d2 7529 | 4c8b ed49 | 8be9 498b | f749 ba10 + 0x00007e24cd063620: da9b e224 | 7e00 0041 + + 0x00007e24cd063628: ; {other} + 0x00007e24cd063628: ffd2 0f1f | 8400 0000 | 0000 4c8b | cd49 8bed | e9b0 f1ff | ff4b 897c | 13f8 4983 | c2f8 4d89 + 0x00007e24cd063648: 5740 e99e | f1ff ff4d | 8b57 404d | 8b5f 48f0 | 8344 24c0 | 0080 3f00 | 0f84 c7f1 | ffff 4488 + 0x00007e24cd063668: 274d 85d2 | 751d 498b | f749 ba10 | da9b e224 | 7e00 0041 + + 0x00007e24cd06367c: ; {other} + 0x00007e24cd06367c: ffd2 0f1f | 8400 0000 | 0000 e9a2 | f1ff ff4b | 897c 13f8 | 4983 c2f8 | 4d89 5740 | e990 f1ff + 0x00007e24cd06369c: ff4d 8b57 | 404d 8b5f | 48f0 8344 | 24c0 0080 | 3f00 0f84 | b9f1 ffff | 4488 274d | 85d2 751d + 0x00007e24cd0636bc: 498b f749 | ba10 da9b | e224 7e00 | 0041 ffd2 + + 0x00007e24cd0636cc: ; {other} + 0x00007e24cd0636cc: 0f1f 8400 | 0000 0000 | e994 f1ff | ff4b 897c | 13f8 4983 | c2f8 4d89 | 5740 e982 | f1ff ff4d + 0x00007e24cd0636ec: 8b57 404d | 8b5f 48f0 | 8344 24c0 | 0080 3f00 | 0f84 adf1 | ffff 4488 | 274d 85d2 | 751d 498b + 0x00007e24cd06370c: f749 ba10 | da9b e224 | 7e00 0041 + + 0x00007e24cd063718: ; {other} + 0x00007e24cd063718: ffd2 0f1f | 8400 0000 | 0000 e988 | f1ff ff4b | 897c 13f8 | 4983 c2f8 | 4d89 5740 | e976 f1ff + 0x00007e24cd063738: ff44 8b5b | 2c45 85db | 0f84 66f5 | ffff 4d8b | 5728 498b | fb48 c1e7 | 034d 85d2 | 0f84 9607 + 0x00007e24cd063758: 0000 4d8b | 5f30 4b89 | 7c13 f849 | 83c2 f84d | 8957 28e9 | 3cf5 ffff | 4885 db0f | 85e2 f5ff + 0x00007e24cd063778: ff48 8beb | e9e8 0000 | 004c 8b54 | 2460 458b | 5a30 4585 | db0f 847f | f5ff ff4d | 8b57 2849 + 0x00007e24cd063798: 8bfb 48c1 | e703 4d85 | d20f 8466 | 0700 004d | 8b5f 304b | 897c 13f8 | 4983 c2f8 | 4d89 5728 + 0x00007e24cd0637b8: e955 f5ff | ff4d 8b57 | 404d 8b5f | 48f0 8344 | 24c0 0080 | 3f00 0f84 | 12f5 ffff | 4488 274d + 0x00007e24cd0637d8: 85d2 751d | 498b f749 | ba10 da9b | e224 7e00 | 0041 ffd2 + + 0x00007e24cd0637ec: ; {other} + 0x00007e24cd0637ec: 0f1f 8400 | 0000 0000 | e9ed f4ff | ff4b 897c | 13f8 4983 | c2f8 4d89 | 5740 e9db | f4ff ff4d + 0x00007e24cd06380c: 8b57 484d | 8b5f 40f0 | 8344 24c0 | 0080 3f00 | 742f 4488 | 274d 85db | 740f 4b89 | 7c1a f849 + 0x00007e24cd06382c: 83c3 f84d | 895f 40eb | 1849 8bf7 | 49ba 10da | 9be2 247e | 0000 41ff + + 0x00007e24cd063844: ; {other} + 0x00007e24cd063844: d20f 1f84 | 0000 0000 | 004c 8b54 | 2460 458b | 5230 498b | da48 c1e3 | 0345 85d2 | 0f85 f5f4 + 0x00007e24cd063864: ffff 488b | ebbe 45ff + + 0x00007e24cd06386c: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd06386c: ffff 90e8 + + 0x00007e24cd063870: ; ImmutableOopMap {rbp=Oop [96]=Oop } + ;*ifnonnull {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::checkNotNull@1 (line 24) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@118 (line 80) + 0x00007e24cd063870: 0c2d e5fe + + 0x00007e24cd063874: ; {other} + 0x00007e24cd063874: 0f1f 8400 | e415 0014 | 4889 6c24 | 1044 8b55 | 1845 85d2 | 0f84 75f1 | ffff 4d8b | 5f28 498b + 0x00007e24cd063894: fa48 c1e7 | 034d 85db | 0f84 1a07 | 0000 4d8b | 5730 4b89 | 7c1a f849 | 83c3 f84d | 895f 28e9 + 0x00007e24cd0638b4: 4bf1 ffff | 458b 5a18 | 4585 db0f | 84b6 f1ff | ff4d 8b57 | 2849 8bfb | 48c1 e703 | 4d85 d20f + 0x00007e24cd0638d4: 8400 0700 | 004d 8b5f | 304b 897c | 13f8 4983 | c2f8 4d89 | 5728 e98c | f1ff ff4d | 8b57 484d + 0x00007e24cd0638f4: 8b5f 40f0 | 8344 24c0 | 0080 3f00 | 0f84 3bf1 | ffff 4488 | 274d 85db | 751d 498b | f749 ba10 + 0x00007e24cd063914: da9b e224 | 7e00 0041 + + 0x00007e24cd06391c: ; {other} + 0x00007e24cd06391c: ffd2 0f1f | 8400 0000 | 0000 e916 | f1ff ff4b | 897c 1af8 | 4983 c3f8 | 4d89 5f40 | e904 f1ff + 0x00007e24cd06393c: ff48 8b5c | 2408 448b | 5b1c 4585 | db0f 8485 | f4ff ff4d | 8b57 2849 | 8bfb 48c1 | e703 4d85 + 0x00007e24cd06395c: d20f 84f9 | 0600 004d | 8b5f 304b | 897c 13f8 | 4983 c2f8 | 4d89 5728 | e95b f4ff | ff4d 8b57 + 0x00007e24cd06397c: 484d 8b5f | 40f0 8344 | 24c0 0041 | 8038 000f | 8475 f4ff | ff45 8820 | 4d85 db75 | 2049 8bf8 + 0x00007e24cd06399c: 498b f749 | ba10 da9b | e224 7e00 | 0041 ffd2 + + 0x00007e24cd0639ac: ; {other} + 0x00007e24cd0639ac: 0f1f 8400 | 0000 0000 | e94d f4ff | ff4f 8944 | 1af8 4983 | c3f8 4d89 | 5f40 e93b | f4ff ff45 + 0x00007e24cd0639cc: 8b5a 1045 | 85db 0f84 | 06f1 ffff | 4d8b 5728 | 498b fb48 | c1e7 034d | 85d2 0f84 | 0c07 0000 + 0x00007e24cd0639ec: 4d8b 5f30 | 4b89 7c13 | f849 83c2 | f84d 8957 | 28e9 dcf0 | ffff 4889 | 4c24 2044 | 8954 2404 + 0x00007e24cd063a0c: 4c8b 5424 | 104c 8954 | 2408 4489 | 2c24 498b | ee49 8bf3 + + 0x00007e24cd063a20: ; {optimized virtual_call} + 0x00007e24cd063a20: 488b d1e8 + + 0x00007e24cd063a24: ; ImmutableOopMap {[8]=Oop [24]=NarrowOop [32]=Oop [96]=Oop } + ;*invokevirtual afterNodeAccess {reexecute=0 rethrow=0 return_oop=0} + ; - java.util.LinkedHashMap::get@21 (line 539) + ; - kotlin.text.CharDirectionality$Companion::valueOf@8 (line 121) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@7 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd063a24: 589d e4fe + + 0x00007e24cd063a28: ; {other} + 0x00007e24cd063a28: 0f1f 8400 | 9817 0015 | 4c8b f544 | 8b2c 244c | 8b54 2408 | 4c89 5424 | 1044 8b54 | 2404 488b + 0x00007e24cd063a48: 4c24 20e9 | e2f1 ffff | 4489 4c24 | 6444 895c | 2460 488b + + 0x00007e24cd063a5c: ; {metadata('androidx/compose/ui/text/CharHelpers_skikoKt$codePointsOutsideDirectionalIsolate$1')} + 0x00007e24cd063a5c: eb48 be38 | 884d 6324 + + 0x00007e24cd063a64: ; {runtime_call _new_instance_Java} + 0x00007e24cd063a64: 7e00 00e8 + + 0x00007e24cd063a68: ; ImmutableOopMap {rbp=Oop [96]=NarrowOop [100]=NarrowOop } + ;*new {reexecute=0 rethrow=0 return_oop=1} + ; - androidx.compose.ui.text.CharHelpers_skikoKt::getCodePointsOutsideDirectionalIsolate@0 (line 105) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@7 (line 84) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd063a68: 143b f2fe + + 0x00007e24cd063a6c: ; {other} + 0x00007e24cd063a6c: 0f1f 8400 | dc17 0016 | 488b dd44 | 8b5c 2460 | 448b 4c24 | 6448 8bc8 | e9e4 eeff | ff48 890c + 0x00007e24cd063a8c: 2444 895c | 2418 4889 + + 0x00007e24cd063a94: ; {metadata('kotlin/sequences/SequenceBuilderIterator')} + 0x00007e24cd063a94: 5c24 6048 | be10 f038 | 6324 7e00 | 0048 8beb + + 0x00007e24cd063aa4: ; {runtime_call _new_instance_Java} + 0x00007e24cd063aa4: 6666 90e8 + + 0x00007e24cd063aa8: ; ImmutableOopMap {rbp=Oop [0]=Oop [24]=NarrowOop [96]=Oop } + ;*new {reexecute=0 rethrow=0 return_oop=1} + ; - kotlin.sequences.SequencesKt__SequenceBuilderKt::iterator@6 (line 37) + ; - kotlin.sequences.SequencesKt__SequenceBuilderKt$sequence$$inlined$Sequence$1::iterator@6 (line 731) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@10 (line 84) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd063aa8: d43a f2fe + + 0x00007e24cd063aac: ; {other} + 0x00007e24cd063aac: 0f1f 8400 | 1c18 0017 | e91a efff + + 0x00007e24cd063ab8: ; {oop(a 'kotlin/SynchronizedLazyImpl'{0x0000000616a7a148})} + 0x00007e24cd063ab8: ff49 ba48 | a1a7 1606 | 0000 0045 | 8b52 1045 | 85d2 0f84 | f6f6 ffff | 4d8b 5f28 | 498b fa48 + 0x00007e24cd063ad8: c1e7 034d | 85db 0f84 | a807 0000 | 4d8b 5730 | 4b89 7c1a | f849 83c3 | f84d 895f | 28e9 ccf6 + 0x00007e24cd063af8: ; {oop(a 'kotlin/SynchronizedLazyImpl'{0x0000000616a7a148})} + 0x00007e24cd063af8: ffff 49ba | 48a1 a716 | 0600 0000 | 458b 520c | 4585 d20f | 8409 f7ff | ff4d 8b5f | 2849 8bfa + 0x00007e24cd063b18: 48c1 e703 | 4d85 db0f | 8484 0700 | 004d 8b57 | 304b 897c | 1af8 4983 | c3f8 4d89 | 5f28 e9df + 0x00007e24cd063b38: f6ff ff4d | 8b57 484d | 8b5f 40f0 | 8344 24c0 | 0080 3f00 | 0f84 b7f6 | ffff 4488 | 274d 85db + 0x00007e24cd063b58: 751d 498b | f749 ba10 | da9b e224 | 7e00 0041 + + 0x00007e24cd063b68: ; {other} + 0x00007e24cd063b68: ffd2 0f1f | 8400 0000 | 0000 e992 | f6ff ff4b | 897c 1af8 | 4983 c3f8 | 4d89 5f40 | e980 f6ff + 0x00007e24cd063b88: ff4c 8b54 | 2460 4c89 | 1424 4889 | 6c24 604d | 8be9 498b | e849 8bf7 | 49ba f0d9 | 9be2 247e + 0x00007e24cd063ba8: 0000 41ff + + 0x00007e24cd063bac: ; {other} + 0x00007e24cd063bac: d20f 1f84 | 0000 0000 | 004c 8bc5 | 4d8b cd48 | 8b6c 2460 | 4c8b 1424 | 4c89 5424 | 60e9 efeb + 0x00007e24cd063bcc: ffff 4c8b | ed49 8be9 | 498b f749 | baf0 d99b | e224 7e00 | 0041 ffd2 + + 0x00007e24cd063be4: ; {other} + 0x00007e24cd063be4: 0f1f 8400 | 0000 0000 | 4c8b cd49 | 8bed e901 | ecff ff49 | 8bf7 49ba | f0d9 9be2 | 247e 0000 + 0x00007e24cd063c04: ; {other} + 0x00007e24cd063c04: 41ff d20f | 1f84 0000 | 0000 00e9 | 24ec ffff | 498b f749 | baf0 d99b | e224 7e00 | 0041 ffd2 + 0x00007e24cd063c24: ; {other} + 0x00007e24cd063c24: 0f1f 8400 | 0000 0000 | e947 ecff | ff4c 8b54 | 2460 4c89 | 5424 0848 | 892c 244c | 894c 2460 + 0x00007e24cd063c44: 4d8b f04d | 8beb 488b | ee48 8bda | 498b f749 | baf0 d99b | e224 7e00 | 0041 ffd2 + + 0x00007e24cd063c60: ; {other} + 0x00007e24cd063c60: 0f1f 8400 | 0000 0000 | 488b d348 | 8bdd 4d8b | dd4d 8bc6 | 4c8b 4c24 | 6048 8b2c | 244c 8b54 + 0x00007e24cd063c80: 2408 4c89 | 5424 60e9 | 80ea ffff | 4889 4424 | f88b 4424 | 1089 4424 | 2048 8b44 | 24f8 4889 + 0x00007e24cd063ca0: 4424 f88b | 4424 0c89 | 4424 1c48 | 8b44 24f8 | 4889 4424 | f88b 4424 | 0889 4424 | 1848 8b44 + 0x00007e24cd063cc0: 24f8 4c8b | 5424 604c | 8954 2410 | 4889 6c24 | 084c 890c | 244c 8944 | 2460 498b | eb49 8bf7 + 0x00007e24cd063ce0: 49ba f0d9 | 9be2 247e | 0000 41ff + + 0x00007e24cd063cec: ; {other} + 0x00007e24cd063cec: d20f 1f84 | 0000 0000 | 004c 8bdd | 4c8b 4424 | 604c 8b0c | 2448 8b6c | 2408 4c8b | 5424 104c + 0x00007e24cd063d0c: 8954 2460 | e932 f6ff | ffbe 45ff | ffff 498b | ea48 894c | 2408 4c89 | 4424 104c | 894c 2418 + 0x00007e24cd063d2c: 4889 7c24 | 2048 8954 + + 0x00007e24cd063d34: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd063d34: 2428 90e8 + + 0x00007e24cd063d38: ; ImmutableOopMap {rbp=Oop [8]=Oop [16]=Oop [24]=Oop [32]=Oop [40]=Oop [96]=Oop } + ;*ifnonnull {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::checkNotNullParameter@1 (line 130) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@3 + 0x00007e24cd063d38: 4428 e5fe + + 0x00007e24cd063d3c: ; {other} + 0x00007e24cd063d3c: 0f1f 8400 | ac1a 0018 | be45 ffff | ff49 8bea | 4889 1424 | 4c89 4424 | 104c 894c | 2418 4889 + 0x00007e24cd063d5c: 7c24 2048 | 894c 2428 + + 0x00007e24cd063d64: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd063d64: 6666 90e8 + + 0x00007e24cd063d68: ; ImmutableOopMap {rbp=Oop [0]=Oop [16]=Oop [24]=Oop [32]=Oop [40]=Oop [96]=Oop } + ;*ifnonnull {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::checkNotNullParameter@1 (line 130) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@9 + 0x00007e24cd063d68: 1428 e5fe + + 0x00007e24cd063d6c: ; {other} + 0x00007e24cd063d6c: 0f1f 8400 | dc1a 0019 | be45 ffff | ff49 8bea | 4889 1424 | 4889 4c24 | 084c 894c | 2418 4889 + 0x00007e24cd063d8c: 7c24 204c | 8944 2428 + + 0x00007e24cd063d94: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd063d94: 6666 90e8 + + 0x00007e24cd063d98: ; ImmutableOopMap {rbp=Oop [0]=Oop [8]=Oop [24]=Oop [32]=Oop [40]=Oop [96]=Oop } + ;*ifnonnull {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::checkNotNullParameter@1 (line 130) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@15 + 0x00007e24cd063d98: e427 e5fe + + 0x00007e24cd063d9c: ; {other} + 0x00007e24cd063d9c: 0f1f 8400 | 0c1b 001a | be45 ffff | ff49 8bea | 4889 1424 | 4889 4c24 | 084c 8944 | 2410 4889 + 0x00007e24cd063dbc: 7c24 204c | 894c 2428 + + 0x00007e24cd063dc4: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd063dc4: 6666 90e8 + + 0x00007e24cd063dc8: ; ImmutableOopMap {rbp=Oop [0]=Oop [8]=Oop [16]=Oop [32]=Oop [40]=Oop [96]=Oop } + ;*ifnonnull {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::checkNotNullParameter@1 (line 130) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@22 + 0x00007e24cd063dc8: b427 e5fe + + 0x00007e24cd063dcc: ; {other} + 0x00007e24cd063dcc: 0f1f 8400 | 3c1b 001b | be45 ffff | ff4c 8914 | 2448 8954 | 2408 4889 | 4c24 104c | 8944 2418 + 0x00007e24cd063dec: 4c89 4c24 + + 0x00007e24cd063df0: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd063df0: 2066 90e8 + + 0x00007e24cd063df4: ; ImmutableOopMap {rbp=Oop [0]=Oop [8]=Oop [16]=Oop [24]=Oop [32]=Oop [96]=Oop } + ;*ifnonnull {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::checkNotNullParameter@1 (line 130) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@29 + 0x00007e24cd063df4: 8827 e5fe + + 0x00007e24cd063df8: ; {other} + 0x00007e24cd063df8: 0f1f 8400 | 681b 001c | be45 ffff | ff4c 8914 | 2448 8954 | 2408 4c89 | 5c24 104c | 8944 2418 + 0x00007e24cd063e18: 4c89 4c24 + + 0x00007e24cd063e1c: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd063e1c: 2066 90e8 + + 0x00007e24cd063e20: ; ImmutableOopMap {rbp=Oop [0]=Oop [8]=Oop [16]=Oop [24]=Oop [32]=Oop [96]=Oop } + ;*ifnonnull {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::checkNotNullParameter@1 (line 130) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@36 + 0x00007e24cd063e20: 5c27 e5fe + + 0x00007e24cd063e24: ; {other} + 0x00007e24cd063e24: 0f1f 8400 | 941b 001d | be45 ffff | ff48 895c | 2460 4489 | 5c24 0444 | 894c 2408 | 4489 5424 + 0x00007e24cd063e44: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd063e44: 0c66 90e8 + + 0x00007e24cd063e48: ; ImmutableOopMap {[4]=NarrowOop [8]=NarrowOop [96]=Oop } + ;*ifnonnull {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::checkNotNullParameter@1 (line 130) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@3 + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd063e48: 3427 e5fe + + 0x00007e24cd063e4c: ; {other} + 0x00007e24cd063e4c: 0f1f 8400 | bc1b 001e | 33ed 4183 | fa02 400f | 94c5 be45 | ffff ff48 + + 0x00007e24cd063e64: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd063e64: 891c 24e8 + + 0x00007e24cd063e68: ; ImmutableOopMap {[0]=Oop } + ;*ifeq {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@54 (line 93) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd063e68: 1427 e5fe + + 0x00007e24cd063e6c: ; {other} + 0x00007e24cd063e6c: 0f1f 8400 | dc1b 001f | 33ed 4183 | fa03 400f | 94c5 be45 | ffff ff48 | 891c 2444 | 894c 2408 + 0x00007e24cd063e8c: 4489 5c24 + + 0x00007e24cd063e90: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd063e90: 0c66 90e8 + + 0x00007e24cd063e94: ; ImmutableOopMap {[0]=Oop [8]=NarrowOop [12]=NarrowOop } + ;*ifne {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@73 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd063e94: e826 e5fe + + 0x00007e24cd063e98: ; {other} + 0x00007e24cd063e98: 0f1f 8400 | 081c 0020 | 33ed 4181 | fa00 0000 | 8040 0f94 | c5be 45ff | ffff 4889 | 1c24 4489 + 0x00007e24cd063eb8: 4c24 0844 | 8954 240c + + 0x00007e24cd063ec0: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd063ec0: 6666 90e8 + + 0x00007e24cd063ec4: ; ImmutableOopMap {[0]=Oop [8]=NarrowOop } + ;*ifeq {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@86 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd063ec4: b826 e5fe + + 0x00007e24cd063ec8: ; {other} + 0x00007e24cd063ec8: 0f1f 8400 | 381c 0021 | becc ffff | ff48 895c | 2460 4489 | 0c24 4489 + + 0x00007e24cd063ee0: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd063ee0: 5c24 04e8 + + 0x00007e24cd063ee4: ; ImmutableOopMap {[0]=NarrowOop [4]=NarrowOop [96]=Oop } + ;*invokevirtual allocateInstance {reexecute=0 rethrow=0 return_oop=0} + ; - java.lang.invoke.DirectMethodHandle::allocateInstance@12 (line 500) + ; - java.lang.invoke.DirectMethodHandle$Holder::newInvokeSpecial@1 + ; - java.lang.invoke.Invokers$Holder::linkToTargetMethod@5 + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@91 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd063ee4: 9826 e5fe + + 0x00007e24cd063ee8: ; {other} + 0x00007e24cd063ee8: 0f1f 8400 | 581c 0022 | 498b f749 | baf0 d99b | e224 7e00 | 0041 ffd2 + + 0x00007e24cd063f00: ; {other} + 0x00007e24cd063f00: 0f1f 8400 | 0000 0000 | e99f edff | ff49 8bf7 | 49ba f0d9 | 9be2 247e | 0000 41ff + + 0x00007e24cd063f1c: ; {other} + 0x00007e24cd063f1c: d20f 1f84 | 0000 0000 | 00e9 e8ed | ffff be45 + + 0x00007e24cd063f2c: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd063f2c: ffff ffe8 + + 0x00007e24cd063f30: ; ImmutableOopMap {[8]=Oop [96]=Oop } + ;*ifeq {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) org.jetbrains.skia.impl.Stats::onNativeCall@3 (line 10) + ; - org.jetbrains.skia.paragraph.Paragraph::getMinIntrinsicWidth@4 (line 39) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@131 (line 81) + 0x00007e24cd063f30: 4c26 e5fe + + 0x00007e24cd063f34: ; {other} + 0x00007e24cd063f34: 0f1f 8400 | a41c 0023 | be45 ffff | ff44 8904 + + 0x00007e24cd063f44: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd063f44: 2466 90e8 + + 0x00007e24cd063f48: ; ImmutableOopMap {rbp=Oop [8]=Oop } + ;*ifeq {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) org.jetbrains.skia.impl.Stats::onNativeCall@3 (line 10) + ; - org.jetbrains.skia.paragraph.Paragraph::getMaxIntrinsicWidth@4 (line 46) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@145 (line 82) + 0x00007e24cd063f48: 3426 e5fe + + 0x00007e24cd063f4c: ; {other} + 0x00007e24cd063f4c: 0f1f 8400 | bc1c 0024 | bef6 ffff + + 0x00007e24cd063f58: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd063f58: ff66 90e8 + + 0x00007e24cd063f5c: ; ImmutableOopMap {} + ;*invokevirtual build {reexecute=0 rethrow=0 return_oop=0} + ; - androidx.compose.ui.text.platform.ParagraphLayouter::layoutParagraph@74 (line 213) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@123 (line 80) + 0x00007e24cd063f5c: 2026 e5fe + + 0x00007e24cd063f60: ; {other} + 0x00007e24cd063f60: 0f1f 8400 | d01c 0025 | bee4 ffff | ff4c 8b54 | 2410 4c89 + + 0x00007e24cd063f74: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd063f74: 5424 08e8 + + 0x00007e24cd063f78: ; ImmutableOopMap {[8]=Oop [24]=NarrowOop [96]=Oop } + ;*iaload {reexecute=0 rethrow=0 return_oop=0} + ; - java.lang.CharacterDataLatin1::getProperties@7 (line 74) + ; - java.lang.CharacterDataLatin1::getDirectionality@2 (line 284) + ; - java.lang.Character::getDirectionality@5 (line 11698) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@4 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd063f78: 0426 e5fe + + 0x00007e24cd063f7c: ; {other} + 0x00007e24cd063f7c: 0f1f 8400 | ec1c 0026 | bee4 ffff | ff4c 8b54 | 2410 4c89 + + 0x00007e24cd063f90: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd063f90: 5424 08e8 + + 0x00007e24cd063f94: ; ImmutableOopMap {[8]=Oop [24]=NarrowOop [96]=Oop } + ;*iaload {reexecute=0 rethrow=0 return_oop=0} + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@11 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd063f94: e825 e5fe + + 0x00007e24cd063f98: ; {other} + 0x00007e24cd063f98: 0f1f 8400 | 081d 0027 | be45 ffff | ff4c 8954 | 2408 4489 + + 0x00007e24cd063fac: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd063fac: 5c24 10e8 + + 0x00007e24cd063fb0: ; ImmutableOopMap {[8]=Oop [24]=NarrowOop [96]=Oop } + ;*tableswitch {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.sequences.SequenceBuilderIterator::hasNext@5 (line 112) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@17 (line 84) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd063fb0: cc25 e5fe + + 0x00007e24cd063fb4: ; {other} + 0x00007e24cd063fb4: 0f1f 8400 | 241d 0028 | 498b f749 | baf0 d99b | e224 7e00 | 0041 ffd2 + + 0x00007e24cd063fcc: ; {other} + 0x00007e24cd063fcc: 0f1f 8400 | 0000 0000 | e92a eaff | ff49 8bf7 | 49ba f0d9 | 9be2 247e | 0000 41ff + + 0x00007e24cd063fe8: ; {other} + 0x00007e24cd063fe8: d20f 1f84 | 0000 0000 | 00e9 85ea | ffff be45 | ffff ff4c | 8b54 2410 | 4c89 5424 + + 0x00007e24cd064004: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd064004: 0866 90e8 + + 0x00007e24cd064008: ; ImmutableOopMap {[8]=Oop [24]=NarrowOop [96]=Oop } + ;*tableswitch {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@12 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd064008: 7425 e5fe + + 0x00007e24cd06400c: ; {other} + 0x00007e24cd06400c: 0f1f 8400 | 7c1d 0029 | 448b 5424 | 0cbe f4ff | ffff 4489 + + 0x00007e24cd064020: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd064020: 5424 0ce8 + + 0x00007e24cd064024: ; ImmutableOopMap {[16]=Oop [24]=NarrowOop [96]=Oop } + ;*checkcast {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.text.CharDirectionality$Companion::getDirectionalityMap@10 (line 118) + ; - kotlin.text.CharDirectionality$Companion::valueOf@1 (line 121) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@7 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd064024: 5825 e5fe + + 0x00007e24cd064028: ; {other} + 0x00007e24cd064028: 0f1f 8400 | 981d 002a | be45 ffff + + 0x00007e24cd064034: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd064034: ff66 90e8 + + 0x00007e24cd064038: ; ImmutableOopMap {rbp=NarrowOop [16]=Oop [24]=NarrowOop [96]=Oop } + ;*ifnonnull {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::checkNotNull@1 (line 24) + ; - kotlin.sequences.SequenceBuilderIterator::hasNext@93 (line 127) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@17 (line 84) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd064038: 4425 e5fe + + 0x00007e24cd06403c: ; {other} + 0x00007e24cd06403c: 0f1f 8400 | ac1d 002b | be45 ffff | ff44 8954 + + 0x00007e24cd06404c: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd06404c: 2404 90e8 + + 0x00007e24cd064050: ; ImmutableOopMap {[4]=NarrowOop [96]=Oop } + ;*ifeq {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) org.jetbrains.skia.impl.Stats::onNativeCall@3 (line 10) + ; - org.jetbrains.skia.paragraph.Paragraph::layout@3 (line 83) + ; - androidx.compose.ui.text.platform.ParagraphLayouter::layoutParagraph@62 (line 209) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@123 (line 80) + 0x00007e24cd064050: 2c25 e5fe + + 0x00007e24cd064054: ; {other} + 0x00007e24cd064054: 0f1f 8400 | c41d 002c | 498b f749 | baf0 d99b | e224 7e00 | 0041 ffd2 + + 0x00007e24cd06406c: ; {other} + 0x00007e24cd06406c: 0f1f 8400 | 0000 0000 | e95b edff | ffbe 45ff | ffff 4c8b | 5424 084c | 8914 2448 | 8944 2410 + 0x00007e24cd06408c: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd06408c: 6666 90e8 + + 0x00007e24cd064090: ; ImmutableOopMap {[0]=Oop [16]=Oop [96]=Oop } + ;*ifeq {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) org.jetbrains.skia.impl.Stats::onNativeCall@3 (line 10) + ; - org.jetbrains.skia.paragraph.Paragraph::layout@3 (line 83) + ; - androidx.compose.ui.text.platform.ParagraphLayouter::layoutParagraph@80 (line 214) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@123 (line 80) + 0x00007e24cd064090: ec24 e5fe + + 0x00007e24cd064094: ; {other} + 0x00007e24cd064094: 0f1f 8400 | 041e 002d | be45 ffff | ff4c 8b54 | 2410 4c89 | 5424 0844 | 8b54 2418 | 4489 5424 + 0x00007e24cd0640b4: 1044 895c + + 0x00007e24cd0640b8: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd0640b8: 2418 90e8 + + 0x00007e24cd0640bc: ; ImmutableOopMap {[8]=Oop [16]=NarrowOop [96]=Oop } + ;*ifne {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) java.lang.CharacterData::of@4 (line 78) + ; - java.lang.Character::getDirectionality@1 (line 11698) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@4 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd0640bc: c024 e5fe + + 0x00007e24cd0640c0: ; {other} + 0x00007e24cd0640c0: 0f1f 8400 | 301e 002e | be45 ffff | ff4c 8b44 | 2410 4c89 | 4424 0844 | 8b4c 2418 | 4489 4c24 + 0x00007e24cd0640e0: 1044 8954 | 2414 4c89 + + 0x00007e24cd0640e8: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd0640e8: 5c24 18e8 + + 0x00007e24cd0640ec: ; ImmutableOopMap {[8]=Oop [16]=NarrowOop [24]=Oop [96]=Oop } + ;*ifle {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) java.util.HashMap::getNode@14 (line 575) + ; - java.util.LinkedHashMap::get@2 (line 536) + ; - kotlin.text.CharDirectionality$Companion::valueOf@8 (line 121) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@7 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd0640ec: 9024 e5fe + + 0x00007e24cd0640f0: ; {other} + 0x00007e24cd0640f0: 0f1f 8400 | 601e 002f | 498b f749 | baf0 d99b | e224 7e00 | 0041 ffd2 + + 0x00007e24cd064108: ; {other} + 0x00007e24cd064108: 0f1f 8400 | 0000 0000 | e9c9 e9ff | ffbe 45ff | ffff 4489 + + 0x00007e24cd06411c: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd06411c: 5424 0ce8 + + 0x00007e24cd064120: ; ImmutableOopMap {[16]=Oop [24]=NarrowOop [96]=Oop } + ;*if_icmpne {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) java.lang.CharacterDataLatin1::getDirectionality@18 (line 287) + ; - java.lang.Character::getDirectionality@5 (line 11698) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@4 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd064120: 5c24 e5fe + + 0x00007e24cd064124: ; {other} + 0x00007e24cd064124: 0f1f 8400 | 941e 0030 | bef6 ffff | ff41 8bea + + 0x00007e24cd064134: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd064134: 6666 90e8 + + 0x00007e24cd064138: ; ImmutableOopMap {rbp=NarrowOop } + ;*invokevirtual updateForegroundPaint {reexecute=0 rethrow=0 return_oop=0} + ; - androidx.compose.ui.text.platform.ParagraphLayouter::layoutParagraph@23 (line 196) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@123 (line 80) + 0x00007e24cd064138: 4424 e5fe + + 0x00007e24cd06413c: ; {other} + 0x00007e24cd06413c: 0f1f 8400 | ac1e 0031 | bef6 ffff + + 0x00007e24cd064148: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd064148: ff66 90e8 + + 0x00007e24cd06414c: ; ImmutableOopMap {} + ;*invokevirtual getForegroundPaint {reexecute=0 rethrow=0 return_oop=0} + ; - androidx.compose.ui.text.platform.ParagraphBuilder::updateForegroundPaint@13 (line 297) + ; - androidx.compose.ui.text.platform.ParagraphLayouter::layoutParagraph@23 (line 196) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@123 (line 80) + 0x00007e24cd06414c: 3024 e5fe + + 0x00007e24cd064150: ; {other} + 0x00007e24cd064150: 0f1f 8400 | c01e 0032 | bef6 ffff + + 0x00007e24cd06415c: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd06415c: ff66 90e8 + + 0x00007e24cd064160: ; ImmutableOopMap {} + ;*invokevirtual length {reexecute=0 rethrow=0 return_oop=0} + ; - androidx.compose.ui.text.platform.ParagraphBuilder::updateForegroundPaint@23 (line 298) + ; - androidx.compose.ui.text.platform.ParagraphLayouter::layoutParagraph@23 (line 196) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@123 (line 80) + 0x00007e24cd064160: 1c24 e5fe + + 0x00007e24cd064164: ; {other} + 0x00007e24cd064164: 0f1f 8400 | d41e 0033 | bef4 ffff | ff44 8954 + + 0x00007e24cd064174: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd064174: 240c 90e8 + + 0x00007e24cd064178: ; ImmutableOopMap {[16]=Oop [24]=NarrowOop [96]=Oop } + ;*checkcast {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.text.CharDirectionality$Companion::valueOf@13 (line 121) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@7 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd064178: 0424 e5fe + + 0x00007e24cd06417c: ; {other} + 0x00007e24cd06417c: 0f1f 8400 | ec1e 0034 | be45 ffff | ff4c 8b4c | 2410 4c89 | 4c24 0844 | 8b4c 2418 | 4489 4c24 + 0x00007e24cd06419c: 104c 895c | 2418 4489 | 4424 2044 | 8954 2424 + + 0x00007e24cd0641ac: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd0641ac: 6666 90e8 + + 0x00007e24cd0641b0: ; ImmutableOopMap {rbp=NarrowOop [8]=Oop [16]=NarrowOop [24]=Oop [32]=NarrowOop [96]=Oop } + ;*ifeq {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) java.util.HashMap::getNode@85 (line 581) + ; - java.util.LinkedHashMap::get@2 (line 536) + ; - kotlin.text.CharDirectionality$Companion::valueOf@8 (line 121) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@7 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd0641b0: cc23 e5fe + + 0x00007e24cd0641b4: ; {other} + 0x00007e24cd0641b4: 0f1f 8400 | 241f 0035 | bef6 ffff | ff44 8954 + + 0x00007e24cd0641c4: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd0641c4: 240c 90e8 + + 0x00007e24cd0641c8: ; ImmutableOopMap {[16]=Oop [24]=NarrowOop [96]=Oop } + ;*monitorenter {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.SynchronizedLazyImpl::getValue@20 (line 81) + ; - kotlin.text.CharDirectionality$Companion::getDirectionalityMap@5 (line 118) + ; - kotlin.text.CharDirectionality$Companion::valueOf@1 (line 121) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@7 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd0641c8: b423 e5fe + + 0x00007e24cd0641cc: ; {other} + 0x00007e24cd0641cc: 0f1f 8400 | 3c1f 0036 | 4c89 4c24 | 2044 895c | 241c 4489 | 5424 044c | 8b54 2410 | 4c89 5424 + 0x00007e24cd0641ec: 0844 892c | 2449 8bee | 498b f148 | 8d54 2440 + + 0x00007e24cd0641fc: ; {runtime_call _complete_monitor_locking_Java} + 0x00007e24cd0641fc: 6666 90e8 + + 0x00007e24cd064200: ; ImmutableOopMap {[8]=Oop [24]=NarrowOop [28]=NarrowOop [32]=Oop [96]=Oop } + ;*monitorenter {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.SynchronizedLazyImpl::getValue@20 (line 81) + ; - kotlin.text.CharDirectionality$Companion::getDirectionalityMap@5 (line 118) + ; - kotlin.text.CharDirectionality$Companion::valueOf@1 (line 121) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@7 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd064200: fcc1 f2fe + + 0x00007e24cd064204: ; {other} + 0x00007e24cd064204: 0f1f 8400 | 741f 0037 | 4c8b f544 | 8b2c 244c | 8b54 2408 | 4c89 5424 | 1044 8b54 | 2404 448b + 0x00007e24cd064224: 5c24 1c4c | 8b4c 2420 | e92d efff | ff49 8bfb | 488d 7424 | 4049 8bd7 | 49ba 50f2 | fce2 247e + 0x00007e24cd064244: 0000 41ff + + 0x00007e24cd064248: ; {other} + 0x00007e24cd064248: d20f 1f84 | 0000 0000 | 00e9 6ff0 | ffff be45 | ffff ff4c | 8b54 2410 | 4c89 5424 | 0844 8b5c + 0x00007e24cd064268: 2418 4489 | 5c24 1044 | 8b54 241c | 4489 5424 | 1889 4424 + + 0x00007e24cd06427c: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd06427c: 1c66 90e8 + + 0x00007e24cd064280: ; ImmutableOopMap {rbp=NarrowOop [8]=Oop [16]=NarrowOop [32]=Oop [40]=Oop [96]=Oop } + ;*ifeq {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) java.util.HashMap::getNode@131 (line 585) + ; - java.util.LinkedHashMap::get@2 (line 536) + ; - kotlin.text.CharDirectionality$Companion::valueOf@8 (line 121) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@7 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd064280: fc22 e5fe + + 0x00007e24cd064284: ; {other} + 0x00007e24cd064284: 0f1f 8400 | f41f 0038 | 498b f749 | baf0 d99b | e224 7e00 | 0041 ffd2 + + 0x00007e24cd06429c: ; {other} + 0x00007e24cd06429c: 0f1f 8400 | 0000 0000 | e91d efff | ff49 8bf7 | 49ba f0d9 | 9be2 247e | 0000 41ff + + 0x00007e24cd0642b8: ; {other} + 0x00007e24cd0642b8: d20f 1f84 | 0000 0000 | 00e9 54ef | ffff be45 | ffff ff4c | 8b44 2410 | 4c89 4424 | 0844 8b4c + 0x00007e24cd0642d8: 2418 4489 | 4c24 1044 | 8954 2414 | 4489 5c24 + + 0x00007e24cd0642e8: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd0642e8: 1c66 90e8 + + 0x00007e24cd0642ec: ; ImmutableOopMap {rbp=NarrowOop [8]=Oop [16]=NarrowOop [28]=NarrowOop [96]=Oop } + ;*if_acmpeq {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.SynchronizedLazyImpl::getValue@35 (line 83) + ; - kotlin.text.CharDirectionality$Companion::getDirectionalityMap@5 (line 118) + ; - kotlin.text.CharDirectionality$Companion::valueOf@1 (line 121) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@7 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd0642ec: 9022 e5fe + + 0x00007e24cd0642f0: ; {other} + 0x00007e24cd0642f0: 0f1f 8400 | 6020 0039 | be45 ffff | ff4c 8b44 | 2410 4c89 | 4424 0844 | 8b44 2418 | 4489 4424 + 0x00007e24cd064310: 1044 8954 | 2414 4489 + + 0x00007e24cd064318: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd064318: 5c24 1ce8 + + 0x00007e24cd06431c: ; ImmutableOopMap {rbp=NarrowOop [8]=Oop [16]=NarrowOop [28]=NarrowOop [96]=Oop } + ;*ifnonnull {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::checkNotNull@1 (line 24) + ; - kotlin.SynchronizedLazyImpl::getValue@48 (line 86) + ; - kotlin.text.CharDirectionality$Companion::getDirectionalityMap@5 (line 118) + ; - kotlin.text.CharDirectionality$Companion::valueOf@1 (line 121) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@7 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd06431c: 6022 e5fe + + 0x00007e24cd064320: ; {other} + 0x00007e24cd064320: 0f1f 8400 | 9020 003a | bede ffff | ff4c 8b54 | 2410 4c89 + + 0x00007e24cd064334: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd064334: 5424 08e8 + + 0x00007e24cd064338: ; ImmutableOopMap {rbp=NarrowOop [8]=Oop [24]=NarrowOop [96]=Oop } + ;*checkcast {reexecute=0 rethrow=0 return_oop=0} + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@31 (line 84) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd064338: 4422 e5fe + + 0x00007e24cd06433c: ; {other} + 0x00007e24cd06433c: 0f1f 8400 | ac20 003b | bede ffff | ff4c 8b5c | 2410 4c89 | 1c24 4489 | 5424 0c48 | 895c 2410 + 0x00007e24cd06435c: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd06435c: 6666 90e8 + + 0x00007e24cd064360: ; ImmutableOopMap {[0]=Oop [16]=Oop [24]=NarrowOop [96]=Oop } + ;*checkcast {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.text.CharDirectionality$Companion::getDirectionalityMap@10 (line 118) + ; - kotlin.text.CharDirectionality$Companion::valueOf@1 (line 121) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@7 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd064360: 1c22 e5fe + + 0x00007e24cd064364: ; {other} + 0x00007e24cd064364: 0f1f 8400 | d420 003c | bede ffff | ff4c 8b5c | 2410 4c89 | 5c24 0844 | 8954 2414 + + 0x00007e24cd064380: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd064380: 6666 90e8 + + 0x00007e24cd064384: ; ImmutableOopMap {rbp=NarrowOop [8]=Oop [24]=NarrowOop [96]=Oop } + ;*checkcast {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.text.CharDirectionality$Companion::valueOf@13 (line 121) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@7 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd064384: f821 e5fe + + 0x00007e24cd064388: ; {other} + 0x00007e24cd064388: 0f1f 8400 | f820 003d | be9d ffff | ff48 8b6c | 2460 4889 + + 0x00007e24cd06439c: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd06439c: 4424 10e8 + + 0x00007e24cd0643a0: ; ImmutableOopMap {rbp=Oop [8]=Oop [16]=Oop } + ;*astore_2 {reexecute=0 rethrow=0 return_oop=0} + ; - org.jetbrains.skia.paragraph.Paragraph::getMinIntrinsicWidth@22 (line 42) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@131 (line 81) + 0x00007e24cd0643a0: dc21 e5fe + + 0x00007e24cd0643a4: ; {other} + 0x00007e24cd0643a4: 0f1f 8400 | 1421 003e | be9d ffff | ff48 8904 + + 0x00007e24cd0643b4: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd0643b4: 2466 90e8 + + 0x00007e24cd0643b8: ; ImmutableOopMap {rbp=Oop [0]=Oop [8]=Oop } + ;*astore_2 {reexecute=0 rethrow=0 return_oop=0} + ; - org.jetbrains.skia.paragraph.Paragraph::getMaxIntrinsicWidth@22 (line 49) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@145 (line 82) + 0x00007e24cd0643b8: c421 e5fe + + 0x00007e24cd0643bc: ; {other} + 0x00007e24cd0643bc: 0f1f 8400 | 2c21 003f | bef6 ffff + + 0x00007e24cd0643c8: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd0643c8: ff66 90e8 + + 0x00007e24cd0643cc: ; ImmutableOopMap {} + ;*invokevirtual getTextDirection-s_7X-co {reexecute=0 rethrow=0 return_oop=0} + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@85 (line 54) + 0x00007e24cd0643cc: b021 e5fe + + 0x00007e24cd0643d0: ; {other} + 0x00007e24cd0643d0: 0f1f 8400 | 4021 0040 | bef6 ffff + + 0x00007e24cd0643dc: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd0643dc: ff66 90e8 + + 0x00007e24cd0643e0: ; ImmutableOopMap {} + ;*invokevirtual getTextDirection-s_7X-co {reexecute=0 rethrow=0 return_oop=0} + ; - androidx.compose.ui.text.TextStyle::getTextDirection-s_7X-co@4 (line 1424) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@85 (line 54) + 0x00007e24cd0643e0: 9c21 e5fe + + 0x00007e24cd0643e4: ; {other} + 0x00007e24cd0643e4: 0f1f 8400 | 5421 0041 | bef6 ffff + + 0x00007e24cd0643f0: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd0643f0: ff66 90e8 + + 0x00007e24cd0643f4: ; ImmutableOopMap {} + ;*invokevirtual getLocaleList {reexecute=0 rethrow=0 return_oop=0} + ; - androidx.compose.ui.text.TextStyle::getLocaleList@4 (line 1390) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@95 (line 54) + 0x00007e24cd0643f4: 8821 e5fe + + 0x00007e24cd0643f8: ; {other} + 0x00007e24cd0643f8: 0f1f 8400 | 6821 0042 | bef6 ffff + + 0x00007e24cd064404: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd064404: ff66 90e8 + + 0x00007e24cd064408: ; ImmutableOopMap {} + ;*invokevirtual layout {reexecute=0 rethrow=0 return_oop=0} + ; - androidx.compose.ui.text.platform.ParagraphLayouter::layoutParagraph@80 (line 214) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@123 (line 80) + 0x00007e24cd064408: 7421 e5fe + + 0x00007e24cd06440c: ; {other} + 0x00007e24cd06440c: 0f1f 8400 | 7c21 0043 | bef4 ffff + + 0x00007e24cd064418: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd064418: ff66 90e8 + + 0x00007e24cd06441c: ; ImmutableOopMap {[16]=Oop [24]=NarrowOop [96]=Oop } + ;*checkcast {reexecute=0 rethrow=0 return_oop=0} + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@31 (line 84) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd06441c: 6021 e5fe + + 0x00007e24cd064420: ; {other} + 0x00007e24cd064420: 0f1f 8400 | 9021 0044 | be9d ffff | ff4c 8b5c | 2410 4c89 | 1c24 448b | 5c24 1c48 | 8944 2420 + 0x00007e24cd064440: 4489 5c24 + + 0x00007e24cd064444: ; {runtime_call UncommonTrapBlob} + 0x00007e24cd064444: 1466 90e8 + + 0x00007e24cd064448: ; ImmutableOopMap {[0]=Oop [20]=NarrowOop [24]=NarrowOop [28]=NarrowOop [32]=Oop [96]=Oop } + ;*astore {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.SynchronizedLazyImpl::getValue@79 (line 81) + ; - kotlin.text.CharDirectionality$Companion::getDirectionalityMap@5 (line 118) + ; - kotlin.text.CharDirectionality$Companion::valueOf@1 (line 121) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::getDirectionality@7 (line 48) + ; - androidx.compose.ui.text.CharHelpers_jvmKt::strongDirectionType@1 (line 24) + ; - androidx.compose.ui.text.CharHelpers_skikoKt::firstStrongDirectionType@39 (line 85) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::contentBasedTextDirection@4 (line 109) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::resolveTextDirection-Ikz0yAw@96 (line 94) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics::@98 (line 54) + 0x00007e24cd064448: 3421 e5fe + + 0x00007e24cd06444c: ; {other} + 0x00007e24cd06444c: 0f1f 8400 | bc21 0045 | eb1d 488b | f0eb 29eb | 0048 8bf0 | eb22 eb18 | eb16 eb14 | eb12 eb10 + 0x00007e24cd06446c: eb0e 488b | f0eb 1148 | 8bf0 eb0c | eb02 eb00 | 488b f0eb | 0348 8bf0 | 4883 c450 + + 0x00007e24cd064488: ; {runtime_call _rethrow_Java} + 0x00007e24cd064488: 5de9 72c8 + + 0x00007e24cd06448c: ; {internal_word} + 0x00007e24cd06448c: f2fe 49ba | 3c2f 06cd | 247e 0000 | 4d89 9770 + + 0x00007e24cd06449c: ; {runtime_call SafepointBlob} + 0x00007e24cd06449c: 0400 00e9 | 5c0f e5fe + + 0x00007e24cd0644a4: ; {runtime_call StubRoutines (final stubs)} + 0x00007e24cd0644a4: e8b7 1fe3 | fee9 0ce2 | ffff f4f4 +[Stub Code] + 0x00007e24cd0644b0: ; {no_reloc} + 0x00007e24cd0644b0: 48bb 0000 | 0000 0000 + + 0x00007e24cd0644b8: ; {runtime_call} + 0x00007e24cd0644b8: 0000 e9fb + + 0x00007e24cd0644bc: ; {static_stub} + 0x00007e24cd0644bc: ffff ff48 | bb00 0000 | 0000 0000 + + 0x00007e24cd0644c8: ; {runtime_call} + 0x00007e24cd0644c8: 00e9 fbff + + 0x00007e24cd0644cc: ; {static_stub} + 0x00007e24cd0644cc: ffff 48bb | 0000 0000 | 0000 0000 + + 0x00007e24cd0644d8: ; {runtime_call} + 0x00007e24cd0644d8: e9fb ffff + + 0x00007e24cd0644dc: ; {static_stub} + 0x00007e24cd0644dc: ff48 bb00 | 0000 0000 + + 0x00007e24cd0644e4: ; {runtime_call} + 0x00007e24cd0644e4: 0000 00e9 | fbff ffff + + 0x00007e24cd0644ec: ; {static_stub} + 0x00007e24cd0644ec: 48bb 0000 | 0000 0000 + + 0x00007e24cd0644f4: ; {runtime_call} + 0x00007e24cd0644f4: 0000 e9fb + + 0x00007e24cd0644f8: ; {static_stub} + 0x00007e24cd0644f8: ffff ff48 | bb00 0000 | 0000 0000 + + 0x00007e24cd064504: ; {runtime_call} + 0x00007e24cd064504: 00e9 fbff + + 0x00007e24cd064508: ; {static_stub} + 0x00007e24cd064508: ffff 48bb | 0000 0000 | 0000 0000 + + 0x00007e24cd064514: ; {runtime_call} + 0x00007e24cd064514: e9fb ffff + + 0x00007e24cd064518: ; {static_stub} + 0x00007e24cd064518: ff48 bb00 | 0000 0000 + + 0x00007e24cd064520: ; {runtime_call} + 0x00007e24cd064520: 0000 00e9 | fbff ffff + + 0x00007e24cd064528: ; {static_stub} + 0x00007e24cd064528: 48bb 0000 | 0000 0000 + + 0x00007e24cd064530: ; {runtime_call} + 0x00007e24cd064530: 0000 e9fb + + 0x00007e24cd064534: ; {static_stub} + 0x00007e24cd064534: ffff ff48 | bb00 0000 | 0000 0000 + + 0x00007e24cd064540: ; {runtime_call} + 0x00007e24cd064540: 00e9 fbff + + 0x00007e24cd064544: ; {static_stub} + 0x00007e24cd064544: ffff 48bb | 0000 0000 | 0000 0000 + + 0x00007e24cd064550: ; {runtime_call} + 0x00007e24cd064550: e9fb ffff + + 0x00007e24cd064554: ; {static_stub} + 0x00007e24cd064554: ff48 bb00 | 0000 0000 + + 0x00007e24cd06455c: ; {runtime_call} + 0x00007e24cd06455c: 0000 00e9 | fbff ffff + + 0x00007e24cd064564: ; {static_stub} + 0x00007e24cd064564: 48bb 0000 | 0000 0000 + + 0x00007e24cd06456c: ; {runtime_call} + 0x00007e24cd06456c: 0000 e9fb + + 0x00007e24cd064570: ; {static_stub} + 0x00007e24cd064570: ffff ff48 | bb00 0000 | 0000 0000 + + 0x00007e24cd06457c: ; {runtime_call} + 0x00007e24cd06457c: 00e9 fbff + + 0x00007e24cd064580: ; {runtime_call ExceptionBlob} + 0x00007e24cd064580: ffff e979 | 39f2 fee8 | 0000 0000 | 4883 2c24 + + 0x00007e24cd064590: ; {runtime_call DeoptimizationBlob} + 0x00007e24cd064590: 05e9 0a23 | e5fe f4f4 +[/MachCode] + + +Compiled method (c1) 4866550 7394 3 androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics (57 bytes) + total in heap [0x00007e24c5921510,0x00007e24c5923f40] = 10800 + relocation [0x00007e24c5921660,0x00007e24c5921948] = 744 + main code [0x00007e24c5921960,0x00007e24c59234b8] = 7000 + stub code [0x00007e24c59234b8,0x00007e24c5923530] = 120 + oops [0x00007e24c5923530,0x00007e24c5923570] = 64 + metadata [0x00007e24c5923570,0x00007e24c5923598] = 40 + scopes data [0x00007e24c5923598,0x00007e24c59239a0] = 1032 + scopes pcs [0x00007e24c59239a0,0x00007e24c5923ed0] = 1328 + dependencies [0x00007e24c5923ed0,0x00007e24c5923ed8] = 8 + nul chk table [0x00007e24c5923ed8,0x00007e24c5923f40] = 104 + +[Constant Pool (empty)] + +[MachCode] +[Verified Entry Point] + # {method} {0x00007e2459c73ff8} 'ActualParagraphIntrinsics' '(Ljava/lang/String;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Ljava/util/List;Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;)Landroidx/compose/ui/text/ParagraphIntrinsics;' in 'androidx/compose/ui/text/platform/SkiaParagraphIntrinsics_skikoKt' + # parm0: rsi:rsi = 'java/lang/String' + # parm1: rdx:rdx = 'androidx/compose/ui/text/TextStyle' + # parm2: rcx:rcx = 'java/util/List' + # parm3: r8:r8 = 'java/util/List' + # parm4: r9:r9 = 'androidx/compose/ui/unit/Density' + # parm5: rdi:rdi = 'androidx/compose/ui/text/font/FontFamily$Resolver' + # [sp+0x120] (sp of caller) + 0x00007e24c5921960: 8984 2400 | c0fe ff55 | 4881 ec10 | 0100 0090 | 4181 7f20 | 0d00 0000 + + 0x00007e24c5921978: ; {runtime_call StubRoutines (final stubs)} + 0x00007e24c5921978: 7405 e8e1 | 4a57 0648 | 8994 24a8 | 0000 0048 | 898c 24b0 | 0000 004c | 8984 24b8 | 0000 004c + 0x00007e24c5921998: 898c 24c0 | 0000 0048 | 89bc 24c8 + + 0x00007e24c59219a4: ; {metadata(method data for {method} {0x00007e2459c73ff8} 'ActualParagraphIntrinsics' '(Ljava/lang/String;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Ljava/util/List;Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;)Landroidx/compose/ui/text/ParagraphIntrinsics;' in 'androidx/compose/ui/text/platform/SkiaParagraphIntrinsics_skikoKt')} + 0x00007e24c59219a4: 0000 0048 | b8d8 ea93 | 5a24 7e00 | 008b 98f4 | 0000 0083 | c302 8998 | f400 0000 | 81e3 fe07 + 0x00007e24c59219c4: 0000 85db | 0f84 0b16 + + 0x00007e24c59219cc: ; {metadata(method data for {method} {0x00007e2459c73ff8} 'ActualParagraphIntrinsics' '(Ljava/lang/String;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Ljava/util/List;Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;)Landroidx/compose/ui/text/ParagraphIntrinsics;' in 'androidx/compose/ui/text/platform/SkiaParagraphIntrinsics_skikoKt')} + 0x00007e24c59219cc: 0000 48b8 | d8ea 935a | 247e 0000 | 4883 8040 | 0100 0001 + + 0x00007e24c59219e0: ; {metadata(method data for {method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59219e0: 48b8 a051 | 6558 247e | 0000 8b98 | f400 0000 | 83c3 0289 | 98f4 0000 | 0081 e3fe | ff1f 0085 + 0x00007e24c5921a00: db0f 84f3 | 1500 0048 + + 0x00007e24c5921a08: ; {metadata(method data for {method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921a08: 85f6 48b8 | a051 6558 | 247e 0000 | 48c7 c340 | 0100 0075 | 0748 c7c3 | 5001 0000 | 4c8b 1c18 + 0x00007e24c5921a28: 4d8d 5b01 | 4c89 1c18 | 4889 b424 | d000 0000 | 0f85 1602 + + 0x00007e24c5921a3c: ; {metadata(method data for {method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921a3c: 0000 48b8 | a051 6558 | 247e 0000 | 4883 8060 | 0100 0001 + + 0x00007e24c5921a50: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921a50: 48b8 5853 | 6558 247e | 0000 8b98 | f400 0000 | 83c3 0289 | 98f4 0000 | 0081 e3fe | ff1f 0085 + 0x00007e24c5921a70: db0f 84a4 | 1500 0090 + + 0x00007e24c5921a78: ; {no_reloc} + 0x00007e24c5921a78: e9ce 1500 | 0000 0000 | 0000 498b | 87b8 0100 | 0048 8d78 | 3049 3bbf | c801 0000 | 0f87 bb15 + 0x00007e24c5921a98: 0000 4989 | bfb8 0100 | 0048 c700 | 0100 0000 | 488b ca49 | ba00 0000 | 6224 7e00 | 0049 2bca + 0x00007e24c5921ab8: 8948 0848 | 33c9 8948 | 0c48 33c9 | 4889 4810 | 4889 4818 | 4889 4820 | 4889 4828 + + 0x00007e24c5921ad4: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921ad4: 48be 5853 | 6558 247e | 0000 4883 | 8640 0100 + + 0x00007e24c5921ae4: ; {oop("text"{0x0000000616431f98})} + 0x00007e24c5921ae4: 0001 48be | 981f 4316 | 0600 0000 | 4889 8424 | a000 0000 | 0f1f 8000 + + 0x00007e24c5921afc: ; {static_call} + 0x00007e24c5921afc: 0000 00e8 + + 0x00007e24c5921b00: ; ImmutableOopMap {[160]=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*invokestatic createParameterIsNullExceptionMessage {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@5 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@3 + 0x00007e24c5921b00: 7cc6 5806 + + 0x00007e24c5921b04: ; {other} + 0x00007e24c5921b04: 0f1f 8400 | f405 0000 | 488b 9424 | a000 0000 + + 0x00007e24c5921b14: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921b14: 48be 5853 | 6558 247e | 0000 4883 | 8650 0100 | 0001 488b | d048 8bb4 | 24a0 0000 | 0066 0f1f + 0x00007e24c5921b34: ; {optimized virtual_call} + 0x00007e24c5921b34: 4400 00e8 + + 0x00007e24c5921b38: ; ImmutableOopMap {[160]=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*invokespecial {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@8 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@3 + 0x00007e24c5921b38: 44bc 5806 + + 0x00007e24c5921b3c: ; {other} + 0x00007e24c5921b3c: 0f1f 8400 | 2c06 0001 + + 0x00007e24c5921b44: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921b44: 48be 5853 | 6558 247e | 0000 4883 | 8660 0100 + + 0x00007e24c5921b54: ; {metadata(method data for {method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921b54: 0001 48be | 685b 6558 | 247e 0000 | 8bbe f400 | 0000 83c7 | 0289 bef4 | 0000 0081 | e7fe ff1f + 0x00007e24c5921b74: 0085 ff0f | 84e5 1400 + + 0x00007e24c5921b7c: ; {oop(a 'java/lang/Class'{0x0000000616017030} = 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921b7c: 0048 be30 | 7001 1606 | 0000 0048 + + 0x00007e24c5921b88: ; {metadata(method data for {method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921b88: 8bfe 48bb | 685b 6558 | 247e 0000 | 4883 8340 | 0100 0001 + + 0x00007e24c5921b9c: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c5921b9c: 48bf a039 | 0558 247e | 0000 8b9f | f400 0000 | 83c3 0289 | 9ff4 0000 | 0081 e3fe | ff1f 0085 + 0x00007e24c5921bbc: db0f 84c0 | 1400 008b | 762c 48c1 | e603 4885 + + 0x00007e24c5921bcc: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c5921bcc: f648 bfa0 | 3905 5824 | 7e00 0048 | c7c3 4001 | 0000 7407 | 48c7 c350 | 0100 0048 | 8b04 1f48 + 0x00007e24c5921bec: 8d40 0148 | 8904 1f0f | 8418 0000 + + 0x00007e24c5921bf8: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c5921bf8: 0048 bfa0 | 3905 5824 | 7e00 00ff | 8760 0100 | 0048 8bfe | e936 0000 + + 0x00007e24c5921c10: ; {oop(a 'java/lang/Class'{0x0000000616017030} = 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921c10: 0048 be30 | 7001 1606 | 0000 0048 + + 0x00007e24c5921c1c: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c5921c1c: 8bfe 48bb | a039 0558 | 247e 0000 | 4883 8378 | 0100 0001 | 0f1f 8000 + + 0x00007e24c5921c34: ; {optimized virtual_call} + 0x00007e24c5921c34: 0000 00e8 + + 0x00007e24c5921c38: ; ImmutableOopMap {[160]=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*invokevirtual initClassName {reexecute=0 rethrow=0 return_oop=0} + ; - java.lang.Class::getName@14 (line 988) + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@3 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@3 + 0x00007e24c5921c38: 44bb 5806 + + 0x00007e24c5921c3c: ; {other} + 0x00007e24c5921c3c: 0f1f 8400 | 2c07 0002 | 488b f848 | 8b84 24a0 | 0000 00e9 | 5a12 0000 + + 0x00007e24c5921c54: ; {metadata(method data for {method} {0x00007e2459c73ff8} 'ActualParagraphIntrinsics' '(Ljava/lang/String;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Ljava/util/List;Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;)Landroidx/compose/ui/text/ParagraphIntrinsics;' in 'androidx/compose/ui/text/platform/SkiaParagraphIntrinsics_skikoKt')} + 0x00007e24c5921c54: 48be d8ea | 935a 247e | 0000 4883 | 8650 0100 + + 0x00007e24c5921c64: ; {metadata(method data for {method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921c64: 0001 48be | a051 6558 | 247e 0000 | 8bbe f400 | 0000 83c7 | 0289 bef4 | 0000 0081 | e7fe ff1f + 0x00007e24c5921c84: 0085 ff0f | 841c 1400 | 0048 85d2 + + 0x00007e24c5921c90: ; {metadata(method data for {method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921c90: 48be a051 | 6558 247e | 0000 48c7 | c740 0100 | 0075 0748 | c7c7 5001 | 0000 488b | 043e 488d + 0x00007e24c5921cb0: 4001 4889 | 043e 0f85 | 1802 0000 + + 0x00007e24c5921cbc: ; {metadata(method data for {method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921cbc: 48be a051 | 6558 247e | 0000 4883 | 8660 0100 + + 0x00007e24c5921ccc: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921ccc: 0001 48be | 5853 6558 | 247e 0000 | 8bbe f400 | 0000 83c7 | 0289 bef4 | 0000 0081 | e7fe ff1f + 0x00007e24c5921cec: 0085 ff0f | 84d5 1300 | 0066 6690 + + 0x00007e24c5921cf8: ; {no_reloc} + 0x00007e24c5921cf8: e9fd 1300 | 0000 0000 | 0000 498b | 87b8 0100 | 0048 8d78 | 3049 3bbf | c801 0000 | 0f87 ea13 + 0x00007e24c5921d18: 0000 4989 | bfb8 0100 | 0048 c700 | 0100 0000 | 488b ca49 | ba00 0000 | 6224 7e00 | 0049 2bca + 0x00007e24c5921d38: 8948 0848 | 33c9 8948 | 0c48 33c9 | 4889 4810 | 4889 4818 | 4889 4820 | 4889 4828 + + 0x00007e24c5921d54: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921d54: 48be 5853 | 6558 247e | 0000 4883 | 8640 0100 + + 0x00007e24c5921d64: ; {oop("style"{0x000000061659e568})} + 0x00007e24c5921d64: 0001 48be | 68e5 5916 | 0600 0000 | 4889 8424 | d800 0000 | 0f1f 8000 + + 0x00007e24c5921d7c: ; {static_call} + 0x00007e24c5921d7c: 0000 00e8 + + 0x00007e24c5921d80: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [216]=Oop } + ;*invokestatic createParameterIsNullExceptionMessage {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@5 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@9 + 0x00007e24c5921d80: fcc3 5806 + + 0x00007e24c5921d84: ; {other} + 0x00007e24c5921d84: 0f1f 8400 | 7408 0003 | 488b 9424 | d800 0000 + + 0x00007e24c5921d94: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921d94: 48be 5853 | 6558 247e | 0000 4883 | 8650 0100 | 0001 488b | d048 8bb4 | 24d8 0000 | 0066 0f1f + 0x00007e24c5921db4: ; {optimized virtual_call} + 0x00007e24c5921db4: 4400 00e8 + + 0x00007e24c5921db8: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [216]=Oop } + ;*invokespecial {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@8 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@9 + 0x00007e24c5921db8: c4b9 5806 + + 0x00007e24c5921dbc: ; {other} + 0x00007e24c5921dbc: 0f1f 8400 | ac08 0004 + + 0x00007e24c5921dc4: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921dc4: 48be 5853 | 6558 247e | 0000 4883 | 8660 0100 + + 0x00007e24c5921dd4: ; {metadata(method data for {method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921dd4: 0001 48be | 685b 6558 | 247e 0000 | 8bbe f400 | 0000 83c7 | 0289 bef4 | 0000 0081 | e7fe ff1f + 0x00007e24c5921df4: 0085 ff0f | 8414 1300 + + 0x00007e24c5921dfc: ; {oop(a 'java/lang/Class'{0x0000000616017030} = 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921dfc: 0048 be30 | 7001 1606 | 0000 0048 + + 0x00007e24c5921e08: ; {metadata(method data for {method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921e08: 8bfe 48bb | 685b 6558 | 247e 0000 | 4883 8340 | 0100 0001 + + 0x00007e24c5921e1c: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c5921e1c: 48bf a039 | 0558 247e | 0000 8b9f | f400 0000 | 83c3 0289 | 9ff4 0000 | 0081 e3fe | ff1f 0085 + 0x00007e24c5921e3c: db0f 84ef | 1200 008b | 762c 48c1 | e603 4885 + + 0x00007e24c5921e4c: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c5921e4c: f648 bfa0 | 3905 5824 | 7e00 0048 | c7c3 4001 | 0000 7407 | 48c7 c350 | 0100 0048 | 8b04 1f48 + 0x00007e24c5921e6c: 8d40 0148 | 8904 1f0f | 8418 0000 + + 0x00007e24c5921e78: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c5921e78: 0048 bfa0 | 3905 5824 | 7e00 00ff | 8760 0100 | 0048 8bfe | e936 0000 + + 0x00007e24c5921e90: ; {oop(a 'java/lang/Class'{0x0000000616017030} = 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921e90: 0048 be30 | 7001 1606 | 0000 0048 + + 0x00007e24c5921e9c: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c5921e9c: 8bfe 48bb | a039 0558 | 247e 0000 | 4883 8378 | 0100 0001 | 0f1f 8000 + + 0x00007e24c5921eb4: ; {optimized virtual_call} + 0x00007e24c5921eb4: 0000 00e8 + + 0x00007e24c5921eb8: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [216]=Oop } + ;*invokevirtual initClassName {reexecute=0 rethrow=0 return_oop=0} + ; - java.lang.Class::getName@14 (line 988) + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@3 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@9 + 0x00007e24c5921eb8: c4b8 5806 + + 0x00007e24c5921ebc: ; {other} + 0x00007e24c5921ebc: 0f1f 8400 | ac09 0005 | 488b f848 | 8b84 24d8 | 0000 00e9 | e20e 0000 | 488b 8c24 | b000 0000 + 0x00007e24c5921edc: ; {metadata(method data for {method} {0x00007e2459c73ff8} 'ActualParagraphIntrinsics' '(Ljava/lang/String;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Ljava/util/List;Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;)Landroidx/compose/ui/text/ParagraphIntrinsics;' in 'androidx/compose/ui/text/platform/SkiaParagraphIntrinsics_skikoKt')} + 0x00007e24c5921edc: 48ba d8ea | 935a 247e | 0000 4883 | 8260 0100 + + 0x00007e24c5921eec: ; {metadata(method data for {method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921eec: 0001 48ba | a051 6558 | 247e 0000 | 8bb2 f400 | 0000 83c6 | 0289 b2f4 | 0000 0081 | e6fe ff1f + 0x00007e24c5921f0c: 0085 f60f | 8443 1200 | 0048 85c9 + + 0x00007e24c5921f18: ; {metadata(method data for {method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921f18: 48ba a051 | 6558 247e | 0000 48c7 | c640 0100 | 0075 0748 | c7c6 5001 | 0000 488b | 3c32 488d + 0x00007e24c5921f38: 7f01 4889 | 3c32 0f85 | 1802 0000 + + 0x00007e24c5921f44: ; {metadata(method data for {method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921f44: 48ba a051 | 6558 247e | 0000 4883 | 8260 0100 + + 0x00007e24c5921f54: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921f54: 0001 48ba | 5853 6558 | 247e 0000 | 8bb2 f400 | 0000 83c6 | 0289 b2f4 | 0000 0081 | e6fe ff1f + 0x00007e24c5921f74: 0085 f60f | 84fc 1100 | 0066 6690 + + 0x00007e24c5921f80: ; {no_reloc} + 0x00007e24c5921f80: e924 1200 | 0000 0000 | 0000 498b | 87b8 0100 | 0048 8d78 | 3049 3bbf | c801 0000 | 0f87 1112 + 0x00007e24c5921fa0: 0000 4989 | bfb8 0100 | 0048 c700 | 0100 0000 | 488b ca49 | ba00 0000 | 6224 7e00 | 0049 2bca + 0x00007e24c5921fc0: 8948 0848 | 33c9 8948 | 0c48 33c9 | 4889 4810 | 4889 4818 | 4889 4820 | 4889 4828 + + 0x00007e24c5921fdc: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5921fdc: 48be 5853 | 6558 247e | 0000 4883 | 8640 0100 + + 0x00007e24c5921fec: ; {oop("annotations"{0x0000000616261c18})} + 0x00007e24c5921fec: 0001 48be | 181c 2616 | 0600 0000 | 4889 8424 | e000 0000 | 0f1f 8000 + + 0x00007e24c5922004: ; {static_call} + 0x00007e24c5922004: 0000 00e8 + + 0x00007e24c5922008: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [224]=Oop } + ;*invokestatic createParameterIsNullExceptionMessage {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@5 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@15 + 0x00007e24c5922008: 74c1 5806 + + 0x00007e24c592200c: ; {other} + 0x00007e24c592200c: 0f1f 8400 | fc0a 0006 | 488b 9424 | e000 0000 + + 0x00007e24c592201c: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c592201c: 48be 5853 | 6558 247e | 0000 4883 | 8650 0100 | 0001 488b | d048 8bb4 | 24e0 0000 | 0066 0f1f + 0x00007e24c592203c: ; {optimized virtual_call} + 0x00007e24c592203c: 4400 00e8 + + 0x00007e24c5922040: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [224]=Oop } + ;*invokespecial {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@8 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@15 + 0x00007e24c5922040: 3cb7 5806 + + 0x00007e24c5922044: ; {other} + 0x00007e24c5922044: 0f1f 8400 | 340b 0007 + + 0x00007e24c592204c: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c592204c: 48be 5853 | 6558 247e | 0000 4883 | 8660 0100 + + 0x00007e24c592205c: ; {metadata(method data for {method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c592205c: 0001 48be | 685b 6558 | 247e 0000 | 8bbe f400 | 0000 83c7 | 0289 bef4 | 0000 0081 | e7fe ff1f + 0x00007e24c592207c: 0085 ff0f | 843b 1100 + + 0x00007e24c5922084: ; {oop(a 'java/lang/Class'{0x0000000616017030} = 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922084: 0048 be30 | 7001 1606 | 0000 0048 + + 0x00007e24c5922090: ; {metadata(method data for {method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922090: 8bfe 48bb | 685b 6558 | 247e 0000 | 4883 8340 | 0100 0001 + + 0x00007e24c59220a4: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c59220a4: 48bf a039 | 0558 247e | 0000 8b9f | f400 0000 | 83c3 0289 | 9ff4 0000 | 0081 e3fe | ff1f 0085 + 0x00007e24c59220c4: db0f 8416 | 1100 008b | 762c 48c1 | e603 4885 + + 0x00007e24c59220d4: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c59220d4: f648 bfa0 | 3905 5824 | 7e00 0048 | c7c3 4001 | 0000 7407 | 48c7 c350 | 0100 0048 | 8b04 1f48 + 0x00007e24c59220f4: 8d40 0148 | 8904 1f0f | 8418 0000 + + 0x00007e24c5922100: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c5922100: 0048 bfa0 | 3905 5824 | 7e00 00ff | 8760 0100 | 0048 8bfe | e936 0000 + + 0x00007e24c5922118: ; {oop(a 'java/lang/Class'{0x0000000616017030} = 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922118: 0048 be30 | 7001 1606 | 0000 0048 + + 0x00007e24c5922124: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c5922124: 8bfe 48bb | a039 0558 | 247e 0000 | 4883 8378 | 0100 0001 | 0f1f 8000 + + 0x00007e24c592213c: ; {optimized virtual_call} + 0x00007e24c592213c: 0000 00e8 + + 0x00007e24c5922140: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [224]=Oop } + ;*invokevirtual initClassName {reexecute=0 rethrow=0 return_oop=0} + ; - java.lang.Class::getName@14 (line 988) + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@3 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@15 + 0x00007e24c5922140: 3cb6 5806 + + 0x00007e24c5922144: ; {other} + 0x00007e24c5922144: 0f1f 8400 | 340c 0008 | 488b f848 | 8b84 24e0 | 0000 00e9 | 620b 0000 | 4c8b 8424 | b800 0000 + 0x00007e24c5922164: ; {metadata(method data for {method} {0x00007e2459c73ff8} 'ActualParagraphIntrinsics' '(Ljava/lang/String;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Ljava/util/List;Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;)Landroidx/compose/ui/text/ParagraphIntrinsics;' in 'androidx/compose/ui/text/platform/SkiaParagraphIntrinsics_skikoKt')} + 0x00007e24c5922164: 48ba d8ea | 935a 247e | 0000 4883 | 8270 0100 + + 0x00007e24c5922174: ; {metadata(method data for {method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922174: 0001 48ba | a051 6558 | 247e 0000 | 8bb2 f400 | 0000 83c6 | 0289 b2f4 | 0000 0081 | e6fe ff1f + 0x00007e24c5922194: 0085 f60f | 846a 1000 | 004d 85c0 + + 0x00007e24c59221a0: ; {metadata(method data for {method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59221a0: 48ba a051 | 6558 247e | 0000 48c7 | c640 0100 | 0075 0748 | c7c6 5001 | 0000 488b | 3c32 488d + 0x00007e24c59221c0: 7f01 4889 | 3c32 0f85 | 1802 0000 + + 0x00007e24c59221cc: ; {metadata(method data for {method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59221cc: 48ba a051 | 6558 247e | 0000 4883 | 8260 0100 + + 0x00007e24c59221dc: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59221dc: 0001 48ba | 5853 6558 | 247e 0000 | 8bb2 f400 | 0000 83c6 | 0289 b2f4 | 0000 0081 | e6fe ff1f + 0x00007e24c59221fc: 0085 f60f | 8423 1000 | 0066 6690 + + 0x00007e24c5922208: ; {no_reloc} + 0x00007e24c5922208: e94b 1000 | 0000 0000 | 0000 498b | 87b8 0100 | 0048 8d78 | 3049 3bbf | c801 0000 | 0f87 3810 + 0x00007e24c5922228: 0000 4989 | bfb8 0100 | 0048 c700 | 0100 0000 | 488b ca49 | ba00 0000 | 6224 7e00 | 0049 2bca + 0x00007e24c5922248: 8948 0848 | 33c9 8948 | 0c48 33c9 | 4889 4810 | 4889 4818 | 4889 4820 | 4889 4828 + + 0x00007e24c5922264: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922264: 48be 5853 | 6558 247e | 0000 4883 | 8640 0100 + + 0x00007e24c5922274: ; {oop("placeholders"{0x0000000616c79110})} + 0x00007e24c5922274: 0001 48be | 1091 c716 | 0600 0000 | 4889 8424 | e800 0000 | 0f1f 8000 + + 0x00007e24c592228c: ; {static_call} + 0x00007e24c592228c: 0000 00e8 + + 0x00007e24c5922290: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [232]=Oop } + ;*invokestatic createParameterIsNullExceptionMessage {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@5 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@21 + 0x00007e24c5922290: ecbe 5806 + + 0x00007e24c5922294: ; {other} + 0x00007e24c5922294: 0f1f 8400 | 840d 0009 | 488b 9424 | e800 0000 + + 0x00007e24c59222a4: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59222a4: 48be 5853 | 6558 247e | 0000 4883 | 8650 0100 | 0001 488b | d048 8bb4 | 24e8 0000 | 0066 0f1f + 0x00007e24c59222c4: ; {optimized virtual_call} + 0x00007e24c59222c4: 4400 00e8 + + 0x00007e24c59222c8: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [232]=Oop } + ;*invokespecial {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@8 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@21 + 0x00007e24c59222c8: b4b4 5806 + + 0x00007e24c59222cc: ; {other} + 0x00007e24c59222cc: 0f1f 8400 | bc0d 000a + + 0x00007e24c59222d4: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59222d4: 48be 5853 | 6558 247e | 0000 4883 | 8660 0100 + + 0x00007e24c59222e4: ; {metadata(method data for {method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59222e4: 0001 48be | 685b 6558 | 247e 0000 | 8bbe f400 | 0000 83c7 | 0289 bef4 | 0000 0081 | e7fe ff1f + 0x00007e24c5922304: 0085 ff0f | 8462 0f00 + + 0x00007e24c592230c: ; {oop(a 'java/lang/Class'{0x0000000616017030} = 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c592230c: 0048 be30 | 7001 1606 | 0000 0048 + + 0x00007e24c5922318: ; {metadata(method data for {method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922318: 8bfe 48bb | 685b 6558 | 247e 0000 | 4883 8340 | 0100 0001 + + 0x00007e24c592232c: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c592232c: 48bf a039 | 0558 247e | 0000 8b9f | f400 0000 | 83c3 0289 | 9ff4 0000 | 0081 e3fe | ff1f 0085 + 0x00007e24c592234c: db0f 843d | 0f00 008b | 762c 48c1 | e603 4885 + + 0x00007e24c592235c: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c592235c: f648 bfa0 | 3905 5824 | 7e00 0048 | c7c3 4001 | 0000 7407 | 48c7 c350 | 0100 0048 | 8b04 1f48 + 0x00007e24c592237c: 8d40 0148 | 8904 1f0f | 8418 0000 + + 0x00007e24c5922388: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c5922388: 0048 bfa0 | 3905 5824 | 7e00 00ff | 8760 0100 | 0048 8bfe | e936 0000 + + 0x00007e24c59223a0: ; {oop(a 'java/lang/Class'{0x0000000616017030} = 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59223a0: 0048 be30 | 7001 1606 | 0000 0048 + + 0x00007e24c59223ac: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c59223ac: 8bfe 48bb | a039 0558 | 247e 0000 | 4883 8378 | 0100 0001 | 0f1f 8000 + + 0x00007e24c59223c4: ; {optimized virtual_call} + 0x00007e24c59223c4: 0000 00e8 + + 0x00007e24c59223c8: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [232]=Oop } + ;*invokevirtual initClassName {reexecute=0 rethrow=0 return_oop=0} + ; - java.lang.Class::getName@14 (line 988) + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@3 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@21 + 0x00007e24c59223c8: b4b3 5806 + + 0x00007e24c59223cc: ; {other} + 0x00007e24c59223cc: 0f1f 8400 | bc0e 000b | 488b f848 | 8b84 24e8 | 0000 00e9 | e207 0000 | 4c8b 8c24 | c000 0000 + 0x00007e24c59223ec: ; {metadata(method data for {method} {0x00007e2459c73ff8} 'ActualParagraphIntrinsics' '(Ljava/lang/String;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Ljava/util/List;Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;)Landroidx/compose/ui/text/ParagraphIntrinsics;' in 'androidx/compose/ui/text/platform/SkiaParagraphIntrinsics_skikoKt')} + 0x00007e24c59223ec: 48ba d8ea | 935a 247e | 0000 4883 | 8280 0100 + + 0x00007e24c59223fc: ; {metadata(method data for {method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59223fc: 0001 48ba | a051 6558 | 247e 0000 | 8bb2 f400 | 0000 83c6 | 0289 b2f4 | 0000 0081 | e6fe ff1f + 0x00007e24c592241c: 0085 f60f | 8491 0e00 | 004d 85c9 + + 0x00007e24c5922428: ; {metadata(method data for {method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922428: 48ba a051 | 6558 247e | 0000 48c7 | c640 0100 | 0075 0748 | c7c6 5001 | 0000 488b | 3c32 488d + 0x00007e24c5922448: 7f01 4889 | 3c32 0f85 | 1802 0000 + + 0x00007e24c5922454: ; {metadata(method data for {method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922454: 48ba a051 | 6558 247e | 0000 4883 | 8260 0100 + + 0x00007e24c5922464: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922464: 0001 48ba | 5853 6558 | 247e 0000 | 8bb2 f400 | 0000 83c6 | 0289 b2f4 | 0000 0081 | e6fe ff1f + 0x00007e24c5922484: 0085 f60f | 844a 0e00 | 0066 6690 + + 0x00007e24c5922490: ; {no_reloc} + 0x00007e24c5922490: e972 0e00 | 0000 0000 | 0000 498b | 87b8 0100 | 0048 8d78 | 3049 3bbf | c801 0000 | 0f87 5f0e + 0x00007e24c59224b0: 0000 4989 | bfb8 0100 | 0048 c700 | 0100 0000 | 488b ca49 | ba00 0000 | 6224 7e00 | 0049 2bca + 0x00007e24c59224d0: 8948 0848 | 33c9 8948 | 0c48 33c9 | 4889 4810 | 4889 4818 | 4889 4820 | 4889 4828 + + 0x00007e24c59224ec: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59224ec: 48be 5853 | 6558 247e | 0000 4883 | 8640 0100 + + 0x00007e24c59224fc: ; {oop("density"{0x0000000616914a50})} + 0x00007e24c59224fc: 0001 48be | 504a 9116 | 0600 0000 | 4889 8424 | f000 0000 | 0f1f 8000 + + 0x00007e24c5922514: ; {static_call} + 0x00007e24c5922514: 0000 00e8 + + 0x00007e24c5922518: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [240]=Oop } + ;*invokestatic createParameterIsNullExceptionMessage {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@5 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@28 + 0x00007e24c5922518: 64bc 5806 + + 0x00007e24c592251c: ; {other} + 0x00007e24c592251c: 0f1f 8400 | 0c10 000c | 488b 9424 | f000 0000 + + 0x00007e24c592252c: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c592252c: 48be 5853 | 6558 247e | 0000 4883 | 8650 0100 | 0001 488b | d048 8bb4 | 24f0 0000 | 0066 0f1f + 0x00007e24c592254c: ; {optimized virtual_call} + 0x00007e24c592254c: 4400 00e8 + + 0x00007e24c5922550: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [240]=Oop } + ;*invokespecial {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@8 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@28 + 0x00007e24c5922550: 2cb2 5806 + + 0x00007e24c5922554: ; {other} + 0x00007e24c5922554: 0f1f 8400 | 4410 000d + + 0x00007e24c592255c: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c592255c: 48be 5853 | 6558 247e | 0000 4883 | 8660 0100 + + 0x00007e24c592256c: ; {metadata(method data for {method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c592256c: 0001 48be | 685b 6558 | 247e 0000 | 8bbe f400 | 0000 83c7 | 0289 bef4 | 0000 0081 | e7fe ff1f + 0x00007e24c592258c: 0085 ff0f | 8489 0d00 + + 0x00007e24c5922594: ; {oop(a 'java/lang/Class'{0x0000000616017030} = 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922594: 0048 be30 | 7001 1606 | 0000 0048 + + 0x00007e24c59225a0: ; {metadata(method data for {method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59225a0: 8bfe 48bb | 685b 6558 | 247e 0000 | 4883 8340 | 0100 0001 + + 0x00007e24c59225b4: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c59225b4: 48bf a039 | 0558 247e | 0000 8b9f | f400 0000 | 83c3 0289 | 9ff4 0000 | 0081 e3fe | ff1f 0085 + 0x00007e24c59225d4: db0f 8464 | 0d00 008b | 762c 48c1 | e603 4885 + + 0x00007e24c59225e4: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c59225e4: f648 bfa0 | 3905 5824 | 7e00 0048 | c7c3 4001 | 0000 7407 | 48c7 c350 | 0100 0048 | 8b04 1f48 + 0x00007e24c5922604: 8d40 0148 | 8904 1f0f | 8418 0000 + + 0x00007e24c5922610: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c5922610: 0048 bfa0 | 3905 5824 | 7e00 00ff | 8760 0100 | 0048 8bfe | e936 0000 + + 0x00007e24c5922628: ; {oop(a 'java/lang/Class'{0x0000000616017030} = 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922628: 0048 be30 | 7001 1606 | 0000 0048 + + 0x00007e24c5922634: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c5922634: 8bfe 48bb | a039 0558 | 247e 0000 | 4883 8378 | 0100 0001 | 0f1f 8000 + + 0x00007e24c592264c: ; {optimized virtual_call} + 0x00007e24c592264c: 0000 00e8 + + 0x00007e24c5922650: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [240]=Oop } + ;*invokevirtual initClassName {reexecute=0 rethrow=0 return_oop=0} + ; - java.lang.Class::getName@14 (line 988) + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@3 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@28 + 0x00007e24c5922650: 2cb1 5806 + + 0x00007e24c5922654: ; {other} + 0x00007e24c5922654: 0f1f 8400 | 4411 000e | 488b f848 | 8b84 24f0 | 0000 00e9 | 6204 0000 | 488b bc24 | c800 0000 + 0x00007e24c5922674: ; {metadata(method data for {method} {0x00007e2459c73ff8} 'ActualParagraphIntrinsics' '(Ljava/lang/String;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Ljava/util/List;Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;)Landroidx/compose/ui/text/ParagraphIntrinsics;' in 'androidx/compose/ui/text/platform/SkiaParagraphIntrinsics_skikoKt')} + 0x00007e24c5922674: 48ba d8ea | 935a 247e | 0000 4883 | 8290 0100 + + 0x00007e24c5922684: ; {metadata(method data for {method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922684: 0001 48ba | a051 6558 | 247e 0000 | 8bb2 f400 | 0000 83c6 | 0289 b2f4 | 0000 0081 | e6fe ff1f + 0x00007e24c59226a4: 0085 f60f | 84b8 0c00 | 0048 85ff + + 0x00007e24c59226b0: ; {metadata(method data for {method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59226b0: 48ba a051 | 6558 247e | 0000 48c7 | c640 0100 | 0075 0748 | c7c6 5001 | 0000 488b | 0432 488d + 0x00007e24c59226d0: 4001 4889 | 0432 0f85 | 1802 0000 + + 0x00007e24c59226dc: ; {metadata(method data for {method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59226dc: 48ba a051 | 6558 247e | 0000 4883 | 8260 0100 + + 0x00007e24c59226ec: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59226ec: 0001 48ba | 5853 6558 | 247e 0000 | 8bb2 f400 | 0000 83c6 | 0289 b2f4 | 0000 0081 | e6fe ff1f + 0x00007e24c592270c: 0085 f60f | 8471 0c00 | 0066 6690 + + 0x00007e24c5922718: ; {no_reloc} + 0x00007e24c5922718: e999 0c00 | 0000 0000 | 0000 498b | 87b8 0100 | 0048 8d78 | 3049 3bbf | c801 0000 | 0f87 860c + 0x00007e24c5922738: 0000 4989 | bfb8 0100 | 0048 c700 | 0100 0000 | 488b ca49 | ba00 0000 | 6224 7e00 | 0049 2bca + 0x00007e24c5922758: 8948 0848 | 33c9 8948 | 0c48 33c9 | 4889 4810 | 4889 4818 | 4889 4820 | 4889 4828 + + 0x00007e24c5922774: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922774: 48be 5853 | 6558 247e | 0000 4883 | 8640 0100 + + 0x00007e24c5922784: ; {oop("fontFamilyResolver"{0x0000000616c787c8})} + 0x00007e24c5922784: 0001 48be | c887 c716 | 0600 0000 | 4889 8424 | f800 0000 | 0f1f 8000 + + 0x00007e24c592279c: ; {static_call} + 0x00007e24c592279c: 0000 00e8 + + 0x00007e24c59227a0: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [248]=Oop } + ;*invokestatic createParameterIsNullExceptionMessage {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@5 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@35 + 0x00007e24c59227a0: dcb9 5806 + + 0x00007e24c59227a4: ; {other} + 0x00007e24c59227a4: 0f1f 8400 | 9412 000f | 488b 9424 | f800 0000 + + 0x00007e24c59227b4: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59227b4: 48be 5853 | 6558 247e | 0000 4883 | 8650 0100 | 0001 488b | d048 8bb4 | 24f8 0000 | 0066 0f1f + 0x00007e24c59227d4: ; {optimized virtual_call} + 0x00007e24c59227d4: 4400 00e8 + + 0x00007e24c59227d8: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [248]=Oop } + ;*invokespecial {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@8 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@35 + 0x00007e24c59227d8: a4af 5806 + + 0x00007e24c59227dc: ; {other} + 0x00007e24c59227dc: 0f1f 8400 | cc12 0010 + + 0x00007e24c59227e4: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59227e4: 48be 5853 | 6558 247e | 0000 4883 | 8660 0100 + + 0x00007e24c59227f4: ; {metadata(method data for {method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59227f4: 0001 48be | 685b 6558 | 247e 0000 | 8bbe f400 | 0000 83c7 | 0289 bef4 | 0000 0081 | e7fe ff1f + 0x00007e24c5922814: 0085 ff0f | 84b0 0b00 + + 0x00007e24c592281c: ; {oop(a 'java/lang/Class'{0x0000000616017030} = 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c592281c: 0048 be30 | 7001 1606 | 0000 0048 + + 0x00007e24c5922828: ; {metadata(method data for {method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922828: 8bfe 48bb | 685b 6558 | 247e 0000 | 4883 8340 | 0100 0001 + + 0x00007e24c592283c: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c592283c: 48bf a039 | 0558 247e | 0000 8b9f | f400 0000 | 83c3 0289 | 9ff4 0000 | 0081 e3fe | ff1f 0085 + 0x00007e24c592285c: db0f 848b | 0b00 008b | 762c 48c1 | e603 4885 + + 0x00007e24c592286c: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c592286c: f648 bfa0 | 3905 5824 | 7e00 0048 | c7c3 4001 | 0000 7407 | 48c7 c350 | 0100 0048 | 8b04 1f48 + 0x00007e24c592288c: 8d40 0148 | 8904 1f0f | 8418 0000 + + 0x00007e24c5922898: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c5922898: 0048 bfa0 | 3905 5824 | 7e00 00ff | 8760 0100 | 0048 8bfe | e936 0000 + + 0x00007e24c59228b0: ; {oop(a 'java/lang/Class'{0x0000000616017030} = 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59228b0: 0048 be30 | 7001 1606 | 0000 0048 + + 0x00007e24c59228bc: ; {metadata(method data for {method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c59228bc: 8bfe 48bb | a039 0558 | 247e 0000 | 4883 8378 | 0100 0001 | 0f1f 8000 + + 0x00007e24c59228d4: ; {optimized virtual_call} + 0x00007e24c59228d4: 0000 00e8 + + 0x00007e24c59228d8: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [248]=Oop } + ;*invokevirtual initClassName {reexecute=0 rethrow=0 return_oop=0} + ; - java.lang.Class::getName@14 (line 988) + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@3 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@35 + 0x00007e24c59228d8: a4ae 5806 + + 0x00007e24c59228dc: ; {other} + 0x00007e24c59228dc: 0f1f 8400 | cc13 0011 | 488b f848 | 8b84 24f8 | 0000 00e9 | de00 0000 + + 0x00007e24c59228f4: ; {metadata('androidx/compose/ui/text/platform/SkiaParagraphIntrinsics')} + 0x00007e24c59228f4: 48ba f839 | 3763 247e | 0000 488b | df49 8b87 | b801 0000 | 488d 7838 | 493b bfc8 | 0100 000f + 0x00007e24c5922914: 87fb 0a00 | 0049 89bf | b801 0000 | 48c7 0001 | 0000 0048 | 8bca 49ba | 0000 0062 | 247e 0000 + 0x00007e24c5922934: 492b ca89 | 4808 4833 | c989 480c | 4833 c948 | c7c7 0500 | 0000 4889 | 4cf8 0848 | ffcf 75f6 + 0x00007e24c5922954: ; {metadata(method data for {method} {0x00007e2459c73ff8} 'ActualParagraphIntrinsics' '(Ljava/lang/String;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Ljava/util/List;Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;)Landroidx/compose/ui/text/ParagraphIntrinsics;' in 'androidx/compose/ui/text/platform/SkiaParagraphIntrinsics_skikoKt')} + 0x00007e24c5922954: 488b d048 | b9d8 ea93 | 5a24 7e00 | 0048 8381 | a001 0000 | 0148 8b94 | 24d0 0000 | 0048 8b8c + 0x00007e24c5922974: 24a8 0000 | 004c 8b84 | 24b0 0000 | 004c 8b8c | 24b8 0000 | 0048 8bbc | 24c0 0000 | 0048 891c + 0x00007e24c5922994: 2448 8bf0 | 4889 8424 | 0001 0000 | 0f1f 8000 + + 0x00007e24c59229a4: ; {optimized virtual_call} + 0x00007e24c59229a4: 0000 00e8 + + 0x00007e24c59229a8: ; ImmutableOopMap {[256]=Oop } + ;*invokespecial {reexecute=0 rethrow=0 return_oop=0} + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@50 (line 37) + 0x00007e24c59229a8: f4fc 7307 + + 0x00007e24c59229ac: ; {other} + 0x00007e24c59229ac: 0f1f 8400 | 9c14 0012 | 488b 8424 | 0001 0000 | 4881 c410 | 0100 005d + + 0x00007e24c59229c4: ; {poll_return} + 0x00007e24c59229c4: 493b a758 | 0400 000f | 8750 0a00 + + 0x00007e24c59229d0: ; {metadata(method data for {method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59229d0: 00c3 48be | 685b 6558 | 247e 0000 | 4883 8670 | 0100 0001 | 488b f048 | 8bd7 0f1f + + 0x00007e24c59229ec: ; {static_call} + 0x00007e24c59229ec: 4400 00e8 + + 0x00007e24c59229f0: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*invokestatic sanitizeStackTrace {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@6 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@35 + 0x00007e24c59229f0: 8cb7 5806 + + 0x00007e24c59229f4: ; {other} + 0x00007e24c59229f4: 0f1f 8400 | e414 0013 + + 0x00007e24c59229fc: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59229fc: 4885 c048 | ba58 5365 | 5824 7e00 | 0075 0c80 | 8a69 0100 | 0001 e9af | 0000 008b | 7808 49ba + 0x00007e24c5922a1c: 0000 0062 | 247e 0000 | 4903 fa48 | 3bba 7801 | 0000 750d | 4883 8280 | 0100 0001 | e960 0000 + 0x00007e24c5922a3c: 0048 3bba | 8801 0000 | 750d 4883 | 8290 0100 | 0001 e94a | 0000 0048 | 83ba 7801 | 0000 0075 + 0x00007e24c5922a5c: 1748 89ba | 7801 0000 | 48c7 8280 | 0100 0001 | 0000 00e9 | 2900 0000 | 4883 ba88 | 0100 0000 + 0x00007e24c5922a7c: 7517 4889 | ba88 0100 | 0048 c782 | 9001 0000 | 0100 0000 | e908 0000 | 0048 8382 | 7001 0000 + 0x00007e24c5922a9c: ; {metadata('java/lang/NullPointerException')} + 0x00007e24c5922a9c: 0148 bf40 | ef05 6224 | 7e00 008b | 5008 49ba | 0000 0062 | 247e 0000 | 4903 d248 | 3b7a 500f + 0x00007e24c5922abc: 8576 0900 | 00e9 0000 | 0000 483b | 00e9 da09 + + 0x00007e24c5922acc: ; {metadata(method data for {method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922acc: 0000 48be | 685b 6558 | 247e 0000 | 4883 8670 | 0100 0001 | 488b f048 + + 0x00007e24c5922ae4: ; {static_call} + 0x00007e24c5922ae4: 8bd7 90e8 + + 0x00007e24c5922ae8: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*invokestatic sanitizeStackTrace {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@6 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@28 + 0x00007e24c5922ae8: 94b6 5806 + + 0x00007e24c5922aec: ; {other} + 0x00007e24c5922aec: 0f1f 8400 | dc15 0014 + + 0x00007e24c5922af4: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922af4: 4885 c048 | ba58 5365 | 5824 7e00 | 0075 0c80 | 8a69 0100 | 0001 e9af | 0000 008b | 7808 49ba + 0x00007e24c5922b14: 0000 0062 | 247e 0000 | 4903 fa48 | 3bba 7801 | 0000 750d | 4883 8280 | 0100 0001 | e960 0000 + 0x00007e24c5922b34: 0048 3bba | 8801 0000 | 750d 4883 | 8290 0100 | 0001 e94a | 0000 0048 | 83ba 7801 | 0000 0075 + 0x00007e24c5922b54: 1748 89ba | 7801 0000 | 48c7 8280 | 0100 0001 | 0000 00e9 | 2900 0000 | 4883 ba88 | 0100 0000 + 0x00007e24c5922b74: 7517 4889 | ba88 0100 | 0048 c782 | 9001 0000 | 0100 0000 | e908 0000 | 0048 8382 | 7001 0000 + 0x00007e24c5922b94: ; {metadata('java/lang/NullPointerException')} + 0x00007e24c5922b94: 0148 bf40 | ef05 6224 | 7e00 008b | 5008 49ba | 0000 0062 | 247e 0000 | 4903 d248 | 3b7a 500f + 0x00007e24c5922bb4: 858c 0800 | 00e9 0000 | 0000 483b | 00e9 e208 + + 0x00007e24c5922bc4: ; {metadata(method data for {method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922bc4: 0000 48be | 685b 6558 | 247e 0000 | 4883 8670 | 0100 0001 | 488b f048 + + 0x00007e24c5922bdc: ; {static_call} + 0x00007e24c5922bdc: 8bd7 90e8 + + 0x00007e24c5922be0: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*invokestatic sanitizeStackTrace {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@6 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@21 + 0x00007e24c5922be0: 9cb5 5806 + + 0x00007e24c5922be4: ; {other} + 0x00007e24c5922be4: 0f1f 8400 | d416 0015 + + 0x00007e24c5922bec: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922bec: 4885 c048 | ba58 5365 | 5824 7e00 | 0075 0c80 | 8a69 0100 | 0001 e9af | 0000 008b | 7808 49ba + 0x00007e24c5922c0c: 0000 0062 | 247e 0000 | 4903 fa48 | 3bba 7801 | 0000 750d | 4883 8280 | 0100 0001 | e960 0000 + 0x00007e24c5922c2c: 0048 3bba | 8801 0000 | 750d 4883 | 8290 0100 | 0001 e94a | 0000 0048 | 83ba 7801 | 0000 0075 + 0x00007e24c5922c4c: 1748 89ba | 7801 0000 | 48c7 8280 | 0100 0001 | 0000 00e9 | 2900 0000 | 4883 ba88 | 0100 0000 + 0x00007e24c5922c6c: 7517 4889 | ba88 0100 | 0048 c782 | 9001 0000 | 0100 0000 | e908 0000 | 0048 8382 | 7001 0000 + 0x00007e24c5922c8c: ; {metadata('java/lang/NullPointerException')} + 0x00007e24c5922c8c: 0148 bf40 | ef05 6224 | 7e00 008b | 5008 49ba | 0000 0062 | 247e 0000 | 4903 d248 | 3b7a 500f + 0x00007e24c5922cac: 85a2 0700 | 00e9 0000 | 0000 483b | 00e9 ea07 + + 0x00007e24c5922cbc: ; {metadata(method data for {method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922cbc: 0000 48be | 685b 6558 | 247e 0000 | 4883 8670 | 0100 0001 | 488b f048 + + 0x00007e24c5922cd4: ; {static_call} + 0x00007e24c5922cd4: 8bd7 90e8 + + 0x00007e24c5922cd8: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*invokestatic sanitizeStackTrace {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@6 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@15 + 0x00007e24c5922cd8: a4b4 5806 + + 0x00007e24c5922cdc: ; {other} + 0x00007e24c5922cdc: 0f1f 8400 | cc17 0016 + + 0x00007e24c5922ce4: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922ce4: 4885 c048 | ba58 5365 | 5824 7e00 | 0075 0c80 | 8a69 0100 | 0001 e9af | 0000 008b | 7808 49ba + 0x00007e24c5922d04: 0000 0062 | 247e 0000 | 4903 fa48 | 3bba 7801 | 0000 750d | 4883 8280 | 0100 0001 | e960 0000 + 0x00007e24c5922d24: 0048 3bba | 8801 0000 | 750d 4883 | 8290 0100 | 0001 e94a | 0000 0048 | 83ba 7801 | 0000 0075 + 0x00007e24c5922d44: 1748 89ba | 7801 0000 | 48c7 8280 | 0100 0001 | 0000 00e9 | 2900 0000 | 4883 ba88 | 0100 0000 + 0x00007e24c5922d64: 7517 4889 | ba88 0100 | 0048 c782 | 9001 0000 | 0100 0000 | e908 0000 | 0048 8382 | 7001 0000 + 0x00007e24c5922d84: ; {metadata('java/lang/NullPointerException')} + 0x00007e24c5922d84: 0148 bf40 | ef05 6224 | 7e00 008b | 5008 49ba | 0000 0062 | 247e 0000 | 4903 d248 | 3b7a 500f + 0x00007e24c5922da4: 85b8 0600 | 00e9 0000 | 0000 483b | 00e9 f206 + + 0x00007e24c5922db4: ; {metadata(method data for {method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922db4: 0000 48be | 685b 6558 | 247e 0000 | 4883 8670 | 0100 0001 | 488b f048 + + 0x00007e24c5922dcc: ; {static_call} + 0x00007e24c5922dcc: 8bd7 90e8 + + 0x00007e24c5922dd0: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*invokestatic sanitizeStackTrace {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@6 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@9 + 0x00007e24c5922dd0: acb3 5806 + + 0x00007e24c5922dd4: ; {other} + 0x00007e24c5922dd4: 0f1f 8400 | c418 0017 + + 0x00007e24c5922ddc: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922ddc: 4885 c048 | ba58 5365 | 5824 7e00 | 0075 0c80 | 8a69 0100 | 0001 e9af | 0000 008b | 7808 49ba + 0x00007e24c5922dfc: 0000 0062 | 247e 0000 | 4903 fa48 | 3bba 7801 | 0000 750d | 4883 8280 | 0100 0001 | e960 0000 + 0x00007e24c5922e1c: 0048 3bba | 8801 0000 | 750d 4883 | 8290 0100 | 0001 e94a | 0000 0048 | 83ba 7801 | 0000 0075 + 0x00007e24c5922e3c: 1748 89ba | 7801 0000 | 48c7 8280 | 0100 0001 | 0000 00e9 | 2900 0000 | 4883 ba88 | 0100 0000 + 0x00007e24c5922e5c: 7517 4889 | ba88 0100 | 0048 c782 | 9001 0000 | 0100 0000 | e908 0000 | 0048 8382 | 7001 0000 + 0x00007e24c5922e7c: ; {metadata('java/lang/NullPointerException')} + 0x00007e24c5922e7c: 0148 bf40 | ef05 6224 | 7e00 008b | 5008 49ba | 0000 0062 | 247e 0000 | 4903 d248 | 3b7a 500f + 0x00007e24c5922e9c: 85ce 0500 | 00e9 0000 | 0000 483b | 00e9 fa05 + + 0x00007e24c5922eac: ; {metadata(method data for {method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922eac: 0000 48be | 685b 6558 | 247e 0000 | 4883 8670 | 0100 0001 | 488b f048 + + 0x00007e24c5922ec4: ; {static_call} + 0x00007e24c5922ec4: 8bd7 90e8 + + 0x00007e24c5922ec8: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*invokestatic sanitizeStackTrace {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@6 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@3 + 0x00007e24c5922ec8: b4b2 5806 + + 0x00007e24c5922ecc: ; {other} + 0x00007e24c5922ecc: 0f1f 8400 | bc19 0018 | 488b bc24 | c800 0000 | 4c8b 8c24 | c000 0000 | 4c8b 8424 | b800 0000 + 0x00007e24c5922eec: 488b 8c24 | b000 0000 | 488b 9424 | a800 0000 | 488b b424 | d000 0000 + + 0x00007e24c5922f04: ; {metadata(method data for {method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922f04: 4885 c049 | bb58 5365 | 5824 7e00 | 0075 0d41 | 808b 6901 | 0000 01e9 | b100 0000 | 448b 6808 + 0x00007e24c5922f24: 49ba 0000 | 0062 247e | 0000 4d03 | ea4d 3bab | 7801 0000 | 750d 4983 | 8380 0100 | 0001 e960 + 0x00007e24c5922f44: 0000 004d | 3bab 8801 | 0000 750d | 4983 8390 | 0100 0001 | e94a 0000 | 0049 83bb | 7801 0000 + 0x00007e24c5922f64: 0075 174d | 89ab 7801 | 0000 49c7 | 8380 0100 | 0001 0000 | 00e9 2900 | 0000 4983 | bb88 0100 + 0x00007e24c5922f84: 0000 7517 | 4d89 ab88 | 0100 0049 | c783 9001 | 0000 0100 | 0000 e908 | 0000 0049 | 8383 7001 + 0x00007e24c5922fa4: ; {metadata('java/lang/NullPointerException')} + 0x00007e24c5922fa4: 0000 0149 | bd40 ef05 | 6224 7e00 | 0044 8b58 | 0849 ba00 | 0000 6224 | 7e00 004d | 03da 4d3b + 0x00007e24c5922fc4: 6b50 0f85 | b104 0000 | e900 0000 | 0048 3b00 | e9cf 0400 + + 0x00007e24c5922fd8: ; {metadata({method} {0x00007e2459c73ff8} 'ActualParagraphIntrinsics' '(Ljava/lang/String;Landroidx/compose/ui/text/TextStyle;Ljava/util/List;Ljava/util/List;Landroidx/compose/ui/unit/Density;Landroidx/compose/ui/text/font/FontFamily$Resolver;)Landroidx/compose/ui/text/ParagraphIntrinsics;' in 'androidx/compose/ui/text/platform/SkiaParagraphIntrinsics_skikoKt')} + 0x00007e24c5922fd8: 0049 baf8 | 3fc7 5924 | 7e00 004c | 8954 2408 | 48c7 0424 | ffff ffff + + 0x00007e24c5922ff0: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c5922ff0: e80b 0e66 + + 0x00007e24c5922ff4: ; ImmutableOopMap {rsi=Oop rdx=Oop rcx=Oop r8=Oop r9=Oop rdi=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop } + ;*synchronization entry + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@-1 + 0x00007e24c5922ff4: 06e9 d4e9 + + 0x00007e24c5922ff8: ; {metadata({method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5922ff8: ffff 49ba | d09b 4058 | 247e 0000 | 4c89 5424 | 0848 c704 | 24ff ffff + + 0x00007e24c5923010: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c5923010: ffe8 ea0d + + 0x00007e24c5923014: ; ImmutableOopMap {rsi=Oop rdx=Oop rcx=Oop r8=Oop r9=Oop rdi=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop } + ;*synchronization entry + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@-1 (line 130) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@3 + 0x00007e24c5923014: 6606 e9ec + + 0x00007e24c5923018: ; {metadata({method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5923018: e9ff ff49 | ba50 9d40 | 5824 7e00 | 004c 8954 | 2408 48c7 | 0424 ffff + + 0x00007e24c5923030: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c5923030: ffff e8c9 + + 0x00007e24c5923034: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*synchronization entry + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@-1 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@3 + 0x00007e24c5923034: 0d66 06e9 | 3bea ffff + + 0x00007e24c592303c: ; {metadata(nullptr)} + 0x00007e24c592303c: 48ba 0000 | 0000 0000 | 0000 b800 + + 0x00007e24c5923048: ; {runtime_call load_klass_patching Runtime1 stub} + 0x00007e24c5923048: 0f05 0ae8 + + 0x00007e24c592304c: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*new {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@0 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@3 + 0x00007e24c592304c: b0f8 6506 | e923 eaff | ff48 8bd2 + + 0x00007e24c5923058: ; {runtime_call fast_new_instance Runtime1 stub} + 0x00007e24c5923058: e8a3 b565 + + 0x00007e24c592305c: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*new {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@0 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@3 + 0x00007e24c592305c: 06e9 72ea + + 0x00007e24c5923060: ; {metadata({method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5923060: ffff 49ba | b8ac 4058 | 247e 0000 | 4c89 5424 | 0848 c704 | 24ff ffff + + 0x00007e24c5923078: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c5923078: ffe8 820d + + 0x00007e24c592307c: ; ImmutableOopMap {[160]=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*synchronization entry + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@-1 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@3 + 0x00007e24c592307c: 6606 e9fa + + 0x00007e24c5923080: ; {metadata({method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c5923080: eaff ff49 | ba30 0843 | 6224 7e00 | 004c 8954 | 2408 48c7 | 0424 ffff + + 0x00007e24c5923098: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c5923098: ffff e861 + + 0x00007e24c592309c: ; ImmutableOopMap {rsi=Oop [160]=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*synchronization entry + ; - java.lang.Class::getName@-1 (line 987) + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@3 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@3 + 0x00007e24c592309c: 0d66 06e9 | 1feb ffff + + 0x00007e24c59230a4: ; {runtime_call throw_null_pointer_exception Runtime1 stub} + 0x00007e24c59230a4: e877 ab65 + + 0x00007e24c59230a8: ; ImmutableOopMap {[160]=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*getfield name {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) java.lang.Class::getName@1 (line 987) + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@3 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@3 + ; {metadata({method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59230a8: 0649 bad0 | 9b40 5824 | 7e00 004c | 8954 2408 | 48c7 0424 | ffff ffff + + 0x00007e24c59230c0: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c59230c0: e83b 0d66 + + 0x00007e24c59230c4: ; ImmutableOopMap {rdx=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*synchronization entry + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@-1 (line 130) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@9 + 0x00007e24c59230c4: 06e9 c3eb + + 0x00007e24c59230c8: ; {metadata({method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59230c8: ffff 49ba | 509d 4058 | 247e 0000 | 4c89 5424 | 0848 c704 | 24ff ffff + + 0x00007e24c59230e0: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c59230e0: ffe8 1a0d + + 0x00007e24c59230e4: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*synchronization entry + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@-1 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@9 + 0x00007e24c59230e4: 6606 e90a + + 0x00007e24c59230e8: ; {metadata(nullptr)} + 0x00007e24c59230e8: ecff ff48 | ba00 0000 | 0000 0000 | 00b8 000f + + 0x00007e24c59230f8: ; {runtime_call load_klass_patching Runtime1 stub} + 0x00007e24c59230f8: 050a e801 + + 0x00007e24c59230fc: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*new {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@0 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@9 + 0x00007e24c59230fc: f865 06e9 | f4eb ffff + + 0x00007e24c5923104: ; {runtime_call fast_new_instance Runtime1 stub} + 0x00007e24c5923104: 488b d2e8 + + 0x00007e24c5923108: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*new {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@0 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@9 + 0x00007e24c5923108: f4b4 6506 | e943 ecff + + 0x00007e24c5923110: ; {metadata({method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5923110: ff49 bab8 | ac40 5824 | 7e00 004c | 8954 2408 | 48c7 0424 | ffff ffff + + 0x00007e24c5923128: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c5923128: e8d3 0c66 + + 0x00007e24c592312c: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [216]=Oop } + ;*synchronization entry + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@-1 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@9 + 0x00007e24c592312c: 06e9 cbec + + 0x00007e24c5923130: ; {metadata({method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c5923130: ffff 49ba | 3008 4362 | 247e 0000 | 4c89 5424 | 0848 c704 | 24ff ffff + + 0x00007e24c5923148: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c5923148: ffe8 b20c + + 0x00007e24c592314c: ; ImmutableOopMap {rsi=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [216]=Oop } + ;*synchronization entry + ; - java.lang.Class::getName@-1 (line 987) + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@3 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@9 + 0x00007e24c592314c: 6606 e9f0 + + 0x00007e24c5923150: ; {runtime_call throw_null_pointer_exception Runtime1 stub} + 0x00007e24c5923150: ecff ffe8 + + 0x00007e24c5923154: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [216]=Oop } + ;*getfield name {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) java.lang.Class::getName@1 (line 987) + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@3 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@9 + 0x00007e24c5923154: c8aa 6506 + + 0x00007e24c5923158: ; {metadata({method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5923158: 49ba d09b | 4058 247e | 0000 4c89 | 5424 0848 | c704 24ff + + 0x00007e24c592316c: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c592316c: ffff ffe8 + + 0x00007e24c5923170: ; ImmutableOopMap {rcx=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*synchronization entry + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@-1 (line 130) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@15 + 0x00007e24c5923170: 8c0c 6606 | e99c edff + + 0x00007e24c5923178: ; {metadata({method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5923178: ff49 ba50 | 9d40 5824 | 7e00 004c | 8954 2408 | 48c7 0424 | ffff ffff + + 0x00007e24c5923190: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c5923190: e86b 0c66 + + 0x00007e24c5923194: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*synchronization entry + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@-1 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@15 + 0x00007e24c5923194: 06e9 e3ed + + 0x00007e24c5923198: ; {metadata(nullptr)} + 0x00007e24c5923198: ffff 48ba | 0000 0000 | 0000 0000 | b800 0f05 + + 0x00007e24c59231a8: ; {runtime_call load_klass_patching Runtime1 stub} + 0x00007e24c59231a8: 0ae8 52f7 + + 0x00007e24c59231ac: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*new {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@0 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@15 + 0x00007e24c59231ac: 6506 e9cd | edff ff48 + + 0x00007e24c59231b4: ; {runtime_call fast_new_instance Runtime1 stub} + 0x00007e24c59231b4: 8bd2 e845 + + 0x00007e24c59231b8: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*new {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@0 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@15 + 0x00007e24c59231b8: b465 06e9 | 1cee ffff + + 0x00007e24c59231c0: ; {metadata({method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59231c0: 49ba b8ac | 4058 247e | 0000 4c89 | 5424 0848 | c704 24ff + + 0x00007e24c59231d4: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c59231d4: ffff ffe8 + + 0x00007e24c59231d8: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [224]=Oop } + ;*synchronization entry + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@-1 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@15 + 0x00007e24c59231d8: 240c 6606 | e9a4 eeff + + 0x00007e24c59231e0: ; {metadata({method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c59231e0: ff49 ba30 | 0843 6224 | 7e00 004c | 8954 2408 | 48c7 0424 | ffff ffff + + 0x00007e24c59231f8: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c59231f8: e803 0c66 + + 0x00007e24c59231fc: ; ImmutableOopMap {rsi=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [224]=Oop } + ;*synchronization entry + ; - java.lang.Class::getName@-1 (line 987) + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@3 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@15 + 0x00007e24c59231fc: 06e9 c9ee + + 0x00007e24c5923200: ; {runtime_call throw_null_pointer_exception Runtime1 stub} + 0x00007e24c5923200: ffff e819 + + 0x00007e24c5923204: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [224]=Oop } + ;*getfield name {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) java.lang.Class::getName@1 (line 987) + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@3 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@15 + ; {metadata({method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5923204: aa65 0649 | bad0 9b40 | 5824 7e00 | 004c 8954 | 2408 48c7 | 0424 ffff + + 0x00007e24c592321c: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c592321c: ffff e8dd + + 0x00007e24c5923220: ; ImmutableOopMap {r8=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*synchronization entry + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@-1 (line 130) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@21 + 0x00007e24c5923220: 0b66 06e9 | 75ef ffff + + 0x00007e24c5923228: ; {metadata({method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5923228: 49ba 509d | 4058 247e | 0000 4c89 | 5424 0848 | c704 24ff + + 0x00007e24c592323c: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c592323c: ffff ffe8 + + 0x00007e24c5923240: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*synchronization entry + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@-1 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@21 + 0x00007e24c5923240: bc0b 6606 | e9bc efff + + 0x00007e24c5923248: ; {metadata(nullptr)} + 0x00007e24c5923248: ff48 ba00 | 0000 0000 | 0000 00b8 | 000f 050a + + 0x00007e24c5923258: ; {runtime_call load_klass_patching Runtime1 stub} + 0x00007e24c5923258: e8a3 f665 + + 0x00007e24c592325c: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*new {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@0 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@21 + 0x00007e24c592325c: 06e9 a6ef | ffff 488b + + 0x00007e24c5923264: ; {runtime_call fast_new_instance Runtime1 stub} + 0x00007e24c5923264: d2e8 96b3 + + 0x00007e24c5923268: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*new {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@0 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@21 + 0x00007e24c5923268: 6506 e9f5 + + 0x00007e24c592326c: ; {metadata({method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c592326c: efff ff49 | bab8 ac40 | 5824 7e00 | 004c 8954 | 2408 48c7 | 0424 ffff + + 0x00007e24c5923284: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c5923284: ffff e875 + + 0x00007e24c5923288: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [232]=Oop } + ;*synchronization entry + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@-1 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@21 + 0x00007e24c5923288: 0b66 06e9 | 7df0 ffff + + 0x00007e24c5923290: ; {metadata({method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c5923290: 49ba 3008 | 4362 247e | 0000 4c89 | 5424 0848 | c704 24ff + + 0x00007e24c59232a4: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c59232a4: ffff ffe8 + + 0x00007e24c59232a8: ; ImmutableOopMap {rsi=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [232]=Oop } + ;*synchronization entry + ; - java.lang.Class::getName@-1 (line 987) + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@3 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@21 + 0x00007e24c59232a8: 540b 6606 | e9a2 f0ff + + 0x00007e24c59232b0: ; {runtime_call throw_null_pointer_exception Runtime1 stub} + 0x00007e24c59232b0: ffe8 6aa9 + + 0x00007e24c59232b4: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [232]=Oop } + ;*getfield name {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) java.lang.Class::getName@1 (line 987) + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@3 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@21 + ; {metadata({method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59232b4: 6506 49ba | d09b 4058 | 247e 0000 | 4c89 5424 | 0848 c704 | 24ff ffff + + 0x00007e24c59232cc: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c59232cc: ffe8 2e0b + + 0x00007e24c59232d0: ; ImmutableOopMap {r9=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*synchronization entry + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@-1 (line 130) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@28 + 0x00007e24c59232d0: 6606 e94e + + 0x00007e24c59232d4: ; {metadata({method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59232d4: f1ff ff49 | ba50 9d40 | 5824 7e00 | 004c 8954 | 2408 48c7 | 0424 ffff + + 0x00007e24c59232ec: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c59232ec: ffff e80d + + 0x00007e24c59232f0: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*synchronization entry + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@-1 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@28 + 0x00007e24c59232f0: 0b66 06e9 | 95f1 ffff + + 0x00007e24c59232f8: ; {metadata(nullptr)} + 0x00007e24c59232f8: 48ba 0000 | 0000 0000 | 0000 b800 + + 0x00007e24c5923304: ; {runtime_call load_klass_patching Runtime1 stub} + 0x00007e24c5923304: 0f05 0ae8 + + 0x00007e24c5923308: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*new {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@0 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@28 + 0x00007e24c5923308: f4f5 6506 | e97f f1ff | ff48 8bd2 + + 0x00007e24c5923314: ; {runtime_call fast_new_instance Runtime1 stub} + 0x00007e24c5923314: e8e7 b265 + + 0x00007e24c5923318: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*new {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@0 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@28 + 0x00007e24c5923318: 06e9 cef1 + + 0x00007e24c592331c: ; {metadata({method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c592331c: ffff 49ba | b8ac 4058 | 247e 0000 | 4c89 5424 | 0848 c704 | 24ff ffff + + 0x00007e24c5923334: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c5923334: ffe8 c60a + + 0x00007e24c5923338: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [240]=Oop } + ;*synchronization entry + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@-1 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@28 + 0x00007e24c5923338: 6606 e956 + + 0x00007e24c592333c: ; {metadata({method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c592333c: f2ff ff49 | ba30 0843 | 6224 7e00 | 004c 8954 | 2408 48c7 | 0424 ffff + + 0x00007e24c5923354: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c5923354: ffff e8a5 + + 0x00007e24c5923358: ; ImmutableOopMap {rsi=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [240]=Oop } + ;*synchronization entry + ; - java.lang.Class::getName@-1 (line 987) + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@3 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@28 + 0x00007e24c5923358: 0a66 06e9 | 7bf2 ffff + + 0x00007e24c5923360: ; {runtime_call throw_null_pointer_exception Runtime1 stub} + 0x00007e24c5923360: e8bb a865 + + 0x00007e24c5923364: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [240]=Oop } + ;*getfield name {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) java.lang.Class::getName@1 (line 987) + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@3 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@28 + ; {metadata({method} {0x00007e2458409bd0} 'checkNotNullParameter' '(Ljava/lang/Object;Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5923364: 0649 bad0 | 9b40 5824 | 7e00 004c | 8954 2408 | 48c7 0424 | ffff ffff + + 0x00007e24c592337c: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c592337c: e87f 0a66 + + 0x00007e24c5923380: ; ImmutableOopMap {rdi=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*synchronization entry + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@-1 (line 130) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@35 + 0x00007e24c5923380: 06e9 27f3 + + 0x00007e24c5923384: ; {metadata({method} {0x00007e2458409d50} 'throwParameterIsNullNPE' '(Ljava/lang/String;)V' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c5923384: ffff 49ba | 509d 4058 | 247e 0000 | 4c89 5424 | 0848 c704 | 24ff ffff + + 0x00007e24c592339c: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c592339c: ffe8 5e0a + + 0x00007e24c59233a0: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*synchronization entry + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@-1 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@35 + 0x00007e24c59233a0: 6606 e96e + + 0x00007e24c59233a4: ; {metadata(nullptr)} + 0x00007e24c59233a4: f3ff ff48 | ba00 0000 | 0000 0000 | 00b8 000f + + 0x00007e24c59233b4: ; {runtime_call load_klass_patching Runtime1 stub} + 0x00007e24c59233b4: 050a e845 + + 0x00007e24c59233b8: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*new {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@0 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@35 + 0x00007e24c59233b8: f565 06e9 | 58f3 ffff + + 0x00007e24c59233c0: ; {runtime_call fast_new_instance Runtime1 stub} + 0x00007e24c59233c0: 488b d2e8 + + 0x00007e24c59233c4: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*new {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@0 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@35 + 0x00007e24c59233c4: 38b2 6506 | e9a7 f3ff + + 0x00007e24c59233cc: ; {metadata({method} {0x00007e245840acb8} 'sanitizeStackTrace' '(Ljava/lang/Throwable;)Ljava/lang/Throwable;' in 'kotlin/jvm/internal/Intrinsics')} + 0x00007e24c59233cc: ff49 bab8 | ac40 5824 | 7e00 004c | 8954 2408 | 48c7 0424 | ffff ffff + + 0x00007e24c59233e4: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c59233e4: e817 0a66 + + 0x00007e24c59233e8: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [248]=Oop } + ;*synchronization entry + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@-1 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@35 + 0x00007e24c59233e8: 06e9 2ff4 + + 0x00007e24c59233ec: ; {metadata({method} {0x00007e2462430830} 'getName' '()Ljava/lang/String;' in 'java/lang/Class')} + 0x00007e24c59233ec: ffff 49ba | 3008 4362 | 247e 0000 | 4c89 5424 | 0848 c704 | 24ff ffff + + 0x00007e24c5923404: ; {runtime_call counter_overflow Runtime1 stub} + 0x00007e24c5923404: ffe8 f609 + + 0x00007e24c5923408: ; ImmutableOopMap {rsi=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [248]=Oop } + ;*synchronization entry + ; - java.lang.Class::getName@-1 (line 987) + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@3 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@35 + 0x00007e24c5923408: 6606 e954 + + 0x00007e24c592340c: ; {runtime_call throw_null_pointer_exception Runtime1 stub} + 0x00007e24c592340c: f4ff ffe8 + + 0x00007e24c5923410: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop [248]=Oop } + ;*getfield name {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) java.lang.Class::getName@1 (line 987) + ; - kotlin.jvm.internal.Intrinsics::sanitizeStackTrace@3 (line 253) + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@11 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@35 + 0x00007e24c5923410: 0ca8 6506 + + 0x00007e24c5923414: ; {runtime_call fast_new_instance Runtime1 stub} + 0x00007e24c5923414: 488b d2e8 + + 0x00007e24c5923418: ; ImmutableOopMap {rbx=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*new {reexecute=0 rethrow=0 return_oop=0} + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@38 (line 37) + 0x00007e24c5923418: e4b1 6506 | e933 f5ff + + 0x00007e24c5923420: ; {internal_word} + 0x00007e24c5923420: ff49 bac4 | 2992 c524 | 7e00 004d | 8997 7004 + + 0x00007e24c5923430: ; {runtime_call SafepointBlob} + 0x00007e24c5923430: 0000 e9c9 | 1f59 0648 + + 0x00007e24c5923438: ; {runtime_call throw_class_cast_exception Runtime1 stub} + 0x00007e24c5923438: 8904 24e8 + + 0x00007e24c592343c: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*checkcast {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@14 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@35 + 0x00007e24c592343c: 60d5 6506 + + 0x00007e24c5923440: ; {runtime_call throw_null_pointer_exception Runtime1 stub} + 0x00007e24c5923440: e8db a765 + + 0x00007e24c5923444: ; ImmutableOopMap {rax=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*athrow {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@17 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@35 + 0x00007e24c5923444: 0648 8904 + + 0x00007e24c5923448: ; {runtime_call throw_class_cast_exception Runtime1 stub} + 0x00007e24c5923448: 24e8 52d5 + + 0x00007e24c592344c: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*checkcast {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@14 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@28 + ; {runtime_call throw_null_pointer_exception Runtime1 stub} + 0x00007e24c592344c: 6506 e8cd + + 0x00007e24c5923450: ; ImmutableOopMap {rax=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*athrow {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@17 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@28 + 0x00007e24c5923450: a765 0648 + + 0x00007e24c5923454: ; {runtime_call throw_class_cast_exception Runtime1 stub} + 0x00007e24c5923454: 8904 24e8 + + 0x00007e24c5923458: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*checkcast {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@14 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@21 + 0x00007e24c5923458: 44d5 6506 + + 0x00007e24c592345c: ; {runtime_call throw_null_pointer_exception Runtime1 stub} + 0x00007e24c592345c: e8bf a765 + + 0x00007e24c5923460: ; ImmutableOopMap {rax=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*athrow {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@17 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@21 + 0x00007e24c5923460: 0648 8904 + + 0x00007e24c5923464: ; {runtime_call throw_class_cast_exception Runtime1 stub} + 0x00007e24c5923464: 24e8 36d5 + + 0x00007e24c5923468: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*checkcast {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@14 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@15 + ; {runtime_call throw_null_pointer_exception Runtime1 stub} + 0x00007e24c5923468: 6506 e8b1 + + 0x00007e24c592346c: ; ImmutableOopMap {rax=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*athrow {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@17 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@15 + 0x00007e24c592346c: a765 0648 + + 0x00007e24c5923470: ; {runtime_call throw_class_cast_exception Runtime1 stub} + 0x00007e24c5923470: 8904 24e8 + + 0x00007e24c5923474: ; ImmutableOopMap {[168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*checkcast {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@14 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@9 + 0x00007e24c5923474: 28d5 6506 + + 0x00007e24c5923478: ; {runtime_call throw_null_pointer_exception Runtime1 stub} + 0x00007e24c5923478: e8a3 a765 + + 0x00007e24c592347c: ; ImmutableOopMap {rax=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop [208]=Oop } + ;*athrow {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@17 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@9 + 0x00007e24c592347c: 0648 8904 + + 0x00007e24c5923480: ; {runtime_call throw_class_cast_exception Runtime1 stub} + 0x00007e24c5923480: 24e8 1ad5 + + 0x00007e24c5923484: ; ImmutableOopMap {rdi=Oop r9=Oop r8=Oop rcx=Oop rdx=Oop rsi=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop } + ;*checkcast {reexecute=0 rethrow=0 return_oop=0} + ; - kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@14 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@3 + ; {runtime_call throw_null_pointer_exception Runtime1 stub} + 0x00007e24c5923484: 6506 e895 + + 0x00007e24c5923488: ; ImmutableOopMap {rdi=Oop r9=Oop r8=Oop rcx=Oop rdx=Oop rsi=Oop rax=Oop [168]=Oop [176]=Oop [184]=Oop [192]=Oop [200]=Oop } + ;*athrow {reexecute=1 rethrow=0 return_oop=0} + ; - (reexecute) kotlin.jvm.internal.Intrinsics::throwParameterIsNullNPE@17 (line 140) + ; - kotlin.jvm.internal.Intrinsics::checkNotNullParameter@5 (line 131) + ; - androidx.compose.ui.text.platform.SkiaParagraphIntrinsics_skikoKt::ActualParagraphIntrinsics@3 + 0x00007e24c5923488: a765 0649 | 8b87 0805 | 0000 49c7 | 8708 0500 | 0000 0000 | 0049 c787 | 1005 0000 | 0000 0000 + 0x00007e24c59234a8: 4881 c410 | 0100 005d + + 0x00007e24c59234b0: ; {runtime_call unwind_exception Runtime1 stub} + 0x00007e24c59234b0: e94b 8165 | 06f4 f4f4 +[Stub Code] + 0x00007e24c59234b8: ; {no_reloc} + 0x00007e24c59234b8: 48bb 0000 | 0000 0000 + + 0x00007e24c59234c0: ; {runtime_call} + 0x00007e24c59234c0: 0000 e9fb + + 0x00007e24c59234c4: ; {static_stub} + 0x00007e24c59234c4: ffff ff48 | bb00 0000 | 0000 0000 + + 0x00007e24c59234d0: ; {runtime_call} + 0x00007e24c59234d0: 00e9 fbff + + 0x00007e24c59234d4: ; {static_stub} + 0x00007e24c59234d4: ffff 48bb | 0000 0000 | 0000 0000 + + 0x00007e24c59234e0: ; {runtime_call} + 0x00007e24c59234e0: e9fb ffff + + 0x00007e24c59234e4: ; {static_stub} + 0x00007e24c59234e4: ff48 bb00 | 0000 0000 + + 0x00007e24c59234ec: ; {runtime_call} + 0x00007e24c59234ec: 0000 00e9 | fbff ffff + + 0x00007e24c59234f4: ; {static_stub} + 0x00007e24c59234f4: 48bb b858 | c759 247e + + 0x00007e24c59234fc: ; {runtime_call I2C/C2I adapters} + 0x00007e24c59234fc: 0000 e921 + + 0x00007e24c5923500: ; {runtime_call handle_exception_from_callee Runtime1 stub} + 0x00007e24c5923500: 0056 06e8 | 78ce 6506 + + 0x00007e24c5923508: ; {external_word} + 0x00007e24c5923508: 48bf 5ad8 | 33e3 247e | 0000 4883 + + 0x00007e24c5923514: ; {runtime_call MacroAssembler::debug64(char*, long, long*)} + 0x00007e24c5923514: e4f0 e815 | 464e 1df4 +[Deopt Handler Code] + 0x00007e24c592351c: ; {section_word} + 0x00007e24c592351c: 49ba 1c35 | 92c5 247e | 0000 4152 + + 0x00007e24c5923528: ; {runtime_call DeoptimizationBlob} + 0x00007e24c5923528: e973 3359 | 06f4 f4f4 +[/MachCode] + + +--------------- P R O C E S S --------------- + +Threads class SMR info: +_java_thread_list=0x00007e235401ee30, length=22, elements={ +0x00007e24dc02ecc0, 0x00007e24dc156b50, 0x00007e24dc1581a0, 0x00007e24dc159da0, +0x00007e24dc15b3e0, 0x00007e24dc15c980, 0x00007e24dc15e520, 0x00007e24dc15fc30, +0x00007e24dc16e9f0, 0x00007e24dc1724d0, 0x00007e24dcd6bdc0, 0x00007e24dcd6d880, +0x00007e24dcd71110, 0x00007e24dcd721d0, 0x00007e23e0313fd0, 0x00007e23e0314d80, +0x00007e23d0000f60, 0x00007e23d0005980, 0x00007e23e031e1f0, 0x00007e23e03a6150, +0x00007e23e2230f00, 0x00007e23800011a0 +} + +Java Threads: ( => current thread ) + 0x00007e24dc02ecc0 JavaThread "main" [_thread_blocked, id=2264501, stack(0x00007e24e1fe2000,0x00007e24e20e2000) (1024K)] + 0x00007e24dc156b50 JavaThread "Reference Handler" daemon [_thread_blocked, id=2264541, stack(0x00007e24b8700000,0x00007e24b8800000) (1024K)] + 0x00007e24dc1581a0 JavaThread "Finalizer" daemon [_thread_blocked, id=2264542, stack(0x00007e24b85ff000,0x00007e24b86ff000) (1024K)] + 0x00007e24dc159da0 JavaThread "Signal Dispatcher" daemon [_thread_blocked, id=2264543, stack(0x00007e24b84fe000,0x00007e24b85fe000) (1024K)] + 0x00007e24dc15b3e0 JavaThread "Service Thread" daemon [_thread_blocked, id=2264544, stack(0x00007e24b83fd000,0x00007e24b84fd000) (1024K)] + 0x00007e24dc15c980 JavaThread "Monitor Deflation Thread" daemon [_thread_blocked, id=2264545, stack(0x00007e24b82fc000,0x00007e24b83fc000) (1024K)] + 0x00007e24dc15e520 JavaThread "C2 CompilerThread0" daemon [_thread_blocked, id=2264547, stack(0x00007e24b81fb000,0x00007e24b82fb000) (1024K)] + 0x00007e24dc15fc30 JavaThread "C1 CompilerThread0" daemon [_thread_blocked, id=2264548, stack(0x00007e24b80fa000,0x00007e24b81fa000) (1024K)] + 0x00007e24dc16e9f0 JavaThread "Notification Thread" daemon [_thread_blocked, id=2264555, stack(0x00007e24a3f00000,0x00007e24a4000000) (1024K)] + 0x00007e24dc1724d0 JavaThread "Common-Cleaner" daemon [_thread_blocked, id=2264556, stack(0x00007e24a3dff000,0x00007e24a3eff000) (1024K)] + 0x00007e24dcd6bdc0 JavaThread "Java2D Disposer" daemon [_thread_blocked, id=2264809, stack(0x00007e246169a000,0x00007e246179a000) (1024K)] + 0x00007e24dcd6d880 JavaThread "AWT-XAWT" daemon [_thread_in_native, id=2264810, stack(0x00007e2461599000,0x00007e2461699000) (1024K)] + 0x00007e24dcd71110 JavaThread "AWT-Shutdown" [_thread_blocked, id=2264815, stack(0x00007e2461498000,0x00007e2461598000) (1024K)] +=>0x00007e24dcd721d0 JavaThread "AWT-EventQueue-0" [_thread_in_native, id=2264816, stack(0x00007e2461397000,0x00007e2461497000) (1024K)] + 0x00007e23e0313fd0 JavaThread "DefaultDispatcher-worker-1" daemon [_thread_blocked, id=2264875, stack(0x00007e2460d1e000,0x00007e2460e1e000) (1024K)] + 0x00007e23e0314d80 JavaThread "DefaultDispatcher-worker-2" daemon [_thread_blocked, id=2264876, stack(0x00007e2460c1d000,0x00007e2460d1d000) (1024K)] + 0x00007e23d0000f60 JavaThread "DefaultDispatcher-worker-3" daemon [_thread_blocked, id=2264877, stack(0x00007e2460b1c000,0x00007e2460c1c000) (1024K)] + 0x00007e23d0005980 JavaThread "kotlinx.coroutines.DefaultExecutor" daemon [_thread_blocked, id=2264878, stack(0x00007e2460a1b000,0x00007e2460b1b000) (1024K)] + 0x00007e23e031e1f0 JavaThread "Reference Cleaner" daemon [_thread_blocked, id=2264882, stack(0x00007e246091a000,0x00007e2460a1a000) (1024K)] + 0x00007e23e03a6150 JavaThread "TimerQueue" daemon [_thread_blocked, id=2264900, stack(0x00007e2460819000,0x00007e2460919000) (1024K)] + 0x00007e23e2230f00 JavaThread "pool-1-thread-14" daemon [_thread_blocked, id=3179730, stack(0x00007e24a30f2000,0x00007e24a31f2000) (1024K)] + 0x00007e23800011a0 JavaThread "pool-1-thread-15" daemon [_thread_blocked, id=3179731, stack(0x00007e23d4500000,0x00007e23d4600000) (1024K)] +Total: 22 + +Other Threads: + 0x00007e24dc149700 VMThread "VM Thread" [id=2264526, stack(0x00007e24b8b70000,0x00007e24b8c70000) (1024K)] + 0x00007e24dc12ed80 WatcherThread "VM Periodic Task Thread" [id=2264520, stack(0x00007e24b8c71000,0x00007e24b8d71000) (1024K)] + 0x00007e24dc05aa80 WorkerThread "GC Thread#0" [id=2264502, stack(0x00007e24bbf30000,0x00007e24bc030000) (1024K)] + 0x00007e2450008bd0 WorkerThread "GC Thread#1" [id=2264674, stack(0x00007e24a3afc000,0x00007e24a3bfc000) (1024K)] + 0x00007e24500096c0 WorkerThread "GC Thread#2" [id=2264675, stack(0x00007e24a39fb000,0x00007e24a3afb000) (1024K)] + 0x00007e245000a1b0 WorkerThread "GC Thread#3" [id=2264676, stack(0x00007e24a38fa000,0x00007e24a39fa000) (1024K)] + 0x00007e245000aca0 WorkerThread "GC Thread#4" [id=2264677, stack(0x00007e24a37f9000,0x00007e24a38f9000) (1024K)] + 0x00007e245000b790 WorkerThread "GC Thread#5" [id=2264678, stack(0x00007e24a36f8000,0x00007e24a37f8000) (1024K)] + 0x00007e245000c690 WorkerThread "GC Thread#6" [id=2264679, stack(0x00007e24a35f7000,0x00007e24a36f7000) (1024K)] + 0x00007e245000d5b0 WorkerThread "GC Thread#7" [id=2264680, stack(0x00007e24a34f6000,0x00007e24a35f6000) (1024K)] + 0x00007e245000e4d0 WorkerThread "GC Thread#8" [id=2264681, stack(0x00007e24a33f5000,0x00007e24a34f5000) (1024K)] + 0x00007e245000f3f0 WorkerThread "GC Thread#9" [id=2264682, stack(0x00007e24a32f4000,0x00007e24a33f4000) (1024K)] + 0x00007e2450010310 WorkerThread "GC Thread#10" [id=2264683, stack(0x00007e24a31f3000,0x00007e24a32f3000) (1024K)] + 0x00007e2450019010 WorkerThread "GC Thread#11" [id=2264871, stack(0x00007e2461296000,0x00007e2461396000) (1024K)] + 0x00007e2450017b50 WorkerThread "GC Thread#12" [id=2265053, stack(0x00007e23d5700000,0x00007e23d5800000) (1024K)] + 0x00007e24dc06b5c0 ConcurrentGCThread "G1 Main Marker" [id=2264503, stack(0x00007e24bbe2f000,0x00007e24bbf2f000) (1024K)] + 0x00007e24dc06c560 WorkerThread "G1 Conc#0" [id=2264504, stack(0x00007e24bbd2e000,0x00007e24bbe2e000) (1024K)] + 0x00007e24ac000d00 WorkerThread "G1 Conc#1" [id=2264872, stack(0x00007e2461195000,0x00007e2461295000) (1024K)] + 0x00007e24ac001840 WorkerThread "G1 Conc#2" [id=2264873, stack(0x00007e2461094000,0x00007e2461194000) (1024K)] + 0x00007e24dc1140a0 ConcurrentGCThread "G1 Refine#0" [id=2264505, stack(0x00007e24b8ef4000,0x00007e24b8ff4000) (1024K)] + 0x00007e24dc115060 ConcurrentGCThread "G1 Service" [id=2264506, stack(0x00007e24b8df3000,0x00007e24b8ef3000) (1024K)] +Total: 21 + +Threads with active compile tasks: +Total: 0 + +VM state: not at safepoint (normal execution) + +VM Mutex/Monitor currently owned by a thread: None + +Heap address: 0x0000000616000000, size: 7840 MB, Compressed Oops mode: Zero based, Oop shift amount: 3 + +CDS archive(s) mapped at: [0x00007e2462000000-0x00007e2462c75000-0x00007e2462c75000), size 13062144, SharedBaseAddress: 0x00007e2462000000, ArchiveRelocationMode: 1. +Compressed class space mapped at: 0x00007e2463000000-0x00007e24a3000000, reserved size: 1073741824 +Narrow klass base: 0x00007e2462000000, Narrow klass shift: 0, Narrow klass range: 0x100000000 + +GC Precious Log: + CardTable entry size: 512 + Card Set container configuration: InlinePtr #cards 4 size 8 Array Of Cards #cards 32 size 80 Howl #buckets 8 coarsen threshold 7372 Howl Bitmap #cards 1024 size 144 coarsen threshold 921 Card regions per heap region 1 cards per card region 8192 + CPUs: 16 total, 16 available + Memory: 31348M + Large Page Support: Disabled + NUMA Support: Disabled + Compressed Oops: Enabled (Zero based) + Heap Region Size: 4M + Heap Min Capacity: 8M + Heap Initial Capacity: 492M + Heap Max Capacity: 7840M + Pre-touch: Disabled + Parallel Workers: 13 + Concurrent Workers: 3 + Concurrent Refinement Workers: 13 + Periodic GC: Disabled + +Heap: + garbage-first heap total reserved 8028160K, committed 81920K, used 19116K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 1 young (4096K), 0 survivors (0K) + Metaspace used 55456K, committed 56192K, reserved 1114112K + class space used 5348K, committed 5696K, reserved 1048576K + +Heap Regions: E=young(eden), S=young(survivor), O=old, HS=humongous(starts), HC=humongous(continues), CS=collection set, F=free, TAMS=top-at-mark-start, PB=parsable bottom +| 0|0x0000000616000000, 0x00000006163ffff8, 0x0000000616400000| 99%| O| |TAMS 0x0000000616000000| PB 0x0000000616000000| Untracked | 0 +| 1|0x0000000616400000, 0x0000000616800000, 0x0000000616800000|100%| O| |TAMS 0x0000000616400000| PB 0x0000000616400000| Untracked | 0 +| 2|0x0000000616800000, 0x0000000616bfffe0, 0x0000000616c00000| 99%| O| |TAMS 0x0000000616800000| PB 0x0000000616800000| Untracked | 0 +| 3|0x0000000616c00000, 0x0000000616ffe020, 0x0000000617000000| 99%| O| |TAMS 0x0000000616c00000| PB 0x0000000616c00000| Untracked | 0 +| 4|0x0000000617000000, 0x000000061711a980, 0x0000000617400000| 27%| O| |TAMS 0x0000000617000000| PB 0x0000000617000000| Untracked | 0 +| 5|0x0000000617400000, 0x0000000617592a80, 0x0000000617800000| 39%| O| |TAMS 0x0000000617400000| PB 0x0000000617400000| Untracked | 0 +| 6|0x0000000617800000, 0x0000000617800000, 0x0000000617c00000| 0%| F| |TAMS 0x0000000617800000| PB 0x0000000617800000| Untracked | 0 +| 7|0x0000000617c00000, 0x0000000617c00000, 0x0000000618000000| 0%| F| |TAMS 0x0000000617c00000| PB 0x0000000617c00000| Untracked | 0 +| 8|0x0000000618000000, 0x0000000618000000, 0x0000000618400000| 0%| F| |TAMS 0x0000000618000000| PB 0x0000000618000000| Untracked | 0 +| 9|0x0000000618400000, 0x0000000618400000, 0x0000000618800000| 0%| F| |TAMS 0x0000000618400000| PB 0x0000000618400000| Untracked | 0 +| 10|0x0000000618800000, 0x0000000618800000, 0x0000000618c00000| 0%| F| |TAMS 0x0000000618800000| PB 0x0000000618800000| Untracked | 0 +| 11|0x0000000618c00000, 0x0000000618c00000, 0x0000000619000000| 0%| F| |TAMS 0x0000000618c00000| PB 0x0000000618c00000| Untracked | 0 +| 12|0x0000000619000000, 0x0000000619000000, 0x0000000619400000| 0%| F| |TAMS 0x0000000619000000| PB 0x0000000619000000| Untracked | 0 +| 13|0x0000000619400000, 0x0000000619400000, 0x0000000619800000| 0%| F| |TAMS 0x0000000619400000| PB 0x0000000619400000| Untracked | 0 +| 14|0x0000000619800000, 0x0000000619800000, 0x0000000619c00000| 0%| F| |TAMS 0x0000000619800000| PB 0x0000000619800000| Untracked | 0 +| 15|0x0000000619c00000, 0x0000000619c00000, 0x000000061a000000| 0%| F| |TAMS 0x0000000619c00000| PB 0x0000000619c00000| Untracked | 0 +| 16|0x000000061a000000, 0x000000061a000000, 0x000000061a400000| 0%| F| |TAMS 0x000000061a000000| PB 0x000000061a000000| Untracked | 0 +| 17|0x000000061a400000, 0x000000061a400000, 0x000000061a800000| 0%| F| |TAMS 0x000000061a400000| PB 0x000000061a400000| Untracked | 0 +| 18|0x000000061a800000, 0x000000061a800000, 0x000000061ac00000| 0%| F| |TAMS 0x000000061a800000| PB 0x000000061a800000| Untracked | 0 +| 19|0x000000061ac00000, 0x000000061ad749b0, 0x000000061b000000| 36%| E| |TAMS 0x000000061ac00000| PB 0x000000061ac00000| Complete | 0 + +Card table byte_map: [0x00007e24c3ab0000,0x00007e24c4a00000] _byte_map_base: 0x00007e24c0a00000 + +Marking Bits: (CMBitMap*) 0x00007e24dc05b5b0 + Bits: [0x00007e24bc030000, 0x00007e24c3ab0000) + +Polling page: 0x00007e24e3a47000 + +Metaspace: + +Usage: + Non-class: 48.93 MB used. + Class: 5.22 MB used. + Both: 54.16 MB used. + +Virtual space: + Non-class space: 64.00 MB reserved, 49.31 MB ( 77%) committed, 1 nodes. + Class space: 1.00 GB reserved, 5.56 MB ( <1%) committed, 1 nodes. + Both: 1.06 GB reserved, 54.88 MB ( 5%) committed. + +Chunk freelists: + Non-Class: 13.81 MB + Class: 10.42 MB + Both: 24.23 MB + +MaxMetaspaceSize: unlimited +CompressedClassSpaceSize: 1.00 GB +Initial GC threshold: 21.00 MB +Current GC threshold: 91.50 MB +CDS: on + - commit_granule_bytes: 65536. + - commit_granule_words: 8192. + - virtual_space_node_default_size: 8388608. + - enlarge_chunks_in_place: 1. + - use_allocation_guard: 0. + + +Internal statistics: + +num_allocs_failed_limit: 6. +num_arena_births: 1024. +num_arena_deaths: 0. +num_vsnodes_births: 2. +num_vsnodes_deaths: 0. +num_space_committed: 878. +num_space_uncommitted: 0. +num_chunks_returned_to_freelist: 6. +num_chunks_taken_from_freelist: 2941. +num_chunk_merges: 6. +num_chunk_splits: 2081. +num_chunks_enlarged: 1613. +num_inconsistent_stats: 0. + +CodeHeap 'non-profiled nmethods': size=119168Kb used=9938Kb max_used=11055Kb free=109230Kb + bounds [0x00007e24cc5a0000, 0x00007e24cd070000, 0x00007e24d3a00000] +CodeHeap 'profiled nmethods': size=119164Kb used=21513Kb max_used=28860Kb free=97650Kb + bounds [0x00007e24c4a00000, 0x00007e24c6630000, 0x00007e24cbe5f000] +CodeHeap 'non-nmethods': size=7428Kb used=3784Kb max_used=5493Kb free=3643Kb + bounds [0x00007e24cbe5f000, 0x00007e24cc43f000, 0x00007e24cc5a0000] + total_blobs=10804 nmethods=8842 adapters=1865 + compilation: enabled + stopped_count=0, restarted_count=0 + full_count=0 + +Compilation events (20 events): +Event: 4860.641 Thread 0x00007e24dc15e520 17302 4 androidx.compose.runtime.snapshots.SnapshotKt::optimisticMerges (405 bytes) +Event: 4860.647 Thread 0x00007e24dc15e520 nmethod 17302 0x00007e24cd067a90 code [0x00007e24cd067ca0, 0x00007e24cd068658] +Event: 4860.647 Thread 0x00007e24dc15e520 17303 ! 4 androidx.compose.runtime.snapshots.MutableSnapshot::innerApplyLocked$runtime (890 bytes) +Event: 4860.653 Thread 0x00007e24dc15e520 nmethod 17303 0x00007e24cd069190 code [0x00007e24cd0693a0, 0x00007e24cd069fd0] +Event: 4860.671 Thread 0x00007e24dc15e520 17304 4 java.lang.invoke.LambdaForm$MH/0x00007e246347f400::linkToTargetMethod (15 bytes) +Event: 4860.672 Thread 0x00007e24dc15e520 nmethod 17304 0x00007e24cd06ad90 code [0x00007e24cd06af20, 0x00007e24cd06b038] +Event: 4860.672 Thread 0x00007e24dc15e520 17305 4 java.lang.invoke.LambdaForm$DMH/0x00007e246347ec00::newInvokeSpecial (32 bytes) +Event: 4860.674 Thread 0x00007e24dc15e520 nmethod 17305 0x00007e24cd06b190 code [0x00007e24cd06b320, 0x00007e24cd06b5d8] +Event: 4860.686 Thread 0x00007e24dc15fc30 17306 3 androidx.compose.foundation.layout.WrapContentNode::measure-3p2s80s (192 bytes) +Event: 4860.686 Thread 0x00007e24dc15e520 17307 4 androidx.compose.ui.text.style.ColorStyle::getAlpha (8 bytes) +Event: 4860.687 Thread 0x00007e24dc15fc30 nmethod 17306 0x00007e24c5d0a290 code [0x00007e24c5d0a640, 0x00007e24c5d0ba70] +Event: 4860.687 Thread 0x00007e24dc15e520 nmethod 17307 0x00007e24cd06b810 code [0x00007e24cd06b9c0, 0x00007e24cd06ba98] +Event: 4860.971 Thread 0x00007e24dc15e520 17308 4 javax.swing.TimerQueue$DelayedTimer::compareTo (9 bytes) +Event: 4860.972 Thread 0x00007e24dc15e520 nmethod 17308 0x00007e24cd06bb10 code [0x00007e24cd06bca0, 0x00007e24cd06bde0] +Event: 4865.448 Thread 0x00007e24dc15e520 17309 4 androidx.compose.ui.platform.CompositionLocalsKt::getLocalWindowInfo (4 bytes) +Event: 4865.448 Thread 0x00007e24dc15e520 nmethod 17309 0x00007e24cc5b3810 code [0x00007e24cc5b3980, 0x00007e24cc5b39f0] +Event: 4866.486 Thread 0x00007e24dc15fc30 17310 3 sun.datatransfer.DataFlavorUtil::getTextCharset (31 bytes) +Event: 4866.486 Thread 0x00007e24dc15fc30 nmethod 17310 0x00007e24c504e110 code [0x00007e24c504e360, 0x00007e24c504eab8] +Event: 4866.486 Thread 0x00007e24dc15fc30 17311 3 jdk.internal.misc.Unsafe::getLongUnaligned (173 bytes) +Event: 4866.486 Thread 0x00007e24dc15fc30 nmethod 17311 0x00007e24c510e590 code [0x00007e24c510e760, 0x00007e24c510eb38] + +GC Heap History (20 events): +Event: 811.069 GC heap before +{Heap before GC invocations=18 (full 3): + garbage-first heap total reserved 8028160K, committed 69632K, used 23736K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 3 young (12288K), 1 survivors (4096K) + Metaspace used 53563K, committed 54272K, reserved 1114112K + class space used 5180K, committed 5504K, reserved 1048576K +} +Event: 811.126 GC heap after +{Heap after GC invocations=19 (full 4): + garbage-first heap total reserved 8028160K, committed 69632K, used 17305K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 0 young (0K), 0 survivors (0K) + Metaspace used 53563K, committed 54272K, reserved 1114112K + class space used 5180K, committed 5504K, reserved 1048576K +} +Event: 1187.634 GC heap before +{Heap before GC invocations=19 (full 4): + garbage-first heap total reserved 8028160K, committed 69632K, used 58265K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 10 young (40960K), 0 survivors (0K) + Metaspace used 53659K, committed 54336K, reserved 1114112K + class space used 5182K, committed 5504K, reserved 1048576K +} +Event: 1187.636 GC heap after +{Heap after GC invocations=20 (full 4): + garbage-first heap total reserved 8028160K, committed 69632K, used 19157K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 1 young (4096K), 1 survivors (4096K) + Metaspace used 53659K, committed 54336K, reserved 1114112K + class space used 5182K, committed 5504K, reserved 1048576K +} +Event: 1201.129 GC heap before +{Heap before GC invocations=20 (full 4): + garbage-first heap total reserved 8028160K, committed 69632K, used 47829K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 9 young (36864K), 1 survivors (4096K) + Metaspace used 53746K, committed 54464K, reserved 1114112K + class space used 5183K, committed 5504K, reserved 1048576K +} +Event: 1201.188 GC heap after +{Heap after GC invocations=21 (full 5): + garbage-first heap total reserved 8028160K, committed 69632K, used 18204K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 0 young (0K), 0 survivors (0K) + Metaspace used 53746K, committed 54464K, reserved 1114112K + class space used 5183K, committed 5504K, reserved 1048576K +} +Event: 4407.897 GC heap before +{Heap before GC invocations=21 (full 5): + garbage-first heap total reserved 8028160K, committed 69632K, used 59164K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 10 young (40960K), 0 survivors (0K) + Metaspace used 53856K, committed 54528K, reserved 1114112K + class space used 5186K, committed 5504K, reserved 1048576K +} +Event: 4407.898 GC heap after +{Heap after GC invocations=22 (full 5): + garbage-first heap total reserved 8028160K, committed 69632K, used 19705K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 1 young (4096K), 1 survivors (4096K) + Metaspace used 53856K, committed 54528K, reserved 1114112K + class space used 5186K, committed 5504K, reserved 1048576K +} +Event: 4617.350 GC heap before +{Heap before GC invocations=22 (full 5): + garbage-first heap total reserved 8028160K, committed 69632K, used 56569K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 10 young (40960K), 1 survivors (4096K) + Metaspace used 53927K, committed 54592K, reserved 1114112K + class space used 5186K, committed 5504K, reserved 1048576K +} +Event: 4617.352 GC heap after +{Heap after GC invocations=23 (full 5): + garbage-first heap total reserved 8028160K, committed 69632K, used 20265K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 1 young (4096K), 1 survivors (4096K) + Metaspace used 53927K, committed 54592K, reserved 1114112K + class space used 5186K, committed 5504K, reserved 1048576K +} +Event: 4621.216 GC heap before +{Heap before GC invocations=23 (full 5): + garbage-first heap total reserved 8028160K, committed 69632K, used 28457K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 4 young (16384K), 1 survivors (4096K) + Metaspace used 53959K, committed 54720K, reserved 1114112K + class space used 5186K, committed 5504K, reserved 1048576K +} +Event: 4621.275 GC heap after +{Heap after GC invocations=24 (full 6): + garbage-first heap total reserved 8028160K, committed 69632K, used 18002K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 0 young (0K), 0 survivors (0K) + Metaspace used 53959K, committed 54720K, reserved 1114112K + class space used 5186K, committed 5504K, reserved 1048576K +} +Event: 4662.265 GC heap before +{Heap before GC invocations=24 (full 6): + garbage-first heap total reserved 8028160K, committed 69632K, used 58962K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 10 young (40960K), 0 survivors (0K) + Metaspace used 54058K, committed 54784K, reserved 1114112K + class space used 5188K, committed 5504K, reserved 1048576K +} +Event: 4662.267 GC heap after +{Heap after GC invocations=25 (full 6): + garbage-first heap total reserved 8028160K, committed 286720K, used 19594K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 1 young (4096K), 1 survivors (4096K) + Metaspace used 54058K, committed 54784K, reserved 1114112K + class space used 5188K, committed 5504K, reserved 1048576K +} +Event: 4711.276 GC heap before +{Heap before GC invocations=25 (full 6): + garbage-first heap total reserved 8028160K, committed 286720K, used 60554K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 12 young (49152K), 1 survivors (4096K) + Metaspace used 54500K, committed 55232K, reserved 1114112K + class space used 5251K, committed 5568K, reserved 1048576K +} +Event: 4711.306 GC heap after +{Heap after GC invocations=26 (full 7): + garbage-first heap total reserved 8028160K, committed 122880K, used 18702K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 0 young (0K), 0 survivors (0K) + Metaspace used 54500K, committed 55232K, reserved 1114112K + class space used 5251K, committed 5568K, reserved 1048576K +} +Event: 4832.046 GC heap before +{Heap before GC invocations=26 (full 7): + garbage-first heap total reserved 8028160K, committed 122880K, used 92430K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 18 young (73728K), 0 survivors (0K) + Metaspace used 55316K, committed 56064K, reserved 1114112K + class space used 5338K, committed 5632K, reserved 1048576K +} +Event: 4832.050 GC heap after +{Heap after GC invocations=27 (full 7): + garbage-first heap total reserved 8028160K, committed 122880K, used 22029K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 1 young (4096K), 1 survivors (4096K) + Metaspace used 55316K, committed 56064K, reserved 1114112K + class space used 5338K, committed 5632K, reserved 1048576K +} +Event: 4861.307 GC heap before +{Heap before GC invocations=27 (full 7): + garbage-first heap total reserved 8028160K, committed 122880K, used 42509K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 7 young (28672K), 1 survivors (4096K) + Metaspace used 55455K, committed 56192K, reserved 1114112K + class space used 5348K, committed 5696K, reserved 1048576K +} +Event: 4861.349 GC heap after +{Heap after GC invocations=28 (full 8): + garbage-first heap total reserved 8028160K, committed 81920K, used 19116K [0x0000000616000000, 0x0000000800000000) + region size 4096K, 0 young (0K), 0 survivors (0K) + Metaspace used 55455K, committed 56192K, reserved 1114112K + class space used 5348K, committed 5696K, reserved 1048576K +} + +Dll operation events (10 events): +Event: 0.001 Loaded shared library /home/jay/.jdks/corretto-22.0.2/lib/libjava.so +Event: 0.038 Loaded shared library /home/jay/.jdks/corretto-22.0.2/lib/libjsvml.so +Event: 0.052 Loaded shared library /home/jay/.jdks/corretto-22.0.2/lib/libnio.so +Event: 0.055 Loaded shared library /home/jay/.jdks/corretto-22.0.2/lib/libzip.so +Event: 0.143 Loaded shared library /home/jay/.jdks/corretto-22.0.2/lib/libjimage.so +Event: 0.619 Loaded shared library /tmp/sqlite-3.34.0-224d6dc6-ab02-412e-96d2-aecc838a44c8-libsqlitejdbc.so +Event: 0.688 Loaded shared library /home/jay/.jdks/corretto-22.0.2/lib/libawt.so +Event: 0.691 Loaded shared library /home/jay/.jdks/corretto-22.0.2/lib/libawt_xawt.so +Event: 0.711 Loaded shared library /home/jay/.jdks/corretto-22.0.2/lib/libfontmanager.so +Event: 0.923 Loaded shared library /home/jay/.skiko/466d99514e1c05f31bc8556b637e21363d14da45e8215a739f8d1d8c22184704/libskiko-linux-x64.so + +Deoptimization events (20 events): +Event: 4852.076 Thread 0x00007e24dcd721d0 Uncommon trap: trap_request=0xffffff45 fr.pc=0x00007e24ccde5248 relative=0x00000000000000a8 +Event: 4852.076 Thread 0x00007e24dcd721d0 Uncommon trap: reason=unstable_if action=reinterpret pc=0x00007e24ccde5248 method=androidx.compose.ui.semantics.AppendedSemanticsElement.equals(Ljava/lang/Object;)Z @ 43 c2 +Event: 4852.076 Thread 0x00007e24dcd721d0 DEOPT PACKING pc=0x00007e24ccde5248 sp=0x00007e24614920b0 +Event: 4852.076 Thread 0x00007e24dcd721d0 DEOPT UNPACKING pc=0x00007e24cbeb6619 sp=0x00007e2461492058 mode 2 +Event: 4854.758 Thread 0x00007e24dcd721d0 Uncommon trap: trap_request=0xffffffde fr.pc=0x00007e24ccf53138 relative=0x0000000000005958 +Event: 4854.758 Thread 0x00007e24dcd721d0 Uncommon trap: reason=class_check action=maybe_recompile pc=0x00007e24ccf53138 method=org.jetbrains.exposed.v1.dao.EntityCache.updateEntities(Lorg/jetbrains/exposed/v1/core/dao/id/IdTable;)V @ 47 c2 +Event: 4854.758 Thread 0x00007e24dcd721d0 DEOPT PACKING pc=0x00007e24ccf53138 sp=0x00007e2461493210 +Event: 4854.758 Thread 0x00007e24dcd721d0 DEOPT UNPACKING pc=0x00007e24cbeb6619 sp=0x00007e2461493118 mode 2 +Event: 4854.790 Thread 0x00007e24dcd6d880 Uncommon trap: trap_request=0xffffffde fr.pc=0x00007e24cd00e7b4 relative=0x0000000000001494 +Event: 4854.790 Thread 0x00007e24dcd6d880 Uncommon trap: reason=class_check action=maybe_recompile pc=0x00007e24cd00e7b4 method=sun.awt.X11.XBaseWindow.dispatchEvent(Lsun/awt/X11/XEvent;)V @ 262 c2 +Event: 4854.790 Thread 0x00007e24dcd6d880 DEOPT PACKING pc=0x00007e24cd00e7b4 sp=0x00007e2461697650 +Event: 4854.790 Thread 0x00007e24dcd6d880 DEOPT UNPACKING pc=0x00007e24cbeb6619 sp=0x00007e2461697620 mode 2 +Event: 4857.149 Thread 0x00007e24dcd721d0 Uncommon trap: trap_request=0xffffff6e fr.pc=0x00007e24cd0510f0 relative=0x0000000000005a10 +Event: 4857.149 Thread 0x00007e24dcd721d0 Uncommon trap: reason=loop_limit_check action=maybe_recompile pc=0x00007e24cd0510f0 method=androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2.invokeSuspend$lambda$22(Landroidx/compose/runtime/Recomposer;Landroidx/collection/MutableScatterSe +Event: 4857.149 Thread 0x00007e24dcd721d0 DEOPT PACKING pc=0x00007e24cd0510f0 sp=0x00007e24614946c0 +Event: 4857.149 Thread 0x00007e24dcd721d0 DEOPT UNPACKING pc=0x00007e24cbeb6619 sp=0x00007e2461494538 mode 2 +Event: 4860.565 Thread 0x00007e24dcd721d0 Uncommon trap: trap_request=0xffffffc6 fr.pc=0x00007e24ccc54f34 relative=0x0000000000001234 +Event: 4860.565 Thread 0x00007e24dcd721d0 Uncommon trap: reason=bimorphic_or_optimized_type_check action=maybe_recompile pc=0x00007e24ccc54f34 method=kotlinx.coroutines.JobSupport.notifyCompletion(Lkotlinx/coroutines/NodeList;Ljava/lang/Throwable;)V @ 85 c2 +Event: 4860.565 Thread 0x00007e24dcd721d0 DEOPT PACKING pc=0x00007e24ccc54f34 sp=0x00007e2461493f40 +Event: 4860.565 Thread 0x00007e24dcd721d0 DEOPT UNPACKING pc=0x00007e24cbeb6619 sp=0x00007e2461493e20 mode 2 + +Classes loaded (20 events): +Event: 4712.281 Loading class java/awt/Toolkit$ToolkitEventMulticaster +Event: 4712.282 Loading class java/awt/Toolkit$ToolkitEventMulticaster done +Event: 4712.283 Loading class sun/awt/X11/XErrorHandler$IgnoreBadWindowHandler +Event: 4712.283 Loading class sun/awt/X11/XErrorHandler$IgnoreBadWindowHandler done +Event: 4744.780 Loading class sun/awt/datatransfer/ClipboardTransferable +Event: 4744.789 Loading class sun/awt/datatransfer/ClipboardTransferable done +Event: 4744.790 Loading class sun/awt/X11/XToolkitThreadBlockedHandler +Event: 4744.790 Loading class sun/awt/datatransfer/ToolkitThreadBlockedHandler +Event: 4744.790 Loading class sun/awt/datatransfer/ToolkitThreadBlockedHandler done +Event: 4744.790 Loading class sun/awt/X11/XToolkitThreadBlockedHandler done +Event: 4744.818 Loading class java/awt/datatransfer/MimeTypeParseException +Event: 4744.818 Loading class java/awt/datatransfer/MimeTypeParseException done +Event: 4744.825 Loading class java/util/AbstractMap$SimpleEntry +Event: 4744.825 Loading class java/util/AbstractMap$SimpleEntry done +Event: 4744.841 Loading class sun/awt/datatransfer/ClipboardTransferable$DataFactory +Event: 4744.841 Loading class sun/awt/datatransfer/ClipboardTransferable$DataFactory done +Event: 4744.841 Loading class sun/datatransfer/DataFlavorUtil$DataFlavorComparator +Event: 4744.841 Loading class sun/datatransfer/DataFlavorUtil$DataFlavorComparator done +Event: 4824.860 Loading class sun/awt/im/CompositionArea +Event: 4824.861 Loading class sun/awt/im/CompositionArea done + +Classes unloaded (0 events): +No events + +Classes redefined (0 events): +No events + +Internal exceptions (20 events): +Event: 4704.321 Thread 0x00007e24dcd721d0 Implicit null exception at 0x00007e24cced15fc to 0x00007e24cced2a04 +Event: 4704.321 Thread 0x00007e24dcd721d0 Implicit null exception at 0x00007e24ccd98228 to 0x00007e24ccd98ef0 +Event: 4712.276 Thread 0x00007e24dcd6d880 Implicit null exception at 0x00007e24ccd27b8c to 0x00007e24ccd2d228 +Event: 4712.279 Thread 0x00007e24dcd721d0 Implicit null exception at 0x00007e24cc7ac2e0 to 0x00007e24cc7ac47c +Event: 4712.279 Thread 0x00007e24dcd721d0 Implicit null exception at 0x00007e24ccdac968 to 0x00007e24ccdacbd0 +Event: 4712.285 Thread 0x00007e24dcd721d0 Implicit null exception at 0x00007e24cce13202 to 0x00007e24cce1373c +Event: 4712.285 Thread 0x00007e24dcd721d0 Implicit null exception at 0x00007e24cc7a4c44 to 0x00007e24cc7a544c +Event: 4714.340 Thread 0x00007e24dcd721d0 Implicit null exception at 0x00007e24cccd80be to 0x00007e24cccd8104 +Event: 4744.818 Thread 0x00007e24dcd721d0 Implicit null exception at 0x00007e24cc77309e to 0x00007e24cc77335c +Event: 4744.833 Thread 0x00007e24dcd721d0 Exception (0x000000061ce13368) +thrown [src/hotspot/share/interpreter/linkResolver.cpp, line 773] +Event: 4820.064 Thread 0x00007e24dcd721d0 Exception (0x000000061a102768) +thrown [src/hotspot/share/interpreter/linkResolver.cpp, line 773] +Event: 4820.077 Thread 0x00007e24dcd721d0 Exception (0x000000061a14bce0) +thrown [src/hotspot/share/interpreter/linkResolver.cpp, line 773] +Event: 4820.077 Thread 0x00007e24dcd721d0 Exception (0x000000061a150df8) +thrown [src/hotspot/share/interpreter/linkResolver.cpp, line 773] +Event: 4820.082 Thread 0x00007e24dcd721d0 Implicit null exception at 0x00007e24ccae2cc9 to 0x00007e24ccae2f2c +Event: 4820.552 Thread 0x00007e24dcd721d0 Implicit null exception at 0x00007e24ccecf7ad to 0x00007e24cced052c +Event: 4822.245 Thread 0x00007e24dcd721d0 Implicit null exception at 0x00007e24cced6596 to 0x00007e24cced68f8 +Event: 4826.535 Thread 0x00007e24dcd721d0 Exception (0x00000006199edae8) +thrown [src/hotspot/share/interpreter/linkResolver.cpp, line 773] +Event: 4826.535 Thread 0x00007e24dcd721d0 Exception (0x00000006199f49f8) +thrown [src/hotspot/share/interpreter/linkResolver.cpp, line 773] +Event: 4826.557 Thread 0x00007e24dcd6d880 Implicit null exception at 0x00007e24ccd1eb30 to 0x00007e24ccd24194 +Event: 4831.506 Thread 0x00007e24dcd721d0 Exception (0x000000061920fb08) +thrown [src/hotspot/share/interpreter/linkResolver.cpp, line 773] + +ZGC Phase Switch (0 events): +No events + +VM Operations (20 events): +Event: 4853.052 Executing VM operation: Cleanup +Event: 4853.052 Executing VM operation: Cleanup done +Event: 4855.052 Executing VM operation: Cleanup +Event: 4855.052 Executing VM operation: Cleanup done +Event: 4856.052 Executing VM operation: Cleanup +Event: 4856.052 Executing VM operation: Cleanup done +Event: 4858.052 Executing VM operation: Cleanup +Event: 4858.052 Executing VM operation: Cleanup done +Event: 4860.052 Executing VM operation: Cleanup +Event: 4860.052 Executing VM operation: Cleanup done +Event: 4861.052 Executing VM operation: Cleanup +Event: 4861.053 Executing VM operation: Cleanup done +Event: 4861.307 Executing VM operation: G1CollectFull (System.gc()) +Event: 4861.349 Executing VM operation: G1CollectFull (System.gc()) done +Event: 4861.725 Executing VM operation: HandshakeAllThreads (HandshakeForDeflation) +Event: 4861.725 Executing VM operation: HandshakeAllThreads (HandshakeForDeflation) done +Event: 4861.725 Executing VM operation: RendezvousGCThreads +Event: 4861.725 Executing VM operation: RendezvousGCThreads done +Event: 4862.725 Executing VM operation: Cleanup +Event: 4862.726 Executing VM operation: Cleanup done + +Memory protections (20 events): +Event: 4712.249 Protecting memory [0x00007e2461f00000,0x00007e2461f04000] with protection modes 0 +Event: 4712.250 Protecting memory [0x00007e23bc0ff000,0x00007e23bc103000] with protection modes 0 +Event: 4712.251 Protecting memory [0x00007e24a3bfd000,0x00007e24a3c01000] with protection modes 0 +Event: 4744.820 Protecting memory [0x00007e23a32ff000,0x00007e23a3303000] with protection modes 0 +Event: 4744.822 Protecting memory [0x00007e2461f00000,0x00007e2461f04000] with protection modes 0 +Event: 4744.823 Protecting memory [0x00007e23d4aff000,0x00007e23d4b03000] with protection modes 0 +Event: 4744.825 Protecting memory [0x00007e24a3cfe000,0x00007e24a3d02000] with protection modes 0 +Event: 4747.199 Protecting memory [0x00007e23a32ff000,0x00007e23a3303000] with protection modes 0 +Event: 4757.158 Protecting memory [0x00007e23a32ff000,0x00007e23a3303000] with protection modes 0 +Event: 4757.158 Protecting memory [0x00007e23d4aff000,0x00007e23d4b03000] with protection modes 0 +Event: 4757.158 Protecting memory [0x00007e24a3cfe000,0x00007e24a3d02000] with protection modes 0 +Event: 4799.062 Protecting memory [0x00007e23a32ff000,0x00007e23a3303000] with protection modes 0 +Event: 4810.911 Protecting memory [0x00007e23a32ff000,0x00007e23a3303000] with protection modes 0 +Event: 4828.433 Protecting memory [0x00007e24a3cfe000,0x00007e24a3d02000] with protection modes 0 +Event: 4828.433 Protecting memory [0x00007e24a3bfd000,0x00007e24a3c01000] with protection modes 0 +Event: 4831.519 Protecting memory [0x00007e24a3cfe000,0x00007e24a3d02000] with protection modes 0 +Event: 4831.554 Protecting memory [0x00007e24a3bfd000,0x00007e24a3c01000] with protection modes 0 +Event: 4849.860 Protecting memory [0x00007e24a3cfe000,0x00007e24a3d02000] with protection modes 0 +Event: 4854.793 Protecting memory [0x00007e24a3cfe000,0x00007e24a3d02000] with protection modes 0 +Event: 4854.799 Protecting memory [0x00007e24a3bfd000,0x00007e24a3c01000] with protection modes 0 + +Nmethod flushes (20 events): +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c5ca7d90 +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c5cd0b10 +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c5cd5b90 +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c5cf5910 +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c5d00510 +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c5d07710 +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c5d49990 +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c5d56d10 +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c5dc2290 +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c5dc3690 +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c5dc3e90 +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c5dca510 +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c5dcef10 +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c5dd0890 +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c5dd0c90 +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c5dd4f90 +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c5e0ab10 +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c6029d10 +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c6338910 +Event: 4861.329 Thread 0x00007e24dc149700 flushing nmethod 0x00007e24c6451990 + +Events (20 events): +Event: 4758.508 Thread 0x00007e243c2d8d30 Thread exited: 0x00007e243c2d8d30 +Event: 4761.195 Thread 0x00007e243c392e80 Thread exited: 0x00007e243c392e80 +Event: 4799.061 Thread 0x00007e24dc15fc30 Thread added: 0x00007e243c382aa0 +Event: 4803.452 Thread 0x00007e243c382aa0 Thread exited: 0x00007e243c382aa0 +Event: 4810.911 Thread 0x00007e24dc15fc30 Thread added: 0x00007e243c3852a0 +Event: 4812.282 Thread 0x00007e243c3852a0 Thread exited: 0x00007e243c3852a0 +Event: 4828.433 Thread 0x00007e24dc15fc30 Thread added: 0x00007e243c18b570 +Event: 4828.433 Thread 0x00007e24dc15fc30 Thread added: 0x00007e243c18bcd0 +Event: 4829.343 Thread 0x00007e243c18bcd0 Thread exited: 0x00007e243c18bcd0 +Event: 4831.031 Thread 0x00007e243c18b570 Thread exited: 0x00007e243c18b570 +Event: 4831.519 Thread 0x00007e24dc15fc30 Thread added: 0x00007e243c18b570 +Event: 4831.553 Thread 0x00007e24dc15e520 Thread added: 0x00007e2439303240 +Event: 4832.051 Thread 0x00007e2439303240 Thread exited: 0x00007e2439303240 +Event: 4833.455 Thread 0x00007e243c18b570 Thread exited: 0x00007e243c18b570 +Event: 4849.859 Thread 0x00007e24dc15fc30 Thread added: 0x00007e243c255be0 +Event: 4850.853 Thread 0x00007e243c255be0 Thread exited: 0x00007e243c255be0 +Event: 4854.793 Thread 0x00007e24dc15fc30 Thread added: 0x00007e243c215830 +Event: 4854.799 Thread 0x00007e24dc15fc30 Thread added: 0x00007e243c2d0d40 +Event: 4855.907 Thread 0x00007e243c215830 Thread exited: 0x00007e243c215830 +Event: 4859.269 Thread 0x00007e243c2d0d40 Thread exited: 0x00007e243c2d0d40 + + +Dynamic libraries: +616000000-61b000000 rw-p 00000000 00:00 0 +61b000000-800000000 ---p 00000000 00:00 0 +63670938d000-63670938e000 r--p 00000000 103:03 43004420 /home/jay/.jdks/corretto-22.0.2/bin/java +63670938e000-63670938f000 r-xp 00001000 103:03 43004420 /home/jay/.jdks/corretto-22.0.2/bin/java +63670938f000-636709390000 r--p 00002000 103:03 43004420 /home/jay/.jdks/corretto-22.0.2/bin/java +636709390000-636709391000 r--p 00002000 103:03 43004420 /home/jay/.jdks/corretto-22.0.2/bin/java +636709391000-636709392000 rw-p 00003000 103:03 43004420 /home/jay/.jdks/corretto-22.0.2/bin/java +636745496000-6367454e0000 rw-p 00000000 00:00 0 [heap] +7e234c000000-7e234c160000 rw-p 00000000 00:00 0 +7e234c160000-7e2350000000 ---p 00000000 00:00 0 +7e2350000000-7e23500ce000 rw-p 00000000 00:00 0 +7e23500ce000-7e2354000000 ---p 00000000 00:00 0 +7e2354000000-7e2354211000 rw-p 00000000 00:00 0 +7e2354211000-7e2358000000 ---p 00000000 00:00 0 +7e235a7b5000-7e235aaa6000 rw-p 00000000 00:00 0 +7e235aaa6000-7e235aea6000 rw-s 1cfaa6000 00:06 514 /dev/dri/renderD128 +7e235affe000-7e235afff000 ---p 00000000 00:00 0 +7e235afff000-7e235b7ff000 rw-p 00000000 00:00 0 +7e235b7ff000-7e235b800000 ---p 00000000 00:00 0 +7e235b800000-7e235c000000 rw-p 00000000 00:00 0 +7e235c000000-7e235ee5f000 rw-p 00000000 00:00 0 +7e235ee5f000-7e2360000000 ---p 00000000 00:00 0 +7e2360000000-7e23600b1000 rw-p 00000000 00:00 0 +7e23600b1000-7e2364000000 ---p 00000000 00:00 0 +7e2364000000-7e23645d7000 rw-p 00000000 00:00 0 +7e23645d7000-7e2368000000 ---p 00000000 00:00 0 +7e2368000000-7e2368252000 rw-p 00000000 00:00 0 +7e2368252000-7e236c000000 ---p 00000000 00:00 0 +7e236c000000-7e236cdcf000 rw-p 00000000 00:00 0 +7e236cdcf000-7e2370000000 ---p 00000000 00:00 0 +7e2370000000-7e2370065000 rw-p 00000000 00:00 0 +7e2370065000-7e2374000000 ---p 00000000 00:00 0 +7e2374000000-7e2374021000 rw-p 00000000 00:00 0 +7e2374021000-7e2378000000 ---p 00000000 00:00 0 +7e2378000000-7e2378e34000 rw-p 00000000 00:00 0 +7e2378e34000-7e237c000000 ---p 00000000 00:00 0 +7e237c000000-7e237c14a000 rw-p 00000000 00:00 0 +7e237c14a000-7e2380000000 ---p 00000000 00:00 0 +7e2380000000-7e2380021000 rw-p 00000000 00:00 0 +7e2380021000-7e2384000000 ---p 00000000 00:00 0 +7e2384000000-7e2384021000 rw-p 00000000 00:00 0 +7e2384021000-7e2388000000 ---p 00000000 00:00 0 +7e2388000000-7e238809d000 rw-p 00000000 00:00 0 +7e238809d000-7e238c000000 ---p 00000000 00:00 0 +7e238c000000-7e238c021000 rw-p 00000000 00:00 0 +7e238c021000-7e2390000000 ---p 00000000 00:00 0 +7e2390000000-7e2390021000 rw-p 00000000 00:00 0 +7e2390021000-7e2394000000 ---p 00000000 00:00 0 +7e2394000000-7e2394118000 rw-p 00000000 00:00 0 +7e2394118000-7e2398000000 ---p 00000000 00:00 0 +7e2398000000-7e2398021000 rw-p 00000000 00:00 0 +7e2398021000-7e239c000000 ---p 00000000 00:00 0 +7e239c000000-7e239c129000 rw-p 00000000 00:00 0 +7e239c129000-7e23a0000000 ---p 00000000 00:00 0 +7e23a0101000-7e23a0324000 rw-p 00000000 00:00 0 +7e23a0324000-7e23a0524000 rw-s 1b4564000 00:06 514 /dev/dri/renderD128 +7e23a0524000-7e23a0724000 rw-s 13045d000 00:06 514 /dev/dri/renderD128 +7e23a0724000-7e23a0725000 ---p 00000000 00:00 0 +7e23a0725000-7e23a0f25000 rw-p 00000000 00:00 0 +7e23a0f25000-7e23a0f26000 ---p 00000000 00:00 0 +7e23a0f26000-7e23a1726000 rw-p 00000000 00:00 0 +7e23a1926000-7e23a1927000 ---p 00000000 00:00 0 +7e23a1927000-7e23a2127000 rw-p 00000000 00:00 0 +7e23a2127000-7e23a2128000 ---p 00000000 00:00 0 +7e23a2128000-7e23a2928000 rw-p 00000000 00:00 0 +7e23a2928000-7e23a2d28000 rw-s 18a728000 00:06 514 /dev/dri/renderD128 +7e23a2dff000-7e23a2fff000 rw-s 112f3b000 00:06 514 /dev/dri/renderD128 +7e23a2fff000-7e23a31ff000 rw-s 126cb9000 00:06 514 /dev/dri/renderD128 +7e23a31ff000-7e23a33ff000 rw-s 1cb3b7000 00:06 514 /dev/dri/renderD128 +7e23a33ff000-7e23a35ff000 rw-s 150de0000 00:06 514 /dev/dri/renderD128 +7e23a35ff000-7e23a3600000 ---p 00000000 00:00 0 +7e23a3600000-7e23a3e00000 rw-p 00000000 00:00 0 +7e23a3e00000-7e23a4000000 rw-s 17ac3e000 00:06 514 /dev/dri/renderD128 +7e23a4000000-7e23a4021000 rw-p 00000000 00:00 0 +7e23a4021000-7e23a8000000 ---p 00000000 00:00 0 +7e23a80bc000-7e23a815a000 r--p 00000000 103:03 17706489 /usr/share/fonts/TTF/DejaVuSans-BoldOblique.ttf +7e23a815a000-7e23a81f8000 r--p 00000000 103:03 17971603 /usr/share/fonts/noto/NotoSans-BoldItalic.ttf +7e23a81f8000-7e23a83f8000 rw-s 109628000 00:06 514 /dev/dri/renderD128 +7e23a83f8000-7e23a85f8000 rw-s 132c63000 00:06 514 /dev/dri/renderD128 +7e23a85f8000-7e23a87f8000 rw-s 1d2ca9000 00:06 514 /dev/dri/renderD128 +7e23a87f8000-7e23a87f9000 ---p 00000000 00:00 0 +7e23a87f9000-7e23a8ff9000 rw-p 00000000 00:00 0 +7e23a8ff9000-7e23a8ffa000 ---p 00000000 00:00 0 +7e23a8ffa000-7e23a97fa000 rw-p 00000000 00:00 0 +7e23a97fa000-7e23a97fb000 ---p 00000000 00:00 0 +7e23a97fb000-7e23a9ffb000 rw-p 00000000 00:00 0 +7e23a9ffb000-7e23a9ffc000 ---p 00000000 00:00 0 +7e23a9ffc000-7e23aa7fc000 rw-p 00000000 00:00 0 +7e23aa7fc000-7e23aa7fd000 ---p 00000000 00:00 0 +7e23aa7fd000-7e23aaffd000 rw-p 00000000 00:00 0 +7e23aaffd000-7e23aaffe000 ---p 00000000 00:00 0 +7e23aaffe000-7e23ab7fe000 rw-p 00000000 00:00 0 +7e23ab7fe000-7e23ab7ff000 ---p 00000000 00:00 0 +7e23ab7ff000-7e23abfff000 rw-p 00000000 00:00 0 +7e23abfff000-7e23ac000000 ---p 00000000 00:00 0 +7e23ac000000-7e23ac800000 rw-p 00000000 00:00 0 +7e23ac800000-7e23ae794000 r--p 00000000 103:03 16926547 /usr/lib/libicudata.so.78.2 +7e23ae794000-7e23ae795000 r--p 01f93000 103:03 16926547 /usr/lib/libicudata.so.78.2 +7e23ae800000-7e23aed3e000 r--p 00000000 103:03 16961541 /usr/lib/libLLVM.so.21.1 +7e23aed3e000-7e23b4557000 r-xp 0053e000 103:03 16961541 /usr/lib/libLLVM.so.21.1 +7e23b4557000-7e23b7b81000 r--p 05d57000 103:03 16961541 /usr/lib/libLLVM.so.21.1 +7e23b7b81000-7e23b7d8a000 r--p 09380000 103:03 16961541 /usr/lib/libLLVM.so.21.1 +7e23b7d8a000-7e23b7dcf000 rw-p 09589000 103:03 16961541 /usr/lib/libLLVM.so.21.1 +7e23b7dcf000-7e23b7e97000 rw-p 00000000 00:00 0 +7e23b7ec7000-7e23b7f63000 r--p 00000000 103:03 17706491 /usr/share/fonts/TTF/DejaVuSans-Oblique.ttf +7e23b7f63000-7e23b8000000 r--p 00000000 103:03 17971604 /usr/share/fonts/noto/NotoSans-Italic.ttf +7e23b8000000-7e23b8021000 rw-p 00000000 00:00 0 +7e23b8021000-7e23bc000000 ---p 00000000 00:00 0 +7e23bc032000-7e23bc098000 r--p 00000000 103:03 17977920 /usr/share/fonts/liberation/LiberationSans-Italic.ttf +7e23bc098000-7e23bc0fe000 r--p 00000000 103:03 17977918 /usr/share/fonts/liberation/LiberationSans-Bold.ttf +7e23bc1ff000-7e23bc3ff000 rw-s 145ba6000 00:06 514 /dev/dri/renderD128 +7e23bc3ff000-7e23bc400000 ---p 00000000 00:00 0 +7e23bc400000-7e23bcc00000 rw-p 00000000 00:00 0 +7e23bcc00000-7e23bcc1a000 r--p 00000000 103:03 17012473 /usr/lib/libgallium-26.0.1-arch1.1.so +7e23bcc1a000-7e23bea9b000 r-xp 0001a000 103:03 17012473 /usr/lib/libgallium-26.0.1-arch1.1.so +7e23bea9b000-7e23bfbee000 r--p 01e9b000 103:03 17012473 /usr/lib/libgallium-26.0.1-arch1.1.so +7e23bfbee000-7e23bfd4c000 r--p 02fee000 103:03 17012473 /usr/lib/libgallium-26.0.1-arch1.1.so +7e23bfd4c000-7e23bfd80000 rw-p 0314c000 103:03 17012473 /usr/lib/libgallium-26.0.1-arch1.1.so +7e23bfd80000-7e23bff4c000 rw-p 00000000 00:00 0 +7e23bff52000-7e23c0000000 r--p 00000000 103:03 17706488 /usr/share/fonts/TTF/DejaVuSans-Bold.ttf +7e23c0000000-7e23c0021000 rw-p 00000000 00:00 0 +7e23c0021000-7e23c4000000 ---p 00000000 00:00 0 +7e23c4000000-7e23c4021000 rw-p 00000000 00:00 0 +7e23c4021000-7e23c8000000 ---p 00000000 00:00 0 +7e23c8000000-7e23c8021000 rw-p 00000000 00:00 0 +7e23c8021000-7e23cc000000 ---p 00000000 00:00 0 +7e23cc000000-7e23cc021000 rw-p 00000000 00:00 0 +7e23cc021000-7e23d0000000 ---p 00000000 00:00 0 +7e23d0000000-7e23d0021000 rw-p 00000000 00:00 0 +7e23d0021000-7e23d4000000 ---p 00000000 00:00 0 +7e23d4000000-7e23d4200000 rw-s 1252b3000 00:06 514 /dev/dri/renderD128 +7e23d4264000-7e23d4464000 rw-s 127ea2000 00:06 514 /dev/dri/renderD128 +7e23d4464000-7e23d44ff000 r--p 00000000 103:03 17971599 /usr/share/fonts/noto/NotoSans-Bold.ttf +7e23d44ff000-7e23d4500000 ---p 00000000 00:00 0 +7e23d4500000-7e23d4504000 ---p 00000000 00:00 0 +7e23d4504000-7e23d4600000 rw-p 00000000 00:00 0 +7e23d4600000-7e23d4800000 rw-s 1a9d35000 00:06 514 /dev/dri/renderD128 +7e23d4800000-7e23d4a01000 rw-s 00000000 103:03 39341502 /home/jay/.cache/mesa_shader_cache/index +7e23d4a02000-7e23d4a66000 r--p 00000000 103:03 17977919 /usr/share/fonts/liberation/LiberationSans-BoldItalic.ttf +7e23d4a66000-7e23d4afe000 r--p 00000000 103:03 17971619 /usr/share/fonts/noto/NotoSans-Medium.ttf +7e23d4bff000-7e23d4c00000 ---p 00000000 00:00 0 +7e23d4c00000-7e23d5400000 rw-p 00000000 00:00 0 +7e23d5400000-7e23d5448000 r--p 00000000 103:03 16926572 /usr/lib/libicuuc.so.78.2 +7e23d5448000-7e23d5565000 r-xp 00048000 103:03 16926572 /usr/lib/libicuuc.so.78.2 +7e23d5565000-7e23d55f8000 r--p 00165000 103:03 16926572 /usr/lib/libicuuc.so.78.2 +7e23d55f8000-7e23d560b000 r--p 001f8000 103:03 16926572 /usr/lib/libicuuc.so.78.2 +7e23d560b000-7e23d560c000 rw-p 0020b000 103:03 16926572 /usr/lib/libicuuc.so.78.2 +7e23d560c000-7e23d560e000 rw-p 00000000 00:00 0 +7e23d5645000-7e23d56ff000 r--p 00000000 103:03 17706492 /usr/share/fonts/TTF/DejaVuSans.ttf +7e23d56ff000-7e23d5700000 ---p 00000000 00:00 0 +7e23d5700000-7e23d5800000 rw-p 00000000 00:00 0 +7e23d5800000-7e23d5897000 r--p 00000000 103:03 16973669 /usr/lib/libstdc++.so.6.0.34 +7e23d5897000-7e23d59ec000 r-xp 00097000 103:03 16973669 /usr/lib/libstdc++.so.6.0.34 +7e23d59ec000-7e23d5a7e000 r--p 001ec000 103:03 16973669 /usr/lib/libstdc++.so.6.0.34 +7e23d5a7e000-7e23d5a8f000 r--p 0027e000 103:03 16973669 /usr/lib/libstdc++.so.6.0.34 +7e23d5a8f000-7e23d5a90000 rw-p 0028f000 103:03 16973669 /usr/lib/libstdc++.so.6.0.34 +7e23d5a90000-7e23d5a94000 rw-p 00000000 00:00 0 +7e23d5a99000-7e23d5b31000 r--p 00000000 103:03 17971621 /usr/share/fonts/noto/NotoSans-Regular.ttf +7e23d5b31000-7e23d5c00000 rw-p 00000000 00:00 0 +7e23d5c00000-7e23d5fbb000 r--s 00000000 103:03 39333467 /home/jay/.cache/fontconfig/923e285e415b1073c8df160bee08820f-le64.cache-9 +7e23d5fe8000-7e23d604d000 r--p 00000000 103:03 17977921 /usr/share/fonts/liberation/LiberationSans-Regular.ttf +7e23d604d000-7e23d624d000 rw-s 1b5975000 00:06 514 /dev/dri/renderD128 +7e23d624d000-7e23d6262000 r--p 00000000 103:03 17009291 /usr/lib/libSPIRV-Tools.so +7e23d6262000-7e23d6381000 r-xp 00015000 103:03 17009291 /usr/lib/libSPIRV-Tools.so +7e23d6381000-7e23d63fc000 r--p 00134000 103:03 17009291 /usr/lib/libSPIRV-Tools.so +7e23d63fc000-7e23d63ff000 r--p 001ae000 103:03 17009291 /usr/lib/libSPIRV-Tools.so +7e23d63ff000-7e23d6400000 rw-p 001b1000 103:03 17009291 /usr/lib/libSPIRV-Tools.so +7e23d6400000-7e23d6511000 r--p 00000000 103:03 39223286 /home/jay/.skiko/466d99514e1c05f31bc8556b637e21363d14da45e8215a739f8d1d8c22184704/libskiko-linux-x64.so +7e23d6511000-7e23d7196000 r-xp 00111000 103:03 39223286 /home/jay/.skiko/466d99514e1c05f31bc8556b637e21363d14da45e8215a739f8d1d8c22184704/libskiko-linux-x64.so +7e23d7196000-7e23d7e31000 r--p 00d96000 103:03 39223286 /home/jay/.skiko/466d99514e1c05f31bc8556b637e21363d14da45e8215a739f8d1d8c22184704/libskiko-linux-x64.so +7e23d7e31000-7e23d7e72000 r--p 01a30000 103:03 39223286 /home/jay/.skiko/466d99514e1c05f31bc8556b637e21363d14da45e8215a739f8d1d8c22184704/libskiko-linux-x64.so +7e23d7e72000-7e23d7e75000 rw-p 01a71000 103:03 39223286 /home/jay/.skiko/466d99514e1c05f31bc8556b637e21363d14da45e8215a739f8d1d8c22184704/libskiko-linux-x64.so +7e23d7e75000-7e23d7e81000 rw-p 00000000 00:00 0 +7e23d7ecb000-7e23d7ee5000 r--p 00000000 103:03 16926629 /usr/lib/libxml2.so.16.1.2 +7e23d7ee5000-7e23d7fb8000 r-xp 0001a000 103:03 16926629 /usr/lib/libxml2.so.16.1.2 +7e23d7fb8000-7e23d7ff5000 r--p 000ed000 103:03 16926629 /usr/lib/libxml2.so.16.1.2 +7e23d7ff5000-7e23d7ffe000 r--p 0012a000 103:03 16926629 /usr/lib/libxml2.so.16.1.2 +7e23d7ffe000-7e23d7fff000 rw-p 00133000 103:03 16926629 /usr/lib/libxml2.so.16.1.2 +7e23d7fff000-7e23d8021000 rw-p 00000000 00:00 0 +7e23d8021000-7e23dc000000 ---p 00000000 00:00 0 +7e23dc000000-7e23dc021000 rw-p 00000000 00:00 0 +7e23dc021000-7e23e0000000 ---p 00000000 00:00 0 +7e23e0000000-7e23e3ffb000 rw-p 00000000 00:00 0 +7e23e3ffb000-7e23e4000000 ---p 00000000 00:00 0 +7e23e4000000-7e23e4021000 rw-p 00000000 00:00 0 +7e23e4021000-7e23e8000000 ---p 00000000 00:00 0 +7e23e8000000-7e23e8025000 rw-p 00000000 00:00 0 +7e23e8025000-7e23ec000000 ---p 00000000 00:00 0 +7e23ec000000-7e23ec021000 rw-p 00000000 00:00 0 +7e23ec021000-7e23f0000000 ---p 00000000 00:00 0 +7e23f0000000-7e23f0720000 rw-p 00000000 00:00 0 +7e23f0720000-7e23f4000000 ---p 00000000 00:00 0 +7e23f4000000-7e23f4021000 rw-p 00000000 00:00 0 +7e23f4021000-7e23f8000000 ---p 00000000 00:00 0 +7e23f8000000-7e23f8461000 rw-p 00000000 00:00 0 +7e23f8461000-7e23fc000000 ---p 00000000 00:00 0 +7e23fc000000-7e23fc59a000 rw-p 00000000 00:00 0 +7e23fc59a000-7e2400000000 ---p 00000000 00:00 0 +7e2400000000-7e2400052000 rw-p 00000000 00:00 0 +7e2400052000-7e2404000000 ---p 00000000 00:00 0 +7e2404000000-7e240402e000 rw-p 00000000 00:00 0 +7e240402e000-7e2408000000 ---p 00000000 00:00 0 +7e2408000000-7e2408021000 rw-p 00000000 00:00 0 +7e2408021000-7e240c000000 ---p 00000000 00:00 0 +7e240c000000-7e240c025000 rw-p 00000000 00:00 0 +7e240c025000-7e2410000000 ---p 00000000 00:00 0 +7e2410000000-7e2410038000 rw-p 00000000 00:00 0 +7e2410038000-7e2414000000 ---p 00000000 00:00 0 +7e2414000000-7e241402e000 rw-p 00000000 00:00 0 +7e241402e000-7e2418000000 ---p 00000000 00:00 0 +7e2418000000-7e2418021000 rw-p 00000000 00:00 0 +7e2418021000-7e241c000000 ---p 00000000 00:00 0 +7e241c000000-7e241c021000 rw-p 00000000 00:00 0 +7e241c021000-7e2420000000 ---p 00000000 00:00 0 +7e2420000000-7e2420021000 rw-p 00000000 00:00 0 +7e2420021000-7e2424000000 ---p 00000000 00:00 0 +7e2424000000-7e2424021000 rw-p 00000000 00:00 0 +7e2424021000-7e2428000000 ---p 00000000 00:00 0 +7e2428000000-7e2428286000 rw-p 00000000 00:00 0 +7e2428286000-7e242c000000 ---p 00000000 00:00 0 +7e242c000000-7e242ce98000 rw-p 00000000 00:00 0 +7e242ce98000-7e2430000000 ---p 00000000 00:00 0 +7e2430000000-7e2430021000 rw-p 00000000 00:00 0 +7e2430021000-7e2434000000 ---p 00000000 00:00 0 +7e2434000000-7e2434021000 rw-p 00000000 00:00 0 +7e2434021000-7e2438000000 ---p 00000000 00:00 0 +7e2438000000-7e2439fd5000 rw-p 00000000 00:00 0 +7e2439fd5000-7e243c000000 ---p 00000000 00:00 0 +7e243c000000-7e243d41f000 rw-p 00000000 00:00 0 +7e243d41f000-7e2440000000 ---p 00000000 00:00 0 +7e2440000000-7e2440021000 rw-p 00000000 00:00 0 +7e2440021000-7e2444000000 ---p 00000000 00:00 0 +7e2444000000-7e2444021000 rw-p 00000000 00:00 0 +7e2444021000-7e2448000000 ---p 00000000 00:00 0 +7e2448000000-7e2448021000 rw-p 00000000 00:00 0 +7e2448021000-7e244c000000 ---p 00000000 00:00 0 +7e244c000000-7e244c021000 rw-p 00000000 00:00 0 +7e244c021000-7e2450000000 ---p 00000000 00:00 0 +7e2450000000-7e24513ab000 rw-p 00000000 00:00 0 +7e24513ab000-7e2454000000 ---p 00000000 00:00 0 +7e2454000000-7e2454021000 rw-p 00000000 00:00 0 +7e2454021000-7e2458000000 ---p 00000000 00:00 0 +7e2458000000-7e2458400000 rw-p 00000000 00:00 0 +7e2458400000-7e2458dc0000 rw-p 00000000 00:00 0 +7e2458dc0000-7e2458f00000 rw-p 00000000 00:00 0 +7e2458f00000-7e24591a0000 rw-p 00000000 00:00 0 +7e24591a0000-7e24591c0000 rw-p 00000000 00:00 0 +7e24591c0000-7e2459300000 rw-p 00000000 00:00 0 +7e2459300000-7e2459740000 rw-p 00000000 00:00 0 +7e2459740000-7e2459780000 rw-p 00000000 00:00 0 +7e2459780000-7e2459dc0000 rw-p 00000000 00:00 0 +7e2459dc0000-7e2459e00000 rw-p 00000000 00:00 0 +7e2459e00000-7e245a100000 rw-p 00000000 00:00 0 +7e245a100000-7e245a200000 rw-p 00000000 00:00 0 +7e245a200000-7e245a980000 rw-p 00000000 00:00 0 +7e245a980000-7e245aa00000 rw-p 00000000 00:00 0 +7e245aa00000-7e245adc0000 rw-p 00000000 00:00 0 +7e245adc0000-7e245ae00000 rw-p 00000000 00:00 0 +7e245ae00000-7e245af80000 rw-p 00000000 00:00 0 +7e245af80000-7e245b000000 rw-p 00000000 00:00 0 +7e245b000000-7e245b100000 rw-p 00000000 00:00 0 +7e245b100000-7e245b120000 rw-p 00000000 00:00 0 +7e245b120000-7e245b200000 ---p 00000000 00:00 0 +7e245b200000-7e245b230000 rw-p 00000000 00:00 0 +7e245b230000-7e245c000000 ---p 00000000 00:00 0 +7e245c000000-7e245c021000 rw-p 00000000 00:00 0 +7e245c021000-7e2460000000 ---p 00000000 00:00 0 +7e2460037000-7e2460044000 r--p 00000000 103:03 16912537 /usr/lib/libncursesw.so.6.6 +7e2460044000-7e246008c000 r-xp 0000d000 103:03 16912537 /usr/lib/libncursesw.so.6.6 +7e246008c000-7e24600a2000 r--p 00055000 103:03 16912537 /usr/lib/libncursesw.so.6.6 +7e24600a2000-7e24600a7000 r--p 0006a000 103:03 16912537 /usr/lib/libncursesw.so.6.6 +7e24600a7000-7e24600a8000 rw-p 0006f000 103:03 16912537 /usr/lib/libncursesw.so.6.6 +7e24600a8000-7e24600aa000 r--p 00000000 103:03 16953982 /usr/lib/libpciaccess.so.0.11.1 +7e24600aa000-7e24600af000 r-xp 00002000 103:03 16953982 /usr/lib/libpciaccess.so.0.11.1 +7e24600af000-7e24600b1000 r--p 00007000 103:03 16953982 /usr/lib/libpciaccess.so.0.11.1 +7e24600b1000-7e24600b2000 r--p 00008000 103:03 16953982 /usr/lib/libpciaccess.so.0.11.1 +7e24600b2000-7e24600b3000 rw-p 00009000 103:03 16953982 /usr/lib/libpciaccess.so.0.11.1 +7e24600b3000-7e24600b9000 r--p 00000000 103:03 16954053 /usr/lib/libedit.so.0.0.75 +7e24600b9000-7e24600da000 r-xp 00006000 103:03 16954053 /usr/lib/libedit.so.0.0.75 +7e24600da000-7e24600e7000 r--p 00027000 103:03 16954053 /usr/lib/libedit.so.0.0.75 +7e24600e7000-7e24600e9000 r--p 00034000 103:03 16954053 /usr/lib/libedit.so.0.0.75 +7e24600e9000-7e24600ea000 rw-p 00036000 103:03 16954053 /usr/lib/libedit.so.0.0.75 +7e24600ea000-7e24600ed000 rw-p 00000000 00:00 0 +7e24600ed000-7e24600ef000 r--p 00000000 103:03 16911744 /usr/lib/libffi.so.8.2.0 +7e24600ef000-7e24600f6000 r-xp 00002000 103:03 16911744 /usr/lib/libffi.so.8.2.0 +7e24600f6000-7e24600f7000 r--p 00009000 103:03 16911744 /usr/lib/libffi.so.8.2.0 +7e24600f7000-7e24600f8000 r--p 0000a000 103:03 16911744 /usr/lib/libffi.so.8.2.0 +7e24600f8000-7e24600f9000 rw-p 0000b000 103:03 16911744 /usr/lib/libffi.so.8.2.0 +7e24600f9000-7e24600fc000 r--p 00000000 103:03 16936348 /usr/lib/libdrm_intel.so.1.131.0 +7e24600fc000-7e2460113000 r-xp 00003000 103:03 16936348 /usr/lib/libdrm_intel.so.1.131.0 +7e2460113000-7e246011c000 r--p 0001a000 103:03 16936348 /usr/lib/libdrm_intel.so.1.131.0 +7e246011c000-7e246011d000 r--p 00023000 103:03 16936348 /usr/lib/libdrm_intel.so.1.131.0 +7e246011d000-7e246011e000 rw-p 00024000 103:03 16936348 /usr/lib/libdrm_intel.so.1.131.0 +7e246011e000-7e2460121000 r--p 00000000 103:03 16933848 /usr/lib/libdrm_amdgpu.so.1.131.0 +7e2460121000-7e2460127000 r-xp 00003000 103:03 16933848 /usr/lib/libdrm_amdgpu.so.1.131.0 +7e2460127000-7e2460129000 r--p 00009000 103:03 16933848 /usr/lib/libdrm_amdgpu.so.1.131.0 +7e2460129000-7e246012a000 r--p 0000a000 103:03 16933848 /usr/lib/libdrm_amdgpu.so.1.131.0 +7e246012a000-7e246012b000 rw-p 0000b000 103:03 16933848 /usr/lib/libdrm_amdgpu.so.1.131.0 +7e246012b000-7e246012e000 r--p 00000000 103:03 16932898 /usr/lib/libelf-0.194.so +7e246012e000-7e2460141000 r-xp 00003000 103:03 16932898 /usr/lib/libelf-0.194.so +7e2460141000-7e2460145000 r--p 00016000 103:03 16932898 /usr/lib/libelf-0.194.so +7e2460145000-7e2460146000 r--p 0001a000 103:03 16932898 /usr/lib/libelf-0.194.so +7e2460146000-7e2460147000 rw-p 0001b000 103:03 16932898 /usr/lib/libelf-0.194.so +7e2460147000-7e2460148000 r--p 00000000 103:03 16936921 /usr/lib/libxshmfence.so.1.0.0 +7e2460148000-7e2460149000 r-xp 00001000 103:03 16936921 /usr/lib/libxshmfence.so.1.0.0 +7e2460149000-7e246014a000 r--p 00002000 103:03 16936921 /usr/lib/libxshmfence.so.1.0.0 +7e246014a000-7e246014b000 r--p 00002000 103:03 16936921 /usr/lib/libxshmfence.so.1.0.0 +7e246014b000-7e246014c000 rw-p 00003000 103:03 16936921 /usr/lib/libxshmfence.so.1.0.0 +7e246014c000-7e246014f000 r--p 00000000 103:03 16948253 /usr/lib/libxcb-sync.so.1.0.0 +7e246014f000-7e2460152000 r-xp 00003000 103:03 16948253 /usr/lib/libxcb-sync.so.1.0.0 +7e2460152000-7e2460153000 r--p 00006000 103:03 16948253 /usr/lib/libxcb-sync.so.1.0.0 +7e2460153000-7e2460154000 r--p 00007000 103:03 16948253 /usr/lib/libxcb-sync.so.1.0.0 +7e2460154000-7e2460155000 rw-p 00008000 103:03 16948253 /usr/lib/libxcb-sync.so.1.0.0 +7e2460155000-7e246015c000 r--p 00000000 103:03 16948230 /usr/lib/libxcb-randr.so.0.1.0 +7e246015c000-7e2460162000 r-xp 00007000 103:03 16948230 /usr/lib/libxcb-randr.so.0.1.0 +7e2460162000-7e2460165000 r--p 0000d000 103:03 16948230 /usr/lib/libxcb-randr.so.0.1.0 +7e2460165000-7e2460166000 r--p 00010000 103:03 16948230 /usr/lib/libxcb-randr.so.0.1.0 +7e2460166000-7e2460167000 rw-p 00011000 103:03 16948230 /usr/lib/libxcb-randr.so.0.1.0 +7e2460167000-7e2460169000 r--p 00000000 103:03 16954118 /usr/lib/libsensors.so.5.0.0 +7e2460169000-7e2460171000 r-xp 00002000 103:03 16954118 /usr/lib/libsensors.so.5.0.0 +7e2460171000-7e2460175000 r--p 0000a000 103:03 16954118 /usr/lib/libsensors.so.5.0.0 +7e2460175000-7e2460176000 r--p 0000e000 103:03 16954118 /usr/lib/libsensors.so.5.0.0 +7e2460176000-7e2460177000 rw-p 0000f000 103:03 16954118 /usr/lib/libsensors.so.5.0.0 +7e2460177000-7e2460183000 r--p 00000000 103:03 16923660 /usr/lib/libzstd.so.1.5.7 +7e2460183000-7e246024a000 r-xp 0000c000 103:03 16923660 /usr/lib/libzstd.so.1.5.7 +7e246024a000-7e246025b000 r--p 000d3000 103:03 16923660 /usr/lib/libzstd.so.1.5.7 +7e246025b000-7e246025c000 r--p 000e4000 103:03 16923660 /usr/lib/libzstd.so.1.5.7 +7e246025c000-7e246025d000 rw-p 000e5000 103:03 16923660 /usr/lib/libzstd.so.1.5.7 +7e246025d000-7e2460261000 r--p 00000000 103:03 16973667 /usr/lib/libgcc_s.so.1 +7e2460261000-7e2460284000 r-xp 00004000 103:03 16973667 /usr/lib/libgcc_s.so.1 +7e2460284000-7e2460288000 r--p 00027000 103:03 16973667 /usr/lib/libgcc_s.so.1 +7e2460288000-7e2460289000 r--p 0002a000 103:03 16973667 /usr/lib/libgcc_s.so.1 +7e2460289000-7e246028a000 rw-p 0002b000 103:03 16973667 /usr/lib/libgcc_s.so.1 +7e246028a000-7e246028d000 r--p 00000000 103:03 16948259 /usr/lib/libxcb-xfixes.so.0.0.0 +7e246028d000-7e2460290000 r-xp 00003000 103:03 16948259 /usr/lib/libxcb-xfixes.so.0.0.0 +7e2460290000-7e2460291000 r--p 00006000 103:03 16948259 /usr/lib/libxcb-xfixes.so.0.0.0 +7e2460291000-7e2460292000 r--p 00007000 103:03 16948259 /usr/lib/libxcb-xfixes.so.0.0.0 +7e2460292000-7e2460293000 rw-p 00008000 103:03 16948259 /usr/lib/libxcb-xfixes.so.0.0.0 +7e2460293000-7e2460294000 r--p 00000000 103:03 16948227 /usr/lib/libxcb-present.so.0.0.0 +7e2460294000-7e2460295000 r-xp 00001000 103:03 16948227 /usr/lib/libxcb-present.so.0.0.0 +7e2460295000-7e2460296000 r--p 00002000 103:03 16948227 /usr/lib/libxcb-present.so.0.0.0 +7e2460296000-7e2460297000 r--p 00002000 103:03 16948227 /usr/lib/libxcb-present.so.0.0.0 +7e2460297000-7e2460298000 rw-p 00003000 103:03 16948227 /usr/lib/libxcb-present.so.0.0.0 +7e2460298000-7e246029a000 r--p 00000000 103:03 16948221 /usr/lib/libxcb-dri3.so.0.1.0 +7e246029a000-7e246029c000 r-xp 00002000 103:03 16948221 /usr/lib/libxcb-dri3.so.0.1.0 +7e246029c000-7e246029d000 r--p 00004000 103:03 16948221 /usr/lib/libxcb-dri3.so.0.1.0 +7e246029d000-7e246029e000 r--p 00004000 103:03 16948221 /usr/lib/libxcb-dri3.so.0.1.0 +7e246029e000-7e246029f000 rw-p 00005000 103:03 16948221 /usr/lib/libxcb-dri3.so.0.1.0 +7e246029f000-7e24602a0000 r--p 00000000 103:03 16948250 /usr/lib/libxcb-shm.so.0.0.0 +7e24602a0000-7e24602a1000 r-xp 00001000 103:03 16948250 /usr/lib/libxcb-shm.so.0.0.0 +7e24602a1000-7e24602a2000 r--p 00002000 103:03 16948250 /usr/lib/libxcb-shm.so.0.0.0 +7e24602a2000-7e24602a3000 r--p 00002000 103:03 16948250 /usr/lib/libxcb-shm.so.0.0.0 +7e24602a3000-7e24602a4000 rw-p 00003000 103:03 16948250 /usr/lib/libxcb-shm.so.0.0.0 +7e24602a4000-7e24602a5000 r--p 00000000 103:03 16936925 /usr/lib/libXxf86vm.so.1.0.0 +7e24602a5000-7e24602a8000 r-xp 00001000 103:03 16936925 /usr/lib/libXxf86vm.so.1.0.0 +7e24602a8000-7e24602a9000 r--p 00004000 103:03 16936925 /usr/lib/libXxf86vm.so.1.0.0 +7e24602a9000-7e24602aa000 r--p 00004000 103:03 16936925 /usr/lib/libXxf86vm.so.1.0.0 +7e24602aa000-7e24602ab000 rw-p 00005000 103:03 16936925 /usr/lib/libXxf86vm.so.1.0.0 +7e24602ab000-7e24602ac000 r--p 00000000 103:03 16911708 /usr/lib/libX11-xcb.so.1.0.0 +7e24602ac000-7e24602ad000 r-xp 00001000 103:03 16911708 /usr/lib/libX11-xcb.so.1.0.0 +7e24602ad000-7e24602ae000 r--p 00002000 103:03 16911708 /usr/lib/libX11-xcb.so.1.0.0 +7e24602ae000-7e24602af000 r--p 00002000 103:03 16911708 /usr/lib/libX11-xcb.so.1.0.0 +7e24602af000-7e24602b0000 rw-p 00003000 103:03 16911708 /usr/lib/libX11-xcb.so.1.0.0 +7e24602b0000-7e24602bc000 r--p 00000000 103:03 16948224 /usr/lib/libxcb-glx.so.0.0.0 +7e24602bc000-7e24602c5000 r-xp 0000c000 103:03 16948224 /usr/lib/libxcb-glx.so.0.0.0 +7e24602c5000-7e24602ca000 r--p 00015000 103:03 16948224 /usr/lib/libxcb-glx.so.0.0.0 +7e24602ca000-7e24602cc000 r--p 0001a000 103:03 16948224 /usr/lib/libxcb-glx.so.0.0.0 +7e24602cc000-7e24602cd000 rw-p 0001c000 103:03 16948224 /usr/lib/libxcb-glx.so.0.0.0 +7e24602cd000-7e24602d2000 r--p 00000000 103:03 16931584 /usr/lib/libdrm.so.2.131.0 +7e24602d2000-7e24602de000 r-xp 00005000 103:03 16931584 /usr/lib/libdrm.so.2.131.0 +7e24602de000-7e24602e2000 r--p 00011000 103:03 16931584 /usr/lib/libdrm.so.2.131.0 +7e24602e2000-7e24602e3000 r--p 00015000 103:03 16931584 /usr/lib/libdrm.so.2.131.0 +7e24602e3000-7e24602e4000 rw-p 00016000 103:03 16931584 /usr/lib/libdrm.so.2.131.0 +7e24602e4000-7e24602e9000 r--p 00000000 103:03 17012417 /usr/lib/libGLX_mesa.so.0.0.0 +7e24602e9000-7e2460328000 r-xp 00005000 103:03 17012417 /usr/lib/libGLX_mesa.so.0.0.0 +7e2460328000-7e2460337000 r--p 00044000 103:03 17012417 /usr/lib/libGLX_mesa.so.0.0.0 +7e2460337000-7e246033b000 r--p 00053000 103:03 17012417 /usr/lib/libGLX_mesa.so.0.0.0 +7e246033b000-7e246033c000 rw-p 00057000 103:03 17012417 /usr/lib/libGLX_mesa.so.0.0.0 +7e246037f000-7e2460381000 r--p 00000000 103:03 16952756 /usr/lib/libXrandr.so.2.2.0 +7e2460381000-7e2460388000 r-xp 00002000 103:03 16952756 /usr/lib/libXrandr.so.2.2.0 +7e2460388000-7e246038a000 r--p 00009000 103:03 16952756 /usr/lib/libXrandr.so.2.2.0 +7e246038a000-7e246038b000 r--p 0000a000 103:03 16952756 /usr/lib/libXrandr.so.2.2.0 +7e246038b000-7e246038c000 rw-p 0000b000 103:03 16952756 /usr/lib/libXrandr.so.2.2.0 +7e246038c000-7e2460393000 r--s 00000000 103:03 16973516 /usr/lib/gconv/gconv-modules.cache +7e2460393000-7e246039d000 r--s 00000000 103:03 5243212 /var/cache/fontconfig/8087dfd67547a1134e1b315c0e6294c3-le64.cache-9 +7e246039d000-7e24603b6000 r--s 00000000 103:03 5243211 /var/cache/fontconfig/ffabee0e3ed22a06206923f7fac5e1c0-le64.cache-9 +7e24603b6000-7e24603bf000 r--s 00000000 103:03 5243210 /var/cache/fontconfig/9f18a0df8bc37d83c3ea2376c06ff3af-le64.cache-9 +7e24603bf000-7e24603cb000 r--s 00000000 103:03 5243209 /var/cache/fontconfig/25af1fc25f11a29b4bde933093acd51c-le64.cache-9 +7e24603cb000-7e2460550000 r--s 00000000 103:03 39335005 /home/jay/.cache/fontconfig/f6b893a7224233d96cb72fd88691c0b4-le64.cache-9 +7e2460550000-7e2460551000 r--p 00000000 103:03 43004326 /home/jay/.jdks/corretto-22.0.2/lib/libjawt.so +7e2460551000-7e2460552000 r-xp 00001000 103:03 43004326 /home/jay/.jdks/corretto-22.0.2/lib/libjawt.so +7e2460552000-7e2460553000 r--p 00002000 103:03 43004326 /home/jay/.jdks/corretto-22.0.2/lib/libjawt.so +7e2460553000-7e2460554000 r--p 00002000 103:03 43004326 /home/jay/.jdks/corretto-22.0.2/lib/libjawt.so +7e2460554000-7e2460555000 rw-p 00003000 103:03 43004326 /home/jay/.jdks/corretto-22.0.2/lib/libjawt.so +7e2460555000-7e2460560000 r--s 00000000 103:03 5243208 /var/cache/fontconfig/2b34ab0a2048ea31d208a7dc116fb2f3-le64.cache-9 +7e2460560000-7e246056b000 r--s 00000000 103:03 5243203 /var/cache/fontconfig/742beb53257c10cf578c07a0f3b00110-le64.cache-9 +7e246056b000-7e2460576000 r--s 00000000 103:03 5243207 /var/cache/fontconfig/cb60976e0ef8d2b17a86838bea532586-le64.cache-9 +7e2460576000-7e246057d000 r--s 00000000 103:03 5244438 /var/cache/fontconfig/c488c95632d3bf326c948e34838d9b57-le64.cache-9 +7e246057d000-7e2460584000 r--s 00000000 103:03 5244437 /var/cache/fontconfig/8a9acce1fb8173e5096d63cadc805c92-le64.cache-9 +7e2460584000-7e246058b000 r--s 00000000 103:03 5244436 /var/cache/fontconfig/46d0b1e646ac3c520992f299c2a9565f-le64.cache-9 +7e246058b000-7e2460592000 r--s 00000000 103:03 5243206 /var/cache/fontconfig/ef84841d405c3d1c8f3cc9c5c80f72c8-le64.cache-9 +7e2460592000-7e2460599000 r--s 00000000 103:03 5244426 /var/cache/fontconfig/d2f34b238ab15d7986deba254baa22c8-le64.cache-9 +7e2460599000-7e24605a0000 r--s 00000000 103:03 5244425 /var/cache/fontconfig/852d1d586dcb28a45640045b11665e85-le64.cache-9 +7e24605a0000-7e24605a7000 r--s 00000000 103:03 5244424 /var/cache/fontconfig/32f5da95e08dfda9d3d17b00b782dc98-le64.cache-9 +7e24605a7000-7e24605ae000 r--s 00000000 103:03 5243205 /var/cache/fontconfig/c3dd6fe964cc3c37b8a3c31c42b79fa7-le64.cache-9 +7e24605ae000-7e24605b5000 r--s 00000000 103:03 5244388 /var/cache/fontconfig/ac33d189200bae18b4ff8e229303c204-le64.cache-9 +7e24605b5000-7e24605bc000 r--s 00000000 103:03 5244387 /var/cache/fontconfig/1cede17219e8e2ce9b2cc7eeedf2db43-le64.cache-9 +7e24605bc000-7e24605c3000 r--s 00000000 103:03 5244386 /var/cache/fontconfig/7ede60ef7d4fba6340b3d43d4f24cca2-le64.cache-9 +7e24605c3000-7e24605ca000 r--s 00000000 103:03 5243204 /var/cache/fontconfig/f42fc0118cf8ebb47dc2bc009e27f80a-le64.cache-9 +7e24605ca000-7e24606b8000 r--s 00000000 103:03 5244380 /var/cache/fontconfig/6d006ae94db972f3bc99bc2999c017b0-le64.cache-9 +7e24606b8000-7e24606e0000 r--s 00000000 103:03 5244379 /var/cache/fontconfig/f2e43df3287529323e79e7929dc44cc9-le64.cache-9 +7e24606e0000-7e246077c000 r--s 00000000 103:03 5244041 /var/cache/fontconfig/17090aa38d5c6f09fb8c5c354938f1d7-le64.cache-9 +7e246077c000-7e2460818000 r--s 00000000 103:03 5243969 /var/cache/fontconfig/df311e82a1a24c41a75c2c930223552e-le64.cache-9 +7e2460818000-7e2460819000 ---p 00000000 00:00 0 +7e2460819000-7e246081d000 ---p 00000000 00:00 0 +7e246081d000-7e2460919000 rw-p 00000000 00:00 0 +7e2460919000-7e246091a000 ---p 00000000 00:00 0 +7e246091a000-7e246091e000 ---p 00000000 00:00 0 +7e246091e000-7e2460a1a000 rw-p 00000000 00:00 0 +7e2460a1a000-7e2460a1b000 ---p 00000000 00:00 0 +7e2460a1b000-7e2460a1f000 ---p 00000000 00:00 0 +7e2460a1f000-7e2460b1b000 rw-p 00000000 00:00 0 +7e2460b1b000-7e2460b1c000 ---p 00000000 00:00 0 +7e2460b1c000-7e2460b20000 ---p 00000000 00:00 0 +7e2460b20000-7e2460c1c000 rw-p 00000000 00:00 0 +7e2460c1c000-7e2460c1d000 ---p 00000000 00:00 0 +7e2460c1d000-7e2460c21000 ---p 00000000 00:00 0 +7e2460c21000-7e2460d1d000 rw-p 00000000 00:00 0 +7e2460d1d000-7e2460d1e000 ---p 00000000 00:00 0 +7e2460d1e000-7e2460d22000 ---p 00000000 00:00 0 +7e2460d22000-7e2460e1e000 rw-p 00000000 00:00 0 +7e2460e1e000-7e2460e1f000 r--p 00000000 103:03 16928316 /usr/lib/libbrotlicommon.so.1.2.0 +7e2460e1f000-7e2460e20000 r-xp 00001000 103:03 16928316 /usr/lib/libbrotlicommon.so.1.2.0 +7e2460e20000-7e2460e3f000 r--p 00002000 103:03 16928316 /usr/lib/libbrotlicommon.so.1.2.0 +7e2460e3f000-7e2460e40000 r--p 00021000 103:03 16928316 /usr/lib/libbrotlicommon.so.1.2.0 +7e2460e40000-7e2460e41000 rw-p 00022000 103:03 16928316 /usr/lib/libbrotlicommon.so.1.2.0 +7e2460e41000-7e2460e47000 r--p 00000000 103:03 16938906 /usr/lib/libpng16.so.16.55.0 +7e2460e47000-7e2460e71000 r-xp 00006000 103:03 16938906 /usr/lib/libpng16.so.16.55.0 +7e2460e71000-7e2460e7a000 r--p 00030000 103:03 16938906 /usr/lib/libpng16.so.16.55.0 +7e2460e7a000-7e2460e7b000 r--p 00039000 103:03 16938906 /usr/lib/libpng16.so.16.55.0 +7e2460e7b000-7e2460e7c000 rw-p 0003a000 103:03 16938906 /usr/lib/libpng16.so.16.55.0 +7e2460e7c000-7e2460e7e000 r--p 00000000 103:03 16924587 /usr/lib/libexpat.so.1.11.2 +7e2460e7e000-7e2460e9c000 r-xp 00002000 103:03 16924587 /usr/lib/libexpat.so.1.11.2 +7e2460e9c000-7e2460ea4000 r--p 00020000 103:03 16924587 /usr/lib/libexpat.so.1.11.2 +7e2460ea4000-7e2460ea6000 r--p 00028000 103:03 16924587 /usr/lib/libexpat.so.1.11.2 +7e2460ea6000-7e2460ea7000 rw-p 0002a000 103:03 16924587 /usr/lib/libexpat.so.1.11.2 +7e2460ea7000-7e2460ead000 r--p 00000000 103:03 16965904 /usr/lib/libfreetype.so.6.20.4 +7e2460ead000-7e2460f45000 r-xp 00006000 103:03 16965904 /usr/lib/libfreetype.so.6.20.4 +7e2460f45000-7e2460f6e000 r--p 0009e000 103:03 16965904 /usr/lib/libfreetype.so.6.20.4 +7e2460f6e000-7e2460f76000 r--p 000c6000 103:03 16965904 /usr/lib/libfreetype.so.6.20.4 +7e2460f76000-7e2460f77000 rw-p 000ce000 103:03 16965904 /usr/lib/libfreetype.so.6.20.4 +7e2460f77000-7e2460f79000 r--p 00000000 103:03 16954228 /usr/lib/libGLX.so.0.0.0 +7e2460f79000-7e2460f93000 r-xp 00002000 103:03 16954228 /usr/lib/libGLX.so.0.0.0 +7e2460f93000-7e2460f96000 r--p 0001c000 103:03 16954228 /usr/lib/libGLX.so.0.0.0 +7e2460f96000-7e2460f97000 r--p 0001f000 103:03 16954228 /usr/lib/libGLX.so.0.0.0 +7e2460f97000-7e2460f98000 rw-p 00020000 103:03 16954228 /usr/lib/libGLX.so.0.0.0 +7e2460f98000-7e2460fa8000 rw-p 00000000 00:00 0 +7e2460fa8000-7e2460faa000 r--p 00000000 103:03 16954232 /usr/lib/libGLdispatch.so.0.0.0 +7e2460faa000-7e2460fe9000 r-xp 00002000 103:03 16954232 /usr/lib/libGLdispatch.so.0.0.0 +7e2460fe9000-7e2460ffc000 r--p 00041000 103:03 16954232 /usr/lib/libGLdispatch.so.0.0.0 +7e2460ffc000-7e2461018000 r--p 00054000 103:03 16954232 /usr/lib/libGLdispatch.so.0.0.0 +7e2461018000-7e2461019000 rw-p 00070000 103:03 16954232 /usr/lib/libGLdispatch.so.0.0.0 +7e2461019000-7e2461021000 rw-p 00000000 00:00 0 +7e2461021000-7e2461050000 r--p 00000000 103:03 16954218 /usr/lib/libGL.so.1.7.0 +7e2461050000-7e246106f000 r-xp 0002f000 103:03 16954218 /usr/lib/libGL.so.1.7.0 +7e246106f000-7e2461083000 r--p 0004e000 103:03 16954218 /usr/lib/libGL.so.1.7.0 +7e2461083000-7e2461091000 r--p 00062000 103:03 16954218 /usr/lib/libGL.so.1.7.0 +7e2461091000-7e2461092000 rw-p 00070000 103:03 16954218 /usr/lib/libGL.so.1.7.0 +7e2461092000-7e2461093000 rw-p 00000000 00:00 0 +7e2461093000-7e2461094000 ---p 00000000 00:00 0 +7e2461094000-7e2461194000 rw-p 00000000 00:00 0 +7e2461194000-7e2461195000 ---p 00000000 00:00 0 +7e2461195000-7e2461295000 rw-p 00000000 00:00 0 +7e2461295000-7e2461296000 ---p 00000000 00:00 0 +7e2461296000-7e2461396000 rw-p 00000000 00:00 0 +7e2461396000-7e2461397000 ---p 00000000 00:00 0 +7e2461397000-7e246139b000 ---p 00000000 00:00 0 +7e246139b000-7e2461497000 rw-p 00000000 00:00 0 +7e2461497000-7e2461498000 ---p 00000000 00:00 0 +7e2461498000-7e246149c000 ---p 00000000 00:00 0 +7e246149c000-7e2461598000 rw-p 00000000 00:00 0 +7e2461598000-7e2461599000 ---p 00000000 00:00 0 +7e2461599000-7e246159d000 ---p 00000000 00:00 0 +7e246159d000-7e2461699000 rw-p 00000000 00:00 0 +7e2461699000-7e246169a000 ---p 00000000 00:00 0 +7e246169a000-7e246169e000 ---p 00000000 00:00 0 +7e246169e000-7e246179a000 rw-p 00000000 00:00 0 +7e246179a000-7e24617a5000 r--p 00000000 103:03 43004324 /home/jay/.jdks/corretto-22.0.2/lib/libfreetype.so +7e24617a5000-7e2461817000 r-xp 0000b000 103:03 43004324 /home/jay/.jdks/corretto-22.0.2/lib/libfreetype.so +7e2461817000-7e2461839000 r--p 0007d000 103:03 43004324 /home/jay/.jdks/corretto-22.0.2/lib/libfreetype.so +7e2461839000-7e246183f000 r--p 0009f000 103:03 43004324 /home/jay/.jdks/corretto-22.0.2/lib/libfreetype.so +7e246183f000-7e2461840000 rw-p 000a5000 103:03 43004324 /home/jay/.jdks/corretto-22.0.2/lib/libfreetype.so +7e2461840000-7e2461847000 r--p 00000000 103:03 43004323 /home/jay/.jdks/corretto-22.0.2/lib/libfontmanager.so +7e2461847000-7e246198a000 r-xp 00007000 103:03 43004323 /home/jay/.jdks/corretto-22.0.2/lib/libfontmanager.so +7e246198a000-7e24619c6000 r--p 0014a000 103:03 43004323 /home/jay/.jdks/corretto-22.0.2/lib/libfontmanager.so +7e24619c6000-7e24619c8000 r--p 00186000 103:03 43004323 /home/jay/.jdks/corretto-22.0.2/lib/libfontmanager.so +7e24619c8000-7e24619c9000 rw-p 00188000 103:03 43004323 /home/jay/.jdks/corretto-22.0.2/lib/libfontmanager.so +7e24619c9000-7e24619ca000 rw-p 00000000 00:00 0 +7e24619ca000-7e24619e1000 r--p 00000000 103:03 16923808 /usr/lib/libX11.so.6.4.0 +7e24619e1000-7e2461a76000 r-xp 00017000 103:03 16923808 /usr/lib/libX11.so.6.4.0 +7e2461a76000-7e2461b05000 r--p 000ac000 103:03 16923808 /usr/lib/libX11.so.6.4.0 +7e2461b05000-7e2461b08000 r--p 0013a000 103:03 16923808 /usr/lib/libX11.so.6.4.0 +7e2461b08000-7e2461b0c000 rw-p 0013d000 103:03 16923808 /usr/lib/libX11.so.6.4.0 +7e2461b0c000-7e2461b2b000 r--p 00000000 103:03 43004320 /home/jay/.jdks/corretto-22.0.2/lib/libawt.so +7e2461b2b000-7e2461bc2000 r-xp 0001f000 103:03 43004320 /home/jay/.jdks/corretto-22.0.2/lib/libawt.so +7e2461bc2000-7e2461bcf000 r--p 000b6000 103:03 43004320 /home/jay/.jdks/corretto-22.0.2/lib/libawt.so +7e2461bcf000-7e2461bd0000 r--p 000c2000 103:03 43004320 /home/jay/.jdks/corretto-22.0.2/lib/libawt.so +7e2461bd0000-7e2461bdb000 rw-p 000c3000 103:03 43004320 /home/jay/.jdks/corretto-22.0.2/lib/libawt.so +7e2461bdb000-7e2461c00000 rw-p 00000000 00:00 0 +7e2461c00000-7e2461cdf000 r-xp 00000000 00:2e 85016 /tmp/sqlite-3.34.0-224d6dc6-ab02-412e-96d2-aecc838a44c8-libsqlitejdbc.so +7e2461cdf000-7e2461ede000 ---p 000df000 00:2e 85016 /tmp/sqlite-3.34.0-224d6dc6-ab02-412e-96d2-aecc838a44c8-libsqlitejdbc.so +7e2461ede000-7e2461ee5000 rw-p 000de000 00:2e 85016 /tmp/sqlite-3.34.0-224d6dc6-ab02-412e-96d2-aecc838a44c8-libsqlitejdbc.so +7e2461ee9000-7e2461eef000 r--s 00000000 103:03 5244440 /var/cache/fontconfig/7491cb2ac7fc5b2a9d11049a14736625-le64.cache-9 +7e2461eef000-7e2461eff000 r--s 00000000 103:03 5244124 /var/cache/fontconfig/8d4af663993b81a124ee82e610bb31f9-le64.cache-9 +7e2462000000-7e2462c75000 rw-p 00001000 103:03 43004318 /home/jay/.jdks/corretto-22.0.2/lib/server/classes.jsa +7e2462c75000-7e2463000000 ---p 00000000 00:00 0 +7e2463000000-7e2463040000 rw-p 00000000 00:00 0 +7e2463040000-7e2463080000 rw-p 00000000 00:00 0 +7e2463080000-7e24631c0000 rw-p 00000000 00:00 0 +7e24631c0000-7e2463200000 rw-p 00000000 00:00 0 +7e2463200000-7e2463240000 rw-p 00000000 00:00 0 +7e2463240000-7e2463280000 rw-p 00000000 00:00 0 +7e2463280000-7e24633c0000 rw-p 00000000 00:00 0 +7e24633c0000-7e24633f0000 rw-p 00000000 00:00 0 +7e24633f0000-7e2463400000 ---p 00000000 00:00 0 +7e2463400000-7e24635a0000 rw-p 00000000 00:00 0 +7e24635a0000-7e24a3000000 ---p 00000000 00:00 0 +7e24a3001000-7e24a3002000 rw-s 00000000 00:01 685560 /memfd:xshmfence (deleted) +7e24a3002000-7e24a300f000 r--s 00000000 103:03 5244439 /var/cache/fontconfig/e95b4d59d280a3acdc6fb85954763694-le64.cache-9 +7e24a300f000-7e24a3010000 r--p 00000000 103:03 16928323 /usr/lib/libbrotlidec.so.1.2.0 +7e24a3010000-7e24a3019000 r-xp 00001000 103:03 16928323 /usr/lib/libbrotlidec.so.1.2.0 +7e24a3019000-7e24a301c000 r--p 0000a000 103:03 16928323 /usr/lib/libbrotlidec.so.1.2.0 +7e24a301c000-7e24a301d000 r--p 0000c000 103:03 16928323 /usr/lib/libbrotlidec.so.1.2.0 +7e24a301d000-7e24a301e000 rw-p 0000d000 103:03 16928323 /usr/lib/libbrotlidec.so.1.2.0 +7e24a301e000-7e24a3024000 r--p 00000000 103:03 16933068 /usr/lib/libfontconfig.so.1.16.0 +7e24a3024000-7e24a3055000 r-xp 00006000 103:03 16933068 /usr/lib/libfontconfig.so.1.16.0 +7e24a3055000-7e24a306c000 r--p 00037000 103:03 16933068 /usr/lib/libfontconfig.so.1.16.0 +7e24a306c000-7e24a306e000 r--p 0004d000 103:03 16933068 /usr/lib/libfontconfig.so.1.16.0 +7e24a306e000-7e24a306f000 rw-p 0004f000 103:03 16933068 /usr/lib/libfontconfig.so.1.16.0 +7e24a306f000-7e24a307b000 r--p 00000000 103:03 16948281 /usr/lib/libxcb.so.1.1.0 +7e24a307b000-7e24a308f000 r-xp 0000c000 103:03 16948281 /usr/lib/libxcb.so.1.1.0 +7e24a308f000-7e24a3098000 r--p 00020000 103:03 16948281 /usr/lib/libxcb.so.1.1.0 +7e24a3098000-7e24a3099000 r--p 00028000 103:03 16948281 /usr/lib/libxcb.so.1.1.0 +7e24a3099000-7e24a309a000 rw-p 00029000 103:03 16948281 /usr/lib/libxcb.so.1.1.0 +7e24a309a000-7e24a309b000 rw-s 00000000 00:01 679848 /memfd:xshmfence (deleted) +7e24a309b000-7e24a309c000 rw-s 21507f000 00:06 514 /dev/dri/renderD128 +7e24a309c000-7e24a30a2000 r--s 00000000 103:03 5244103 /var/cache/fontconfig/b67b32625a2bb51b023d3814a918f351-le64.cache-9 +7e24a30a2000-7e24a30b2000 r--s 00000000 103:03 5244093 /var/cache/fontconfig/491f45a0a771fef1c10b9b647a97fb82-le64.cache-9 +7e24a30b2000-7e24a30c6000 r--s 00000000 103:03 5243942 /var/cache/fontconfig/614d1caaa4d7914789410f6367de37ca-le64.cache-9 +7e24a30c6000-7e24a30d5000 r--s 00000000 103:03 5244091 /var/cache/fontconfig/1dce2cb908b447e938fc03acd9b47fcf-le64.cache-9 +7e24a30d5000-7e24a30db000 r--s 00000000 103:03 5244086 /var/cache/fontconfig/aaac3452274625c4167ca2eab9cb5e70-le64.cache-9 +7e24a30db000-7e24a30e6000 r--s 00000000 103:03 39336607 /home/jay/.cache/fontconfig/4b31aef11cb0687b6d280d34cbe23592-le64.cache-9 +7e24a30e6000-7e24a30e7000 rw-s 11a598000 00:06 514 /dev/dri/renderD128 +7e24a30e7000-7e24a30e8000 rw-s 19ea35000 00:06 514 /dev/dri/renderD128 +7e24a30e8000-7e24a30ea000 r--s 00000000 103:03 5244085 /var/cache/fontconfig/4c31730dec557ab86b580f3ca5555446-le64.cache-9 +7e24a30ea000-7e24a30ed000 r--s 00000000 103:03 5244084 /var/cache/fontconfig/6ba42ae0000f58711b5caaf10d690066-le64.cache-9 +7e24a30ed000-7e24a30ef000 r--s 00000000 103:03 5244073 /var/cache/fontconfig/3f1df0fe0284fef7cc33df8b1d039122-le64.cache-9 +7e24a30ef000-7e24a30f1000 r--s 00000000 103:03 5244072 /var/cache/fontconfig/bfb830de4b3e0bf031b5adbbfd7ab8e8-le64.cache-9 +7e24a30f1000-7e24a30f2000 ---p 00000000 00:00 0 +7e24a30f2000-7e24a30f6000 ---p 00000000 00:00 0 +7e24a30f6000-7e24a31f2000 rw-p 00000000 00:00 0 +7e24a31f2000-7e24a31f3000 ---p 00000000 00:00 0 +7e24a31f3000-7e24a32f3000 rw-p 00000000 00:00 0 +7e24a32f3000-7e24a32f4000 ---p 00000000 00:00 0 +7e24a32f4000-7e24a33f4000 rw-p 00000000 00:00 0 +7e24a33f4000-7e24a33f5000 ---p 00000000 00:00 0 +7e24a33f5000-7e24a34f5000 rw-p 00000000 00:00 0 +7e24a34f5000-7e24a34f6000 ---p 00000000 00:00 0 +7e24a34f6000-7e24a35f6000 rw-p 00000000 00:00 0 +7e24a35f6000-7e24a35f7000 ---p 00000000 00:00 0 +7e24a35f7000-7e24a36f7000 rw-p 00000000 00:00 0 +7e24a36f7000-7e24a36f8000 ---p 00000000 00:00 0 +7e24a36f8000-7e24a37f8000 rw-p 00000000 00:00 0 +7e24a37f8000-7e24a37f9000 ---p 00000000 00:00 0 +7e24a37f9000-7e24a38f9000 rw-p 00000000 00:00 0 +7e24a38f9000-7e24a38fa000 ---p 00000000 00:00 0 +7e24a38fa000-7e24a39fa000 rw-p 00000000 00:00 0 +7e24a39fa000-7e24a39fb000 ---p 00000000 00:00 0 +7e24a39fb000-7e24a3afb000 rw-p 00000000 00:00 0 +7e24a3afb000-7e24a3afc000 ---p 00000000 00:00 0 +7e24a3afc000-7e24a3bfc000 rw-p 00000000 00:00 0 +7e24a3bfc000-7e24a3bfd000 ---p 00000000 00:00 0 +7e24a3bfd000-7e24a3c01000 ---p 00000000 00:00 0 +7e24a3c01000-7e24a3cfd000 rw-p 00000000 00:00 0 +7e24a3cfd000-7e24a3cfe000 ---p 00000000 00:00 0 +7e24a3cfe000-7e24a3d02000 ---p 00000000 00:00 0 +7e24a3d02000-7e24a3dfe000 rw-p 00000000 00:00 0 +7e24a3dfe000-7e24a3dff000 ---p 00000000 00:00 0 +7e24a3dff000-7e24a3e03000 ---p 00000000 00:00 0 +7e24a3e03000-7e24a3eff000 rw-p 00000000 00:00 0 +7e24a3eff000-7e24a3f00000 ---p 00000000 00:00 0 +7e24a3f00000-7e24a3f04000 ---p 00000000 00:00 0 +7e24a3f04000-7e24a4000000 rw-p 00000000 00:00 0 +7e24a4000000-7e24a4021000 rw-p 00000000 00:00 0 +7e24a4021000-7e24a8000000 ---p 00000000 00:00 0 +7e24a8000000-7e24a8021000 rw-p 00000000 00:00 0 +7e24a8021000-7e24ac000000 ---p 00000000 00:00 0 +7e24ac000000-7e24ac021000 rw-p 00000000 00:00 0 +7e24ac021000-7e24b0000000 ---p 00000000 00:00 0 +7e24b0000000-7e24b0021000 rw-p 00000000 00:00 0 +7e24b0021000-7e24b4000000 ---p 00000000 00:00 0 +7e24b4000000-7e24b4034000 rw-p 00000000 00:00 0 +7e24b4034000-7e24b8000000 ---p 00000000 00:00 0 +7e24b8000000-7e24b8001000 r--s 00000000 103:03 39334777 /home/jay/.cache/fontconfig/e502d8dd850f51a8c8eaee3fe9b9ee87-le64.cache-9 +7e24b8001000-7e24b8008000 r--s 00000000 103:03 39337150 /home/jay/.cache/fontconfig/90704cb24f1756612f7baca861e90f4b-le64.cache-9 +7e24b8008000-7e24b800a000 r--p 00000000 103:03 16925443 /usr/lib/libbz2.so.1.0.8 +7e24b800a000-7e24b8017000 r-xp 00002000 103:03 16925443 /usr/lib/libbz2.so.1.0.8 +7e24b8017000-7e24b8019000 r--p 0000f000 103:03 16925443 /usr/lib/libbz2.so.1.0.8 +7e24b8019000-7e24b801a000 r--p 00010000 103:03 16925443 /usr/lib/libbz2.so.1.0.8 +7e24b801a000-7e24b801b000 rw-p 00011000 103:03 16925443 /usr/lib/libbz2.so.1.0.8 +7e24b801b000-7e24b801e000 r--p 00000000 103:03 16952678 /usr/lib/libXcursor.so.1.0.2 +7e24b801e000-7e24b8024000 r-xp 00003000 103:03 16952678 /usr/lib/libXcursor.so.1.0.2 +7e24b8024000-7e24b8026000 r--p 00009000 103:03 16952678 /usr/lib/libXcursor.so.1.0.2 +7e24b8026000-7e24b8027000 r--p 0000a000 103:03 16952678 /usr/lib/libXcursor.so.1.0.2 +7e24b8027000-7e24b8028000 rw-p 0000b000 103:03 16952678 /usr/lib/libXcursor.so.1.0.2 +7e24b8028000-7e24b802d000 r--p 00000000 103:03 43004343 /home/jay/.jdks/corretto-22.0.2/lib/libjsvml.so +7e24b802d000-7e24b806e000 r-xp 00005000 103:03 43004343 /home/jay/.jdks/corretto-22.0.2/lib/libjsvml.so +7e24b806e000-7e24b80f7000 r--p 00046000 103:03 43004343 /home/jay/.jdks/corretto-22.0.2/lib/libjsvml.so +7e24b80f7000-7e24b80f8000 r--p 000ce000 103:03 43004343 /home/jay/.jdks/corretto-22.0.2/lib/libjsvml.so +7e24b80f8000-7e24b80f9000 rw-p 000cf000 103:03 43004343 /home/jay/.jdks/corretto-22.0.2/lib/libjsvml.so +7e24b80f9000-7e24b80fa000 ---p 00000000 00:00 0 +7e24b80fa000-7e24b80fe000 ---p 00000000 00:00 0 +7e24b80fe000-7e24b81fa000 rw-p 00000000 00:00 0 +7e24b81fa000-7e24b81fb000 ---p 00000000 00:00 0 +7e24b81fb000-7e24b81ff000 ---p 00000000 00:00 0 +7e24b81ff000-7e24b82fb000 rw-p 00000000 00:00 0 +7e24b82fb000-7e24b82fc000 ---p 00000000 00:00 0 +7e24b82fc000-7e24b8300000 ---p 00000000 00:00 0 +7e24b8300000-7e24b83fc000 rw-p 00000000 00:00 0 +7e24b83fc000-7e24b83fd000 ---p 00000000 00:00 0 +7e24b83fd000-7e24b8401000 ---p 00000000 00:00 0 +7e24b8401000-7e24b84fd000 rw-p 00000000 00:00 0 +7e24b84fd000-7e24b84fe000 ---p 00000000 00:00 0 +7e24b84fe000-7e24b8502000 ---p 00000000 00:00 0 +7e24b8502000-7e24b85fe000 rw-p 00000000 00:00 0 +7e24b85fe000-7e24b85ff000 ---p 00000000 00:00 0 +7e24b85ff000-7e24b8603000 ---p 00000000 00:00 0 +7e24b8603000-7e24b86ff000 rw-p 00000000 00:00 0 +7e24b86ff000-7e24b8700000 ---p 00000000 00:00 0 +7e24b8700000-7e24b8704000 ---p 00000000 00:00 0 +7e24b8704000-7e24b8800000 rw-p 00000000 00:00 0 +7e24b8800000-7e24b8aed000 r--p 00000000 103:03 16972648 /usr/lib/locale/locale-archive +7e24b8aed000-7e24b8aef000 r--p 00000000 103:03 16951501 /usr/lib/libXfixes.so.3.1.0 +7e24b8aef000-7e24b8af2000 r-xp 00002000 103:03 16951501 /usr/lib/libXfixes.so.3.1.0 +7e24b8af2000-7e24b8af3000 r--p 00005000 103:03 16951501 /usr/lib/libXfixes.so.3.1.0 +7e24b8af3000-7e24b8af4000 r--p 00005000 103:03 16951501 /usr/lib/libXfixes.so.3.1.0 +7e24b8af4000-7e24b8af5000 rw-p 00006000 103:03 16951501 /usr/lib/libXfixes.so.3.1.0 +7e24b8af5000-7e24b8b09000 r--p 00000000 103:03 43004322 /home/jay/.jdks/corretto-22.0.2/lib/libawt_xawt.so +7e24b8b09000-7e24b8b4e000 r-xp 00014000 103:03 43004322 /home/jay/.jdks/corretto-22.0.2/lib/libawt_xawt.so +7e24b8b4e000-7e24b8b66000 r--p 00059000 103:03 43004322 /home/jay/.jdks/corretto-22.0.2/lib/libawt_xawt.so +7e24b8b66000-7e24b8b6b000 r--p 00071000 103:03 43004322 /home/jay/.jdks/corretto-22.0.2/lib/libawt_xawt.so +7e24b8b6b000-7e24b8b6d000 rw-p 00076000 103:03 43004322 /home/jay/.jdks/corretto-22.0.2/lib/libawt_xawt.so +7e24b8b6d000-7e24b8b6f000 rw-p 00000000 00:00 0 +7e24b8b6f000-7e24b8b70000 ---p 00000000 00:00 0 +7e24b8b70000-7e24b8c70000 rw-p 00000000 00:00 0 +7e24b8c70000-7e24b8c71000 ---p 00000000 00:00 0 +7e24b8c71000-7e24b8d71000 rw-p 00000000 00:00 0 +7e24b8d71000-7e24b8df2000 rw-p 00000000 00:00 0 +7e24b8df2000-7e24b8df3000 ---p 00000000 00:00 0 +7e24b8df3000-7e24b8ef3000 rw-p 00000000 00:00 0 +7e24b8ef3000-7e24b8ef4000 ---p 00000000 00:00 0 +7e24b8ef4000-7e24b8ff4000 rw-p 00000000 00:00 0 +7e24b8ff4000-7e24bbc00000 rw-p 00000000 00:00 0 +7e24bbc00000-7e24bbc01000 r--p 00000000 103:03 16952747 /usr/lib/libXinerama.so.1.0.0 +7e24bbc01000-7e24bbc02000 r-xp 00001000 103:03 16952747 /usr/lib/libXinerama.so.1.0.0 +7e24bbc02000-7e24bbc03000 r--p 00002000 103:03 16952747 /usr/lib/libXinerama.so.1.0.0 +7e24bbc03000-7e24bbc04000 r--p 00002000 103:03 16952747 /usr/lib/libXinerama.so.1.0.0 +7e24bbc04000-7e24bbc05000 rw-p 00003000 103:03 16952747 /usr/lib/libXinerama.so.1.0.0 +7e24bbc05000-7e24bbc07000 r--p 00000000 103:03 16948190 /usr/lib/libXdmcp.so.6.0.0 +7e24bbc07000-7e24bbc09000 r-xp 00002000 103:03 16948190 /usr/lib/libXdmcp.so.6.0.0 +7e24bbc09000-7e24bbc0b000 r--p 00004000 103:03 16948190 /usr/lib/libXdmcp.so.6.0.0 +7e24bbc0b000-7e24bbc0c000 r--p 00005000 103:03 16948190 /usr/lib/libXdmcp.so.6.0.0 +7e24bbc0c000-7e24bbc0d000 rw-p 00006000 103:03 16948190 /usr/lib/libXdmcp.so.6.0.0 +7e24bbc0d000-7e24bbc10000 r--p 00000000 103:03 16951505 /usr/lib/libXi.so.6.1.0 +7e24bbc10000-7e24bbc1c000 r-xp 00003000 103:03 16951505 /usr/lib/libXi.so.6.1.0 +7e24bbc1c000-7e24bbc1e000 r--p 0000f000 103:03 16951505 /usr/lib/libXi.so.6.1.0 +7e24bbc1e000-7e24bbc1f000 r--p 00011000 103:03 16951505 /usr/lib/libXi.so.6.1.0 +7e24bbc1f000-7e24bbc20000 rw-p 00012000 103:03 16951505 /usr/lib/libXi.so.6.1.0 +7e24bbc20000-7e24bbc22000 r--p 00000000 103:03 16939742 /usr/lib/libXrender.so.1.3.0 +7e24bbc22000-7e24bbc29000 r-xp 00002000 103:03 16939742 /usr/lib/libXrender.so.1.3.0 +7e24bbc29000-7e24bbc2a000 r--p 00009000 103:03 16939742 /usr/lib/libXrender.so.1.3.0 +7e24bbc2a000-7e24bbc2b000 r--p 00009000 103:03 16939742 /usr/lib/libXrender.so.1.3.0 +7e24bbc2b000-7e24bbc2c000 rw-p 0000a000 103:03 16939742 /usr/lib/libXrender.so.1.3.0 +7e24bbc2c000-7e24bbd2d000 rw-p 00000000 00:00 0 +7e24bbd2d000-7e24bbd2e000 ---p 00000000 00:00 0 +7e24bbd2e000-7e24bbe2e000 rw-p 00000000 00:00 0 +7e24bbe2e000-7e24bbe2f000 ---p 00000000 00:00 0 +7e24bbe2f000-7e24bbf2f000 rw-p 00000000 00:00 0 +7e24bbf2f000-7e24bbf30000 ---p 00000000 00:00 0 +7e24bbf30000-7e24bc030000 rw-p 00000000 00:00 0 +7e24bc030000-7e24bc170000 rw-p 00000000 00:00 0 +7e24bc170000-7e24c3ab0000 ---p 00000000 00:00 0 +7e24c3ab0000-7e24c3ad8000 rw-p 00000000 00:00 0 +7e24c3ad8000-7e24c4a00000 ---p 00000000 00:00 0 +7e24c4a00000-7e24c6630000 rwxp 00000000 00:00 0 +7e24c6630000-7e24cbe5f000 ---p 00000000 00:00 0 +7e24cbe5f000-7e24cc43f000 rwxp 00000000 00:00 0 +7e24cc43f000-7e24cc5a0000 ---p 00000000 00:00 0 +7e24cc5a0000-7e24cd070000 rwxp 00000000 00:00 0 +7e24cd070000-7e24d3a00000 ---p 00000000 00:00 0 +7e24d3a00000-7e24dbfc6000 r--s 00000000 103:03 43003264 /home/jay/.jdks/corretto-22.0.2/lib/modules +7e24dbfc6000-7e24dbfc9000 r--s 00000000 103:03 5244047 /var/cache/fontconfig/f349e9996a5320f6dd491cedd2b1f964-le64.cache-9 +7e24dbfc9000-7e24dbfcd000 r--p 00000000 103:03 16951436 /usr/lib/libXext.so.6.4.0 +7e24dbfcd000-7e24dbfd8000 r-xp 00004000 103:03 16951436 /usr/lib/libXext.so.6.4.0 +7e24dbfd8000-7e24dbfdb000 r--p 0000f000 103:03 16951436 /usr/lib/libXext.so.6.4.0 +7e24dbfdb000-7e24dbfdc000 r--p 00011000 103:03 16951436 /usr/lib/libXext.so.6.4.0 +7e24dbfdc000-7e24dbfdd000 rw-p 00012000 103:03 16951436 /usr/lib/libXext.so.6.4.0 +7e24dbffd000-7e24dbffe000 rw-s 00000000 00:01 711675 /memfd:xshmfence (deleted) +7e24dbffe000-7e24dbfff000 rw-s 00000000 00:01 711676 /memfd:xshmfence (deleted) +7e24dbfff000-7e24dc000000 rw-s 18b36e000 00:06 514 /dev/dri/renderD128 +7e24dc000000-7e24dcd8c000 rw-p 00000000 00:00 0 +7e24dcd8c000-7e24e0000000 ---p 00000000 00:00 0 +7e24e0000000-7e24e0001000 r--p 00000000 103:03 16936903 /usr/lib/libXau.so.6.0.0 +7e24e0001000-7e24e0002000 r-xp 00001000 103:03 16936903 /usr/lib/libXau.so.6.0.0 +7e24e0002000-7e24e0003000 r--p 00002000 103:03 16936903 /usr/lib/libXau.so.6.0.0 +7e24e0003000-7e24e0004000 r--p 00002000 103:03 16936903 /usr/lib/libXau.so.6.0.0 +7e24e0004000-7e24e0005000 rw-p 00003000 103:03 16936903 /usr/lib/libXau.so.6.0.0 +7e24e0005000-7e24e0007000 r--p 00000000 103:03 43003279 /home/jay/.jdks/corretto-22.0.2/lib/libzip.so +7e24e0007000-7e24e000b000 r-xp 00002000 103:03 43003279 /home/jay/.jdks/corretto-22.0.2/lib/libzip.so +7e24e000b000-7e24e000d000 r--p 00006000 103:03 43003279 /home/jay/.jdks/corretto-22.0.2/lib/libzip.so +7e24e000d000-7e24e000e000 r--p 00007000 103:03 43003279 /home/jay/.jdks/corretto-22.0.2/lib/libzip.so +7e24e000e000-7e24e000f000 rw-p 00008000 103:03 43003279 /home/jay/.jdks/corretto-22.0.2/lib/libzip.so +7e24e000f000-7e24e0012000 r--p 00000000 103:03 43003274 /home/jay/.jdks/corretto-22.0.2/lib/libnet.so +7e24e0012000-7e24e0019000 r-xp 00003000 103:03 43003274 /home/jay/.jdks/corretto-22.0.2/lib/libnet.so +7e24e0019000-7e24e001b000 r--p 0000a000 103:03 43003274 /home/jay/.jdks/corretto-22.0.2/lib/libnet.so +7e24e001b000-7e24e001c000 r--p 0000b000 103:03 43003274 /home/jay/.jdks/corretto-22.0.2/lib/libnet.so +7e24e001c000-7e24e001d000 rw-p 0000c000 103:03 43003274 /home/jay/.jdks/corretto-22.0.2/lib/libnet.so +7e24e001d000-7e24e01db000 rw-p 00000000 00:00 0 +7e24e01db000-7e24e1103000 ---p 00000000 00:00 0 +7e24e1103000-7e24e1e26000 rw-p 00000000 00:00 0 +7e24e1e26000-7e24e1ef9000 ---p 00000000 00:00 0 +7e24e1ef9000-7e24e1f32000 rw-p 00000000 00:00 0 +7e24e1f32000-7e24e1fe2000 ---p 00000000 00:00 0 +7e24e1fe2000-7e24e1fe6000 ---p 00000000 00:00 0 +7e24e1fe6000-7e24e20e2000 rw-p 00000000 00:00 0 +7e24e20e2000-7e24e20f2000 r--p 00000000 103:03 16911891 /usr/lib/libm.so.6 +7e24e20f2000-7e24e2189000 r-xp 00010000 103:03 16911891 /usr/lib/libm.so.6 +7e24e2189000-7e24e21fe000 r--p 000a7000 103:03 16911891 /usr/lib/libm.so.6 +7e24e21fe000-7e24e21ff000 r--p 0011b000 103:03 16911891 /usr/lib/libm.so.6 +7e24e21ff000-7e24e2200000 rw-p 0011c000 103:03 16911891 /usr/lib/libm.so.6 +7e24e2200000-7e24e2497000 r--p 00000000 103:03 43004316 /home/jay/.jdks/corretto-22.0.2/lib/server/libjvm.so +7e24e2497000-7e24e3320000 r-xp 00297000 103:03 43004316 /home/jay/.jdks/corretto-22.0.2/lib/server/libjvm.so +7e24e3320000-7e24e3606000 r--p 01120000 103:03 43004316 /home/jay/.jdks/corretto-22.0.2/lib/server/libjvm.so +7e24e3606000-7e24e36d7000 r--p 01405000 103:03 43004316 /home/jay/.jdks/corretto-22.0.2/lib/server/libjvm.so +7e24e36d7000-7e24e3706000 rw-p 014d6000 103:03 43004316 /home/jay/.jdks/corretto-22.0.2/lib/server/libjvm.so +7e24e3706000-7e24e377d000 rw-p 00000000 00:00 0 +7e24e377d000-7e24e377e000 rw-s 1e2087000 00:06 514 /dev/dri/renderD128 +7e24e377e000-7e24e3780000 r--p 00000000 103:03 16951583 /usr/lib/libXtst.so.6.1.0 +7e24e3780000-7e24e3783000 r-xp 00002000 103:03 16951583 /usr/lib/libXtst.so.6.1.0 +7e24e3783000-7e24e3784000 r--p 00005000 103:03 16951583 /usr/lib/libXtst.so.6.1.0 +7e24e3784000-7e24e3785000 r--p 00005000 103:03 16951583 /usr/lib/libXtst.so.6.1.0 +7e24e3785000-7e24e3786000 rw-p 00006000 103:03 16951583 /usr/lib/libXtst.so.6.1.0 +7e24e3786000-7e24e378e000 r--p 00000000 103:03 43003275 /home/jay/.jdks/corretto-22.0.2/lib/libnio.so +7e24e378e000-7e24e3797000 r-xp 00008000 103:03 43003275 /home/jay/.jdks/corretto-22.0.2/lib/libnio.so +7e24e3797000-7e24e379b000 r--p 00011000 103:03 43003275 /home/jay/.jdks/corretto-22.0.2/lib/libnio.so +7e24e379b000-7e24e379c000 r--p 00015000 103:03 43003275 /home/jay/.jdks/corretto-22.0.2/lib/libnio.so +7e24e379c000-7e24e379d000 rw-p 00016000 103:03 43003275 /home/jay/.jdks/corretto-22.0.2/lib/libnio.so +7e24e379d000-7e24e37e7000 rw-p 00000000 00:00 0 +7e24e37e7000-7e24e37ea000 ---p 00000000 00:00 0 +7e24e37ea000-7e24e37eb000 r--p 00000000 103:03 16911919 /usr/lib/librt.so.1 +7e24e37eb000-7e24e37ec000 r-xp 00001000 103:03 16911919 /usr/lib/librt.so.1 +7e24e37ec000-7e24e37ed000 r--p 00002000 103:03 16911919 /usr/lib/librt.so.1 +7e24e37ed000-7e24e37ee000 r--p 00002000 103:03 16911919 /usr/lib/librt.so.1 +7e24e37ee000-7e24e37ef000 rw-p 00003000 103:03 16911919 /usr/lib/librt.so.1 +7e24e37ef000-7e24e37f1000 rw-p 00000000 00:00 0 +7e24e37f1000-7e24e3815000 r--p 00000000 103:03 16911873 /usr/lib/libc.so.6 +7e24e3815000-7e24e3986000 r-xp 00024000 103:03 16911873 /usr/lib/libc.so.6 +7e24e3986000-7e24e39d4000 r--p 00195000 103:03 16911873 /usr/lib/libc.so.6 +7e24e39d4000-7e24e39d8000 r--p 001e2000 103:03 16911873 /usr/lib/libc.so.6 +7e24e39d8000-7e24e39da000 rw-p 001e6000 103:03 16911873 /usr/lib/libc.so.6 +7e24e39da000-7e24e39e2000 rw-p 00000000 00:00 0 +7e24e39e2000-7e24e39e3000 r--p 00000000 103:03 16911884 /usr/lib/libdl.so.2 +7e24e39e3000-7e24e39e4000 r-xp 00001000 103:03 16911884 /usr/lib/libdl.so.2 +7e24e39e4000-7e24e39e5000 r--p 00002000 103:03 16911884 /usr/lib/libdl.so.2 +7e24e39e5000-7e24e39e6000 r--p 00002000 103:03 16911884 /usr/lib/libdl.so.2 +7e24e39e6000-7e24e39e7000 rw-p 00003000 103:03 16911884 /usr/lib/libdl.so.2 +7e24e39e7000-7e24e39e8000 r--p 00000000 103:03 16911914 /usr/lib/libpthread.so.0 +7e24e39e8000-7e24e39e9000 r-xp 00001000 103:03 16911914 /usr/lib/libpthread.so.0 +7e24e39e9000-7e24e39ea000 r--p 00002000 103:03 16911914 /usr/lib/libpthread.so.0 +7e24e39ea000-7e24e39eb000 r--p 00002000 103:03 16911914 /usr/lib/libpthread.so.0 +7e24e39eb000-7e24e39ec000 rw-p 00003000 103:03 16911914 /usr/lib/libpthread.so.0 +7e24e39ec000-7e24e39ef000 r--p 00000000 103:03 43003272 /home/jay/.jdks/corretto-22.0.2/lib/libjli.so +7e24e39ef000-7e24e39f9000 r-xp 00003000 103:03 43003272 /home/jay/.jdks/corretto-22.0.2/lib/libjli.so +7e24e39f9000-7e24e39fc000 r--p 0000d000 103:03 43003272 /home/jay/.jdks/corretto-22.0.2/lib/libjli.so +7e24e39fc000-7e24e39fd000 r--p 00010000 103:03 43003272 /home/jay/.jdks/corretto-22.0.2/lib/libjli.so +7e24e39fd000-7e24e39fe000 rw-p 00011000 103:03 43003272 /home/jay/.jdks/corretto-22.0.2/lib/libjli.so +7e24e39fe000-7e24e3a01000 r--p 00000000 103:03 16915710 /usr/lib/libz.so.1.3.2 +7e24e3a01000-7e24e3a11000 r-xp 00003000 103:03 16915710 /usr/lib/libz.so.1.3.2 +7e24e3a11000-7e24e3a17000 r--p 00013000 103:03 16915710 /usr/lib/libz.so.1.3.2 +7e24e3a17000-7e24e3a18000 r--p 00018000 103:03 16915710 /usr/lib/libz.so.1.3.2 +7e24e3a18000-7e24e3a19000 rw-p 00019000 103:03 16915710 /usr/lib/libz.so.1.3.2 +7e24e3a19000-7e24e3a1a000 rw-p 00000000 00:00 0 +7e24e3a1a000-7e24e3a1b000 rw-p 00000000 00:00 0 +7e24e3a1b000-7e24e3a29000 r--p 00000000 103:03 43003270 /home/jay/.jdks/corretto-22.0.2/lib/libjava.so +7e24e3a29000-7e24e3a37000 r-xp 0000e000 103:03 43003270 /home/jay/.jdks/corretto-22.0.2/lib/libjava.so +7e24e3a37000-7e24e3a3c000 r--p 0001c000 103:03 43003270 /home/jay/.jdks/corretto-22.0.2/lib/libjava.so +7e24e3a3c000-7e24e3a3d000 r--p 00021000 103:03 43003270 /home/jay/.jdks/corretto-22.0.2/lib/libjava.so +7e24e3a3d000-7e24e3a3e000 rw-p 00022000 103:03 43003270 /home/jay/.jdks/corretto-22.0.2/lib/libjava.so +7e24e3a3e000-7e24e3a3f000 rw-p 00000000 00:00 0 +7e24e3a3f000-7e24e3a47000 rw-s 00000000 00:2e 85014 /tmp/hsperfdata_jay/2264499 +7e24e3a47000-7e24e3a48000 ---p 00000000 00:00 0 +7e24e3a48000-7e24e3a49000 r--p 00000000 00:00 0 +7e24e3a49000-7e24e3a4a000 ---p 00000000 00:00 0 +7e24e3a4a000-7e24e3a4e000 r--p 00000000 103:03 43003271 /home/jay/.jdks/corretto-22.0.2/lib/libjimage.so +7e24e3a4e000-7e24e3a62000 r-xp 00004000 103:03 43003271 /home/jay/.jdks/corretto-22.0.2/lib/libjimage.so +7e24e3a62000-7e24e3a6d000 r--p 00018000 103:03 43003271 /home/jay/.jdks/corretto-22.0.2/lib/libjimage.so +7e24e3a6d000-7e24e3a6f000 r--p 00022000 103:03 43003271 /home/jay/.jdks/corretto-22.0.2/lib/libjimage.so +7e24e3a6f000-7e24e3a70000 rw-p 00024000 103:03 43003271 /home/jay/.jdks/corretto-22.0.2/lib/libjimage.so +7e24e3a70000-7e24e3a72000 rw-p 00000000 00:00 0 +7e24e3a72000-7e24e3a76000 r--p 00000000 00:00 0 [vvar] +7e24e3a76000-7e24e3a78000 r-xp 00000000 00:00 0 [vdso] +7e24e3a78000-7e24e3a79000 r--p 00000000 103:03 16911816 /usr/lib/ld-linux-x86-64.so.2 +7e24e3a79000-7e24e3aa3000 r-xp 00001000 103:03 16911816 /usr/lib/ld-linux-x86-64.so.2 +7e24e3aa3000-7e24e3aae000 r--p 0002b000 103:03 16911816 /usr/lib/ld-linux-x86-64.so.2 +7e24e3aae000-7e24e3ab0000 r--p 00036000 103:03 16911816 /usr/lib/ld-linux-x86-64.so.2 +7e24e3ab0000-7e24e3ab1000 rw-p 00038000 103:03 16911816 /usr/lib/ld-linux-x86-64.so.2 +7e24e3ab1000-7e24e3ab2000 rw-p 00000000 00:00 0 +7fff69527000-7fff6954b000 rw-p 00000000 00:00 0 [stack] +ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0 [vsyscall] +Total number of mappings: 819 + + +VM Arguments: +jvm_args: -Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en -Duser.variant +java_command: com.jaytux.grader.MainKt +java_class_path (initial): /home/jay/kotlin/grader/composeApp/build/classes/kotlin/desktop/main:/home/jay/kotlin/grader/composeApp/build/classes/java/desktopMain:/home/jay/kotlin/grader/composeApp/build/processedResources/desktop/main:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.exposed/exposed-dao/1.1.1/29bb5dbb98ce5eb13bb5e8dd4238f3a6df78d63f/exposed-dao-1.1.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.exposed/exposed-migration-jdbc/1.1.1/2f9050354d908353e7b2c503d8bc16be6c8261cf/exposed-migration-jdbc-1.1.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.exposed/exposed-jdbc/1.1.1/1992e73acde3d9a7d7a5f2b31e79e0741d7a0869/exposed-jdbc-1.1.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.exposed/exposed-migration-core/1.1.1/e095e43d21ede68d46f815ef85e0d08faf634ca8/exposed-migration-core-1.1.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.exposed/exposed-kotlin-datetime/1.1.1/652bf597bdcb7ba050dfc3890e8ac9b8043dc116/exposed-kotlin-datetime-1.1.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.exposed/exposed-core/1.1.1/c3b2aab8ee80437c6af0e30198d3b2bf9eff777c/exposed-core-1.1.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/com.mohamedrejeb.richeditor/richeditor-compose-desktop/1.0.0-rc11/3b954be78eddb2308694cfc9f2186c990139e62c/richeditor-compose-desktop-1.0.0-rc11.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.material3/material3-desktop/1.9.0/19004c4eb3dc6618eb66a076bbe3d7e1a2e7b85/material3-desktop-1.9.0.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.desktop/desktop-jvm/1.9.0/760a7f1c3278719f2ab9fa443228956e64a7a18e/desktop-jvm-1.9.0.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.material/material-desktop/1.9.0/67e948eefe3e565d3be2ddf0918a12f676537b0d/material-desktop-1.9.0.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.components/components-resources-desktop/1.9.0/263d44e856cb89a759959eec68dafae6d1931110/library-desktop-1.9.0.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.components/components-ui-tooling-preview-desktop/1.9.0/5b3acb8bd7379767b72faafacfb25852a6d2d328/library-desktop-1.9.0.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-reflect/2.2.20/665c83286bdf6e8ed541ff485e0d322ffeca8d2b/kotlin-reflect-2.2.20.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-datetime-jvm/0.7.1-0.6.x-compat/b1b640d848677394c1a6731bc6b97a8f0193cda1/kotlinx-datetime-jvm-0.7.1-0.6.x-compat.jar:/home/jay/.gradle/caches/modules-2/files-2.1/io.github.vinceglb/filekit-dialogs-compose-jvm/0.10.0-beta04/652b92b5fa18166ab5edf028fca29f5ca7d025de/filekit-dialogs-compose-jvm.jar:/home/jay/.gradle/caches/modules-2/files-2.1/io.github.vinceglb/filekit-dialogs-jvm/0.10.0-beta04/2411f5ee12b9206174773f41f71c2cd204a878/filekit-dialogs-jvm.jar:/home/jay/.gradle/caches/modules-2/files-2.1/io.github.vinceglb/filekit-coil-jvm/0.10.0-beta04/a774460116aa2bd45d45ba47d372b4acb550f4da/filekit-coil-jvm.jar:/home/jay/.gradle/caches/modules-2/files-2.1/io.github.vinceglb/filekit-core-jvm/0.10.0-beta04/3bfa16534093d481a465ac7f551538c60b7dc7c4/filekit-core-jvm.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.androidx.lifecycle/lifecycle-viewmodel-compose-desktop/2.9.6/5cf03bfbc0f7139a4d7081d5da78c97287f3c65f/lifecycle-viewmodel-compose-desktop-2.9.6.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.skiko/skiko-awt-runtime-linux-x64/0.9.22.2/3272fd9cbab7a3d74b07705c73bcd4761ba6209a/skiko-awt-runtime-linux-x64-0.9.22.2.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.material/material-ripple-desktop/1.9.1/b0741397d2a9b93d7c9510c68196a27b717c07e9/material-ripple-desktop-1.9.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/io.coil-kt.coil3/coil-compose-jvm/3.2.0-rc02/135acd4cdde92967b798eb66d00a64f0d57fe834/coil-compose-jvm-3.2.0-rc02.jar:/home/jay/.gradle/caches/modules-2/files-2.1/io.coil-kt.coil3/coil-compose-core-jvm/3.2.0-rc02/126d67f5fa4d2a0ba415101a06cb77ea6cef7930/coil-compose-core-jvm-3.2.0-rc02.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.foundation/foundation-desktop/1.9.1/737b624257ae2639cefe2ed8aecd2011f4a3aa0d/foundation-desktop-1.9.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.animation/animation-desktop/1.9.1/bd1d694de3da4fd10bd8ab27f091785a3e6bcfb7/animation-desktop-1.9.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.animation/animation-core-desktop/1.9.1/47a335ae4cb43a1e5f950a1a6a44ac86be531ba5/animation-core-desktop-1.9.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.foundation/foundation-layout-desktop/1.9.1/1046ee6bfb6a1494a946af7a4ab0f63226412f13/foundation-layout-desktop-1.9.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.ui/ui-desktop/1.9.1/934f75ab21f0394f393bd05b9f0bd4812672ce20/ui-desktop-1.9.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.ui/ui-text-desktop/1.9.1/bd0f7eca77ec10ff33a8dcad3ea6ee7845015ab5/ui-text-desktop-1.9.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.ui/ui-graphics-desktop/1.9.1/94e03ee7a8da852f08141b07241de12161a50e37/ui-graphics-desktop-1.9.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/io.coil-kt.coil3/coil-jvm/3.2.0-rc02/432f72329ae925b191ed015aacbb1052c9077d2/coil-jvm-3.2.0-rc02.jar:/home/jay/.gradle/caches/modules-2/files-2.1/io.coil-kt.coil3/coil-core-jvm/3.2.0-rc02/1c42d649e54989e17f75b090281a8237fa53a710/coil-core-jvm-3.2.0-rc02.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.skiko/skiko-awt/0.9.22.2/f1dab255d499b8ef215b308b531de32029c41dd6/skiko-awt-0.9.22.2.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk8/2.1.21/fb62497994f5cfa4ad41fcff05020c35976307c6/kotlin-stdlib-jdk8-2.1.21.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.ui/ui-backhandler-desktop/1.9.1/b7f509317df9bd537c4458bcae9239caa7b57d65/ui-backhandler-desktop-1.9.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.androidx.lifecycle/lifecycle-runtime-compose-desktop/2.9.6/7b6b6793f3c4c5996b20d1d99cf728e5fac00364/lifecycle-runtime-compose-desktop-2.9.6.jar:/home/jay/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-viewmodel-savedstate-desktop/2.9.4/72a1919b08c5a4da224d8a65ce1589aa69934e8a/lifecycle-viewmodel-savedstate-desktop-2.9.4.jar:/home/jay/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-runtime-desktop/2.9.4/1cc820319ec0139e76b8a2fe4be0b356b4e624c4/lifecycle-runtime-desktop-2.9.4.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.runtime/runtime-saveable-desktop/1.9.1/9b0e2a8ce3ae7d2b1a40307bc9271933b238cfd4/runtime-saveable-desktop-1.9.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.ui/ui-tooling-preview-desktop/1.9.0/75badc23517c7b5385e9b307a3b215e61bb7c56e/ui-tooling-preview-desktop-1.9.0.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.ui/ui-unit-desktop/1.9.1/4ff1a779620c559d32f1a915186ee60519a62950/ui-unit-desktop-1.9.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.ui/ui-geometry-desktop/1.9.1/606e5a5b02206cc37f413369647eadc2dc577fee/ui-geometry-desktop-1.9.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.runtime/runtime-desktop/1.9.3/edbd39fc9691f4ba1e29c6690341148db4272752/runtime-desktop-1.9.3.jar:/home/jay/.gradle/caches/modules-2/files-2.1/androidx.compose.runtime/runtime-annotation-jvm/1.9.4/3195cb969ccebf099b765ecbf41e563c73eaf356/runtime-annotation-jvm-1.9.4.jar:/home/jay/.gradle/caches/modules-2/files-2.1/androidx.compose.runtime/runtime-desktop/1.9.4/1006732369660319982cb5a9af71783d3ffdc0ad/runtime-desktop-1.9.4.jar:/home/jay/.gradle/caches/modules-2/files-2.1/androidx.compose.runtime/runtime-saveable-desktop/1.9.4/e781301950a900a1a0c712574b143e442c52f57e/runtime-saveable-desktop-1.9.4.jar:/home/jay/.gradle/caches/modules-2/files-2.1/androidx.savedstate/savedstate-compose-desktop/1.3.3/cd60b543d5722a8b5e6cea1e4ccdec8b4375a22b/savedstate-compose-desktop-1.3.3.jar:/home/jay/.gradle/caches/modules-2/files-2.1/androidx.savedstate/savedstate-desktop/1.3.3/1c5bfc3fb56614538528060a06f2c03e34fa5188/savedstate-desktop-1.3.3.jar:/home/jay/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-common-jvm/2.9.4/ab739bccdb3541983385af169565c7c035d897e7/lifecycle-common-jvm-2.9.4.jar:/home/jay/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-runtime-compose-desktop/2.9.4/86a4ffec845d4e488078118a0b5095bd1fabcafe/lifecycle-runtime-compose-desktop-2.9.4.jar:/home/jay/.gradle/caches/modules-2/files-2.1/androidx.lifecycle/lifecycle-viewmodel-desktop/2.9.4/93fee6d78f0df0e38f36e0fa2eff74f8da6d5481/lifecycle-viewmodel-desktop-2.9.4.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-swing/1.10.2/ccb5a2e7c83fa76da0ba4677f05678d3bd3eed57/kotlinx-coroutines-swing-1.10.2.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-core-jvm/1.10.2/4a9f78ef49483748e2c129f3d124b8fa249dafbf/kotlinx-coroutines-core-jvm-1.10.2.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.compose.ui/ui-util-desktop/1.9.1/3f9edd3d5eb28417c667ccbf2931416f3871ed40/ui-util-desktop-1.9.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/atomicfu-jvm/0.23.2/a4601dc42dceb031a586058e8356ff778a57dea0/atomicfu-jvm-0.23.2.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk7/2.1.21/f5e72fe5f9501e0d27ec633beb3996c29641b877/kotlin-stdlib-jdk7-2.1.21.jar:/home/jay/.gradle/caches/modules-2/files-2.1/androidx.collection/collection-jvm/1.5.0/7ba2c69414d46ebc2dd76598bdd0a75c54281a57/collection-jvm-1.5.0.jar:/home/jay/.gradle/caches/modules-2/files-2.1/androidx.arch.core/core-common/2.2.0/5e1b8b81dfd5f52c56a8d53b18ca759c19a301f3/core-common-2.2.0.jar:/home/jay/.gradle/caches/modules-2/files-2.1/androidx.annotation/annotation-jvm/1.9.1/b17951747e38bf3986a24431b9ba0d039958aa5f/annotation-jvm-1.9.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/com.mohamedrejeb.ksoup/ksoup-html-jvm/0.5.0/5f542c4995e8d0f2671d22840c47dd7b203be832/ksoup-html-jvm-0.5.0.jar:/home/jay/.gradle/caches/modules-2/files-2.1/com.mohamedrejeb.ksoup/ksoup-entities-jvm/0.5.0/c0b88bac9b4fb54ee183d27ca8434519bee5bbdf/ksoup-entities-jvm-0.5.0.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains/markdown-jvm/0.7.3/83df25f4bb0a51e979774c02530824af8ec6b03e/markdown-jvm-0.7.3.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-io-core-jvm/0.7.0/1d9595ed390f6304ce90a049e6b2f1fab3b408c4/kotlinx-io-core-jvm-0.7.0.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-serialization-core-jvm/1.7.3/1f226780b845ff9206474c05159245d861556249/kotlinx-serialization-core-jvm-1.7.3.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-io-bytestring-jvm/0.7.0/ffe5bd231da40d21870250703326113277dbf9c3/kotlinx-io-bytestring-jvm-0.7.0.jar:/home/jay/.gradle/caches/modules-2/files-2.1/com.squareup.okio/okio-jvm/3.11.0/e19f243ee46335ab089613a25f3ea1f65df285b1/okio-jvm-3.11.0.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/2.3.0/ebc4eb2b6e6c91b6c844c1e3183920d86f2ef656/kotlin-stdlib-2.3.0.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-simple/2.0.12/5fb15030fb6158ef4f63ce4f889f72f4259a7bc3/slf4j-simple-2.0.12.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.xerial/sqlite-jdbc/3.34.0/fd29bb0124e3f79c80b2753162a6a3873c240bcf/sqlite-jdbc-3.34.0.jar:/home/jay/.gradle/caches/modules-2/files-2.1/dev.dirs/directories/26/a7fef4c8ef0831ba9ab5c029f04f6cd42d68ea18/directories-26.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains/annotations/23.0.0/8cc20c07506ec18e0834947b84a864bfc094484e/annotations-23.0.0.jar:/home/jay/.gradle/caches/modules-2/files-2.1/com.github.hypfvieh/dbus-java-transport-native-unixsocket/5.1.1/40db43e95df145299a9dc97f611c8a4e1f7477a3/dbus-java-transport-native-unixsocket-5.1.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/com.github.hypfvieh/dbus-java-core/5.1.1/36af749ddaefd567bd4e8a41c24845a584ce76d9/dbus-java-core-5.1.1.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-api/2.0.16/172931663a09a1fa515567af5fbef00897d3c04/slf4j-api-2.0.16.jar:/home/jay/.gradle/caches/modules-2/files-2.1/net.java.dev.jna/jna-platform/5.17.0/a4934c44d25a9d8c2ddf4203affd20330cb3426f/jna-platform-5.17.0.jar:/home/jay/.gradle/caches/modules-2/files-2.1/net.java.dev.jna/jna/5.17.0/33d12735bef894440780fce64f9758d420c7bae2/jna-5.17.0.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jetbrains.runtime/jbr-api/1.5.0/4158e485a7a4ecfd521e03095d81e0225529e8d2/jbr-api-1.5.0.jar:/home/jay/.gradle/caches/modules-2/files-2.1/org.jspecify/jspecify/1.0.0/7425a601c1c7ec76645a78d22b8c6a627edee507/jspecify-1.0.0.jar +Launcher Type: SUN_STANDARD + +[Global flags] + intx CICompilerCount = 12 {product} {ergonomic} + uint ConcGCThreads = 3 {product} {ergonomic} + uint G1ConcRefinementThreads = 13 {product} {ergonomic} + size_t G1HeapRegionSize = 4194304 {product} {ergonomic} + size_t InitialHeapSize = 515899392 {product} {ergonomic} + size_t MarkStackSize = 4194304 {product} {ergonomic} + size_t MaxHeapSize = 8220835840 {product} {ergonomic} + size_t MaxNewSize = 4932501504 {product} {ergonomic} + size_t MinHeapDeltaBytes = 4194304 {product} {ergonomic} + size_t MinHeapSize = 8388608 {product} {ergonomic} + uintx NonNMethodCodeHeapSize = 7602480 {pd product} {ergonomic} + uintx NonProfiledCodeHeapSize = 122027880 {pd product} {ergonomic} + uintx ProfiledCodeHeapSize = 122027880 {pd product} {ergonomic} + uintx ReservedCodeCacheSize = 251658240 {pd product} {ergonomic} + bool SegmentedCodeCache = true {product} {ergonomic} + size_t SoftMaxHeapSize = 8220835840 {manageable} {ergonomic} + bool UseCompressedOops = true {product lp64_product} {ergonomic} + bool UseG1GC = true {product} {ergonomic} + +Logging: +Log output configuration: + #0: stdout all=warning uptime,level,tags foldmultilines=false + #1: stderr all=off uptime,level,tags foldmultilines=false + +Environment Variables: +PATH=/home/jay/.local/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/opt/cuda/bin:/usr/lib/jvm/default/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl:/opt/rocm/bin:/usr/lib/rustup/bin +SHELL=/usr/bin/zsh +DISPLAY=:0 +LANG=en_US.UTF-8 + +Active Locale: +LC_ALL=en_US.UTF-8 +LC_COLLATE=en_US.UTF-8 +LC_CTYPE=en_US.UTF-8 +LC_MESSAGES=en_US.UTF-8 +LC_MONETARY=en_US.UTF-8 +LC_NUMERIC=en_US.UTF-8 +LC_TIME=en_US.UTF-8 + +Signal Handlers: + SIGSEGV: crash_handler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, unblocked + SIGBUS: crash_handler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, unblocked + SIGFPE: crash_handler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, unblocked + SIGPIPE: javaSignalHandler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, blocked + SIGXFSZ: javaSignalHandler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, blocked + SIGILL: crash_handler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, unblocked + SIGUSR2: SR_handler in libjvm.so, mask=00000000000000000000000000000000, flags=SA_RESTART|SA_SIGINFO, blocked + SIGHUP: UserHandler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, blocked + SIGINT: UserHandler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, blocked + SIGTERM: UserHandler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, blocked + SIGQUIT: UserHandler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, blocked + SIGTRAP: crash_handler in libjvm.so, mask=11100100010111111101111111111110, flags=SA_RESTART|SA_SIGINFO, unblocked + + +Periodic native trim disabled + +--------------- S Y S T E M --------------- + +OS: +DISTRIB_ID="Arch" +DISTRIB_RELEASE="rolling" +DISTRIB_DESCRIPTION="Arch Linux" +uname: Linux 6.12.75-1-lts #1 SMP PREEMPT_DYNAMIC Wed, 04 Mar 2026 14:59:39 +0000 x86_64 +OS uptime: 2 days 2:50 hours +libc: glibc 2.43 NPTL 2.43 +rlimit (soft/hard): STACK 8192k/infinity , CORE infinity/infinity , NPROC 124622/124622 , NOFILE 524288/524288 , AS infinity/infinity , CPU infinity/infinity , DATA infinity/infinity , FSIZE infinity/infinity , MEMLOCK 8192k/8192k +load average: 3.06 3.19 2.63 + +/proc/meminfo: +MemTotal: 32101040 kB +MemFree: 1855044 kB +MemAvailable: 5378372 kB +Buffers: 24248 kB +Cached: 2001544 kB +SwapCached: 306404 kB +Active: 16531396 kB +Inactive: 3809932 kB +Active(anon): 14742064 kB +Inactive(anon): 2190208 kB +Active(file): 1789332 kB +Inactive(file): 1619724 kB +Unevictable: 564 kB +Mlocked: 564 kB +SwapTotal: 20971512 kB +SwapFree: 8731212 kB +Zswap: 2199188 kB +Zswapped: 9019228 kB +Dirty: 2852 kB +Writeback: 0 kB +AnonPages: 18108592 kB +Mapped: 1401512 kB +Shmem: 320948 kB +KReclaimable: 576816 kB +Slab: 1082048 kB +SReclaimable: 576816 kB +SUnreclaim: 505232 kB +KernelStack: 57960 kB +PageTables: 269312 kB +SecPageTables: 4924 kB +NFS_Unstable: 0 kB +Bounce: 0 kB +WritebackTmp: 0 kB +CommitLimit: 37022032 kB +Committed_AS: 57543524 kB +VmallocTotal: 34359738367 kB +VmallocUsed: 230772 kB +VmallocChunk: 0 kB +Percpu: 13888 kB +HardwareCorrupted: 0 kB +AnonHugePages: 6815744 kB +ShmemHugePages: 0 kB +ShmemPmdMapped: 0 kB +FileHugePages: 337920 kB +FilePmdMapped: 325632 kB +CmaTotal: 0 kB +CmaFree: 0 kB +Unaccepted: 0 kB +HugePages_Total: 0 +HugePages_Free: 0 +HugePages_Rsvd: 0 +HugePages_Surp: 0 +Hugepagesize: 2048 kB +Hugetlb: 0 kB +DirectMap4k: 21054956 kB +DirectMap2M: 11728896 kB +DirectMap1G: 0 kB + +/sys/kernel/mm/transparent_hugepage/enabled: [always] madvise never +/sys/kernel/mm/transparent_hugepage/hpage_pmd_size: 2097152 +/sys/kernel/mm/transparent_hugepage/shmem_enabled: always within_size advise [never] deny force +/sys/kernel/mm/transparent_hugepage/defrag (defrag/compaction efforts parameter): always defer defer+madvise [madvise] never + +Process Memory: +Virtual Size: 14655452K (peak: 14672956K) +Resident Set Size: 570460K (peak: 660252K) (anon: 415636K, file: 154024K, shmem: 800K) +Swapped out: 44904K +C-Heap outstanding allocations: 106045K, retained: 177182K +glibc malloc tunables: (default) + +/proc/sys/kernel/threads-max (system-wide limit on the number of threads): 249245 +/proc/sys/vm/max_map_count (maximum number of memory map areas a process may have): 1048576 +/proc/sys/vm/swappiness (control to define how aggressively the kernel swaps out anonymous memory): 60 +/proc/sys/kernel/pid_max (system-wide limit on number of process identifiers): 4194304 + +container information not found. +Steal ticks since vm start: 0 +Steal ticks percentage since vm start: 0.000 + +CPU: total 16 (initial active 16) (16 cores per cpu, 2 threads per core) family 25 model 117 stepping 2 microcode 0xa705208, cx8, cmov, fxsr, ht, mmx, 3dnowpref, sse, sse2, sse3, ssse3, sse4a, sse4.1, sse4.2, popcnt, lzcnt, tsc, tscinvbit, avx, avx2, aes, erms, clmul, bmi1, bmi2, adx, avx512f, avx512dq, avx512cd, avx512bw, avx512vl, sha, fma, vzeroupper, avx512_vpopcntdq, avx512_vpclmulqdq, avx512_vaes, avx512_vnni, clflush, clflushopt, avx512_vbmi2, avx512_vbmi, rdtscp, rdpid, fsrm, gfni, avx512_bitalg, f16c, pku, ospke, cet_ss, avx512_ifma +CPU Model and flags from /proc/cpuinfo: +model name : AMD Ryzen 7 8845HS w/ Radeon 780M Graphics +flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ht syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good amd_lbr_v2 nopl xtopology nonstop_tsc cpuid extd_apicid aperfmperf rapl pni pclmulqdq monitor ssse3 fma cx16 sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand lahf_lm cmp_legacy svm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw ibs skinit wdt tce topoext perfctr_core perfctr_nb bpext perfctr_llc mwaitx cpb cat_l3 cdp_l3 hw_pstate ssbd mba perfmon_v2 ibrs ibpb stibp ibrs_enhanced vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid cqm rdt_a avx512f avx512dq rdseed adx smap avx512ifma clflushopt clwb avx512cd sha_ni avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves cqm_llc cqm_occup_llc cqm_mbm_total cqm_mbm_local user_shstk avx512_bf16 clzero irperf xsaveerptr rdpru wbnoinvd cppc arat npt lbrv svm_lock nrip_save tsc_scale vmcb_clean flushbyasid decodeassists pausefilter pfthreshold vgif x2avic v_spec_ctrl vnmi avx512vbmi umip pku ospke avx512_vbmi2 gfni vaes vpclmulqdq avx512_vnni avx512_bitalg avx512_vpopcntdq rdpid overflow_recov succor smca fsrm flush_l1d + +Online cpus: 0-15 +Offline cpus: +BIOS frequency limitation: +Frequency switch latency (ns): 0 +Available cpu frequencies: +Current governor: powersave +Core performance/turbo boost: 1 + +Memory: 4k page, physical 32101040k(5378372k free), swap 20971512k(8731212k free) +Page Sizes: 4k + +vm_info: OpenJDK 64-Bit Server VM (22.0.2+9-FR) for linux-amd64 JRE (22.0.2+9-FR), built on 2024-07-09T01:12:11Z by "jenkins" with gcc 13.2.0 + +END. diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/App.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/App.kt index add8528..2c6d48b 100644 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/App.kt +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/App.kt @@ -1,43 +1,37 @@ package com.jaytux.grader -import androidx.compose.foundation.layout.* import androidx.compose.material3.* import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import com.jaytux.grader.ui.ChevronLeft -import com.jaytux.grader.ui.CoursesView -import com.jaytux.grader.ui.toDp -import com.jaytux.grader.viewmodel.CourseListState -import org.jetbrains.compose.ui.tooling.preview.Preview +import com.jaytux.grader.data.v2.BaseAssignment +import com.jaytux.grader.data.v2.Course +import com.jaytux.grader.data.v2.Edition +import com.jaytux.grader.ui.EditionTitle +import com.jaytux.grader.ui.EditionView +import com.jaytux.grader.ui.GroupsGradingTitle +import com.jaytux.grader.ui.GroupsGradingView +import com.jaytux.grader.ui.HomeTitle +import com.jaytux.grader.ui.HomeView +import com.jaytux.grader.ui.PeerEvalsGradingTitle +import com.jaytux.grader.ui.PeerEvalsGradingView +import com.jaytux.grader.ui.SolosGradingTitle +import com.jaytux.grader.ui.SolosGradingView +import com.jaytux.grader.viewmodel.Navigator -data class UiRoute(val heading: String, val content: @Composable (push: (UiRoute) -> Unit) -> Unit) +object Home : Navigator.IDestination +data class EditionDetail(val ed: Edition, val course: Course) : Navigator.IDestination +data class GroupGrading(val course: Course, val edition: Edition, val assignment: BaseAssignment) : Navigator.IDestination +data class SoloGrading(val course: Course, val edition: Edition, val assignment: BaseAssignment) : Navigator.IDestination +data class PeerEvalGrading(val course: Course, val edition: Edition, val assignment: BaseAssignment) : Navigator.IDestination @Composable -@Preview fun App() { MaterialTheme { - val courseList = CourseListState() - var stack by remember { - val start = UiRoute("Courses Overview") { CoursesView(courseList, it) } - mutableStateOf(listOf(start)) - } - - Column { - Surface(Modifier.fillMaxWidth(), color = MaterialTheme.colorScheme.primary, tonalElevation = 10.dp, shadowElevation = 10.dp) { - Row(Modifier.padding(10.dp)) { - IconButton({ stack = stack.toMutableList().also { it.removeLast() } }, enabled = stack.size >= 2) { - Icon(ChevronLeft, "Back", Modifier.size(MaterialTheme.typography.headlineLarge.fontSize.toDp())) - } - Text(stack.last().heading, Modifier.align(Alignment.CenterVertically), style = MaterialTheme.typography.headlineLarge) - } - } - Surface(Modifier.fillMaxSize()) { - Box { - stack.last().content { stack += (it) } - } - } + Navigator.NavHost(Home) { + composable({ HomeTitle() }) { _, token -> HomeView(token) } + composable({ EditionTitle(it) }) { data, token -> EditionView(data, token) } + composable({ GroupsGradingTitle(it) }) { data, token -> GroupsGradingView(data, token) } + composable({ SolosGradingTitle(it) }) { data, token -> SolosGradingView(data, token) } + composable({ PeerEvalsGradingTitle(it) }) { data, token -> PeerEvalsGradingView(data, token) } } } } \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/Either.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/Either.kt new file mode 100644 index 0000000..9f18628 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/Either.kt @@ -0,0 +1,48 @@ +package com.jaytux.grader + +sealed class Either { + class Error(val error: E) : Either() { + override fun toString(): String = "Error($error)" + } + class Value(val value: V) : Either() { + override fun toString(): String = "Value($value)" + } + + fun isError() = this is Error + fun isValue() = this is Value + + fun map(f: (V) -> R) = when(this) { + is Error -> this + is Value -> Value(f(value)) + } + + suspend fun mapSuspend(f: suspend (V) -> R) = when(this) { + is Error -> this + is Value -> Value(f(value)) + } + + fun mapError(f: (E) -> R) = when(this) { + is Error -> Error(f(error)) + is Value -> this + } + + suspend fun mapErrorSuspend(f: suspend (E) -> R) = when(this) { + is Error -> Error(f(error)) + is Value -> this + } + + fun fold(fError: (E) -> R, fValue: (V) -> R): R = when(this) { + is Error -> fError(error) + is Value -> fValue(value) + } + + suspend fun foldSuspend(fError: suspend (E) -> R, fValue: suspend (V) -> R): R = when(this) { + is Error -> fError(error) + is Value -> fValue(value) + } + + companion object { + fun E.error(): Either = Error(this) + fun V.value(): Either = Value(this) + } +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/Util.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/Util.kt index 030f877..a837c20 100644 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/Util.kt +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/Util.kt @@ -1,10 +1,16 @@ package com.jaytux.grader +import androidx.compose.ui.platform.ClipEntry +import androidx.compose.ui.platform.Clipboard import androidx.compose.ui.platform.ClipboardManager import androidx.compose.ui.text.AnnotatedString +import com.jaytux.grader.data.Database import com.mohamedrejeb.richeditor.model.RichTextState import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch +import java.time.Clock +import java.time.LocalDateTime +import java.util.prefs.Preferences fun String.maxN(n: Int): String { return if (this.length > n) { @@ -14,10 +20,25 @@ fun String.maxN(n: Int): String { } } -fun RichTextState.toClipboard(clip: ClipboardManager) { +suspend fun RichTextState.toClipboard(clip: ClipboardManager) { clip.setText(AnnotatedString(this.toMarkdown())) } -fun RichTextState.loadClipboard(clip: ClipboardManager, scope: CoroutineScope) { +suspend fun RichTextState.loadClipboard(clip: ClipboardManager, scope: CoroutineScope) { scope.launch { setMarkdown(clip.getText()?.text ?: "") } -} \ No newline at end of file +} + +object Preferences { + private val _p = Preferences.userNodeForPackage(this::class.java) + + operator fun get(key: String): String? = _p.get(key, null) + operator fun set(key: String, value: String) { + _p.put(key, value) + } + + var exportPath + get() = get("exportPath") ?: System.getProperty("user.home") + "/grader_export" + set(value) { set("exportPath", value) } +} + +infix fun Pair.app(x: T3) = Triple(first, second, x) diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/DSL.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/DSL.kt deleted file mode 100644 index 6f68497..0000000 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/DSL.kt +++ /dev/null @@ -1,145 +0,0 @@ -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 -import org.jetbrains.exposed.sql.kotlin.datetime.datetime - -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 contact = varchar("contact", 50) - val note = text("note") -} - -object GroupStudents : UUIDTable("grpStudents") { - val groupId = reference("group_id", Groups.id) - val studentId = reference("student_id", Students.id) - val role = varchar("role", 50).nullable() - - init { - uniqueIndex(groupId, studentId) // can't figure out how to make this a composite key - } -} - -object EditionStudents : Table("editionStudents") { - 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 number = integer("number").nullable() - val name = varchar("name", 50) - val assignment = text("assignment") - val deadline = datetime("deadline") - val globalCriterion = reference("global_crit", GroupAssignmentCriteria.id) -} - -object GroupAssignmentCriteria : UUIDTable("grpAsCr") { - val assignmentId = reference("group_assignment_id", GroupAssignments.id) - val name = varchar("name", 50) - val desc = text("description") -} - -object SoloAssignments : UUIDTable("soloAssgmts") { - val editionId = reference("edition_id", Editions.id) - val number = integer("number").nullable() - val name = varchar("name", 50) - val assignment = text("assignment") - val deadline = datetime("deadline") - val globalCriterion = reference("global_crit", SoloAssignmentCriteria.id) -} - -object SoloAssignmentCriteria : UUIDTable("soloAsCr") { - val assignmentId = reference("solo_assignment_id", SoloAssignments.id) - val name = varchar("name", 50) - val desc = text("description") -} - -object PeerEvaluations : UUIDTable("peerEvals") { - val editionId = reference("edition_id", Editions.id) - val number = integer("number").nullable() - val name = varchar("name", 50) -} - -object GroupFeedbacks : CompositeIdTable("grpFdbks") { - val assignmentId = reference("group_assignment_id", GroupAssignments.id) - val criterionId = reference("criterion_id", GroupAssignmentCriteria.id) - val groupId = reference("group_id", Groups.id) - val feedback = text("feedback") - val grade = varchar("grade", 32) - - override val primaryKey = PrimaryKey(groupId, criterionId) -} - -object IndividualFeedbacks : CompositeIdTable("indivFdbks") { - val assignmentId = reference("group_assignment_id", GroupAssignments.id) - val criterionId = reference("criterion_id", GroupAssignmentCriteria.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(studentId, criterionId) -} - -object SoloFeedbacks : CompositeIdTable("soloFdbks") { - val assignmentId = reference("solo_assignment_id", SoloAssignments.id) - val criterionId = reference("criterion_id", SoloAssignmentCriteria.id) - val studentId = reference("student_id", Students.id) - val feedback = text("feedback") - val grade = varchar("grade", 32) - - override val primaryKey = PrimaryKey(studentId, criterionId) -} - -object PeerEvaluationContents : CompositeIdTable("peerEvalCnts") { - val peerEvaluationId = reference("peer_evaluation_id", PeerEvaluations.id) - val groupId = reference("group_id", Groups.id) - val content = text("content") - - override val primaryKey = PrimaryKey(peerEvaluationId, groupId) -} - -object StudentToGroupEvaluation : CompositeIdTable("stToGrEv") { - val peerEvaluationId = reference("peer_evaluation_id", PeerEvaluations.id) - val studentId = reference("student_id", Students.id) - val grade = varchar("grade", 32) - val note = text("note") - - override val primaryKey = PrimaryKey(peerEvaluationId, studentId) -} - -object StudentToStudentEvaluation : CompositeIdTable("stToStEv") { - val peerEvaluationId = reference("peer_evaluation_id", PeerEvaluations.id) - val studentIdFrom = reference("student_id_from", Students.id) - val studentIdTo = reference("student_id_to", Students.id) - val grade = varchar("grade", 32) - val note = text("note") - - override val primaryKey = PrimaryKey(peerEvaluationId, studentIdFrom, studentIdTo) -} \ 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 index f247bbe..bcedd60 100644 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/Database.kt +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/Database.kt @@ -1,42 +1,64 @@ package com.jaytux.grader.data -import MigrationUtils -import org.jetbrains.exposed.sql.Database -import org.jetbrains.exposed.sql.SchemaUtils -import org.jetbrains.exposed.sql.and -import org.jetbrains.exposed.sql.selectAll -import org.jetbrains.exposed.sql.transactions.transaction -import org.jetbrains.exposed.sql.update +import com.jaytux.grader.app +import com.jaytux.grader.data.v2.CategoricGrade +import com.jaytux.grader.data.v2.CategoricGradeOption +import com.jaytux.grader.data.v2.CategoricGradeOptions +import com.jaytux.grader.data.v2.CategoricGrades +import com.jaytux.grader.data.v2.Courses +import com.jaytux.grader.data.v2.NumericGrade +import com.jaytux.grader.data.v2.v2Tables +import dev.dirs.ProjectDirectories +import org.jetbrains.exposed.v1.jdbc.SchemaUtils +import org.jetbrains.exposed.v1.jdbc.transactions.transaction +import kotlin.getValue +import kotlin.io.path.Path +import kotlin.io.path.createDirectories +import kotlin.io.path.exists +import org.jetbrains.exposed.v1.jdbc.Database +import org.jetbrains.exposed.v1.jdbc.batchInsert +import org.jetbrains.exposed.v1.jdbc.transactions.TransactionManager object Database { + val dataDir: String = ProjectDirectories.from("com", "jaytux", "grader").dataDir.also { + val path = Path(it) + if(!path.exists()) path.createDirectories() + } val db by lazy { - val actual = Database.connect("jdbc:sqlite:file:./grader.db", "org.sqlite.JDBC") - transaction { - SchemaUtils.create( - Courses, Editions, Groups, - Students, GroupStudents, EditionStudents, - GroupAssignments, SoloAssignments, GroupAssignmentCriteria, SoloAssignmentCriteria, - GroupFeedbacks, IndividualFeedbacks, SoloFeedbacks, - PeerEvaluations, PeerEvaluationContents, StudentToStudentEvaluation, - StudentToGroupEvaluation - ) - - val migrate = MigrationUtils.statementsRequiredForDatabaseMigration( - Courses, Editions, Groups, - Students, GroupStudents, EditionStudents, - GroupAssignments, SoloAssignments, GroupAssignmentCriteria, SoloAssignmentCriteria, - GroupFeedbacks, IndividualFeedbacks, SoloFeedbacks, - PeerEvaluations, PeerEvaluationContents, StudentToStudentEvaluation, - StudentToGroupEvaluation, - withLogs = true - ) - - println(" --- Migration --- ") - migrate.forEach { println(it); exec(it) } - println(" --- End migration --- ") + val actual = Database.connect("jdbc:sqlite:file:${dataDir}/grader.db", "org.sqlite.JDBC") + transaction(actual) { + SchemaUtils.create(*v2Tables) } + actual } - fun init() { db } + fun init() { + TransactionManager.defaultDatabase = db + transaction { + if(CategoricGrade.count() == 0L) { + val (pf, af) = CategoricGrades.batchInsert(listOf("Pass/Fail", "Default A-F"), shouldReturnGeneratedValues = true) { + this[CategoricGrades.name] = it + }.map { + it[CategoricGrades.id] + } + + CategoricGradeOptions.batchInsert( + listOf("Pass", "Fail").mapIndexed { idx, it -> it to pf app idx } + + listOf("A (Excellent)", "B (Good)", "C (Satisfactory)", "D (Poor)", "F (Fail)").mapIndexed { idx, it -> it to af app idx } + ) { + this[CategoricGradeOptions.option] = it.first + this[CategoricGradeOptions.gradeId] = it.second + this[CategoricGradeOptions.index] = it.third + } + } + + if(NumericGrade.count() == 0L) { + NumericGrade.new { + name = "Max-20" + max = 20.0 + } + } + } + } } \ 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 deleted file mode 100644 index b585d90..0000000 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/Entities.kt +++ /dev/null @@ -1,139 +0,0 @@ -package com.jaytux.grader.data - -import com.jaytux.grader.data.GroupAssignment.Companion.referrersOn -import org.jetbrains.exposed.dao.Entity -import org.jetbrains.exposed.dao.EntityClass -import org.jetbrains.exposed.dao.id.EntityID -import java.util.UUID - -class Course(id: EntityID) : Entity(id) { - companion object : EntityClass(Courses) - - var name by Courses.name - val editions by Edition referrersOn Editions.courseId -} - -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 EditionStudents - val soloAssignments by SoloAssignment referrersOn SoloAssignments.editionId - val groupAssignments by GroupAssignment referrersOn GroupAssignments.editionId - val peerEvaluations by PeerEvaluation referrersOn PeerEvaluations.editionId -} - -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 - val studentRoles by GroupMember referrersOn GroupStudents.groupId -} - -class GroupMember(id: EntityID) : Entity(id) { - companion object : EntityClass(GroupStudents) - - var student by Student referencedOn GroupStudents.studentId - var group by Group referencedOn GroupStudents.groupId - var role by GroupStudents.role -} - -class Student(id: EntityID) : Entity(id) { - companion object : EntityClass(Students) - - var name by Students.name - var note by Students.note - var contact by Students.contact - val groups by Group via GroupStudents - val courses by Edition via EditionStudents -} - -class GroupAssignment(id: EntityID) : Entity(id) { - companion object : EntityClass(GroupAssignments) - - var edition by Edition referencedOn GroupAssignments.editionId - var number by GroupAssignments.number - var name by GroupAssignments.name - var assignment by GroupAssignments.assignment - var deadline by GroupAssignments.deadline - var globalCriterion by GroupAssignmentCriterion referencedOn GroupAssignments.globalCriterion - - val criteria by GroupAssignmentCriterion referrersOn GroupAssignmentCriteria.assignmentId -} - -class GroupAssignmentCriterion(id: EntityID) : Entity(id) { - companion object : EntityClass(GroupAssignmentCriteria) - - var assignment by GroupAssignment referencedOn GroupAssignmentCriteria.assignmentId - var name by GroupAssignmentCriteria.name - var description by GroupAssignmentCriteria.desc - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as GroupAssignmentCriterion - - if (name != other.name) return false - if (description != other.description) return false - - return true - } - - override fun hashCode(): Int { - var result = name.hashCode() - result = 31 * result + description.hashCode() - return result - } -} - -class SoloAssignment(id: EntityID) : Entity(id) { - companion object : EntityClass(SoloAssignments) - - var edition by Edition referencedOn SoloAssignments.editionId - var number by SoloAssignments.number - var name by SoloAssignments.name - var assignment by SoloAssignments.assignment - var deadline by SoloAssignments.deadline - var globalCriterion by SoloAssignmentCriterion referencedOn SoloAssignments.globalCriterion - - val criteria by SoloAssignmentCriterion referrersOn SoloAssignmentCriteria.assignmentId -} - -class SoloAssignmentCriterion(id: EntityID) : Entity(id) { - companion object : EntityClass(SoloAssignmentCriteria) - - var assignment by SoloAssignment referencedOn SoloAssignmentCriteria.assignmentId - var name by SoloAssignmentCriteria.name - var description by SoloAssignmentCriteria.desc - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as SoloAssignmentCriterion - - if (name != other.name) return false - if (description != other.description) return false - - return true - } - - override fun hashCode(): Int { - var result = name.hashCode() - result = 31 * result + description.hashCode() - return result - } -} - -class PeerEvaluation(id: EntityID) : Entity(id) { - companion object : EntityClass(PeerEvaluations) - - var edition by Edition referencedOn PeerEvaluations.editionId - var number by PeerEvaluations.number - var name by PeerEvaluations.name -} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/Exporter.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/Exporter.kt index 3e02a8f..65220ef 100644 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/Exporter.kt +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/Exporter.kt @@ -1,90 +1,118 @@ package com.jaytux.grader.data -import com.jaytux.grader.viewmodel.Assignment -import com.jaytux.grader.viewmodel.GroupAssignmentState -import io.github.vinceglb.filekit.PlatformFile - -class MdBuilder { - private val content = StringBuilder() - - fun appendHeader(text: String, level: Int = 1) { - require(level in 1..6) { "Header level must be between 1 and 6" } - content.appendLine() - content.appendLine("#".repeat(level) + " $text") - content.appendLine() - } - fun appendMd(text: String) { content.appendLine(text) } - fun appendParagraph(text: String, bold: Boolean = false, italic: Boolean = false) { - val formattedText = buildString { - if (bold) append("**") - if (italic) append("_") - append(text) - if (italic) append("_") - if (bold) append("**") - } - content.appendLine(formattedText) - content.appendLine() - } - - fun build(): String = content.toString() -} - -fun GroupAssignmentState.LocalGFeedback.exportTo(path: PlatformFile, assignment: GroupAssignment) { - val builder = MdBuilder() - builder.appendHeader("${assignment.name} Feedback for ${group.name}") - if(feedback.global != null && feedback.global.grade.isNotBlank()) { - val global = feedback.global.grade - builder.appendParagraph("Overall grade: ${feedback.global.grade}", true, true) - - individuals.forEach { (student, it) -> - val (_, data) = it - if(data.global != null && data.global.grade.isNotBlank() && data.global.grade != global) { - builder.appendParagraph("${student.name} grade: ${data.global.grade}", true, true) - } - } - } - - fun appendFeedback(heading: String, group: GroupAssignmentState.FeedbackEntry?, byStudent: List>) { - if(group != null || byStudent.isNotEmpty()) { - builder.appendHeader(heading, 2) - if(group != null) { - if(group.grade.isNotBlank()) { - builder.appendParagraph("Group grade: ${group.grade}", true, true) - } - if(group.feedback.isNotBlank()) { - builder.appendMd(group.feedback) - } - } - - byStudent.forEach { (student, it) -> - if(it.grade.isNotBlank() || it.feedback.isNotBlank()) builder.appendHeader(student.name, 3) - if(it.grade.isNotBlank()) { - builder.appendParagraph("Grade: ${it.grade}", true, true) - } - if(it.feedback.isNotBlank()) { - builder.appendMd(it.feedback) - } - } - } - } - - appendFeedback("Overall Feedback", feedback.global, - individuals.mapNotNull { it.second.second.global?.let { g -> it.first to g } } - ) - - val criteria = (feedback.byCriterion.map { (c, _) -> c } + - individuals.flatMap { (_, it) -> it.second.byCriterion.map { (c, _) -> c } }).distinctBy { it.id.value } - - criteria.forEach { c -> - appendFeedback( - c.name, - feedback.byCriterion.firstOrNull { it.criterion.id == c.id }?.entry, - individuals.mapNotNull { (student, it) -> - val entry = it.second.byCriterion.firstOrNull { it.criterion.id == c.id }?.entry - entry?.let { student to it } - } - ) - } - - path.file.writeText(builder.build()) -} \ No newline at end of file +//class MdBuilder { +// private val content = StringBuilder() +// +// fun appendHeader(text: String, level: Int = 1) { +// require(level in 1..6) { "Header level must be between 1 and 6" } +// content.appendLine() +// content.appendLine("#".repeat(level) + " $text") +// content.appendLine() +// } +// fun appendMd(text: String) { content.appendLine(text) } +// fun appendParagraph(text: String, bold: Boolean = false, italic: Boolean = false) { +// val formattedText = buildString { +// if (bold) append("**") +// if (italic) append("_") +// append(text) +// if (italic) append("_") +// if (bold) append("**") +// } +// content.appendLine(formattedText) +// content.appendLine() +// } +// +// fun build(title: String, scheme: String = "dark"): String = "${prologue(title, scheme)}\n\n${content.toString()}" +// private fun prologue(title: String, scheme: String = "dark") = """ +// --- +// title: $title +// date: ${Clock.System.now()} +// header-includes: +// - '' +// - '' +// --- +// """.trimIndent() +//} +// +//object Exporter { +// private fun MdBuilder.appendGroupFeedback(assignment: GroupAssignment, it: GroupAssignmentState.LocalGFeedback) { +// appendHeader("${assignment.name} (group: ${it.group.name})", 1) +// if (it.feedback.global != null && it.feedback.global.grade.isNotBlank()) { +// val global = it.feedback.global.grade +// appendParagraph("Overall grade: ${it.feedback.global.grade}", true, true) +// +// it.individuals.forEach { (student, it) -> +// val (_, data) = it +// if (data.global != null && data.global.grade.isNotBlank() && data.global.grade != global) { +// appendParagraph("${student.name} grade: ${data.global.grade}", true, true) +// } +// } +// } +// +// fun appendFeedback( +// heading: String, +// group: GroupAssignmentState.FeedbackEntry?, +// byStudent: List> +// ) { +// if (group != null || byStudent.isNotEmpty()) { +// appendHeader(heading, 2) +// if (group != null) { +// if (group.grade.isNotBlank()) { +// appendParagraph("Group grade: ${group.grade}", true, true) +// } +// if (group.feedback.isNotBlank()) { +// appendMd(group.feedback) +// } +// } +// +// byStudent.forEach { (student, it) -> +// if (it.grade.isNotBlank() || it.feedback.isNotBlank()) appendHeader(student.name, 3) +// if (it.grade.isNotBlank()) { +// appendParagraph("Grade: ${it.grade}", true, true) +// } +// if (it.feedback.isNotBlank()) { +// appendMd(it.feedback) +// } +// } +// } +// } +// +// appendFeedback( +// "Overall Feedback", it.feedback.global, +// it.individuals.mapNotNull { ind -> ind.second.second.global?.let { g -> ind.first to g } } +// ) +// +// val criteria = (it.feedback.byCriterion.map { (c, _) -> c } + +// it.individuals.flatMap { (_, x) -> x.second.byCriterion.map { (c, _) -> c } }).distinctBy { x -> x.id.value } +// +// criteria.forEach { c -> +// appendFeedback( +// c.name, +// it.feedback.byCriterion.firstOrNull { it.criterion.id == c.id }?.entry, +// it.individuals.mapNotNull { (student, s) -> +// val entry = s.second.byCriterion.firstOrNull { it.criterion.id == c.id }?.entry +// entry?.let { student to it } +// } +// ) +// } +// } +// +// private fun MdBuilder.outputTo(path: Path, title: String) { +// val contents = build(title) +// val buffer = Buffer() +// buffer.write(contents.toByteArray()) +// SystemFileSystem.sink(path, false).write(buffer, buffer.size) +// } +// +// fun GroupAssignmentState.LocalGFeedback.exportTo(path: Path, assignment: GroupAssignment) { +// val builder = MdBuilder() +// builder.appendGroupFeedback(assignment, this) +// builder.outputTo(path, "${assignment.name} (for group ${group.name})") +// } +// +// fun GroupAssignmentState.batchExport(dirPath: Path) { +// feedback.entities.value.forEach { (_, it) -> +// it.exportTo(dirPath / "${it.group.name} (${assignment.name}).md", assignment) +// } +// } +//} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/v2/DSLv2.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/v2/DSLv2.kt new file mode 100644 index 0000000..ea205bd --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/v2/DSLv2.kt @@ -0,0 +1,181 @@ +package com.jaytux.grader.data.v2 + +import org.jetbrains.exposed.v1.core.dao.id.CompositeIdTable +import org.jetbrains.exposed.v1.core.dao.id.java.UUIDTable +import org.jetbrains.exposed.v1.datetime.datetime + +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) + val archived = bool("archived").default(false) + + 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 contact = varchar("contact", 50) + val note = text("note") +} + +object GroupStudents : UUIDTable("grpStudents") { + val groupId = reference("group_id", Groups.id) + val studentId = reference("student_id", Students.id) + val role = varchar("role", 50).nullable() + + init { + uniqueIndex(groupId, studentId) + } +} + +object EditionStudents : CompositeIdTable("editionStudents") { + val editionId = reference("edition_id", Editions.id) + val studentId = reference("student_id", Students.id) + + override val primaryKey = PrimaryKey(editionId, studentId) +} + +object BaseAssignments : UUIDTable("baseAssgmts") { + val editionId = reference("edition_id", Editions.id) + val name = varchar("name", 50) + val assignment = text("assignment") + val globalCriterion = reference("global_crit", Criteria.id) + val deadline = datetime("deadline") + val number = integer("number").nullable() + val type = enumerationByName("type", 20, AssignmentType::class) +} + +object Criteria : UUIDTable("criteria") { + val assignmentId = reference("assignment_id", BaseAssignments.id) + val name = varchar("name", 50) + val desc = text("desc") + val gradeType = enumerationByName("grade_type", 20, GradeType::class) + val categoricGrade = reference("categoric_grade_id", CategoricGrades.id).nullable() + val numericGrade = reference("numeric_grade_id", NumericGrades.id).nullable() +} + +object GroupAssignments : UUIDTable("grpAssgmts") { + val baseAssignmentId = reference("base_assignment_id", BaseAssignments.id).uniqueIndex() +} + +object SoloAssignments : UUIDTable("soloAssgmts") { + val baseAssignmentId = reference("base_assignment_id", BaseAssignments.id).uniqueIndex() +} + +object BaseFeedbacks : UUIDTable("baseFeedbacks") { + val criterionId = reference("criterion_id", Criteria.id) + val feedback = text("feedback") + val gradeFreeText = varchar("grade_text", 32).nullable() + val gradeCategoric = reference("grade_categoric", CategoricGradeOptions.id).nullable() + val gradeNumeric = double("grade_numeric").nullable() +} + +object GroupFeedbacks : CompositeIdTable("grpFdbks") { + val groupId = reference("group_id", Groups.id) + val feedbackId = reference("feedback_id", BaseFeedbacks.id) + + override val primaryKey = PrimaryKey(groupId, feedbackId) +} + +object StudentOverrideFeedbacks : UUIDTable("studOvrFdbks") { + val groupId = reference("group_id", Groups.id) + val studentId = reference("student_id", Students.id) + val feedbackId = reference("feedback_id", BaseFeedbacks.id) + val overrides = reference("overrides", GroupFeedbacks.feedbackId) +} + +object SoloFeedbacks : CompositeIdTable("soloFdbks") { + val studentId = reference("student_id", Students.id) + val feedbackId = reference("feedback_id", BaseFeedbacks.id) + + override val primaryKey = PrimaryKey(studentId, feedbackId) +} + +object PeerEvaluations : UUIDTable("peerEvals") { + val baseAssignmentId = reference("base_assignment_id", BaseAssignments.id).uniqueIndex() +} + +object PeerEvaluationFeedbacks : CompositeIdTable("peerEvalFdbks") { + val groupId = reference("group_id", Groups.id) + val feedbackId = reference("feedback_id", BaseFeedbacks.id) + + override val primaryKey = PrimaryKey(groupId, feedbackId) +} + +object PeerEvaluationStudentOverrideFeedbacks : UUIDTable("peerEvalStudOvrFdbks") { + val groupId = reference("group_id", Groups.id) + val studentId = reference("student_id", Students.id) + val feedbackId = reference("feedback_id", BaseFeedbacks.id) + val overrides = reference("overrides", BaseFeedbacks.id) +} + +object PeerEvaluationS2GEvaluations : UUIDTable("peerEvalS2GEvals") { + val peerEvalId = reference("peer_eval_id", PeerEvaluations.id) + val studentId = reference("student_id", Students.id) + val groupId = reference("group_id", Groups.id) + val evaluationId = reference("evaluation_id", BaseFeedbacks.id) + + init { + uniqueIndex(peerEvalId, groupId, studentId) + } +} + +object PeerEvaluationS2SEvaluations : UUIDTable("peerEvalS2SEvals") { + val peerEvalId = reference("peer_eval_id", PeerEvaluations.id) + val studentId = reference("student_id", Students.id) + val evaluatedStudentId = reference("evaluated_student_id", Students.id) + val evaluationId = reference("evaluation_id", BaseFeedbacks.id) + + init { + uniqueIndex(peerEvalId, studentId, evaluatedStudentId) + } +} + +object CategoricGrades : UUIDTable("categoricGrades") { + val name = varchar("name", 50).uniqueIndex() +} + +object CategoricGradeOptions : UUIDTable("categoricGradeOpts") { + val gradeId = reference("grade_id", CategoricGrades.id) + val option = varchar("option", 50) + val index = integer("index") + + init { + uniqueIndex(gradeId, option) + } +} + +object NumericGrades : UUIDTable("numericGrades") { + val name = varchar("name", 50).uniqueIndex() + val max = double("max") +} + +enum class GradeType { + CATEGORIC, NUMERIC, PERCENTAGE, NONE +} + +enum class AssignmentType(val display: String) { + GROUP("Group Assignment"), SOLO("Individual Assignment"), PEER_EVALUATION("Peer Evaluation") +} + +val v2Tables = arrayOf( + Courses, Editions, Groups, Students, GroupStudents, EditionStudents, BaseAssignments, Criteria, GroupAssignments, + SoloAssignments, BaseFeedbacks, GroupFeedbacks, StudentOverrideFeedbacks, SoloFeedbacks, PeerEvaluations, + PeerEvaluationFeedbacks, PeerEvaluationStudentOverrideFeedbacks, PeerEvaluationS2GEvaluations, + PeerEvaluationS2SEvaluations, CategoricGrades, CategoricGradeOptions, NumericGrades +) \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/v2/Entitiesv2.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/v2/Entitiesv2.kt new file mode 100644 index 0000000..272fd41 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/v2/Entitiesv2.kt @@ -0,0 +1,190 @@ +package com.jaytux.grader.data.v2 + +import org.jetbrains.exposed.v1.dao.Entity +import org.jetbrains.exposed.v1.dao.EntityClass +import org.jetbrains.exposed.v1.core.dao.id.EntityID +import org.jetbrains.exposed.v1.dao.java.UUIDEntity +import org.jetbrains.exposed.v1.dao.java.UUIDEntityClass +import java.util.UUID + +class Course(id: EntityID) : UUIDEntity(id) { + companion object : UUIDEntityClass(Courses) + + var name by Courses.name + + val editions by Edition referrersOn Editions.courseId orderBy Editions.name +} + +class Edition(id: EntityID) : UUIDEntity(id) { + companion object : EntityClass(Editions) + + var course by Course referencedOn Editions.courseId + var name by Editions.name + var archived by Editions.archived + + val students by Student via EditionStudents orderBy Students.name + val groups by Group referrersOn Groups.editionId orderBy Groups.name + val assignments by BaseAssignment referrersOn BaseAssignments.editionId orderBy BaseAssignments.number +} + +class Group(id: EntityID) : UUIDEntity(id) { + companion object : EntityClass(Groups) + + var edition by Edition referencedOn Groups.editionId + var name by Groups.name + + val students by GroupStudent referrersOn GroupStudents.groupId + val feedbacks by BaseFeedback via GroupFeedbacks +} + +class Student(id: EntityID) : UUIDEntity(id) { + companion object : EntityClass(Students) + + var name by Students.name + var note by Students.note + var contact by Students.contact + + val editions by Edition via EditionStudents orderBy Editions.name + val groups by GroupStudent referrersOn GroupStudents.studentId +} + +class GroupStudent(id: EntityID) : UUIDEntity(id) { + companion object : EntityClass(GroupStudents) + + var student by Student referencedOn GroupStudents.studentId + var group by Group referencedOn GroupStudents.groupId + var role by GroupStudents.role +} + +class BaseAssignment(id: EntityID) : UUIDEntity(id) { + companion object : EntityClass(BaseAssignments) + + var name by BaseAssignments.name + var assignment by BaseAssignments.assignment + var globalCriterion by Criterion referencedOn BaseAssignments.globalCriterion + var deadline by BaseAssignments.deadline + var number by BaseAssignments.number + var edition by Edition referencedOn BaseAssignments.editionId + var type by BaseAssignments.type + + private val _asGroupAssignment by GroupAssignment referrersOn GroupAssignments.baseAssignmentId + private val _asSoloAssignment by SoloAssignment referrersOn SoloAssignments.baseAssignmentId + private val _asPeerEvaluation by PeerEvaluation referrersOn PeerEvaluations.baseAssignmentId + val asGroupAssignment get() = _asGroupAssignment.singleOrNull() + val asSoloAssignment get() = _asSoloAssignment.singleOrNull() + val asPeerEvaluation get() = _asPeerEvaluation.singleOrNull() + + val criteria by Criterion referrersOn Criteria.assignmentId orderBy Criteria.name + val nonBaseCriteria get() = criteria.filterNot { it.id.value == globalCriterion.id.value } +} + +class GroupAssignment(id: EntityID) : UUIDEntity(id) { + companion object : EntityClass(GroupAssignments) + + var base by BaseAssignment referencedOn GroupAssignments.baseAssignmentId +} + +class SoloAssignment(id: EntityID) : UUIDEntity(id) { + companion object : EntityClass(SoloAssignments) + + var base by BaseAssignment referencedOn SoloAssignments.baseAssignmentId +} + +class PeerEvaluation(id: EntityID) : UUIDEntity(id) { + companion object : EntityClass(PeerEvaluations) + + var base by BaseAssignment referencedOn PeerEvaluations.baseAssignmentId +} + +class CategoricGrade(id: EntityID) : UUIDEntity(id) { + companion object : EntityClass(CategoricGrades) + + var name by CategoricGrades.name + + val options by CategoricGradeOption referrersOn CategoricGradeOptions.gradeId orderBy CategoricGradeOptions.index +} + +class CategoricGradeOption(id: EntityID) : UUIDEntity(id) { + companion object : EntityClass(CategoricGradeOptions) + + var grade by CategoricGrade referencedOn CategoricGradeOptions.gradeId + var option by CategoricGradeOptions.option + var index by CategoricGradeOptions.index +} + +class NumericGrade(id: EntityID) : UUIDEntity(id) { + companion object : EntityClass(NumericGrades) + + var name by NumericGrades.name + var max by NumericGrades.max +} + +class Criterion(id: EntityID) : UUIDEntity(id) { + companion object : EntityClass(Criteria) + + var assignment by BaseAssignment referencedOn Criteria.assignmentId + var name by Criteria.name + var desc by Criteria.desc + var gradeType by Criteria.gradeType + var categoricGrade by CategoricGrade optionalReferencedOn Criteria.categoricGrade + var numericGrade by NumericGrade optionalReferencedOn Criteria.numericGrade + + val feedbacks by BaseFeedback referrersOn BaseFeedbacks.criterionId +} + +class BaseFeedback(id: EntityID) : UUIDEntity(id) { + companion object : EntityClass(BaseFeedbacks) + + var criterion by Criterion referencedOn BaseFeedbacks.criterionId + var feedback by BaseFeedbacks.feedback + var gradeFreeText by BaseFeedbacks.gradeFreeText + var gradeCategoric by CategoricGradeOption optionalReferencedOn BaseFeedbacks.gradeCategoric + var gradeNumeric by BaseFeedbacks.gradeNumeric + + private val _forStudentIfSolo by Student via SoloFeedbacks + private val _forGroupIfGroup by Group via GroupFeedbacks + private val _forGroupIfPeer by Group via PeerEvaluationFeedbacks + + val asSoloFeedback get() = _forStudentIfSolo.singleOrNull() + val asGroupFeedback get() = _forGroupIfGroup.singleOrNull() + val asPeerEvaluationFeedback get() = _forGroupIfPeer.singleOrNull() + + val forStudentsOverrideIfGroup by StudentOverrideFeedback referrersOn StudentOverrideFeedbacks.overrides + val forStudentsOverrideIfPeer by PeerEvaluationStudentOverrideFeedback referrersOn PeerEvaluationStudentOverrideFeedbacks.overrides +} + +class StudentOverrideFeedback(id: EntityID) : UUIDEntity(id) { + companion object : EntityClass(StudentOverrideFeedbacks) + + var group by Group referencedOn StudentOverrideFeedbacks.groupId + var student by Student referencedOn StudentOverrideFeedbacks.studentId + var feedback by BaseFeedback referencedOn StudentOverrideFeedbacks.feedbackId + var overrides by BaseFeedback referencedOn StudentOverrideFeedbacks.overrides +} + +class PeerEvaluationStudentOverrideFeedback(id: EntityID) : UUIDEntity(id) { + companion object : EntityClass(PeerEvaluationStudentOverrideFeedbacks) + + var group by Group referencedOn PeerEvaluationStudentOverrideFeedbacks.groupId + var student by Student referencedOn PeerEvaluationStudentOverrideFeedbacks.studentId + var feedback by BaseFeedback referencedOn PeerEvaluationStudentOverrideFeedbacks.feedbackId + var overrides by BaseFeedback referencedOn PeerEvaluationStudentOverrideFeedbacks.overrides +} + +class PeerEvaluationS2G(id: EntityID) : UUIDEntity(id) { + companion object : EntityClass(PeerEvaluationS2GEvaluations) + + var peerEvaluation by PeerEvaluation referencedOn PeerEvaluationS2GEvaluations.peerEvalId + var student by Student referencedOn PeerEvaluationS2GEvaluations.studentId + var group by Group referencedOn PeerEvaluationS2GEvaluations.groupId + var evaluation by BaseFeedback referencedOn PeerEvaluationS2GEvaluations.evaluationId +} + +class PeerEvaluationS2S(id: EntityID) : UUIDEntity(id) { + companion object : EntityClass(PeerEvaluationS2SEvaluations) + + var peerEvaluation by PeerEvaluation referencedOn PeerEvaluationS2SEvaluations.peerEvalId + var student by Student referencedOn PeerEvaluationS2SEvaluations.studentId + var evaluatedStudent by Student referencedOn PeerEvaluationS2SEvaluations.evaluatedStudentId + var evaluation by BaseFeedback referencedOn PeerEvaluationS2SEvaluations.evaluationId +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/v2/uml.md b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/v2/uml.md new file mode 100644 index 0000000..99f157c --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/data/v2/uml.md @@ -0,0 +1,157 @@ +```mermaid +erDiagram + COURSES { + uuid id PK + string name + } + + EDITIONS { + uuid id PK + uuid courseId FK + string name + } + COURSES ||--o{ EDITIONS : has + + GROUPS { + uuid id PK + uuid editionId FK + string name + } + EDITIONS ||--o{ GROUPS : has + + STUDENTS { + uuid id PK + string name + string contact + string note + } + EDITIONS }o--o{ STUDENTS : "has (through edition_students)" + + GROUP_STUDENTS { + uuid id PK + uuid groupId FK + uuid studentId FK + maybe(string) role + } + STUDENTS ||--o{ GROUP_STUDENTS : belongs_to + GROUPS ||--o{ GROUP_STUDENTS : has + + BASE_ASSIGNMENTS { + uuid id PK + uuid editionId FK + string name + string assignment + uuid globalCriterion FK + datetime deadline + maybe(int) number + } + EDITIONS ||--o{ BASE_ASSIGNMENTS : has + BASE_ASSIGNMENTS ||--|| CRITERIA : "global/main criterion" + + CRITERIA { + uuid id PK + uuid assignmentId FK + string name + string desc + GradeType gradeType + maybe(uuid) categoricGrade FK + maybe(uuid) numericGrade FK + } + CRITERIA ||--o{ BASE_ASSIGNMENTS : belongs_to + CRITERIA o|--o{ CATEGORIC_GRADES : "if categoric" + CRITERIA o|--o{ NUMERIC_GRADES : "if numeric" + + GROUP_ASSIGNMENTS { + uuid id PK + uuid baseAssignmentId FK + } + BASE_ASSIGNMENTS ||--o{ GROUP_ASSIGNMENTS : is + + SOLO_ASSIGNMENTS { + uuid id PK + uuid baseAssignmentId FK + } + BASE_ASSIGNMENTS ||--o{ SOLO_ASSIGNMENTS : is + + BASE_FEEDBACKS { + uuid id PK + uuid criterionId FK + string feedback + maybe(string) gradeFreeText + maybe(uuid) gradeCategoric FK + maybe(double) gradeNumeric + } + CRITERIA ||--o{ BASE_FEEDBACKS : has + GROUPS }o--o{ BASE_FEEDBACKS : "has (through group_feedbacks)" + STUDENTS }o--o{ BASE_FEEDBACKS : "has (through solo_feedbacks)" + CATEGORIC_GRADES |o--o{ BASE_FEEDBACKS : "if categoric" + + STUDENT_OVERRIDE_FEEDBACKS { + uuid id PK + uuid groupId FK + uuid studentId FK + uuid feedbackId FK + } + GROUPS }o--|| STUDENT_OVERRIDE_FEEDBACKS : "original feedback" + STUDENTS }o--|| STUDENT_OVERRIDE_FEEDBACKS : "overridden for" + BASE_FEEDBACKS ||--o{ STUDENT_OVERRIDE_FEEDBACKS : has + + PEER_EVALUATIONS { + uuid id PK + uuid baseAssignmentId FK + } + BASE_ASSIGNMENTS ||--o{ PEER_EVALUATIONS : has + GROUPS }o--o{ PEER_EVALUATIONS : "has (through peer_evaluation_groups)" + + PEER_EVALUATION_STUDENT_OVERRIDE_FEEDBACKS { + uuid id PK + uuid groupId FK + uuid studentId FK + uuid feedbackId FK + } + GROUPS }o--|| PEER_EVALUATION_STUDENT_OVERRIDE_FEEDBACKS : "original feedback" + STUDENTS }o--|| PEER_EVALUATION_STUDENT_OVERRIDE_FEEDBACKS : "overridden for" + BASE_FEEDBACKS ||--o{ PEER_EVALUATION_STUDENT_OVERRIDE_FEEDBACKS : has + + PEER_EVALUATION_S2G_EVALUATIONS { + uuid id PK + uuid peerEvalId FK + uuid studentId FK + uuid groupId FK + uuid evaluationId FK + } + PEER_EVALUATIONS }o--|| PEER_EVALUATION_S2G_EVALUATIONS : has + STUDENTS }o--|| PEER_EVALUATION_S2G_EVALUATIONS : "evaluates" + GROUPS }o--|| PEER_EVALUATION_S2G_EVALUATIONS : "is evaluated" + BASE_FEEDBACKS ||--o{ PEER_EVALUATION_S2G_EVALUATIONS : "evaluation" + + PEER_EVALUATION_S2S_EVALUATIONS { + uuid id PK + uuid peerEvalId FK + uuid studentId FK + uuid evaluatedStudentId FK + uuid evaluationId FK + } + PEER_EVALUATIONS }o--|| PEER_EVALUATION_S2S_EVALUATIONS : has + STUDENTS }o--|| PEER_EVALUATION_S2S_EVALUATIONS : "evaluates" + STUDENTS }o--|| PEER_EVALUATION_S2S_EVALUATIONS : "is evaluated" + BASE_FEEDBACKS ||--o{ PEER_EVALUATION_S2S_EVALUATIONS : "evaluation" + + CATEGORIC_GRADES { + uuid id PK + string name + } + + CATEGORIC_GRADE_OPTIONS { + uuid id PK + uuid gradeId FK + string option + } + CATEGORIC_GRADES ||--o{ CATEGORIC_GRADE_OPTIONS : has + + NUMERIC_GRADES { + uuid id PK + string name + double max + } +``` \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Assignments.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Assignments.kt index 4ddc5a7..13ffb46 100644 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Assignments.kt +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Assignments.kt @@ -1,721 +1,715 @@ package com.jaytux.grader.ui -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.* -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.TransformOrigin -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.layout.layout -import androidx.compose.ui.text.font.FontStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.rememberTextMeasurer -import androidx.compose.ui.unit.Constraints -import androidx.compose.ui.unit.dp -import com.jaytux.grader.data.GroupAssignmentCriterion -import com.jaytux.grader.data.SoloAssignmentCriterion -import com.jaytux.grader.data.Student -import com.jaytux.grader.data.exportTo -import com.jaytux.grader.maxN -import com.jaytux.grader.viewmodel.GroupAssignmentState -import com.jaytux.grader.viewmodel.PeerEvaluationState -import com.jaytux.grader.viewmodel.SoloAssignmentState -import com.mohamedrejeb.richeditor.model.rememberRichTextState -import com.mohamedrejeb.richeditor.ui.material3.OutlinedRichTextEditor -import io.github.vinceglb.filekit.dialogs.compose.rememberFileSaverLauncher -import kotlinx.coroutines.launch -import kotlinx.datetime.LocalDateTime -@Composable -fun GroupAssignmentView(state: GroupAssignmentState) { - val task by state.task - val deadline by state.deadline - val allFeedback by state.feedback.entities - val criteria by state.criteria.entities - - var idx by remember(state) { mutableStateOf(0) } - - Column(Modifier.padding(10.dp)) { - if(allFeedback.any { it.second.feedback == null }) { - Text("Groups in bold have no feedback yet.", fontStyle = FontStyle.Italic) - } - else { - Text("All groups have feedback.", fontStyle = FontStyle.Italic) - } - - TabRow(idx) { - Tab(idx == 0, { idx = 0 }) { Text("Task and Criteria") } - allFeedback.forEachIndexed { i, it -> - val (group, feedback) = it - Tab(idx == i + 1, { idx = i + 1 }) { - Text(group.name, fontWeight = feedback.feedback?.let { FontWeight.Normal } ?: FontWeight.Bold) - } - } - } - - if(idx == 0) { - groupTaskWidget( - task, deadline, criteria, - onSetTask = { state.updateTask(it) }, - onSetDeadline = { state.updateDeadline(it) }, - onAddCriterion = { state.addCriterion(it) }, - onModCriterion = { c, n, d -> state.updateCriterion(c, n, d) }, - onRmCriterion = { state.deleteCriterion(it) } - ) - } - else { - groupFeedback(state, allFeedback[idx - 1].second) - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun groupTaskWidget( - taskMD: String, - deadline: LocalDateTime, - criteria: List, - onSetTask: (String) -> Unit, - onSetDeadline: (LocalDateTime) -> Unit, - onAddCriterion: (name: String) -> Unit, - onModCriterion: (cr: GroupAssignmentCriterion, name: String, desc: String) -> Unit, - onRmCriterion: (cr: GroupAssignmentCriterion) -> Unit -) { - var critIdx by remember { mutableStateOf(0) } - var adding by remember { mutableStateOf(false) } - var confirming by remember { mutableStateOf(false) } - - Row { - Surface(Modifier.weight(0.25f), tonalElevation = 10.dp) { - Column(Modifier.padding(10.dp)) { - LazyColumn(Modifier.weight(1f)) { - item { - Surface( - Modifier.fillMaxWidth().clickable { critIdx = 0 }, - tonalElevation = if (critIdx == 0) 50.dp else 0.dp, - shape = MaterialTheme.shapes.medium - ) { - Text("Assignment", Modifier.padding(5.dp), fontStyle = FontStyle.Italic) - } - } - - itemsIndexed(criteria) { i, crit -> - Surface( - Modifier.fillMaxWidth().clickable { critIdx = i + 1 }, - tonalElevation = if (critIdx == i + 1) 50.dp else 0.dp, - shape = MaterialTheme.shapes.medium - ) { - Text(crit.name, Modifier.padding(5.dp)) - } - } - } - Button({ adding = true }, Modifier.align(Alignment.CenterHorizontally).fillMaxWidth()) { - Text("Add evaluation criterion") - } - } - } - Box(Modifier.weight(0.75f).padding(10.dp)) { - if (critIdx == 0) { - val updTask = rememberRichTextState() - - LaunchedEffect(taskMD) { updTask.setMarkdown(taskMD) } - - Column { - Row { - DateTimePicker(deadline, onSetDeadline) - } - RichTextField(updTask, Modifier.fillMaxWidth().weight(1f)) { Text("Task") } - CancelSaveRow( - true, - { updTask.setMarkdown(taskMD) }, - "Reset", - "Update" - ) { onSetTask(updTask.toMarkdown()) } - } - } - else { - val crit = criteria[critIdx - 1] - var name by remember(crit) { mutableStateOf(crit.name) } - var desc by remember(crit) { mutableStateOf(crit.description) } - - Column { - Row { - OutlinedTextField(name, { name = it }, Modifier.weight(0.8f)) - Spacer(Modifier.weight(0.1f)) - Button({ onModCriterion(crit, name, desc) }, Modifier.weight(0.1f)) { - Text("Update") - } - } - OutlinedTextField( - desc, { desc = it }, Modifier.fillMaxWidth().weight(1f), - label = { Text("Description") }, - singleLine = false, - minLines = 5 - ) - Button({ confirming = true }, Modifier.fillMaxWidth()) { - Text("Remove criterion") - } - } - } - } - } - - if(adding) { - AddStringDialog( - "Evaluation criterion name", criteria.map{ it.name }, { adding = false } - ) { onAddCriterion(it) } - } - - if(confirming && critIdx != 0) { - ConfirmDeleteDialog( - "an evaluation criterion", - { confirming = false }, { onRmCriterion(criteria[critIdx - 1]); critIdx = 0 } - ) { - Text(criteria[critIdx - 1].name) - } - } -} - -@Composable -fun groupFeedback(state: GroupAssignmentState, fdbk: GroupAssignmentState.LocalGFeedback) { - val (group, feedback, individual) = fdbk - var studentIdx by remember(fdbk) { mutableStateOf(0) } - var critIdx by remember(fdbk) { mutableStateOf(0) } - val criteria by state.criteria.entities - val suggestions by state.autofill.entities - val exporting by remember { mutableStateOf(false) } - - val onSave = { grade: String, fdbk: String -> - when { - studentIdx == 0 && critIdx == 0 -> state.upsertGroupFeedback(group, fdbk, grade) - studentIdx == 0 && critIdx != 0 -> state.upsertGroupFeedback(group, fdbk, grade, criteria[critIdx - 1]) - studentIdx != 0 && critIdx == 0 -> state.upsertIndividualFeedback(individual[studentIdx - 1].first, group, fdbk, grade) - else -> state.upsertIndividualFeedback(individual[studentIdx - 1].first, group, fdbk, grade, criteria[critIdx - 1]) - } - } - - val scope = rememberCoroutineScope() - val exporter = rememberFileSaverLauncher { file -> - file?.let { - scope.launch { fdbk.exportTo(it, state.assignment) } - } - } - - val critGrade: (Int) -> String? = { crit: Int -> - when { - studentIdx == 0 && crit == 0 -> feedback.global?.grade?.ifBlank { null } - studentIdx == 0 && crit != 0 -> feedback.byCriterion[crit - 1].entry?.grade?.ifBlank { null } - studentIdx != 0 && crit == 0 -> individual[studentIdx - 1].second.second.global?.grade?.ifBlank { null } - else -> individual[studentIdx - 1].second.second.byCriterion[crit - 1].entry?.grade?.ifBlank { null } - }.also { println("Mapping criterion #${crit} to grade ${it}") } - } - - Row { - Surface(Modifier.weight(0.25f), tonalElevation = 10.dp) { - Column(Modifier.padding(10.dp)) { - LazyColumn(Modifier.weight(1f)) { - item { - Surface( - Modifier.fillMaxWidth().clickable { studentIdx = 0 }, - tonalElevation = if (studentIdx == 0) 50.dp else 0.dp, - shape = MaterialTheme.shapes.medium - ) { - Text("Group feedback", Modifier.padding(5.dp), fontStyle = FontStyle.Italic) - } - } - - itemsIndexed(individual.toList()) { i, (student, details) -> - val (role, _) = details - Surface( - Modifier.fillMaxWidth().clickable { studentIdx = i + 1 }, - tonalElevation = if (studentIdx == i + 1) 50.dp else 0.dp, - shape = MaterialTheme.shapes.medium - ) { - Text("${student.name} (${role ?: "no role"})", Modifier.padding(5.dp)) - } - } - } - - Button( - { exporter.launch("${state.assignment.name} (${fdbk.group.name})", "md") }, - Modifier.align(Alignment.CenterHorizontally).fillMaxWidth() - ) { - Text("Export group feedback") - } - } - } - - Column(Modifier.weight(0.75f).padding(10.dp)) { - TabRow(critIdx) { - Tab(critIdx == 0, { critIdx = 0 }) { - Text( - "General feedback", - Modifier.padding(5.dp), - fontStyle = FontStyle.Italic - ) - } - criteria.forEachIndexed { i, c -> - Tab(critIdx == i + 1, { critIdx = i + 1 }) { - Text( - c.name, - Modifier.padding(5.dp) - ) - } - } - } - - Spacer(Modifier.height(5.dp)) - - groupFeedbackPane( - criteria, critIdx, { critIdx = it }, - when { - studentIdx == 0 && critIdx == 0 -> feedback.global - studentIdx == 0 && critIdx != 0 -> feedback.byCriterion[critIdx - 1].entry - studentIdx != 0 && critIdx == 0 -> individual[studentIdx - 1].second.second.global - else -> individual[studentIdx - 1].second.second.byCriterion[critIdx - 1].entry - }, - suggestions, onSave, - if(critIdx == 0 && criteria.isNotEmpty()) criteria.mapIndexed { idx, it -> it.name to critGrade(idx + 1) } else null, - key = studentIdx to critIdx - ) - } - } -} - -@Composable -fun groupFeedbackPane( - criteria: List, - currentCriterion: Int, - onSelectCriterion: (Int) -> Unit, - rawFeedback: GroupAssignmentState.FeedbackEntry?, - autofill: List, - onSave: (String, String) -> Unit, - critGrades: List>? = null, - modifier: Modifier = Modifier, - key: Any? = null -) { - var grade by remember(rawFeedback, key) { mutableStateOf(rawFeedback?.grade ?: "") } - val feedback = rememberRichTextState() - - LaunchedEffect(currentCriterion, criteria, rawFeedback, key) { - feedback.setMarkdown(rawFeedback?.feedback ?: "") - } - - Column(modifier) { - Row { - Text("Grade: ", Modifier.align(Alignment.CenterVertically)) - OutlinedTextField(grade, { grade = it }, Modifier.weight(0.2f)) - Spacer(Modifier.weight(0.6f)) - Button( - { onSave(grade, feedback.toMarkdown()) }, - Modifier.weight(0.2f).align(Alignment.CenterVertically) - ) { - Text("Save") - } - } - Spacer(Modifier.height(5.dp)) - Row { - RichTextField(feedback, outerModifier = Modifier.weight(0.7f).fillMaxHeight()) { Text("Feedback") } - critGrades?.let { grades -> - Spacer(Modifier.width(10.dp)) - LazyColumn(Modifier.weight(0.3f)) { - item { - Text("Criteria grades", Modifier.padding(5.dp), style = MaterialTheme.typography.headlineMedium) - } - items(grades) { (crit, grade) -> - Column { - Text(crit, Modifier.padding(5.dp), fontWeight = FontWeight.Bold) - Row { - Spacer(Modifier.width(5.dp)) - if(grade == null) Text("(no grade yet)", Modifier.padding(5.dp), fontStyle = FontStyle.Italic) - else Text(grade, Modifier.padding(5.dp)) - } - Spacer(Modifier.width(10.dp)) - } - } - } - } - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun SoloAssignmentView(state: SoloAssignmentState) { - val task by state.task - val deadline by state.deadline - val suggestions by state.autofill.entities - val grades by state.feedback.entities - val criteria by state.criteria.entities - - var tab by remember(state) { mutableStateOf(0) } - var idx by remember(state, tab) { mutableStateOf(0) } - var critIdx by remember(state, tab, idx) { mutableStateOf(0) } - var adding by remember(state, tab) { mutableStateOf(false) } - var confirming by remember(state, tab) { mutableStateOf(false) } - - val updateGrade = { grade: String -> - state.upsertFeedback( - grades[idx].first, - if(critIdx == 0) grades[idx].second.global?.feedback else grades[idx].second.byCriterion[critIdx - 1].second?.feedback, - grade, - if(critIdx == 0) null else criteria[critIdx - 1] - ) - } - - val updateFeedback = { feedback: String -> - state.upsertFeedback( - grades[idx].first, - feedback, - if(critIdx == 0) grades[idx].second.global?.grade else grades[idx].second.byCriterion[critIdx - 1].second?.grade, - if(critIdx == 0) null else criteria[critIdx - 1] - ) - } - - Column(Modifier.padding(10.dp)) { - Row { - Surface(Modifier.weight(0.25f), tonalElevation = 10.dp) { - Column(Modifier.padding(10.dp)) { - TabRow(tab) { - Tab(tab == 0, { tab = 0 }) { Text("Task/Criteria") } - Tab(tab == 1, { tab = 1 }) { Text("Students") } - } - - LazyColumn(Modifier.weight(1f)) { - if (tab == 0) { - item { - Surface( - Modifier.fillMaxWidth().clickable { idx = 0 }, - tonalElevation = if (idx == 0) 50.dp else 0.dp, - shape = MaterialTheme.shapes.medium - ) { - Text("Assignment", Modifier.padding(5.dp), fontStyle = FontStyle.Italic) - } - } - - itemsIndexed(criteria) { i, crit -> - Surface( - Modifier.fillMaxWidth().clickable { idx = i + 1 }, - tonalElevation = if (idx == i + 1) 50.dp else 0.dp, - shape = MaterialTheme.shapes.medium - ) { - Text(crit.name, Modifier.padding(5.dp)) - } - } - } else { - itemsIndexed(grades.toList()) { i, (student, _) -> - Surface( - Modifier.fillMaxWidth().clickable { idx = i }, - tonalElevation = if (idx == i) 50.dp else 0.dp, - shape = MaterialTheme.shapes.medium - ) { - Text(student.name, Modifier.padding(5.dp)) - } - } - } - } - - if (tab == 0) { - Button({ adding = true }, Modifier.align(Alignment.CenterHorizontally).fillMaxWidth()) { - Text("Add evaluation criterion") - } - } - } - } - - Column(Modifier.weight(0.75f).padding(10.dp)) { - if(tab == 0) { - if (idx == 0) { - val updTask = rememberRichTextState() - - LaunchedEffect(task) { updTask.setMarkdown(task) } - - Row { - DateTimePicker(deadline, { state.updateDeadline(it) }) - } - RichTextStyleRow(state = updTask) - OutlinedRichTextEditor( - state = updTask, - modifier = Modifier.fillMaxWidth().weight(1f), - singleLine = false, - minLines = 5, - label = { Text("Task") } - ) - CancelSaveRow( - true, - { updTask.setMarkdown(task) }, - "Reset", - "Update" - ) { state.updateTask(updTask.toMarkdown()) } - } else { - val crit = criteria[idx - 1] - var name by remember(crit) { mutableStateOf(crit.name) } - var desc by remember(crit) { mutableStateOf(crit.description) } - - Column { - Row { - OutlinedTextField(name, { name = it }, Modifier.weight(0.8f)) - Spacer(Modifier.weight(0.1f)) - Button({ state.updateCriterion(crit, name, desc) }, Modifier.weight(0.1f)) { - Text("Update") - } - } - OutlinedTextField( - desc, { desc = it }, Modifier.fillMaxWidth().weight(1f), - label = { Text("Description") }, - singleLine = false, - minLines = 5 - ) - Button({ confirming = true }, Modifier.fillMaxWidth()) { - Text("Remove criterion") - } - } - } - } - else { - soloFeedbackPane( - criteria, critIdx, { critIdx = it }, grades[idx].second.global, - if(critIdx == 0) grades[idx].second.global else grades[idx].second.byCriterion[critIdx - 1].second, - suggestions, updateGrade, updateFeedback, - key = tab to idx - ) - } - } - } - } - - if(adding) { - AddStringDialog( - "Evaluation criterion name", criteria.map{ it.name }, { adding = false } - ) { state.addCriterion(it) } - } - - if(confirming && idx != 0) { - ConfirmDeleteDialog( - "an evaluation criterion", - { confirming = false }, { state.deleteCriterion(criteria[idx - 1]); idx = 0 } - ) { - Text(criteria[idx - 1].name) - } - } -} - -@Composable -fun soloFeedbackPane( - criteria: List, - currentCriterion: Int, - onSelectCriterion: (Int) -> Unit, - globFeedback: SoloAssignmentState.LocalFeedback?, - criterionFeedback: SoloAssignmentState.LocalFeedback?, - autofill: List, - onSetGrade: (String) -> Unit, - onSetFeedback: (String) -> Unit, - modifier: Modifier = Modifier, - key: Any? = null -) { - var grade by remember(globFeedback, key) { mutableStateOf(globFeedback?.grade ?: "") } - val feedback = rememberRichTextState() - - LaunchedEffect(currentCriterion, criteria, criterionFeedback, key) { - feedback.setMarkdown(criterionFeedback?.feedback ?: "") - } - Column(modifier) { - Row { - Text("Overall grade: ", Modifier.align(Alignment.CenterVertically)) - OutlinedTextField(grade, { grade = it }, Modifier.weight(0.2f)) - Spacer(Modifier.weight(0.6f)) - Button( - { onSetGrade(grade); onSetFeedback(feedback.toMarkdown()) }, - Modifier.weight(0.2f).align(Alignment.CenterVertically) - ) { - Text("Save") - } - } - TabRow(currentCriterion) { - Tab(currentCriterion == 0, { onSelectCriterion(0) }) { Text("General feedback", fontStyle = FontStyle.Italic) } - criteria.forEachIndexed { i, c -> - Tab(currentCriterion == i + 1, { onSelectCriterion(i + 1) }) { Text(c.name) } - } - } - Spacer(Modifier.height(5.dp)) - RichTextField(feedback, Modifier.fillMaxWidth().weight(1f)) { Text("Feedback") } - } -} - -@Composable -fun PeerEvaluationView(state: PeerEvaluationState) { - val contents by state.contents.entities - var idx by remember(state) { mutableStateOf(0) } - var editing by remember(state) { mutableStateOf?>(null) } - val measure = rememberTextMeasurer() - - val isSelected = { from: Student, to: Student? -> - editing?.let { (f, t, _) -> f == from && t == to } ?: false - } - - Column(Modifier.padding(10.dp)) { - TabRow(idx) { - contents.forEachIndexed { i, it -> - Tab(idx == i, { idx = i; editing = null }) { Text(it.group.name) } - } - } - Spacer(Modifier.height(10.dp)) - - Row { - val current = contents[idx] - val horScroll = rememberLazyListState() - val style = LocalTextStyle.current - val textLenMeasured = remember(state, idx) { - current.students.maxOf { (s, _) -> - measure.measure(s.name, style).size.width - } + 10 - } - val cellSize = 75.dp - - Column(Modifier.weight(0.5f)) { - Row { - Box { FromTo(textLenMeasured.dp) } - LazyRow(Modifier.height(textLenMeasured.dp), state = horScroll) { - item { VLine() } - items(current.students) { (s, _) -> - Box( - Modifier.width(cellSize).height(textLenMeasured.dp), - contentAlignment = Alignment.TopCenter - ) { - var _h: Int = 0 - Text(s.name, Modifier.layout{ m, c -> - val p = m.measure(c.copy(minWidth = c.maxWidth, maxWidth = Constraints.Infinity)) - _h = p.height - layout(p.height, p.width) { p.place(0, 0) } - }.graphicsLayer { - rotationZ = -90f - transformOrigin = TransformOrigin(0f, 0.5f) - translationX = _h.toFloat() / 2f - translationY = textLenMeasured.dp.value - 15f - }) - } - } - item { VLine() } - item { - Box( - Modifier.width(cellSize).height(textLenMeasured.dp), - contentAlignment = Alignment.TopCenter - ) { - var _h: Int = 0 - Text("Group Rating", Modifier.layout{ m, c -> - val p = m.measure(c.copy(minWidth = c.maxWidth, maxWidth = Constraints.Infinity)) - _h = p.height - layout(p.height, p.width) { p.place(0, 0) } - }.graphicsLayer { - rotationZ = -90f - transformOrigin = TransformOrigin(0f, 0.5f) - translationX = _h.toFloat() / 2f - translationY = textLenMeasured.dp.value - 15f - }, fontWeight = FontWeight.Bold) - } - } - item { VLine() } - } - } - MeasuredLazyColumn(key = idx) { - measuredItem { HLine() } - items(current.students) { (from, role, glob, map) -> - Row(Modifier.height(cellSize)) { - Column(Modifier.width(textLenMeasured.dp).align(Alignment.CenterVertically)) { - Text(from.name, Modifier.width(textLenMeasured.dp)) - role?.let { r -> - Row { - Spacer(Modifier.width(10.dp)) - Text( - r, - style = MaterialTheme.typography.bodySmall, - fontStyle = FontStyle.Italic - ) - } - } - } - LazyRow(state = horScroll) { - item { VLine() } - items(map) { (to, entry) -> - PEGradeWidget(entry, - { editing = Triple(from, to, entry) }, { editing = null }, - isSelected(from, to), Modifier.size(cellSize, cellSize) - ) - } - item { VLine() } - item { - PEGradeWidget(glob, - { editing = Triple(from, null, glob) }, { editing = null }, - isSelected(from, null), Modifier.size(cellSize, cellSize)) - } - item { VLine() } - } - } - } - measuredItem { HLine() } - } - } - - Column(Modifier.weight(0.5f)) { - var groupLevel by remember(state, idx) { mutableStateOf(contents[idx].content) } - editing?.let { - Column(Modifier.weight(0.5f)) { - val (from, to, data) = it - - var sGrade by remember(editing) { mutableStateOf(data?.grade ?: "") } - var sMsg by remember(editing) { mutableStateOf(data?.feedback ?: "") } - - Box(Modifier.padding(5.dp)) { - to?.let { s2 -> - if(from == s2) - Text("Self-evaluation by ${from.name}", fontWeight = FontWeight.Bold) - else - Text("Evaluation of ${s2.name} by ${from.name}", fontWeight = FontWeight.Bold) - } ?: Text("Group-level evaluation by ${from.name}", fontWeight = FontWeight.Bold) - } - - Row { - Text("Grade: ", Modifier.align(Alignment.CenterVertically)) - OutlinedTextField(sGrade, { sGrade = it }, Modifier.weight(0.2f)) - Spacer(Modifier.weight(0.6f)) - Button( - { state.upsertIndividualFeedback(from, to, sGrade, sMsg); editing = null }, - Modifier.weight(0.2f).align(Alignment.CenterVertically), - enabled = sGrade.isNotBlank() || sMsg.isNotBlank() - ) { - Text("Save") - } - } - - OutlinedTextField( - sMsg, { sMsg = it }, Modifier.fillMaxWidth().weight(1f), - label = { Text("Feedback") }, - singleLine = false, - minLines = 5 - ) - } - } - - Column(Modifier.weight(0.5f)) { - Row { - Text("Group-level notes", Modifier.weight(1f).align(Alignment.CenterVertically), fontWeight = FontWeight.Bold) - Button( - { state.upsertGroupFeedback(current.group, groupLevel); editing = null }, - enabled = groupLevel != contents[idx].content - ) { Text("Update") } - } - - OutlinedTextField( - groupLevel, { groupLevel = it }, Modifier.fillMaxWidth().weight(1f), - label = { Text("Group-level notes") }, - singleLine = false, - minLines = 5 - ) - } - } - } - } -} \ No newline at end of file +//@Composable +//fun GroupAssignmentView(state: GroupAssignmentState) { +// val task by state.task +// val deadline by state.deadline +// val allFeedback by state.feedback.entities +// val criteria by state.criteria.entities +// +// var idx by remember(state) { mutableStateOf(0) } +// +// Column(Modifier.padding(10.dp)) { +// if(allFeedback.any { it.second.feedback == null }) { +// Text("Groups in bold have no feedback yet.", fontStyle = FontStyle.Italic) +// } +// else { +// Text("All groups have feedback.", fontStyle = FontStyle.Italic) +// } +// +// TabRow(idx) { +// Tab(idx == 0, { idx = 0 }) { Text("Task and Criteria") } +// allFeedback.forEachIndexed { i, it -> +// val (group, feedback) = it +// Tab(idx == i + 1, { idx = i + 1 }) { +// Text(group.name, fontWeight = feedback.feedback?.let { FontWeight.Normal } ?: FontWeight.Bold) +// } +// } +// } +// +// if(idx == 0) { +// groupTaskWidget( +// task, deadline, criteria, +// onSetTask = { state.updateTask(it) }, +// onSetDeadline = { state.updateDeadline(it) }, +// onAddCriterion = { state.addCriterion(it) }, +// onModCriterion = { c, n, d -> state.updateCriterion(c, n, d) }, +// onRmCriterion = { state.deleteCriterion(it) } +// ) +// } +// else { +// groupFeedback(state, allFeedback[idx - 1].second) +// } +// } +//} +// +//@OptIn(ExperimentalMaterial3Api::class) +//@Composable +//fun groupTaskWidget( +// taskMD: String, +// deadline: LocalDateTime, +// criteria: List, +// onSetTask: (String) -> Unit, +// onSetDeadline: (LocalDateTime) -> Unit, +// onAddCriterion: (name: String) -> Unit, +// onModCriterion: (cr: GroupAssignmentCriterion, name: String, desc: String) -> Unit, +// onRmCriterion: (cr: GroupAssignmentCriterion) -> Unit +//) { +// var critIdx by remember { mutableStateOf(0) } +// var adding by remember { mutableStateOf(false) } +// var confirming by remember { mutableStateOf(false) } +// +// Row { +// Surface(Modifier.weight(0.25f), tonalElevation = 10.dp) { +// Column(Modifier.padding(10.dp)) { +// LazyColumn(Modifier.weight(1f)) { +// item { +// Surface( +// Modifier.fillMaxWidth().clickable { critIdx = 0 }, +// tonalElevation = if (critIdx == 0) 50.dp else 0.dp, +// shape = MaterialTheme.shapes.medium +// ) { +// Text("Assignment", Modifier.padding(5.dp), fontStyle = FontStyle.Italic) +// } +// } +// +// itemsIndexed(criteria) { i, crit -> +// Surface( +// Modifier.fillMaxWidth().clickable { critIdx = i + 1 }, +// tonalElevation = if (critIdx == i + 1) 50.dp else 0.dp, +// shape = MaterialTheme.shapes.medium +// ) { +// Text(crit.name, Modifier.padding(5.dp)) +// } +// } +// } +// Button({ adding = true }, Modifier.align(Alignment.CenterHorizontally).fillMaxWidth()) { +// Text("Add evaluation criterion") +// } +// } +// } +// Box(Modifier.weight(0.75f).padding(10.dp)) { +// if (critIdx == 0) { +// val updTask = rememberRichTextState() +// +// LaunchedEffect(taskMD) { updTask.setMarkdown(taskMD) } +// +// Column { +// Row { +// DateTimePicker(deadline, onSetDeadline) +// } +// RichTextField(updTask, Modifier.fillMaxWidth().weight(1f)) { Text("Task") } +// CancelSaveRow( +// true, +// { updTask.setMarkdown(taskMD) }, +// "Reset", +// "Update" +// ) { onSetTask(updTask.toMarkdown()) } +// } +// } +// else { +// val crit = criteria[critIdx - 1] +// var name by remember(crit) { mutableStateOf(crit.name) } +// var desc by remember(crit) { mutableStateOf(crit.description) } +// +// Column { +// Row { +// OutlinedTextField(name, { name = it }, Modifier.weight(0.8f)) +// Spacer(Modifier.weight(0.1f)) +// Button({ onModCriterion(crit, name, desc) }, Modifier.weight(0.1f)) { +// Text("Update") +// } +// } +// OutlinedTextField( +// desc, { desc = it }, Modifier.fillMaxWidth().weight(1f), +// label = { Text("Description") }, +// singleLine = false, +// minLines = 5 +// ) +// Button({ confirming = true }, Modifier.fillMaxWidth()) { +// Text("Remove criterion") +// } +// } +// } +// } +// } +// +// if(adding) { +// AddStringDialog( +// "Evaluation criterion name", criteria.map{ it.name }, { adding = false } +// ) { onAddCriterion(it) } +// } +// +// if(confirming && critIdx != 0) { +// ConfirmDeleteDialog( +// "an evaluation criterion", +// { confirming = false }, { onRmCriterion(criteria[critIdx - 1]); critIdx = 0 } +// ) { +// Text(criteria[critIdx - 1].name) +// } +// } +//} +// +//@Composable +//fun groupFeedback(state: GroupAssignmentState, fdbk: GroupAssignmentState.LocalGFeedback) { +// val (group, feedback, individual) = fdbk +// var studentIdx by remember(fdbk) { mutableStateOf(0) } +// var critIdx by remember(fdbk) { mutableStateOf(0) } +// val criteria by state.criteria.entities +// val suggestions by state.autofill.entities +// +// val onSave = { grade: String, fdbk: String -> +// when { +// studentIdx == 0 && critIdx == 0 -> state.upsertGroupFeedback(group, fdbk, grade) +// studentIdx == 0 && critIdx != 0 -> state.upsertGroupFeedback(group, fdbk, grade, criteria[critIdx - 1]) +// studentIdx != 0 && critIdx == 0 -> state.upsertIndividualFeedback(individual[studentIdx - 1].first, group, fdbk, grade) +// else -> state.upsertIndividualFeedback(individual[studentIdx - 1].first, group, fdbk, grade, criteria[critIdx - 1]) +// } +// } +// +// val scope = rememberCoroutineScope() +// val exporter = rememberFileSaverLauncher { file -> +// file?.let { +// it.toKotlinxIoPath().parent?.let { path -> Preferences.set("exportPath", path.toString()) } +// scope.launch { fdbk.exportTo(it.toKotlinxIoPath(), state.assignment) } +// } +// } +// +// fun critGrade(crit: Int, student: Int = studentIdx): String? = when { +// student == 0 && crit == 0 -> feedback.global?.grade?.ifBlank { null } +// student == 0 && crit != 0 -> feedback.byCriterion[crit - 1].entry?.grade?.ifBlank { null } +// student != 0 && crit == 0 -> individual[student - 1].second.second.global?.grade?.ifBlank { null } +// else -> individual[student - 1].second.second.byCriterion[crit - 1].entry?.grade?.ifBlank { null } +// } +// +// Row { +// Surface(Modifier.weight(0.25f), tonalElevation = 10.dp) { +// Column(Modifier.padding(10.dp)) { +// LazyColumn(Modifier.weight(1f)) { +// item { +// Surface( +// Modifier.fillMaxWidth().clickable { studentIdx = 0 }, +// tonalElevation = if (studentIdx == 0) 50.dp else 0.dp, +// shape = MaterialTheme.shapes.medium +// ) { +// Text("Group feedback", Modifier.padding(5.dp), fontStyle = FontStyle.Italic) +// } +// } +// +// itemsIndexed(individual.toList()) { i, (student, details) -> +// val (role, _) = details +// Surface( +// Modifier.fillMaxWidth().clickable { studentIdx = i + 1 }, +// tonalElevation = if (studentIdx == i + 1) 50.dp else 0.dp, +// shape = MaterialTheme.shapes.medium +// ) { +// Text("${student.name} (${role ?: "no role"})", Modifier.padding(5.dp)) +// } +// } +// } +// +// Button( +// { exporter.launch("${state.assignment.name} (${fdbk.group.name})", "md", Preferences.get("exportPath")?.let { PlatformFile(it) }) }, +// Modifier.align(Alignment.CenterHorizontally).fillMaxWidth() +// ) { +// Text("Export group feedback") +// } +// } +// } +// +// Column(Modifier.weight(0.75f).padding(10.dp)) { +// TabRow(critIdx) { +// Tab(critIdx == 0, { critIdx = 0 }) { +// Text( +// "General feedback", +// Modifier.padding(5.dp), +// fontStyle = FontStyle.Italic +// ) +// } +// criteria.forEachIndexed { i, c -> +// Tab(critIdx == i + 1, { critIdx = i + 1 }) { +// Text( +// c.name, +// Modifier.padding(5.dp) +// ) +// } +// } +// } +// +// Spacer(Modifier.height(5.dp)) +// +// groupFeedbackPane( +// criteria, critIdx, { critIdx = it }, +// when { +// studentIdx == 0 && critIdx == 0 -> feedback.global +// studentIdx == 0 && critIdx != 0 -> feedback.byCriterion[critIdx - 1].entry +// studentIdx != 0 && critIdx == 0 -> individual[studentIdx - 1].second.second.global +// else -> individual[studentIdx - 1].second.second.byCriterion[critIdx - 1].entry +// }, +// suggestions, onSave, +// if(critIdx == 0 && criteria.isNotEmpty()) criteria.mapIndexed { idx, it -> it.name to critGrade(idx + 1) } else null, +// if(studentIdx != 0 && critIdx == 0 && criteria.isNotEmpty()) { +// criteria.mapIndexed { idx, it -> critGrade(idx + 1, 0) } +// } else null, +// if(studentIdx != 0 && critIdx == 0) critGrade(0, 0) else null, +// key = studentIdx to critIdx +// ) +// } +// } +//} +// +//@Composable +//fun groupFeedbackPane( +// criteria: List, +// currentCriterion: Int, +// onSelectCriterion: (Int) -> Unit, +// rawFeedback: GroupAssignmentState.FeedbackEntry?, +// autofill: List, +// onSave: (String, String) -> Unit, +// critGrades: List>? = null, +// groupCritGrades: List? = null, +// groupOverallGrade: String? = null, +// modifier: Modifier = Modifier, +// key: Any? = null +//) { +// var grade by remember(rawFeedback, key) { mutableStateOf(rawFeedback?.grade ?: "") } +// val feedback = rememberRichTextState() +// +// LaunchedEffect(currentCriterion, criteria, rawFeedback, key) { +// feedback.setMarkdown(rawFeedback?.feedback ?: "") +// } +// +// Column(modifier) { +// Row { +// Text("Grade: ", Modifier.align(Alignment.CenterVertically)) +// OutlinedTextField( +// grade, { grade = it }, Modifier.weight(0.45f), +// label = { Text(groupOverallGrade?.let { "Overall group grade: $it" } ?: "Grade") } +// ) +// Spacer(Modifier.weight(0.35f)) +// Button( +// { onSave(grade, feedback.toMarkdown()) }, +// Modifier.weight(0.2f).align(Alignment.CenterVertically) +// ) { +// Text("Save") +// } +// } +// Spacer(Modifier.height(5.dp)) +// Row { +// RichTextField(feedback, outerModifier = Modifier.weight(0.7f).fillMaxHeight()) { Text("Feedback") } +// critGrades?.let { grades -> +// Spacer(Modifier.width(10.dp)) +// LazyColumn(Modifier.weight(0.3f)) { +// item { +// Text("Criteria grades", Modifier.padding(5.dp), style = MaterialTheme.typography.headlineMedium) +// } +// itemsIndexed(grades) { idx, (crit, grade) -> +// Column { +// Text(crit, Modifier.padding(5.dp), fontWeight = FontWeight.Bold) +// Row { +// Spacer(Modifier.width(5.dp)) +// +// val (text, style) = if(grade == null || grade.isBlank()) { +// if(groupCritGrades == null || groupCritGrades[idx]?.isBlank() != false) { +// "(no grade yet)" +// } else { +// "Group grade: ${groupCritGrades[idx]}" +// } to FontStyle.Italic +// } else { +// if(groupCritGrades == null || groupCritGrades[idx]?.isBlank() != false) { +// grade to FontStyle.Normal +// } +// else { +// "$grade (group: ${groupCritGrades[idx]})" to FontStyle.Normal +// } +// } +// +// Text(text, Modifier.padding(5.dp), fontStyle = style) +// } +// Spacer(Modifier.width(10.dp)) +// } +// } +// } +// } +// } +// } +//} +// +//@OptIn(ExperimentalMaterial3Api::class) +//@Composable +//fun SoloAssignmentView(state: SoloAssignmentState) { +// val task by state.task +// val deadline by state.deadline +// val suggestions by state.autofill.entities +// val grades by state.feedback.entities +// val criteria by state.criteria.entities +// +// var tab by remember(state) { mutableStateOf(0) } +// var idx by remember(state, tab) { mutableStateOf(0) } +// var critIdx by remember(state, tab, idx) { mutableStateOf(0) } +// var adding by remember(state, tab) { mutableStateOf(false) } +// var confirming by remember(state, tab) { mutableStateOf(false) } +// +// val updateGrade = { grade: String -> +// state.upsertFeedback( +// grades[idx].first, +// if(critIdx == 0) grades[idx].second.global?.feedback else grades[idx].second.byCriterion[critIdx - 1].second?.feedback, +// grade, +// if(critIdx == 0) null else criteria[critIdx - 1] +// ) +// } +// +// val updateFeedback = { feedback: String -> +// state.upsertFeedback( +// grades[idx].first, +// feedback, +// if(critIdx == 0) grades[idx].second.global?.grade else grades[idx].second.byCriterion[critIdx - 1].second?.grade, +// if(critIdx == 0) null else criteria[critIdx - 1] +// ) +// } +// +// Column(Modifier.padding(10.dp)) { +// Row { +// Surface(Modifier.weight(0.25f), tonalElevation = 10.dp) { +// Column(Modifier.padding(10.dp)) { +// TabRow(tab) { +// Tab(tab == 0, { tab = 0 }) { Text("Task/Criteria") } +// Tab(tab == 1, { tab = 1 }) { Text("Students") } +// } +// +// LazyColumn(Modifier.weight(1f)) { +// if (tab == 0) { +// item { +// Surface( +// Modifier.fillMaxWidth().clickable { idx = 0 }, +// tonalElevation = if (idx == 0) 50.dp else 0.dp, +// shape = MaterialTheme.shapes.medium +// ) { +// Text("Assignment", Modifier.padding(5.dp), fontStyle = FontStyle.Italic) +// } +// } +// +// itemsIndexed(criteria) { i, crit -> +// Surface( +// Modifier.fillMaxWidth().clickable { idx = i + 1 }, +// tonalElevation = if (idx == i + 1) 50.dp else 0.dp, +// shape = MaterialTheme.shapes.medium +// ) { +// Text(crit.name, Modifier.padding(5.dp)) +// } +// } +// } else { +// itemsIndexed(grades.toList()) { i, (student, _) -> +// Surface( +// Modifier.fillMaxWidth().clickable { idx = i }, +// tonalElevation = if (idx == i) 50.dp else 0.dp, +// shape = MaterialTheme.shapes.medium +// ) { +// Text(student.name, Modifier.padding(5.dp)) +// } +// } +// } +// } +// +// if (tab == 0) { +// Button({ adding = true }, Modifier.align(Alignment.CenterHorizontally).fillMaxWidth()) { +// Text("Add evaluation criterion") +// } +// } +// } +// } +// +// Column(Modifier.weight(0.75f).padding(10.dp)) { +// if(tab == 0) { +// if (idx == 0) { +// val updTask = rememberRichTextState() +// +// LaunchedEffect(task) { updTask.setMarkdown(task) } +// +// Row { +// DateTimePicker(deadline, { state.updateDeadline(it) }) +// } +// RichTextStyleRow(state = updTask) +// OutlinedRichTextEditor( +// state = updTask, +// modifier = Modifier.fillMaxWidth().weight(1f), +// singleLine = false, +// minLines = 5, +// label = { Text("Task") } +// ) +// CancelSaveRow( +// true, +// { updTask.setMarkdown(task) }, +// "Reset", +// "Update" +// ) { state.updateTask(updTask.toMarkdown()) } +// } else { +// val crit = criteria[idx - 1] +// var name by remember(crit) { mutableStateOf(crit.name) } +// var desc by remember(crit) { mutableStateOf(crit.description) } +// +// Column { +// Row { +// OutlinedTextField(name, { name = it }, Modifier.weight(0.8f)) +// Spacer(Modifier.weight(0.1f)) +// Button({ state.updateCriterion(crit, name, desc) }, Modifier.weight(0.1f)) { +// Text("Update") +// } +// } +// OutlinedTextField( +// desc, { desc = it }, Modifier.fillMaxWidth().weight(1f), +// label = { Text("Description") }, +// singleLine = false, +// minLines = 5 +// ) +// Button({ confirming = true }, Modifier.fillMaxWidth()) { +// Text("Remove criterion") +// } +// } +// } +// } +// else { +// soloFeedbackPane( +// criteria, critIdx, { critIdx = it }, grades[idx].second.global, +// if(critIdx == 0) grades[idx].second.global else grades[idx].second.byCriterion[critIdx - 1].second, +// suggestions, updateGrade, updateFeedback, +// key = tab to idx +// ) +// } +// } +// } +// } +// +// if(adding) { +// AddStringDialog( +// "Evaluation criterion name", criteria.map{ it.name }, { adding = false } +// ) { state.addCriterion(it) } +// } +// +// if(confirming && idx != 0) { +// ConfirmDeleteDialog( +// "an evaluation criterion", +// { confirming = false }, { state.deleteCriterion(criteria[idx - 1]); idx = 0 } +// ) { +// Text(criteria[idx - 1].name) +// } +// } +//} +// +//@Composable +//fun soloFeedbackPane( +// criteria: List, +// currentCriterion: Int, +// onSelectCriterion: (Int) -> Unit, +// globFeedback: SoloAssignmentState.LocalFeedback?, +// criterionFeedback: SoloAssignmentState.LocalFeedback?, +// autofill: List, +// onSetGrade: (String) -> Unit, +// onSetFeedback: (String) -> Unit, +// modifier: Modifier = Modifier, +// key: Any? = null +//) { +// var grade by remember(globFeedback, key) { mutableStateOf(globFeedback?.grade ?: "") } +// val feedback = rememberRichTextState() +// +// LaunchedEffect(currentCriterion, criteria, criterionFeedback, key) { +// feedback.setMarkdown(criterionFeedback?.feedback ?: "") +// } +// Column(modifier) { +// Row { +// Text("Overall grade: ", Modifier.align(Alignment.CenterVertically)) +// OutlinedTextField(grade, { grade = it }, Modifier.weight(0.2f)) +// Spacer(Modifier.weight(0.6f)) +// Button( +// { onSetGrade(grade); onSetFeedback(feedback.toMarkdown()) }, +// Modifier.weight(0.2f).align(Alignment.CenterVertically) +// ) { +// Text("Save") +// } +// } +// TabRow(currentCriterion) { +// Tab(currentCriterion == 0, { onSelectCriterion(0) }) { Text("General feedback", fontStyle = FontStyle.Italic) } +// criteria.forEachIndexed { i, c -> +// Tab(currentCriterion == i + 1, { onSelectCriterion(i + 1) }) { Text(c.name) } +// } +// } +// Spacer(Modifier.height(5.dp)) +// RichTextField(feedback, Modifier.fillMaxWidth().weight(1f)) { Text("Feedback") } +// } +//} +// +//@Composable +//fun PeerEvaluationView(state: PeerEvaluationState) { +// val contents by state.contents.entities +// var idx by remember(state) { mutableStateOf(0) } +// var editing by remember(state) { mutableStateOf?>(null) } +// val measure = rememberTextMeasurer() +// +// val isSelected = { from: Student, to: Student? -> +// editing?.let { (f, t, _) -> f == from && t == to } ?: false +// } +// +// Column(Modifier.padding(10.dp)) { +// TabRow(idx) { +// contents.forEachIndexed { i, it -> +// Tab(idx == i, { idx = i; editing = null }) { Text(it.group.name) } +// } +// } +// Spacer(Modifier.height(10.dp)) +// +// Row { +// val current = contents[idx] +// val horScroll = rememberLazyListState() +// val style = LocalTextStyle.current +// val textLenMeasured = remember(state, idx) { +// current.students.maxOf { (s, _) -> +// measure.measure(s.name, style).size.width +// } + 10 +// } +// val cellSize = 75.dp +// +// Column(Modifier.weight(0.5f)) { +// Row { +// Box { FromTo(textLenMeasured.dp) } +// LazyRow(Modifier.height(textLenMeasured.dp), state = horScroll) { +// item { VLine() } +// items(current.students) { (s, _) -> +// Box( +// Modifier.width(cellSize).height(textLenMeasured.dp), +// contentAlignment = Alignment.TopCenter +// ) { +// var _h: Int = 0 +// Text(s.name, Modifier.layout{ m, c -> +// val p = m.measure(c.copy(minWidth = c.maxWidth, maxWidth = Constraints.Infinity)) +// _h = p.height +// layout(p.height, p.width) { p.place(0, 0) } +// }.graphicsLayer { +// rotationZ = -90f +// transformOrigin = TransformOrigin(0f, 0.5f) +// translationX = _h.toFloat() / 2f +// translationY = textLenMeasured.dp.value - 15f +// }) +// } +// } +// item { VLine() } +// item { +// Box( +// Modifier.width(cellSize).height(textLenMeasured.dp), +// contentAlignment = Alignment.TopCenter +// ) { +// var _h: Int = 0 +// Text("Group Rating", Modifier.layout{ m, c -> +// val p = m.measure(c.copy(minWidth = c.maxWidth, maxWidth = Constraints.Infinity)) +// _h = p.height +// layout(p.height, p.width) { p.place(0, 0) } +// }.graphicsLayer { +// rotationZ = -90f +// transformOrigin = TransformOrigin(0f, 0.5f) +// translationX = _h.toFloat() / 2f +// translationY = textLenMeasured.dp.value - 15f +// }, fontWeight = FontWeight.Bold) +// } +// } +// item { VLine() } +// } +// } +// MeasuredLazyColumn(key = idx) { +// measuredItem { HLine() } +// items(current.students) { (from, role, glob, map) -> +// Row(Modifier.height(cellSize)) { +// Column(Modifier.width(textLenMeasured.dp).align(Alignment.CenterVertically)) { +// Text(from.name, Modifier.width(textLenMeasured.dp)) +// role?.let { r -> +// Row { +// Spacer(Modifier.width(10.dp)) +// Text( +// r, +// style = MaterialTheme.typography.bodySmall, +// fontStyle = FontStyle.Italic +// ) +// } +// } +// } +// LazyRow(state = horScroll) { +// item { VLine() } +// items(map) { (to, entry) -> +// PEGradeWidget(entry, +// { editing = Triple(from, to, entry) }, { editing = null }, +// isSelected(from, to), Modifier.size(cellSize, cellSize) +// ) +// } +// item { VLine() } +// item { +// PEGradeWidget(glob, +// { editing = Triple(from, null, glob) }, { editing = null }, +// isSelected(from, null), Modifier.size(cellSize, cellSize)) +// } +// item { VLine() } +// } +// } +// } +// measuredItem { HLine() } +// } +// } +// +// Column(Modifier.weight(0.5f)) { +// var groupLevel by remember(state, idx) { mutableStateOf(contents[idx].content) } +// editing?.let { +// Column(Modifier.weight(0.5f)) { +// val (from, to, data) = it +// +// var sGrade by remember(editing) { mutableStateOf(data?.grade ?: "") } +// var sMsg by remember(editing) { mutableStateOf(data?.feedback ?: "") } +// +// Box(Modifier.padding(5.dp)) { +// to?.let { s2 -> +// if(from == s2) +// Text("Self-evaluation by ${from.name}", fontWeight = FontWeight.Bold) +// else +// Text("Evaluation of ${s2.name} by ${from.name}", fontWeight = FontWeight.Bold) +// } ?: Text("Group-level evaluation by ${from.name}", fontWeight = FontWeight.Bold) +// } +// +// Row { +// Text("Grade: ", Modifier.align(Alignment.CenterVertically)) +// OutlinedTextField(sGrade, { sGrade = it }, Modifier.weight(0.2f)) +// Spacer(Modifier.weight(0.6f)) +// Button( +// { state.upsertIndividualFeedback(from, to, sGrade, sMsg); editing = null }, +// Modifier.weight(0.2f).align(Alignment.CenterVertically), +// enabled = sGrade.isNotBlank() || sMsg.isNotBlank() +// ) { +// Text("Save") +// } +// } +// +// OutlinedTextField( +// sMsg, { sMsg = it }, Modifier.fillMaxWidth().weight(1f), +// label = { Text("Feedback") }, +// singleLine = false, +// minLines = 5 +// ) +// } +// } +// +// Column(Modifier.weight(0.5f)) { +// Row { +// Text("Group-level notes", Modifier.weight(1f).align(Alignment.CenterVertically), fontWeight = FontWeight.Bold) +// Button( +// { state.upsertGroupFeedback(current.group, groupLevel); editing = null }, +// enabled = groupLevel != contents[idx].content +// ) { Text("Update") } +// } +// +// OutlinedTextField( +// groupLevel, { groupLevel = it }, Modifier.fillMaxWidth().weight(1f), +// label = { Text("Group-level notes") }, +// singleLine = false, +// minLines = 5 +// ) +// } +// } +// } +// } +//} diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/AssignmentsView.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/AssignmentsView.kt new file mode 100644 index 0000000..ef32e9d --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/AssignmentsView.kt @@ -0,0 +1,500 @@ +package com.jaytux.grader.ui + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.material3.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.DpSize +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.* +import com.jaytux.grader.GroupGrading +import com.jaytux.grader.PeerEvalGrading +import com.jaytux.grader.SoloGrading +import com.jaytux.grader.data.v2.AssignmentType +import com.jaytux.grader.viewmodel.EditionVM +import com.jaytux.grader.viewmodel.Navigator +import com.jaytux.grader.viewmodel.UiGradeType +import com.mohamedrejeb.richeditor.model.rememberRichTextState +import kotlinx.coroutines.launch +import kotlinx.datetime.* +import kotlinx.datetime.format.MonthNames +import kotlinx.datetime.format.char +import kotlin.time.Instant + +@Composable +fun AssignmentsView(vm: EditionVM, token: Navigator.NavToken) = Row(Modifier.fillMaxSize()) { + val assignments by vm.assignmentList.entities + val focus by vm.focusIndex + val scope = rememberCoroutineScope() + + val descRtf = rememberRichTextState() + val assignment = remember(assignments, focus) { + assignments.getOrNull(focus)?.also { + scope.launch { descRtf.setMarkdown(it.global.criterion.desc) } + } + } + + var updatingDeadline by remember { mutableStateOf(false) } + var addingRubric by remember { mutableStateOf(false) } + var editingRubric by remember { mutableStateOf(-1) } + var updatingGrade by remember { mutableStateOf(false) } + + val navToGrading = lambda@{ + if(assignment == null) return@lambda + when(assignment.assignment.type) { + AssignmentType.GROUP -> token.navTo(GroupGrading(vm.course, vm.edition, assignment.assignment)) + AssignmentType.SOLO -> token.navTo(SoloGrading(vm.course, vm.edition, assignment.assignment)) + AssignmentType.PEER_EVALUATION -> token.navTo(PeerEvalGrading(vm.course, vm.edition, assignment.assignment)) + } + } + + Surface(Modifier.weight(0.25f).fillMaxHeight(), tonalElevation = 7.dp) { + ListOrEmpty(assignments, { Text("No groups yet.") }) { idx, it -> + QuickAssignment(idx, it, vm) + } + } + + Surface(Modifier.weight(0.75f).fillMaxHeight(), tonalElevation = 1.dp) { + if (assignment == null) { + Box(Modifier.fillMaxSize()) { + Text("Select an assignment to see details.", Modifier.padding(10.dp).align(Alignment.Center), fontStyle = FontStyle.Italic) + } + } else { + Column(Modifier.padding(10.dp)) { + Text(assignment.assignment.name, style = MaterialTheme.typography.headlineMedium) + Text("Deadline: ${assignment.assignment.deadline.format(fmt)}", Modifier.padding(top = 5.dp).clickable { updatingDeadline = true }, fontStyle = FontStyle.Italic) + Row { + Text("${assignment.assignment.type.display} using grading ", Modifier.align(Alignment.CenterVertically)) + Surface(shape = MaterialTheme.shapes.small, tonalElevation = 10.dp) { + Box(Modifier.clickable { updatingGrade = true }.padding(3.dp)) { + Text(when(val t = assignment.global.gradeType){ + is UiGradeType.Categoric -> t.grade.name + UiGradeType.FreeText -> "by free-form grades" + is UiGradeType.Numeric -> t.grade.name + UiGradeType.Percentage -> "by percentages" + }) + } + } + } + Row { + Column(Modifier.weight(0.75f)) { + Row { + Text("Description:", style = MaterialTheme.typography.headlineSmall, modifier = Modifier.padding(top = 10.dp).weight(1f)) + Button({ vm.setDesc(assignment, descRtf.toMarkdown()) }) { + Text("Update") + } + } + Spacer(Modifier.height(10.dp)) + RichTextField(descRtf) + } + Spacer(Modifier.width(10.dp)) + Surface(Modifier.weight(0.25f), color = Color.White) { + Column(Modifier.padding(15.dp)) { + Row { + Text("Grading Rubrics", Modifier.weight(1f), style = MaterialTheme.typography.headlineSmall) + IconButton({ addingRubric = true }) { + Icon(CirclePlus, "Add grading rubric") + } + } + Spacer(Modifier.height(10.dp)) + LazyColumn(Modifier.weight(1f)) { + itemsIndexed(assignment.criteria) { idx, it -> + Row(Modifier.padding(5.dp)) { + Column(Modifier.weight(1f)) { + Text(it.criterion.name) + Text(it.criterion.desc, Modifier.padding(start = 10.dp), fontStyle = FontStyle.Italic) + } + IconButton({ editingRubric = idx }, Modifier.align(Alignment.Top)) { + Icon(Edit, "Edit grading rubric") + } + } + } + } + Spacer(Modifier.height(10.dp)) + Button({ navToGrading() }, Modifier.fillMaxWidth()) { + Text("Go to grading") + } + } + } + } + } + } + } + + if(updatingDeadline) { + if(assignment == null) updatingDeadline = false + else { + DeadlinePicker(assignment.assignment.deadline, { updatingDeadline = false }) { + vm.modAssignment(assignment.assignment, null, it) + } + } + } + + if(addingRubric) { + if(assignment == null) addingRubric = false + else { + AddCriterionDialog(null, vm, assignment.criteria.map { it.criterion.name }, { addingRubric = false }) { name, desc, type -> + vm.mkCriterion(assignment.assignment, name, desc, type) + } + } + } + + if(editingRubric != -1) { + if(assignment == null) editingRubric = -1 + else { + AddCriterionDialog(assignment.criteria[editingRubric], vm, assignment.criteria.map { it.criterion.name }, { editingRubric = -1 }) { name, desc, type -> + vm.modCriterion(assignment.criteria[editingRubric].criterion, name, desc, type) + } + } + } + + if(updatingGrade) { + if(assignment == null) updatingGrade = false + else { + SetGradingDialog(assignment.assignment.name, assignment.global.gradeType, vm, { updatingGrade = false }) { type -> + vm.modCriterion(assignment.global.criterion, null, null, type) + } + } + } +} + +val fmt = LocalDateTime.Format { + date(LocalDate.Format { + day(); char(' '); monthName(MonthNames.ENGLISH_ABBREVIATED); char(' '); year() + }) + char(' ') + time(LocalTime.Format { + amPmHour(); char(':'); minute(); char(' '); amPmMarker("AM", "PM") + }) +} + +@Composable +fun QuickAssignment(idx: Int, assignment: EditionVM.AssignmentData, vm: EditionVM) { + val focus by vm.focusIndex + Surface(tonalElevation = if(focus == idx) 15.dp else 0.dp, shape = MaterialTheme.shapes.small) { + Column(Modifier.fillMaxWidth().clickable { vm.focus(idx) }.padding(10.dp)) { + Text(assignment.assignment.name, fontWeight = FontWeight.Bold) + Text("Deadline: ${assignment.assignment.deadline.format(fmt)}", Modifier.padding(start = 10.dp), fontStyle = FontStyle.Italic) + } + } +} + +@Composable +fun AddAssignmentDialog(label: String, taken: List, onClose: () -> Unit, current: String = "", onSave: (String, AssignmentType) -> Unit) = DialogWindow( + onCloseRequest = onClose, + state = rememberDialogState(size = DpSize(750.dp, 300.dp), position = WindowPosition(Alignment.Center)) +) { + val focus = remember { FocusRequester() } + + Surface(Modifier.fillMaxSize()) { + Box(Modifier.fillMaxSize().padding(10.dp)) { + var type by remember { mutableStateOf(AssignmentType.SOLO) } + var name by remember(current) { mutableStateOf(current) } + Column(Modifier.align(Alignment.Center)) { + SingleChoiceSegmentedButtonRow(Modifier.fillMaxWidth()) { + AssignmentType.entries.forEachIndexed { idx, it -> + SegmentedButton( + shape = SegmentedButtonDefaults.itemShape(idx, AssignmentType.entries.size), + selected = type == it, + onClick = { type = it } + ) { Text(it.display) } + } + } + OutlinedTextField(name, { name = it }, Modifier.fillMaxWidth().focusRequester(focus), label = { Text(label) }, isError = name in taken) + CancelSaveRow(name.isNotBlank() && name !in taken, onClose) { + onSave(name, type) + onClose() + } + } + } + } + + LaunchedEffect(Unit) { focus.requestFocus() } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun DeadlinePicker(deadline: LocalDateTime, onDismiss: () -> Unit, onSave: (LocalDateTime) -> Unit) { + val state = rememberDatePickerState(deadline.date.toJavaLocalDate()) + val (h, m) = deadline.time.let { it.hour to it.minute } + val time = rememberTimePickerState(h, m) + + val reconstruct = { + val inst = Instant.fromEpochMilliseconds(state.selectedDateMillis!!) + val date = inst.toLocalDateTime(TimeZone.currentSystemDefault()) + LocalDateTime(date.date, LocalTime(time.hour, time.minute)) + } + + Dialog(onDismiss, DialogProperties()) { + Surface(tonalElevation = 5.dp, shape = MaterialTheme.shapes.extraLarge) { + Column(Modifier.padding(15.dp)) { + DatePicker(state, Modifier.fillMaxWidth()) + TimeInput(time, Modifier.fillMaxWidth()) + Row { + Spacer(Modifier.weight(1f)) + Button(onDismiss) { + Text("Cancel") + } + Spacer(Modifier.width(10.dp)) + Button({ onSave(reconstruct()); onDismiss() }) { + Text("Save") + } + } + } + } + } +} + +@Composable +fun AddCriterionDialog(current: EditionVM.CriterionData?, vm: EditionVM, taken: List, onClose: () -> Unit, onSave: (name: String, desc: String, type: UiGradeType) -> Unit) = DialogWindow( + onCloseRequest = onClose, + state = rememberDialogState(size = DpSize(750.dp, 600.dp), position = WindowPosition(Alignment.Center)) +) { + val focus = remember { FocusRequester() } + var type by remember(current) { mutableStateOf(current?.gradeType ?: UiGradeType.FreeText) } + var name by remember(current) { mutableStateOf(current?.criterion?.name ?: "") } + var desc by remember(current) { mutableStateOf(current?.criterion?.desc ?: "") } + val categories by vm.categoricGrades.entities + val numeric by vm.numericGrades.entities + + Surface(Modifier.fillMaxSize()) { + Box(Modifier.fillMaxSize().padding(10.dp)) { + Column(Modifier.align(Alignment.Center)) { + OutlinedTextField(name, { name = it }, Modifier.fillMaxWidth().focusRequester(focus), label = { Text("Criterion Name") }, isError = name in taken, singleLine = true) + OutlinedTextField(desc, { desc = it }, Modifier.fillMaxWidth(), label = { Text("Short Description") }, singleLine = true) + Surface(shape = MaterialTheme.shapes.small, color = Color.White, modifier = Modifier.fillMaxWidth().padding(5.dp)) { + Column { + GradeTypePicker(type, categories, numeric, { n, o -> vm.mkScale(n, o) }, { n, m -> vm.mkNumericScale(n, m) }, Modifier.weight(1f)) { type = it } + + CancelSaveRow(name.isNotBlank() && (name !in taken || name == current?.criterion?.name), onClose) { + onSave(name, desc, type) + onClose() + } + } + } + } + } + } + + LaunchedEffect(current) { focus.requestFocus() } +} + +@Composable +fun SetGradingDialog(name: String, current: UiGradeType, vm: EditionVM, onClose: () -> Unit, onSave: (type: UiGradeType) -> Unit) = DialogWindow( + onCloseRequest = onClose, + state = rememberDialogState(size = DpSize(750.dp, 600.dp), position = WindowPosition(Alignment.Center)) +) { + val focus = remember { FocusRequester() } + val categories by vm.categoricGrades.entities + val numeric by vm.numericGrades.entities + var type by remember(current) { mutableStateOf(current) } + + Surface(Modifier.fillMaxSize()) { + Box(Modifier.fillMaxSize().padding(10.dp)) { + Column(Modifier.align(Alignment.Center)) { + Text("Select a grading scale for $name", style = MaterialTheme.typography.headlineSmall, modifier = Modifier.padding(bottom = 10.dp)) + Surface(shape = MaterialTheme.shapes.small, color = Color.White, modifier = Modifier.fillMaxWidth().padding(5.dp)) { + Column { + GradeTypePicker(type, categories, numeric, { n, o -> vm.mkScale(n, o) }, { n, m -> vm.mkNumericScale(n, m) }, Modifier.weight(1f)) { type = it } + + CancelSaveRow(true, onClose) { + onSave(type) + onClose() + } + } + } + } + } + } + + LaunchedEffect(current) { focus.requestFocus() } +} + +@Composable +fun GradeTypePicker( + type: UiGradeType, categories: List, numeric: List, + mkCat: (String, List) -> Unit, mkNum: (String, Double) -> Unit, + modifier: Modifier = Modifier, + onUpdate: (UiGradeType) -> Unit +) = Column(modifier) { + var selectedCategory by remember(categories) { + mutableStateOf( + if(type is UiGradeType.Categoric) categories.indexOfFirst { it.grade.id == type.grade.id } + else -1 + ) + } + var selectedNumeric by remember(numeric) { + mutableStateOf( + if(type is UiGradeType.Numeric) numeric.indexOfFirst { it.grade.id == type.grade.id } + else -1 + ) + } + var adding by remember { mutableStateOf(false) } + + SingleChoiceSegmentedButtonRow(Modifier.fillMaxWidth()) { + SegmentedButton( + type is UiGradeType.FreeText, onClick = { onUpdate(UiGradeType.FreeText) }, + shape = SegmentedButtonDefaults.itemShape(0, 4) + ) { + Text("Free-form grade") + } + SegmentedButton( + type is UiGradeType.Percentage, onClick = { onUpdate(UiGradeType.Percentage) }, + shape = SegmentedButtonDefaults.itemShape(1, 4) + ) { + Text("Percentage") + } + SegmentedButton( + type is UiGradeType.Categoric, onClick = { onUpdate(categories[maxOf(selectedCategory, 0)]) }, + shape = SegmentedButtonDefaults.itemShape(2, 4) + ) { + Text("Grading System") + } + SegmentedButton( + type is UiGradeType.Numeric, onClick = { onUpdate(numeric[maxOf(selectedNumeric, 0)]) }, + shape = SegmentedButtonDefaults.itemShape(3, 4) + ) { + Text("Numeric Grade") + } + } + (type as? UiGradeType.Categoric)?.let { + LazyColumn(Modifier.weight(1f)) { + itemsIndexed(categories) { idx, it -> + Surface( + tonalElevation = if (selectedCategory == idx) 15.dp else 0.dp, + shape = MaterialTheme.shapes.small + ) { + Column(Modifier.fillMaxWidth().clickable { selectedCategory = idx; onUpdate(it) }.padding(10.dp)) { + Text(it.grade.name, fontWeight = FontWeight.Bold) + Text( + "(${it.options.size} options)", + Modifier.padding(start = 10.dp), + fontStyle = FontStyle.Italic + ) + } + } + } + + item { + Button({ adding = true }, Modifier.fillMaxWidth()) { + Text("Add grading system") + } + } + } + } ?: (type as? UiGradeType.Numeric)?.let { + LazyColumn(Modifier.weight(1f)) { + itemsIndexed(numeric) { idx, it -> + Surface( + tonalElevation = if (selectedNumeric == idx) 15.dp else 0.dp, + shape = MaterialTheme.shapes.small + ) { + Column(Modifier.fillMaxWidth().clickable { selectedNumeric = idx; onUpdate(it) }.padding(10.dp)) { + Text(it.grade.name, fontWeight = FontWeight.Bold) + Text( + "(graded as X/${it.grade.max})", + Modifier.padding(start = 10.dp), + fontStyle = FontStyle.Italic + ) + } + } + } + + item { + Button({ adding = true }, Modifier.fillMaxWidth()) { + Text("Add numeric system") + } + } + } + } ?: Spacer(Modifier.weight(1f)) + + if(adding) { + when(type) { + is UiGradeType.Categoric -> AddCatScaleDialog(categories.map { it.grade.name }, { adding = false }) { name, options -> + mkCat(name, options) + } + is UiGradeType.Numeric -> AddNumScaleDialog(numeric.map { it.grade.name }, { adding = false }) { name, max -> + mkNum(name, max) + } + else -> adding = false + } + } +} + +@Composable +fun AddCatScaleDialog(taken: List, onClose: () -> Unit, onSave: (String, List) -> Unit) = DialogWindow( + onCloseRequest = onClose, + state = rememberDialogState(size = DpSize(750.dp, 600.dp), position = WindowPosition(Alignment.Center)) +) { + val focus = remember { FocusRequester() } + var name by remember { mutableStateOf("") } + var options by remember { mutableStateOf(listOf()) } + var adding by remember { mutableStateOf("") } + + Surface(Modifier.fillMaxSize()) { + Box(Modifier.fillMaxSize().padding(10.dp)) { + Column(Modifier.align(Alignment.Center)) { + OutlinedTextField(name, { name = it }, Modifier.fillMaxWidth().focusRequester(focus), label = { Text("Grading system name") }, isError = name in taken, singleLine = true) + Text("Grade options:", style = MaterialTheme.typography.headlineSmall, modifier = Modifier.padding(top = 10.dp)) + LazyColumn(Modifier.weight(1f)) { + itemsIndexed(options) { idx, it -> + Row(Modifier.fillMaxWidth().padding(5.dp)) { + Text(it, Modifier.weight(1f)) + IconButton({ options = options.filterNot { o -> o == it } }) { + Icon(Delete, "Delete grading option") + } + } + } + item { + Row { + OutlinedTextField(adding, { adding = it }, Modifier.weight(1f).align(Alignment.CenterVertically).padding(5.dp), label = { Text("New option") }, isError = adding in options, singleLine = true) + Button({ options = options + adding; adding = "" }, Modifier.align(Alignment.CenterVertically).padding(5.dp), enabled = adding.isNotBlank() && adding !in options) { + Text("Add") + } + } + } + } + CancelSaveRow(name.isNotBlank() && name !in taken, onClose) { + onSave(name, options) + onClose() + } + } + } + } + + LaunchedEffect(Unit) { focus.requestFocus() } +} + +@Composable +fun AddNumScaleDialog(taken: List, onClose: () -> Unit, onSave: (String, Double) -> Unit) = DialogWindow( + onCloseRequest = onClose, + state = rememberDialogState(size = DpSize(750.dp, 300.dp), position = WindowPosition(Alignment.Center)) +) { + val focus = remember { FocusRequester() } + var name by remember { mutableStateOf("") } + var maxStr by remember { mutableStateOf("0") } + + Surface(Modifier.fillMaxSize()) { + Box(Modifier.fillMaxSize().padding(10.dp)) { + Column(Modifier.align(Alignment.Center)) { + OutlinedTextField(name, { name = it }, Modifier.fillMaxWidth().focusRequester(focus), label = { Text("Grading system name") }, isError = name in taken, singleLine = true) + OutlinedTextField(maxStr, { maxStr = it.toDoubleOrNull()?.let { _ -> it } ?: "0" }, Modifier.fillMaxWidth(), label = { Text("Maximum grade") }, singleLine = true) + + CancelSaveRow(name.isNotBlank() && name !in taken && (maxStr.toDoubleOrNull() ?: 0.0) > 0.0, onClose) { + onSave(name, maxStr.toDoubleOrNull()!!) + onClose() + } + } + } + } + + LaunchedEffect(Unit) { focus.requestFocus() } +} \ 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 index 7cc9759..6918524 100644 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Courses.kt +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Courses.kt @@ -1,109 +1,87 @@ package com.jaytux.grader.ui -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Delete -import androidx.compose.material.icons.filled.Edit -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton -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.dp -import com.jaytux.grader.UiRoute -import com.jaytux.grader.data.Edition -import com.jaytux.grader.viewmodel.CourseListState -import com.jaytux.grader.viewmodel.EditionListState -import com.jaytux.grader.viewmodel.EditionState - -@Composable -fun CoursesView(state: CourseListState, push: (UiRoute) -> Unit) { - val data by state.courses.entities - var showDialog by remember { mutableStateOf(false) } - - Box(Modifier.padding(15.dp)) { - ListOrEmpty( - data, - { Text("You have no courses yet.", Modifier.align(Alignment.CenterHorizontally)) }, - { Text("Add a course") }, - { showDialog = true }, - addAfterLazy = false - ) { _, it -> - CourseWidget(state.getEditions(it), { state.delete(it) }, push) - } - } - - if(showDialog) AddStringDialog("Course name", data.map { it.name }, { showDialog = false }) { state.new(it) } -} - -@Composable -fun CourseWidget(state: EditionListState, onDelete: () -> Unit, push: (UiRoute) -> Unit) { - val editions by state.editions.entities - var isOpened by remember { mutableStateOf(false) } - var showDialog by remember { mutableStateOf(false) } - - val callback = { it: Edition -> - val s = EditionState(it) - val route = UiRoute("${state.course.name}: ${it.name}") { - EditionView(s) - } - push(route) - } - - Surface(Modifier.fillMaxWidth().padding(horizontal = 5.dp, vertical = 10.dp).clickable { isOpened = !isOpened }, shape = MaterialTheme.shapes.medium, tonalElevation = 2.dp, shadowElevation = 2.dp) { - Row { - Column(Modifier.weight(1f).padding(5.dp)) { - Row { - Icon( - if (isOpened) ChevronDown else ChevronRight, "Toggle editions", - Modifier.size(MaterialTheme.typography.headlineMedium.fontSize.toDp()) - .align(Alignment.CenterVertically) - ) - Column { - Text(state.course.name, style = MaterialTheme.typography.headlineMedium) - } - } - Row { - Spacer(Modifier.width(25.dp)) - Text( - "${editions.size} edition(s)", - fontStyle = FontStyle.Italic, - style = MaterialTheme.typography.bodySmall - ) - } - - if(isOpened) { - Row { - Spacer(Modifier.width(25.dp)) - Column { - editions.forEach { EditionWidget(it, { callback(it) }) { state.delete(it) } } - Button({ showDialog = true }, Modifier.fillMaxWidth()) { Text("Add edition") } - } - } - } - } - Column { - IconButton({ onDelete() }) { Icon(Icons.Default.Delete, "Remove") } - IconButton({ TODO() }, enabled = false) { Icon(Icons.Default.Edit, "Edit") } - } - } - } - - if(showDialog) AddStringDialog("Edition name", editions.map { it.name }, { showDialog = false }) { state.new(it) } -} - -@Composable -fun EditionWidget(edition: Edition, onOpen: () -> Unit, onDelete: () -> Unit) { - Surface(Modifier.fillMaxWidth().padding(horizontal = 5.dp, vertical = 10.dp).clickable { onOpen() }, shape = MaterialTheme.shapes.medium, tonalElevation = 2.dp, shadowElevation = 2.dp) { - Row(Modifier.padding(5.dp)) { - Text(edition.name, Modifier.weight(1f), style = MaterialTheme.typography.headlineSmall) - IconButton({ onDelete() }) { Icon(Icons.Default.Delete, "Remove") } - } - } -} \ No newline at end of file +//@Composable +//fun CoursesView(state: CourseListState, push: (UiRoute) -> Unit) { +// val data by state.courses.entities +// var showDialog by remember { mutableStateOf(false) } +// +// Box(Modifier.padding(15.dp)) { +// ListOrEmpty( +// data, +// { Text("You have no courses yet.", Modifier.align(Alignment.CenterHorizontally)) }, +// { Text("Add a course") }, +// { showDialog = true }, +// addAfterLazy = false +// ) { _, it -> +// CourseWidget(state.getEditions(it), { state.delete(it) }, push) +// } +// } +// +// if(showDialog) AddStringDialog("Course name", data.map { it.name }, { showDialog = false }) { state.new(it) } +//} +// +//@Composable +//fun CourseWidget(state: EditionListState, onDelete: () -> Unit, push: (UiRoute) -> Unit) { +// val editions by state.editions.entities +// var isOpened by remember { mutableStateOf(false) } +// var showDialog by remember { mutableStateOf(false) } +// +// val callback = { it: Edition -> +// val s = EditionState(it) +// val route = UiRoute("${state.course.name}: ${it.name}") { +// EditionView(s) +// } +// push(route) +// } +// +// Surface(Modifier.fillMaxWidth().padding(horizontal = 5.dp, vertical = 10.dp).clickable { isOpened = !isOpened }, shape = MaterialTheme.shapes.medium, tonalElevation = 2.dp, shadowElevation = 2.dp) { +// Row { +// Column(Modifier.weight(1f).padding(5.dp)) { +// Row { +// Icon( +// if (isOpened) ChevronDown else ChevronRight, "Toggle editions", +// Modifier.size(MaterialTheme.typography.headlineMedium.fontSize.toDp()) +// .align(Alignment.CenterVertically) +// ) +// Column { +// Text(state.course.name, style = MaterialTheme.typography.headlineMedium) +// } +// } +// Row { +// Spacer(Modifier.width(25.dp)) +// Text( +// "${editions.size} edition(s)", +// fontStyle = FontStyle.Italic, +// style = MaterialTheme.typography.bodySmall +// ) +// } +// +// if(isOpened) { +// Row { +// Spacer(Modifier.width(25.dp)) +// Column { +// editions.forEach { EditionWidget(it, { callback(it) }) { state.delete(it) } } +// Button({ showDialog = true }, Modifier.fillMaxWidth()) { Text("Add edition") } +// } +// } +// } +// } +// Column { +// IconButton({ onDelete() }) { Icon(Icons.Default.Delete, "Remove") } +// IconButton({ TODO() }, enabled = false) { Icon(Icons.Default.Edit, "Edit") } +// } +// } +// } +// +// if(showDialog) AddStringDialog("Edition name", editions.map { it.name }, { showDialog = false }) { state.new(it) } +//} +// +//@Composable +//fun EditionWidget(edition: Edition, onOpen: () -> Unit, onDelete: () -> Unit) { +// Surface(Modifier.fillMaxWidth().padding(horizontal = 5.dp, vertical = 10.dp).clickable { onOpen() }, shape = MaterialTheme.shapes.medium, tonalElevation = 2.dp, shadowElevation = 2.dp) { +// Row(Modifier.padding(5.dp)) { +// Text(edition.name, Modifier.weight(1f), style = MaterialTheme.typography.headlineSmall) +// IconButton({ onDelete() }) { Icon(Icons.Default.Delete, "Remove") } +// } +// } +//} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/EditionView.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/EditionView.kt new file mode 100644 index 0000000..f279c65 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/EditionView.kt @@ -0,0 +1,100 @@ +package com.jaytux.grader.ui + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.material3.Button +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.PrimaryScrollableTabRow +import androidx.compose.material3.PrimaryTabRow +import androidx.compose.material3.Tab +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.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel +import com.jaytux.grader.EditionDetail +import com.jaytux.grader.data.v2.BaseAssignment +import com.jaytux.grader.data.v2.Student +import com.jaytux.grader.viewmodel.EditionVM +import com.jaytux.grader.viewmodel.Navigator + +@Composable +fun EditionTitle(data: EditionDetail) = Text("Courses / ${data.course.name} / ${data.ed.name}") + +@Composable +fun EditionView(data: EditionDetail, token: Navigator.NavToken) { + val vm = viewModel(key = data.ed.id.toString()) { EditionVM(data.ed, data.course) } + val tab by vm.selectedTab + var adding by remember { mutableStateOf(false) } + + val groups by vm.groupList.entities + val assignments by vm.assignmentList.entities + + + Column(Modifier.padding(10.dp)) { + Row { + Text("${vm.course.name} - ${vm.edition.name}", Modifier.weight(1f), style = MaterialTheme.typography.headlineMedium) + Button({ adding = true }) { + Icon(CirclePlus, "Add ${tab.addText}") + Spacer(Modifier.width(5.dp)) + Text("Add ${tab.addText}") + } + } + Spacer(Modifier.height(5.dp)) + PrimaryScrollableTabRow(tab.ordinal, edgePadding = 10.dp) { + EditionVM.Tab.entries.forEach { + Tab(tab == it, onClick = { vm.switchTo(it) }, modifier = Modifier.padding(horizontal = 5.dp)) { it.renderTab() } + } + } + Box(Modifier.weight(1f)) { + when (tab) { + EditionVM.Tab.STUDENTS -> StudentsView(vm) + EditionVM.Tab.GROUPS -> GroupsView(vm) + EditionVM.Tab.ASSIGNMENTS -> AssignmentsView(vm, token) + } + } + } + + if(adding) { + when(tab) { + EditionVM.Tab.STUDENTS -> + AddStringDialog("Student Name", listOf(), { adding = false }, "") { vm.mkStudent(it, "", "") } + EditionVM.Tab.GROUPS -> + AddStringDialog("Group Name", groups.map { it.group.name }, { adding = false }, "") { vm.mkGroup(it) } + EditionVM.Tab.ASSIGNMENTS -> + AddAssignmentDialog("Assignment Name", assignments.map { it.assignment.name }, { adding = false }, "") { name, type -> vm.mkAssignment(name, type) } + } + } +} + +@Composable +fun StudentsTabHeader() = Row(Modifier.padding(all = 5.dp)) { + Icon(UserIcon, "Students") + Spacer(Modifier.width(5.dp)) + Text("Students") +} + +@Composable +fun GroupsTabHeader() = Row(Modifier.padding(all = 5.dp)) { + Icon(UserGroupIcon, "Groups") + Spacer(Modifier.width(5.dp)) + Text("Groups") +} + +@Composable +fun AssignmentsTabHeader() = Row(Modifier.padding(all = 5.dp)) { + Icon(AssignmentIcon, "Assignments") + Spacer(Modifier.width(5.dp)) + Text("Assignments") +} diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Editions.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Editions.kt index 44c1e89..eb1ef9c 100644 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Editions.kt +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Editions.kt @@ -1,419 +1,409 @@ package com.jaytux.grader.ui -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.ArrowDownward -import androidx.compose.material.icons.filled.ArrowUpward -import androidx.compose.material.icons.filled.Delete -import androidx.compose.material.icons.filled.Edit -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.unit.DpSize -import androidx.compose.ui.unit.dp -import androidx.compose.ui.window.DialogWindow -import androidx.compose.ui.window.WindowPosition -import androidx.compose.ui.window.rememberDialogState -import com.jaytux.grader.data.Course -import com.jaytux.grader.data.Edition -import com.jaytux.grader.data.Group -import com.jaytux.grader.data.Student -import com.jaytux.grader.viewmodel.* -data class Navigators( - val student: (Student) -> Unit, - val group: (Group) -> Unit, - val assignment: (Assignment) -> Unit -) - -@Composable -fun EditionView(state: EditionState) = Row(Modifier.padding(0.dp)) { - val course = state.course; val edition = state.edition - val students by state.students.entities - val availableStudents by state.availableStudents.entities - val groups by state.groups.entities - val solo by state.solo.entities - val groupAs by state.groupAs.entities - val peers by state.peer.entities - val mergedAssignments by remember(solo, groupAs, peers) { mutableStateOf(Assignment.merge(groupAs, solo, peers)) } - val hist by state.history - - val navs = Navigators( - student = { state.navTo(OpenPanel.Student, students.indexOfFirst{ s -> s.id == it.id }) }, - group = { state.navTo(OpenPanel.Group, groups.indexOfFirst { g -> g.id == it.id }) }, - assignment = { state.navTo(OpenPanel.Assignment, mergedAssignments.indexOfFirst { a -> a.id() == it.id() }) } - ) - - val (id, tab) = hist.last() - Surface(Modifier.weight(0.25f), tonalElevation = 5.dp) { - TabLayout( - OpenPanel.entries, - tab.ordinal, - { state.navTo(OpenPanel.entries[it]) }, - { Text(it.tabName) } - ) { - when(tab) { - OpenPanel.Student -> StudentPanel( - course, edition, students, availableStudents, id, - { state.navTo(it) }, - { name, note, contact, add -> state.newStudent(name, contact, note, add) }, - { students -> state.addToCourse(students) }, - { s, name -> state.setStudentName(s, name) } - ) { s, idx -> state.delete(s); if(id == idx) state.clearHistoryIndex() } - - OpenPanel.Group -> GroupPanel( - course, edition, groups, id, - { state.navTo(it) }, - { name -> state.newGroup(name) }, - { g, name -> state.setGroupName(g, name) } - ) { g, idx -> state.delete(g); if(id == idx) state.clearHistoryIndex() } - - OpenPanel.Assignment -> AssignmentPanel( - course, edition, mergedAssignments, id, - { state.navTo(it) }, - { type, name -> state.newAssignment(type, name) }, - { a, name -> state.setAssignmentTitle(a, name) }, - { a1, a2 -> state.swapOrder(a1, a2) } - ) { a, idx -> state.delete(a); if(id == idx) state.clearHistoryIndex() } - } - } - } - - Column(Modifier.weight(0.75f)) { - Row { - IconButton({ state.back() }, enabled = hist.size >= 2) { - Icon(ChevronLeft, "Back", Modifier.size(MaterialTheme.typography.headlineMedium.fontSize.toDp()).align(Alignment.CenterVertically)) - } - when(tab) { - OpenPanel.Student -> { - if(id == -1) PaneHeader("Nothing selected", "students", course, edition) - else PaneHeader(students[id].name, "student", course, edition) - } - OpenPanel.Group -> { - if(id == -1) PaneHeader("Nothing selected", "groups", course, edition) - else PaneHeader(groups[id].name, "group", course, edition) - } - OpenPanel.Assignment -> { - if(id == -1) PaneHeader("Nothing selected", "assignments", course, edition) - else { - when(val a = mergedAssignments[id]) { - is Assignment.SAssignment -> PaneHeader(a.name(), "individual assignment", course, edition) - is Assignment.GAssignment -> PaneHeader(a.name(), "group assignment", course, edition) - is Assignment.PeerEval -> PaneHeader(a.name(), "peer evaluation", course, edition) - } - } - } - } - } - Box(Modifier.weight(1f)) { - if (id != -1) { - when (tab) { - OpenPanel.Student -> StudentView(StudentState(students[id], edition), navs) - OpenPanel.Group -> GroupView(GroupState(groups[id]), navs) - OpenPanel.Assignment -> { - when (val a = mergedAssignments[id]) { - is Assignment.SAssignment -> SoloAssignmentView(SoloAssignmentState(a.assignment)) - is Assignment.GAssignment -> GroupAssignmentView(GroupAssignmentState(a.assignment)) - is Assignment.PeerEval -> PeerEvaluationView(PeerEvaluationState(a.evaluation)) - } - } - } - } - } - } -} - -@Composable -fun StudentPanel( - course: Course, edition: Edition, students: List, available: List, - selected: Int, onSelect: (Int) -> Unit, - onAdd: (name: String, note: String, contact: String, addToEdition: Boolean) -> Unit, - onImport: (List) -> Unit, onUpdate: (Student, String) -> Unit, onDelete: (Student, Int) -> Unit -) = Column(Modifier.padding(10.dp)) { - var showDialog by remember { mutableStateOf(false) } - var deleting by remember { mutableStateOf(-1) } - var editing by remember { mutableStateOf(-1) } - - Text("Student list (${students.size})", style = MaterialTheme.typography.headlineMedium) - - ListOrEmpty( - students, - { Text( - "Course ${course.name} (edition ${edition.name})\nhas no students yet.", - Modifier.align(Alignment.CenterHorizontally), textAlign = TextAlign.Center - ) }, - { Text("Add a student") }, - { showDialog = true } - ) { idx, it -> - SelectEditDeleteRow( - selected == idx, - { onSelect(idx) }, { onSelect(-1) }, - { editing = idx }, { deleting = idx } - ) { - Text(it.name, Modifier.padding(5.dp)) - } - } - - if(showDialog) { - StudentDialog(course, edition, { showDialog = false }, available, onImport, onAdd) - } - else if(editing != -1) { - AddStringDialog("Student name", students.map { it.name }, { editing = -1 }, students[editing].name) { - onUpdate(students[editing], it) - } - } - else if(deleting != -1) { - ConfirmDeleteDialog( - "a student", - { deleting = -1 }, - { onDelete(students[deleting], deleting) } - ) { Text(students[deleting].name) } - } -} - -@Composable -fun GroupPanel( - course: Course, edition: Edition, groups: List, - selected: Int, onSelect: (Int) -> Unit, - onAdd: (String) -> Unit, onUpdate: (Group, String) -> Unit, onDelete: (Group, Int) -> Unit -) = Column(Modifier.padding(10.dp)) { - var showDialog by remember { mutableStateOf(false) } - var deleting by remember { mutableStateOf(-1) } - var editing by remember { mutableStateOf(-1) } - - Text("Group list (${groups.size})", style = MaterialTheme.typography.headlineMedium) - - ListOrEmpty( - groups, - { Text( - "Course ${course.name} (edition ${edition.name})\nhas no groups yet.", - Modifier.align(Alignment.CenterHorizontally), textAlign = TextAlign.Center - ) }, - { Text("Add a group") }, - { showDialog = true } - ) { idx, it -> - SelectEditDeleteRow( - selected == idx, - { onSelect(idx) }, { onSelect(-1) }, - { editing = idx }, { deleting = idx } - ) { - Text(it.name, Modifier.padding(5.dp)) - } - } - - if(showDialog) { - AddStringDialog("Group name", groups.map{ it.name }, { showDialog = false }) { onAdd(it) } - } - else if(editing != -1) { - AddStringDialog("Group name", groups.map { it.name }, { editing = -1 }, groups[editing].name) { - onUpdate(groups[editing], it) - } - } - else if(deleting != -1) { - ConfirmDeleteDialog( - "a group", - { deleting = -1 }, - { onDelete(groups[deleting], deleting) } - ) { Text(groups[deleting].name) } - } -} - -@Composable -fun AssignmentPanel( - course: Course, edition: Edition, assignments: List, - selected: Int, onSelect: (Int) -> Unit, - onAdd: (AssignmentType, String) -> Unit, onUpdate: (Assignment, String) -> Unit, - onSwapOrder: (Assignment, Assignment) -> Unit, onDelete: (Assignment, Int) -> Unit -) = Column(Modifier.padding(10.dp)) { - var showDialog by remember { mutableStateOf(false) } - var deleting by remember { mutableStateOf(-1) } - var editing by remember { mutableStateOf(-1) } - - val dialog: @Composable (String, List, () -> Unit, String, (AssignmentType, String) -> Unit) -> Unit = - { label, taken, onClose, current, onSave -> - DialogWindow( - onCloseRequest = onClose, - state = rememberDialogState(size = DpSize(400.dp, 300.dp), position = WindowPosition(Alignment.Center)) - ) { - var name by remember(current) { mutableStateOf(current) } - var tab by remember { mutableStateOf(AssignmentType.Solo) } - - Surface(Modifier.fillMaxSize()) { - TabLayout( - AssignmentType.entries, - tab.ordinal, - { tab = AssignmentType.entries[it] }, - { Text(it.show) } - ) { - Box(Modifier.fillMaxSize().padding(10.dp)) { - Column(Modifier.align(Alignment.Center)) { - OutlinedTextField( - name, - { name = it }, - Modifier.fillMaxWidth(), - label = { Text(label) }, - isError = name in taken - ) - CancelSaveRow(name.isNotBlank() && name !in taken, onClose) { - onSave(tab, name) - onClose() - } - } - } - } - } - } - } - - Text("Assignment list (${assignments.size})", style = MaterialTheme.typography.headlineMedium) - - ListOrEmpty( - assignments, - { Text( - "Course ${course.name} (edition ${edition.name})\nhas no assignments yet.", - Modifier.align(Alignment.CenterHorizontally), textAlign = TextAlign.Center - ) }, - { Text("Add an assignment") }, - { showDialog = true } - ) { idx, it -> - Selectable( - selected == idx, - { onSelect(idx) }, { onSelect(-1) } - ) { - Row { - Text(it.name(), Modifier.padding(5.dp).align(Alignment.CenterVertically).weight(1f)) - Column(Modifier.padding(2.dp)) { - Icon(Icons.Default.ArrowUpward, "Move up", Modifier.clickable { - if(idx > 0) onSwapOrder(assignments[idx], assignments[idx - 1]) - }) - Icon(Icons.Default.ArrowDownward, "Move down", Modifier.clickable { - if(idx < assignments.size - 1) onSwapOrder(assignments[idx], assignments[idx + 1]) - }) - } - Column(Modifier.padding(2.dp)) { - Icon(Icons.Default.Edit, "Edit", Modifier.clickable { editing = idx }) - Icon(Icons.Default.Delete, "Delete", Modifier.clickable { deleting = idx }) - } - } - } - } - - if(showDialog) { - dialog("Assignment name", assignments.map{ it.name() }, { showDialog = false }, "", onAdd) - } - else if(editing != -1) { - AddStringDialog("Assignment name", assignments.map { it.name() }, { editing = -1 }, assignments[editing].name()) { - onUpdate(assignments[editing], it) - } - } - else if(deleting != -1) { - ConfirmDeleteDialog( - "an assignment", - { deleting = -1 }, - { onDelete(assignments[deleting], deleting) } - ) { if(deleting != -1) Text(assignments[deleting].name()) } - } -} - -@Composable -fun StudentDialog( - course: Course, - edition: Edition, - onClose: () -> Unit, - availableStudents: List, - onImport: (List) -> Unit, - onAdd: (name: String, note: String, contact: String, addToEdition: Boolean) -> Unit -) = DialogWindow( - onCloseRequest = onClose, - state = rememberDialogState(size = DpSize(600.dp, 400.dp), position = WindowPosition(Alignment.Center)) -) { - Surface(Modifier.fillMaxSize()) { - Column(Modifier.padding(10.dp)) { - var isImport by remember { mutableStateOf(false) } - TabRow(if(isImport) 1 else 0) { - Tab(!isImport, { isImport = false }) { Text("Add new student") } - Tab(isImport, { isImport = true }) { Text("Add existing student") } - } - - if(isImport) { - if(availableStudents.isEmpty()) { - Box(Modifier.fillMaxSize()) { - Text("No students available to add to this course.", Modifier.align(Alignment.Center)) - } - } - else { - var selected by remember { mutableStateOf(setOf()) } - - val onClick = { idx: Int -> - selected = if(idx in selected) selected - idx else selected + idx - } - - Text("Select students to add to ${course.name} ${edition.name}") - LazyColumn { - itemsIndexed(availableStudents) { idx, student -> - Surface( - Modifier.fillMaxWidth().clickable { onClick(idx) }, - tonalElevation = if (selected.contains(idx)) 5.dp else 0.dp - ) { - Row { - Checkbox(selected.contains(idx), { onClick(idx) }) - Text(student.name, Modifier.padding(5.dp)) - } - } - } - } - CancelSaveRow(selected.isNotEmpty(), onClose) { - onImport(selected.map { idx -> availableStudents[idx] }) - onClose() - } - } - } - else { - Box(Modifier.fillMaxSize()) { - var name by remember { mutableStateOf("") } - var contact by remember { mutableStateOf("") } - var note by remember { mutableStateOf("") } - var add by remember { mutableStateOf(true) } - - Column(Modifier.align(Alignment.Center)) { - OutlinedTextField( - name, - { name = it }, - Modifier.fillMaxWidth(), - singleLine = true, - label = { Text("Student name") }) - OutlinedTextField( - contact, - { contact = it }, - Modifier.fillMaxWidth(), - singleLine = true, - label = { Text("Student contact") }) - OutlinedTextField( - note, - { note = it }, - Modifier.fillMaxWidth(), - singleLine = false, - minLines = 3, - label = { Text("Note") }) - Row { - Checkbox(add, { add = it }) - Text( - "Add student to ${course.name} ${edition.name}?", - Modifier.align(Alignment.CenterVertically) - ) - } - CancelSaveRow(name.isNotBlank() && contact.isNotBlank(), onClose) { - onAdd(name, note, contact, add) - onClose() - } - } - } - } - } - } -} \ No newline at end of file +//data class Navigators( +// val student: (Student) -> Unit, +// val group: (Group) -> Unit, +// val assignment: (Assignment) -> Unit +//) +// +//@Composable +//fun EditionView(state: EditionState) = Row(Modifier.padding(0.dp)) { +// val course = state.course; val edition = state.edition +// val students by state.students.entities +// val availableStudents by state.availableStudents.entities +// val groups by state.groups.entities +// val solo by state.solo.entities +// val groupAs by state.groupAs.entities +// val peers by state.peer.entities +// val mergedAssignments by remember(solo, groupAs, peers) { mutableStateOf(Assignment.merge(groupAs, solo, peers)) } +// val hist by state.history +// +// val scope = rememberCoroutineScope() +// +// var groupExporting by remember { mutableStateOf(null) } +// val groupPopup = rememberDirectoryPickerLauncher(directory = PlatformFile(Preferences.exportPath)) { path -> +// if(path != null) { +// groupExporting?.let { +// Preferences.exportPath = path.toKotlinxIoPath().toString() +// scope.launch { it.batchExport(path.toKotlinxIoPath()) } +// } +// } +// } +// +// val navs = Navigators( +// student = { state.navTo(OpenPanel.Student, students.indexOfFirst{ s -> s.id == it.id }) }, +// group = { state.navTo(OpenPanel.Group, groups.indexOfFirst { g -> g.id == it.id }) }, +// assignment = { state.navTo(OpenPanel.Assignment, mergedAssignments.indexOfFirst { a -> a.id() == it.id() }) } +// ) +// +// val (id, tab) = hist.last() +// Surface(Modifier.weight(0.25f), tonalElevation = 5.dp) { +// TabLayout( +// OpenPanel.entries, +// tab.ordinal, +// { state.navTo(OpenPanel.entries[it]) }, +// { Text(it.tabName) } +// ) { +// when(tab) { +// OpenPanel.Student -> StudentPanel( +// course, edition, students, availableStudents, id, +// { state.navTo(it) }, +// { name, note, contact, add -> state.newStudent(name, contact, note, add) }, +// { students -> state.addToCourse(students) }, +// { s, name -> state.setStudentName(s, name) } +// ) { s, idx -> state.delete(s); if(id == idx) state.clearHistoryIndex() } +// +// OpenPanel.Group -> GroupPanel( +// course, edition, groups, id, +// { state.navTo(it) }, +// { name -> state.newGroup(name) }, +// { g, name -> state.setGroupName(g, name) } +// ) { g, idx -> state.delete(g); if(id == idx) state.clearHistoryIndex() } +// +// OpenPanel.Assignment -> AssignmentPanel( +// course, edition, mergedAssignments, id, +// { state.navTo(it) }, +// { type, name -> state.newAssignment(type, name) }, +// { a, name -> state.setAssignmentTitle(a, name) }, +// { a1, a2 -> state.swapOrder(a1, a2) } +// ) { a, idx -> state.delete(a); if(id == idx) state.clearHistoryIndex() } +// } +// } +// } +// +// Column(Modifier.weight(0.75f)) { +// Row { +// IconButton({ state.back() }, enabled = hist.size >= 2) { +// Icon(ChevronLeft, "Back", Modifier.size(MaterialTheme.typography.headlineMedium.fontSize.toDp()).align(Alignment.CenterVertically)) +// } +// when(tab) { +// OpenPanel.Student -> { +// if(id == -1) PaneHeader("Nothing selected", "students", course, edition) +// else PaneHeader(students[id].name, "student", course, edition) +// } +// OpenPanel.Group -> { +// if(id == -1) PaneHeader("Nothing selected", "groups", course, edition) +// else PaneHeader(groups[id].name, "group", course, edition) +// } +// OpenPanel.Assignment -> { +// if(id == -1) PaneHeader("Nothing selected", "assignments", course, edition) +// else { +// when(val a = mergedAssignments[id]) { +// is Assignment.SAssignment -> PaneHeader(a.name(), "individual assignment", course, edition) +// is Assignment.GAssignment -> PaneHeader(a.name(), "group assignment", course, edition) { +// groupExporting = GroupAssignmentState(a.assignment); groupPopup.launch() +// } +// is Assignment.PeerEval -> PaneHeader(a.name(), "peer evaluation", course, edition) +// } +// } +// } +// } +// } +// Box(Modifier.weight(1f)) { +// if (id != -1) { +// when (tab) { +// OpenPanel.Student -> StudentView(StudentState(students[id], edition), navs) +// OpenPanel.Group -> GroupView(GroupState(groups[id]), navs) +// OpenPanel.Assignment -> { +// when (val a = mergedAssignments[id]) { +// is Assignment.SAssignment -> SoloAssignmentView(SoloAssignmentState(a.assignment)) +// is Assignment.GAssignment -> GroupAssignmentView(GroupAssignmentState(a.assignment)) +// is Assignment.PeerEval -> PeerEvaluationView(PeerEvaluationState(a.evaluation)) +// } +// } +// } +// } +// } +// } +//} +// +//@Composable +//fun StudentPanel( +// course: Course, edition: Edition, students: List, available: List, +// selected: Int, onSelect: (Int) -> Unit, +// onAdd: (name: String, note: String, contact: String, addToEdition: Boolean) -> Unit, +// onImport: (List) -> Unit, onUpdate: (Student, String) -> Unit, onDelete: (Student, Int) -> Unit +//) = Column(Modifier.padding(10.dp)) { +// var showDialog by remember { mutableStateOf(false) } +// var deleting by remember { mutableStateOf(-1) } +// var editing by remember { mutableStateOf(-1) } +// +// Text("Student list (${students.size})", style = MaterialTheme.typography.headlineMedium) +// +// ListOrEmpty( +// students, +// { Text( +// "Course ${course.name} (edition ${edition.name})\nhas no students yet.", +// Modifier.align(Alignment.CenterHorizontally), textAlign = TextAlign.Center +// ) }, +// { Text("Add a student") }, +// { showDialog = true } +// ) { idx, it -> +// SelectEditDeleteRow( +// selected == idx, +// { onSelect(idx) }, { onSelect(-1) }, +// { editing = idx }, { deleting = idx } +// ) { +// Text(it.name, Modifier.padding(5.dp)) +// } +// } +// +// if(showDialog) { +// StudentDialog(course, edition, { showDialog = false }, available, onImport, onAdd) +// } +// else if(editing != -1) { +// AddStringDialog("Student name", students.map { it.name }, { editing = -1 }, students[editing].name) { +// onUpdate(students[editing], it) +// } +// } +// else if(deleting != -1) { +// ConfirmDeleteDialog( +// "a student", +// { deleting = -1 }, +// { onDelete(students[deleting], deleting) } +// ) { Text(students[deleting].name) } +// } +//} +// +//@Composable +//fun GroupPanel( +// course: Course, edition: Edition, groups: List, +// selected: Int, onSelect: (Int) -> Unit, +// onAdd: (String) -> Unit, onUpdate: (Group, String) -> Unit, onDelete: (Group, Int) -> Unit +//) = Column(Modifier.padding(10.dp)) { +// var showDialog by remember { mutableStateOf(false) } +// var deleting by remember { mutableStateOf(-1) } +// var editing by remember { mutableStateOf(-1) } +// +// Text("Group list (${groups.size})", style = MaterialTheme.typography.headlineMedium) +// +// ListOrEmpty( +// groups, +// { Text( +// "Course ${course.name} (edition ${edition.name})\nhas no groups yet.", +// Modifier.align(Alignment.CenterHorizontally), textAlign = TextAlign.Center +// ) }, +// { Text("Add a group") }, +// { showDialog = true } +// ) { idx, it -> +// SelectEditDeleteRow( +// selected == idx, +// { onSelect(idx) }, { onSelect(-1) }, +// { editing = idx }, { deleting = idx } +// ) { +// Text(it.name, Modifier.padding(5.dp)) +// } +// } +// +// if(showDialog) { +// AddStringDialog("Group name", groups.map{ it.name }, { showDialog = false }) { onAdd(it) } +// } +// else if(editing != -1) { +// AddStringDialog("Group name", groups.map { it.name }, { editing = -1 }, groups[editing].name) { +// onUpdate(groups[editing], it) +// } +// } +// else if(deleting != -1) { +// ConfirmDeleteDialog( +// "a group", +// { deleting = -1 }, +// { onDelete(groups[deleting], deleting) } +// ) { Text(groups[deleting].name) } +// } +//} +// +//@Composable +//fun AssignmentPanel( +// course: Course, edition: Edition, assignments: List, +// selected: Int, onSelect: (Int) -> Unit, +// onAdd: (AssignmentType, String) -> Unit, onUpdate: (Assignment, String) -> Unit, +// onSwapOrder: (Assignment, Assignment) -> Unit, onDelete: (Assignment, Int) -> Unit +//) = Column(Modifier.padding(10.dp)) { +// var showDialog by remember { mutableStateOf(false) } +// var deleting by remember { mutableStateOf(-1) } +// var editing by remember { mutableStateOf(-1) } +// +// val dialog: @Composable (String, List, () -> Unit, String, (AssignmentType, String) -> Unit) -> Unit = +// { label, taken, onClose, current, onSave -> +// DialogWindow( +// onCloseRequest = onClose, +// state = rememberDialogState(size = DpSize(400.dp, 300.dp), position = WindowPosition(Alignment.Center)) +// ) { +// var name by remember(current) { mutableStateOf(current) } +// var tab by remember { mutableStateOf(AssignmentType.Solo) } +// +// Surface(Modifier.fillMaxSize()) { +// TabLayout( +// AssignmentType.entries, +// tab.ordinal, +// { tab = AssignmentType.entries[it] }, +// { Text(it.show) } +// ) { +// Box(Modifier.fillMaxSize().padding(10.dp)) { +// Column(Modifier.align(Alignment.Center)) { +// OutlinedTextField( +// name, +// { name = it }, +// Modifier.fillMaxWidth(), +// label = { Text(label) }, +// isError = name in taken +// ) +// CancelSaveRow(name.isNotBlank() && name !in taken, onClose) { +// onSave(tab, name) +// onClose() +// } +// } +// } +// } +// } +// } +// } +// +// Text("Assignment list (${assignments.size})", style = MaterialTheme.typography.headlineMedium) +// +// ListOrEmpty( +// assignments, +// { Text( +// "Course ${course.name} (edition ${edition.name})\nhas no assignments yet.", +// Modifier.align(Alignment.CenterHorizontally), textAlign = TextAlign.Center +// ) }, +// { Text("Add an assignment") }, +// { showDialog = true } +// ) { idx, it -> +// Selectable( +// selected == idx, +// { onSelect(idx) }, { onSelect(-1) } +// ) { +// Row { +// Text(it.name(), Modifier.padding(5.dp).align(Alignment.CenterVertically).weight(1f)) +// Column(Modifier.padding(2.dp)) { +// Icon(Icons.Default.ArrowUpward, "Move up", Modifier.clickable { +// if(idx > 0) onSwapOrder(assignments[idx], assignments[idx - 1]) +// }) +// Icon(Icons.Default.ArrowDownward, "Move down", Modifier.clickable { +// if(idx < assignments.size - 1) onSwapOrder(assignments[idx], assignments[idx + 1]) +// }) +// } +// Column(Modifier.padding(2.dp)) { +// Icon(Icons.Default.Edit, "Edit", Modifier.clickable { editing = idx }) +// Icon(Icons.Default.Delete, "Delete", Modifier.clickable { deleting = idx }) +// } +// } +// } +// } +// +// if(showDialog) { +// dialog("Assignment name", assignments.map{ it.name() }, { showDialog = false }, "", onAdd) +// } +// else if(editing != -1) { +// AddStringDialog("Assignment name", assignments.map { it.name() }, { editing = -1 }, assignments[editing].name()) { +// onUpdate(assignments[editing], it) +// } +// } +// else if(deleting != -1) { +// ConfirmDeleteDialog( +// "an assignment", +// { deleting = -1 }, +// { onDelete(assignments[deleting], deleting) } +// ) { if(deleting != -1) Text(assignments[deleting].name()) } +// } +//} +// +//@Composable +//fun StudentDialog( +// course: Course, +// edition: Edition, +// onClose: () -> Unit, +// availableStudents: List, +// onImport: (List) -> Unit, +// onAdd: (name: String, note: String, contact: String, addToEdition: Boolean) -> Unit +//) = DialogWindow( +// onCloseRequest = onClose, +// state = rememberDialogState(size = DpSize(600.dp, 400.dp), position = WindowPosition(Alignment.Center)) +//) { +// Surface(Modifier.fillMaxSize()) { +// Column(Modifier.padding(10.dp)) { +// var isImport by remember { mutableStateOf(false) } +// TabRow(if(isImport) 1 else 0) { +// Tab(!isImport, { isImport = false }) { Text("Add new student") } +// Tab(isImport, { isImport = true }) { Text("Add existing student") } +// } +// +// if(isImport) { +// if(availableStudents.isEmpty()) { +// Box(Modifier.fillMaxSize()) { +// Text("No students available to add to this course.", Modifier.align(Alignment.Center)) +// } +// } +// else { +// var selected by remember { mutableStateOf(setOf()) } +// +// val onClick = { idx: Int -> +// selected = if(idx in selected) selected - idx else selected + idx +// } +// +// Text("Select students to add to ${course.name} ${edition.name}") +// LazyColumn { +// itemsIndexed(availableStudents) { idx, student -> +// Surface( +// Modifier.fillMaxWidth().clickable { onClick(idx) }, +// tonalElevation = if (selected.contains(idx)) 5.dp else 0.dp +// ) { +// Row { +// Checkbox(selected.contains(idx), { onClick(idx) }) +// Text(student.name, Modifier.padding(5.dp)) +// } +// } +// } +// } +// CancelSaveRow(selected.isNotEmpty(), onClose) { +// onImport(selected.map { idx -> availableStudents[idx] }) +// onClose() +// } +// } +// } +// else { +// Box(Modifier.fillMaxSize()) { +// var name by remember { mutableStateOf("") } +// var contact by remember { mutableStateOf("") } +// var note by remember { mutableStateOf("") } +// var add by remember { mutableStateOf(true) } +// +// Column(Modifier.align(Alignment.Center)) { +// OutlinedTextField( +// name, +// { name = it }, +// Modifier.fillMaxWidth(), +// singleLine = true, +// label = { Text("Student name") }) +// OutlinedTextField( +// contact, +// { contact = it }, +// Modifier.fillMaxWidth(), +// singleLine = true, +// label = { Text("Student contact") }) +// OutlinedTextField( +// note, +// { note = it }, +// Modifier.fillMaxWidth(), +// singleLine = false, +// minLines = 3, +// label = { Text("Note") }) +// Row { +// Checkbox(add, { add = it }) +// Text( +// "Add student to ${course.name} ${edition.name}?", +// Modifier.align(Alignment.CenterVertically) +// ) +// } +// CancelSaveRow(name.isNotBlank() && contact.isNotBlank(), onClose) { +// onAdd(name, note, contact, add) +// onClose() +// } +// } +// } +// } +// } +// } +//} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/GroupsGradingView.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/GroupsGradingView.kt new file mode 100644 index 0000000..1e68cb8 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/GroupsGradingView.kt @@ -0,0 +1,266 @@ +package com.jaytux.grader.ui + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.Button +import androidx.compose.material3.Checkbox +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.LocalTextStyle +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.PrimaryScrollableTabRow +import androidx.compose.material3.ProvideTextStyle +import androidx.compose.material3.Surface +import androidx.compose.material3.Tab +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.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel +import com.jaytux.grader.GroupGrading +import com.jaytux.grader.app +import com.jaytux.grader.data.v2.CategoricGrade +import com.jaytux.grader.data.v2.Criterion +import com.jaytux.grader.data.v2.GradeType +import com.jaytux.grader.data.v2.Group +import com.jaytux.grader.data.v2.Student +import com.jaytux.grader.viewmodel.Grade +import com.jaytux.grader.viewmodel.GroupsGradingVM +import com.jaytux.grader.viewmodel.Navigator +import org.jetbrains.exposed.v1.jdbc.transactions.transaction +import java.util.UUID + +@Composable +fun GroupsGradingTitle(data: GroupGrading) = Text("Courses / ${data.course.name} / ${data.edition.name} / Group Assignments / ${data.assignment.name} / Grading") + +@Composable +fun GroupsGradingView(data: GroupGrading, token: Navigator.NavToken) { + val vm = viewModel(key = data.assignment.id.toString()) { + GroupsGradingVM(data.course, data.edition, data.assignment) + } + val groups by vm.groupList.entities + val focus by vm.focus + + val selectedGroup = remember(focus, groups) { groups.getOrNull(focus) } + + Column(Modifier.padding(10.dp)) { + Text("Grading ${vm.base.name}", Modifier.weight(1f), style = MaterialTheme.typography.headlineMedium) + Text("Group assignment in ${vm.course.name} - ${vm.edition.name}") + Spacer(Modifier.height(5.dp)) + Row(Modifier.fillMaxSize()) { + Surface(Modifier.weight(0.25f).fillMaxHeight(), tonalElevation = 7.dp) { + ListOrEmpty(groups, { Text("No groups yet.") }) { idx, it -> + QuickAGroup(idx == focus, { vm.focusGroup(idx) }, it) + } + } + + Surface(Modifier.weight(0.75f).fillMaxHeight(), tonalElevation = 1.dp) { + if (focus == -1 || selectedGroup == null) { + Box(Modifier.weight(0.75f).fillMaxHeight()) { + Text("Select a group to start grading.", Modifier.align(Alignment.Center)) + } + } else { + Column(Modifier.weight(0.75f).padding(15.dp)) { + Row { + IconButton({ vm.focusPrev() }, Modifier.align(Alignment.CenterVertically), enabled = focus > 0) { + Icon(DoubleBack, "Previous group") + } + Spacer(Modifier.width(10.dp)) + Text(selectedGroup.group.name, Modifier.align(Alignment.CenterVertically), style = MaterialTheme.typography.headlineSmall) + Spacer(Modifier.weight(1f)) + IconButton({ vm.focusNext() }, Modifier.align(Alignment.CenterVertically), enabled = focus < groups.size - 1) { + Icon(DoubleForward, "Next group") + } + } + + Spacer(Modifier.height(10.dp)) + + val global by vm.globalGrade.entity + val byCriteria by vm.gradeList.entities + + Surface(Modifier.fillMaxSize(), color = Color.White, shape = MaterialTheme.shapes.medium) { + LazyColumn { + items(byCriteria ?: listOf()) { (crit, fdbk) -> + var isOpen by remember(selectedGroup) { mutableStateOf(false) } + Column(Modifier.padding(5.dp)) { + GFWidget(crit, selectedGroup.group, fdbk, vm, global to byCriteria, isOpen) { isOpen = !isOpen } + Spacer(Modifier.height(5.dp)) + } + } + global?.let { fdbk -> + item { + Box(Modifier.padding(5.dp)) { + GFWidget( + vm.global, selectedGroup.group, fdbk, vm, global to byCriteria, true, + (byCriteria ?: listOf()).flatMap { (_, it) -> + it.overrides.mapNotNull { o -> + o.second?.let { _ -> o.first.id.value } + } + }.toSet() + ) {} + } + } + } + } + } + } + } + } + } + } +} + +@Composable +fun QuickAGroup(isFocus: Boolean, onFocus: () -> Unit, group: GroupsGradingVM.GroupData) { + Surface(tonalElevation = if(isFocus) 15.dp else 0.dp, shape = MaterialTheme.shapes.small) { + Column(Modifier.fillMaxWidth().clickable { onFocus() }.padding(10.dp)) { + Text(group.group.name, fontWeight = FontWeight.Bold) + Text("${group.students.size} student(s)", Modifier.padding(start = 10.dp), fontStyle = FontStyle.Italic) + } + } +} + +private fun gradeState(crit: GroupsGradingVM.CritData, current: Grade?): Grade = transaction { + if(current == null) Grade.default(crit.criterion.gradeType, crit.cat, crit.num) + when(crit.criterion.gradeType) { + GradeType.CATEGORIC -> + if(current is Grade.Categoric && current.grade.id == crit.criterion.categoricGrade?.id) current + else Grade.default(GradeType.CATEGORIC, crit.cat, crit.num) + GradeType.NUMERIC -> + if(current is Grade.Numeric && current.grade.id == crit.criterion.numericGrade?.id) current + else Grade.default(GradeType.NUMERIC, crit.cat, crit.num) + GradeType.PERCENTAGE -> + current as? Grade.Percentage ?: Grade.default(GradeType.PERCENTAGE, crit.cat, crit.num) + GradeType.NONE -> + current as? Grade.FreeText ?: Grade.default(GradeType.NONE, crit.cat, crit.num) + } +} + +@Composable +fun GFWidget(crit: GroupsGradingVM.CritData, gr: Group, feedback: GroupsGradingVM.FeedbackData, vm: GroupsGradingVM, key: Any, isOpen: Boolean, markOverridden: Set = setOf(), onToggle: () -> Unit) = Surface( + Modifier.fillMaxWidth(), + shape = MaterialTheme.shapes.medium, + shadowElevation = 3.dp +) { + Column { + Surface(tonalElevation = 5.dp) { + Row(Modifier.fillMaxWidth().clickable { onToggle() }.padding(10.dp)) { + Icon(if(isOpen) ChevronDown else ChevronRight, "Toggle criterion detail grading", Modifier.align(Alignment.CenterVertically)) + Spacer(Modifier.width(5.dp)) + Text(crit.criterion.name, Modifier.align(Alignment.CenterVertically), style = MaterialTheme.typography.bodyLarge) + Spacer(Modifier.width(5.dp)) + feedback.groupLevel?.grade?.let { + Row(Modifier.align(Alignment.Bottom)) { + ProvideTextStyle(MaterialTheme.typography.bodySmall) { + Text("(Grade: ") + it.render() + Text(")") + } + } + } + } + } + + if(isOpen) { + Row(Modifier.padding(10.dp)) { + var grade by remember(key, feedback) { mutableStateOf(gradeState(crit, feedback.groupLevel?.grade)) } + var text by remember(key, feedback) { mutableStateOf(feedback.groupLevel?.feedback ?: "") } + Column(Modifier.weight(0.5f).height(IntrinsicSize.Min)) { + + GradePicker(grade, key = crit to gr) { grade = it } + Spacer(Modifier.height(5.dp)) + OutlinedTextField(text, { text = it }, label = { Text("Feedback") }, singleLine = false, minLines = 5, modifier = Modifier.fillMaxWidth().weight(1f)) + Spacer(Modifier.height(5.dp)) + Button({ vm.modGroupFeedback(crit.criterion, gr, grade, text) }) { + Text("Save grade and feedback") + } + } + + feedback.groupLevel?.let { groupLevel -> + Spacer(Modifier.width(10.dp)) + + Surface(Modifier.weight(0.5f).height(IntrinsicSize.Min), tonalElevation = 10.dp, shape = MaterialTheme.shapes.small) { + Column(Modifier.padding(10.dp)) { + Text("Individual overrides", style = MaterialTheme.typography.bodyLarge) + feedback.overrides.forEach { (student, it) -> + var enable by remember(key, it) { mutableStateOf(false) } + var maybeRemoving by remember(key, it) { mutableStateOf(false) } + var sGrade by remember(key, it) { mutableStateOf(gradeState(crit, it?.grade ?: grade)) } + var sText by remember(key, it) { mutableStateOf(it?.feedback ?: "") } + + Column { + Row { + Checkbox(enable, { if(it) { enable = true } else { maybeRemoving = true } }) + Spacer(Modifier.width(5.dp)) + Text(student.name, Modifier.align(Alignment.CenterVertically)) + if(student.id.value in markOverridden) { + Spacer(Modifier.width(5.dp)) + Text("(Overridden)", Modifier.align(Alignment.CenterVertically), style = MaterialTheme.typography.bodySmall, fontStyle = FontStyle.Italic, color = Color.Red) + } + } + + if(enable) Row { + Spacer(Modifier.width(15.dp)) + Surface(color = Color.White, shape = MaterialTheme.shapes.small) { + Column(Modifier.padding(10.dp)) { + Spacer(Modifier.height(5.dp)) + GradePicker(sGrade, key = crit to gr app student) { sGrade = it } + Spacer(Modifier.height(5.dp)) + OutlinedTextField(sText, { sText = it }, label = { Text("Feedback") }, singleLine = true, modifier = Modifier.fillMaxWidth()) + Spacer(Modifier.height(5.dp)) + Button({ vm.modOverrideFeedback(crit.criterion, gr, student, groupLevel, sGrade, sText) }) { + Text("Save override") + } + } + } + } + } + + if(maybeRemoving) { + ConfirmDeleteDialog("the individual grade for ${student.name}", { maybeRemoving = false }, { + maybeRemoving = false + enable = false + vm.rmOverrideFeedback(crit.criterion, gr, student) + }) { + Column { + Row { + Text("Grade:") + sGrade.render() + } + Row { + Text("Feedback:") + if(sText.isBlank()) Text("No feedback", fontStyle = FontStyle.Italic) + else Text(sText) + } + } + } + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/GroupsView.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/GroupsView.kt new file mode 100644 index 0000000..83ace41 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/GroupsView.kt @@ -0,0 +1,285 @@ +package com.jaytux.grader.ui + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.draganddrop.dragAndDropSource +import androidx.compose.foundation.draganddrop.dragAndDropTarget +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.LocalTextStyle +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +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.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.Modifier +import androidx.compose.ui.draganddrop.DragAndDropEvent +import androidx.compose.ui.draganddrop.DragAndDropTarget +import androidx.compose.ui.draganddrop.DragAndDropTransferAction +import androidx.compose.ui.draganddrop.DragAndDropTransferData +import androidx.compose.ui.draganddrop.DragAndDropTransferable +import androidx.compose.ui.draganddrop.awtTransferable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import com.jaytux.grader.data.v2.Group +import com.jaytux.grader.data.v2.Student +import com.jaytux.grader.viewmodel.EditionVM +import org.jetbrains.exposed.v1.jdbc.transactions.transaction +import java.awt.datatransfer.DataFlavor +import java.awt.datatransfer.StringSelection +import java.awt.datatransfer.Transferable +import java.util.UUID + +@Composable +fun GroupsView(vm: EditionVM) = Row(Modifier.fillMaxSize()) { + val groups by vm.groupList.entities + val focus by vm.focusIndex + var swappingRole by remember { mutableStateOf(-1) } + + val group = remember(groups, focus) { if(focus != -1) groups[focus] else null } + val grades by vm.groupGrades.entities + + Surface(Modifier.weight(0.25f).fillMaxHeight(), tonalElevation = 7.dp) { + ListOrEmpty(groups, { Text("No groups yet.") }) { idx, it -> + QuickGroup(idx, it, vm) + } + } + + Surface(Modifier.weight(0.75f).fillMaxHeight(), tonalElevation = 1.dp) { + if(group == null) { + Box(Modifier.weight(0.75f).fillMaxHeight()) { + Text("Select a group to view details.", Modifier.align(Alignment.Center)) + } + } + else { + Column(Modifier.padding(10.dp)) { + Text(group.group.name, style = MaterialTheme.typography.headlineMedium) + Spacer(Modifier.height(5.dp)) + Row(Modifier.padding(5.dp)) { + var showTargetBorder by remember { mutableStateOf(false) } + val ddTarget = remember { + DDTarget({ showTargetBorder = true }, { showTargetBorder = false }, { DDTarget.extractStudent(it) }) { + vm.addStudentToGroup(it, group.group, null) + } + } + + Column(Modifier.weight(0.75f)) { + Surface( + Modifier.weight(0.5f).then(if(showTargetBorder) Modifier.border(BorderStroke(3.dp, Color.Black)) else Modifier) + .dragAndDropTarget({ true }, target = ddTarget), + shape = MaterialTheme.shapes.medium, color = Color.White, shadowElevation = 1.dp) { + LazyColumn { + item { + Surface(tonalElevation = 15.dp) { + Row(Modifier.fillMaxWidth().padding(10.dp)) { + Text("Members", style = MaterialTheme.typography.headlineSmall, modifier = Modifier.padding(10.dp)) + } + } + } + + itemsIndexed(group.members) { idx, (student, role) -> + Row(Modifier.clickable { vm.focus(student) }.padding(10.dp)) { + Column(Modifier.weight(1f)) { + Text(student.name, fontWeight = FontWeight.Bold) + if(student.contact.isEmpty()) + Text("No contact info.", fontStyle = FontStyle.Italic, color = LocalTextStyle.current.color.copy(alpha = 0.5f)) + else Text(student.contact) + } + if(role != null) { + Surface(Modifier.align(Alignment.CenterVertically), tonalElevation = 5.dp, shape = MaterialTheme.shapes.small) { + Box(Modifier.clickable { swappingRole = -1 }.clickable { swappingRole = idx }) { + Text(role, Modifier.padding(horizontal = 5.dp, vertical = 2.dp), style = MaterialTheme.typography.labelMedium) + } + } + } + else { + Text("No role", Modifier.align(Alignment.CenterVertically).clickable { swappingRole = idx }, fontStyle = FontStyle.Italic, color = LocalTextStyle.current.color.copy(alpha = 0.5f)) + } + IconButton({ vm.rmStudentFromGroup(student, group.group) }, Modifier.align(Alignment.CenterVertically)) { + Icon(PersonMinus, "Remove ${student.name} from group") + } + } + } + + if(group.members.isEmpty()) { + item { + Box(Modifier.fillMaxWidth().padding(vertical = 5.dp)) { + Text("No members yet.", Modifier.align(Alignment.Center), fontStyle = FontStyle.Italic, color = LocalTextStyle.current.color.copy(alpha = 0.5f)) + } + } + } + } + } + + Spacer(Modifier.height(10.dp)) + + Column(Modifier.weight(0.5f)) { + Text("Grade Summary: ", style = MaterialTheme.typography.headlineSmall) + Surface(shape = MaterialTheme.shapes.medium, color = Color.White) { + LazyColumn { + item { + Surface(tonalElevation = 15.dp) { + Row(Modifier.padding(10.dp)) { + Text("Assignment", Modifier.weight(0.66f)) + Text("Grade", Modifier.weight(0.33f)) + } + } + } + + items(grades ?: listOf()) { + Column(Modifier.padding(10.dp)) { + Row { + Text(it.first.name, Modifier.weight(0.66f)) + it.second?.render(Modifier.weight(0.33f)) + ?: Text("---", Modifier.weight(0.33f), color = LocalTextStyle.current.color.copy(alpha = 0.5f)) + } + } + } + + if((grades ?: listOf()).isEmpty()) { + item { + Box(Modifier.fillMaxWidth().padding(vertical = 5.dp)) { + Text("No grades yet.", Modifier.align(Alignment.Center), fontStyle = FontStyle.Italic, color = LocalTextStyle.current.color.copy(alpha = 0.5f)) + } + } + } + } + } + } + } + + Spacer(Modifier.width(10.dp)) + + val available by vm.groupAvailableStudents.entities + Surface(Modifier.weight(0.25f), shape = MaterialTheme.shapes.medium, color = Color.White, shadowElevation = 1.dp) { + LazyColumn { + item { + Surface(tonalElevation = 15.dp) { + Row(Modifier.fillMaxWidth().padding(10.dp)) { + Text("Available Students", style = MaterialTheme.typography.headlineSmall, modifier = Modifier.padding(10.dp)) + } + } + } + + items(available ?: listOf()) { student -> + AvailableStudent(student, group.group, vm) + } + + if((available ?: listOf()).isEmpty()) { + item { + Box(Modifier.fillMaxWidth().padding(vertical = 5.dp)) { + Text("No available students.", Modifier.align(Alignment.Center), fontStyle = FontStyle.Italic, color = LocalTextStyle.current.color.copy(alpha = 0.5f)) + } + } + } + } + } + } + } + } + } + + if(swappingRole != -1) { + if(group != null) { + val roles by vm.usedRoles.entities + RolePicker(roles, group.members[swappingRole].second, { swappingRole = -1 }) { upd -> + vm.setStudentRole(group.members[swappingRole].first, group.group, upd) + } + } + else { + swappingRole = -1 + } + } +} + +private class DDTarget(val onStart: () -> Unit, val onEnd: () -> Unit, val validator: (Transferable) -> T?, val handle: (T) -> Unit) : DragAndDropTarget { + override fun onStarted(event: DragAndDropEvent) { + onStart() + super.onStarted(event) + } + + override fun onEnded(event: DragAndDropEvent) { + onEnd() + super.onEnded(event) + } + + @OptIn(ExperimentalComposeUiApi::class) + override fun onDrop(event: DragAndDropEvent): Boolean { + println("Action at the target: ${event.action}") + + return validator(event.awtTransferable)?.let { + handle(it) + true + } ?: false + } + + companion object { + @OptIn(ExperimentalComposeUiApi::class) + fun mkStudentTransferable(student: Student) = DragAndDropTransferable(StringSelection("com.jaytux.grader:student:${student.id.value}")) + + fun extractStudent(transf: Transferable): Student? { + if(transf.isDataFlavorSupported(DataFlavor.stringFlavor)) { + val raw = transf.getTransferData(DataFlavor.stringFlavor) as String + val prefix = "com.jaytux.grader:student:" + if(raw.startsWith(prefix)) { + val id = UUID.fromString(raw.removePrefix(prefix)) + return transaction { Student.findById(id) } + } + } + return null + } + } +} + +@Composable +fun QuickGroup(idx: Int, group: EditionVM.GroupData, vm: EditionVM) { + val focus by vm.focusIndex + Surface(tonalElevation = if(focus == idx) 15.dp else 0.dp, shape = MaterialTheme.shapes.small) { + Column(Modifier.fillMaxWidth().clickable { vm.focus(idx) }.padding(10.dp)) { + Text(group.group.name, fontWeight = FontWeight.Bold) + Text("${group.members.size} member(s)", Modifier.padding(start = 10.dp), fontStyle = FontStyle.Italic) + } + } +} + +@OptIn(ExperimentalComposeUiApi::class) +@Composable +fun AvailableStudent(student: Student, group: Group, vm: EditionVM) { + Row(Modifier.padding(10.dp).dragAndDropSource( + drawDragDecoration = {}, + ) { + DragAndDropTransferData( + transferable = DDTarget.mkStudentTransferable(student), + supportedActions = listOf(DragAndDropTransferAction.Move), + dragDecorationOffset = it, + onTransferCompleted = { act -> println("Source action: $act") } + ) + }) { + Text(student.name, Modifier.align(Alignment.CenterVertically).weight(1f), fontWeight = FontWeight.Bold) + IconButton({ vm.addStudentToGroup(student, group, null) }) { + Icon(CirclePlus, "Add ${student.name} to group") + } + } +} diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/HomeView.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/HomeView.kt new file mode 100644 index 0000000..571b724 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/HomeView.kt @@ -0,0 +1,147 @@ +package com.jaytux.grader.ui + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import androidx.lifecycle.viewmodel.compose.viewModel +import com.jaytux.grader.EditionDetail +import com.jaytux.grader.data.v2.Edition +import com.jaytux.grader.viewmodel.HomeVM +import com.jaytux.grader.viewmodel.Navigator + +@Composable +fun HomeTitle() = Text("Grader") + +@Composable +fun HomeView(token: Navigator.NavToken) { + val vm = viewModel() + val courses by vm.courses.entities + var addingCourse by remember { mutableStateOf(false) } + + LazyColumn(Modifier.padding(15.dp)) { + item { + Row { + Text("Courses Overview", Modifier.weight(0.8f), style = MaterialTheme.typography.headlineMedium) + Button({ addingCourse = true }) { + Icon(CirclePlus, "Add course") + Spacer(Modifier.width(5.dp)) + Text("Add course") + } + } + } + + items(courses) { + CourseCard(it, vm) { e -> token.navTo(EditionDetail(e, it.course)) } + } + } + + if(addingCourse) { + AddStringDialog("Course Name", courses.map { it.course.name }, { addingCourse = false }, "") { + vm.mkCourse(it) + } + } +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun CourseCard(course: HomeVM.CourseData, vm: HomeVM, onOpenEdition: (Edition) -> Unit) { + var addingEdition by remember { mutableStateOf(false) } + var deleting by remember { mutableStateOf(false) } + Surface(shape = MaterialTheme.shapes.medium, tonalElevation = 2.dp, shadowElevation = 5.dp, modifier = Modifier.fillMaxWidth().padding(10.dp)) { + Column(Modifier.padding(8.dp)) { + Row { + Text(course.course.name, style = MaterialTheme.typography.headlineSmall, modifier = Modifier.weight(1f)) + IconButton({ deleting = true }) { Icon(Delete, "Delete course") } + } + + Row { + Text("Editions", style = MaterialTheme.typography.headlineSmall, modifier = Modifier.weight(1f)) + Button({ addingEdition = true }) { + Icon(CirclePlus, "Add edition") + Spacer(Modifier.width(5.dp)) + Text("Add edition") + } + } + + FlowRow(horizontalArrangement = Arrangement.SpaceEvenly) { + course.editions.forEach { EditionCard(course.course.name, it, vm, onOpenEdition) } + } + + if(course.archived.isNotEmpty()) { + Text("Archived editions", style = MaterialTheme.typography.headlineSmall) + FlowRow(horizontalArrangement = Arrangement.SpaceEvenly) { + course.archived.forEach { EditionCard(course.course.name, it, vm, onOpenEdition) } + } + } + } + } + + if(addingEdition) { + AddStringDialog("Edition Name (in ${course.course.name})", course.editions.map { it.edition.name }, { addingEdition = false }, "") { + vm.mkEdition(course.course, it) + } + } + + if(deleting) { + ConfirmDeleteDialog("a course", { deleting = false }, { vm.rmCourse(course.course) }) { + Text(course.course.name) + } + } +} + +@Composable +fun EditionCard(courseName: String, edition: HomeVM.EditionData, vm: HomeVM, onOpen: (Edition) -> Unit) { + val type = if(edition.edition.archived) "Archived" else "Active" + var deleting by remember { mutableStateOf(false) } + + Surface(shape = MaterialTheme.shapes.medium, tonalElevation = 2.dp, shadowElevation = 5.dp, modifier = Modifier.padding(10.dp).clickable { onOpen(edition.edition) }) { + Column(Modifier.padding(10.dp).width(IntrinsicSize.Min)) { + Column(Modifier.width(IntrinsicSize.Max)) { + Text(edition.edition.name, style = MaterialTheme.typography.headlineSmall) + Text( + "$type\n${edition.students.size} student(s) • ${edition.groups.size} group(s) • ${edition.assignments.size} assignment(s)", + style = MaterialTheme.typography.bodyMedium + ) + } + + Spacer(Modifier.height(5.dp)) + Row { + if(edition.edition.archived) { + Button({ vm.unarchiveEdition(edition.edition) }, Modifier.weight(0.5f)) { + Icon(Unarchive, "Unarchive edition") + Spacer(Modifier.width(5.dp)) + Text("Unarchive edition") + } + } + else { + Button({ vm.archiveEdition(edition.edition) }, Modifier.weight(0.5f)) { + Icon(Archive, "Archive edition") + Spacer(Modifier.width(5.dp)) + Text("Archive edition") + } + } + Spacer(Modifier.width(10.dp)) + Button({ deleting = true }, Modifier.weight(0.5f)) { + Icon(Delete, "Archive edition") + Spacer(Modifier.width(5.dp)) + Text("Delete edition") + } + } + } + } + + if(deleting) { + ConfirmDeleteDialog("an edition", { deleting = false }, { vm.rmEdition(edition.edition) }) { + Column { + Text(edition.edition.name, Modifier.align(Alignment.CenterHorizontally)) + Text("Edition in course $courseName", Modifier.align(Alignment.CenterHorizontally)) + } + } + } +} diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Icons.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Icons.kt index fe5507f..36efb51 100644 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Icons.kt +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Icons.kt @@ -61,7 +61,7 @@ val ChevronDown: ImageVector by lazy { }.build() } -public val ChevronLeft: ImageVector by lazy { +val ChevronLeft: ImageVector by lazy { ImageVector.Builder( name = "ChevronLeft", defaultWidth = 24.dp, @@ -86,3 +86,1306 @@ public val ChevronLeft: ImageVector by lazy { } }.build() } + +val Delete: ImageVector by lazy { + ImageVector.Builder( + name = "delete", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 960f, + viewportHeight = 960f + ).apply { + path( + fill = SolidColor(Color.Black) + ) { + moveTo(280f, 840f) + quadToRelative(-33f, 0f, -56.5f, -23.5f) + reflectiveQuadTo(200f, 760f) + verticalLineToRelative(-520f) + horizontalLineToRelative(-40f) + verticalLineToRelative(-80f) + horizontalLineToRelative(200f) + verticalLineToRelative(-40f) + horizontalLineToRelative(240f) + verticalLineToRelative(40f) + horizontalLineToRelative(200f) + verticalLineToRelative(80f) + horizontalLineToRelative(-40f) + verticalLineToRelative(520f) + quadToRelative(0f, 33f, -23.5f, 56.5f) + reflectiveQuadTo(680f, 840f) + horizontalLineTo(280f) + close() + moveToRelative(400f, -600f) + horizontalLineTo(280f) + verticalLineToRelative(520f) + horizontalLineToRelative(400f) + verticalLineToRelative(-520f) + close() + moveTo(360f, 680f) + horizontalLineToRelative(80f) + verticalLineToRelative(-360f) + horizontalLineToRelative(-80f) + verticalLineToRelative(360f) + close() + moveToRelative(160f, 0f) + horizontalLineToRelative(80f) + verticalLineToRelative(-360f) + horizontalLineToRelative(-80f) + verticalLineToRelative(360f) + close() + moveTo(280f, 240f) + verticalLineToRelative(520f) + verticalLineToRelative(-520f) + close() + } + }.build() +} + +val CirclePlus: ImageVector by lazy { + ImageVector.Builder( + name = "circle-plus", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 24f, + viewportHeight = 24f + ).apply { + path( + fill = SolidColor(Color.Transparent), + stroke = SolidColor(Color.Black), + strokeLineWidth = 2f, + strokeLineCap = StrokeCap.Round, + strokeLineJoin = StrokeJoin.Round + ) { + moveTo(22f, 12f) + arcTo(10f, 10f, 0f, false, true, 12f, 22f) + arcTo(10f, 10f, 0f, false, true, 2f, 12f) + arcTo(10f, 10f, 0f, false, true, 22f, 12f) + close() + } + path( + fill = SolidColor(Color.Transparent), + stroke = SolidColor(Color.Black), + strokeLineWidth = 2f, + strokeLineCap = StrokeCap.Round, + strokeLineJoin = StrokeJoin.Round + ) { + moveTo(8f, 12f) + horizontalLineToRelative(8f) + } + path( + fill = SolidColor(Color.Transparent), + stroke = SolidColor(Color.Black), + strokeLineWidth = 2f, + strokeLineCap = StrokeCap.Round, + strokeLineJoin = StrokeJoin.Round + ) { + moveTo(12f, 8f) + verticalLineToRelative(8f) + } + }.build() +} + +val LibraryPlus: ImageVector by lazy { + ImageVector.Builder( + name = "library-plus", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 24f, + viewportHeight = 24f + ).apply { + path( + fill = SolidColor(Color.Transparent), + stroke = SolidColor(Color.Black), + strokeLineWidth = 2f, + strokeLineCap = StrokeCap.Round, + strokeLineJoin = StrokeJoin.Round + ) { + moveTo(7f, 3f) + moveToRelative(0f, 2.667f) + arcToRelative(2.667f, 2.667f, 0f, false, true, 2.667f, -2.667f) + horizontalLineToRelative(8.666f) + arcToRelative(2.667f, 2.667f, 0f, false, true, 2.667f, 2.667f) + verticalLineToRelative(8.666f) + arcToRelative(2.667f, 2.667f, 0f, false, true, -2.667f, 2.667f) + horizontalLineToRelative(-8.666f) + arcToRelative(2.667f, 2.667f, 0f, false, true, -2.667f, -2.667f) + close() + } + path( + fill = SolidColor(Color.Transparent), + stroke = SolidColor(Color.Black), + strokeLineWidth = 2f, + strokeLineCap = StrokeCap.Round, + strokeLineJoin = StrokeJoin.Round + ) { + moveTo(4.012f, 7.26f) + arcToRelative(2.005f, 2.005f, 0f, false, false, -1.012f, 1.737f) + verticalLineToRelative(10f) + curveToRelative(0f, 1.1f, 0.9f, 2f, 2f, 2f) + horizontalLineToRelative(10f) + curveToRelative(0.75f, 0f, 1.158f, -0.385f, 1.5f, -1f) + } + path( + fill = SolidColor(Color.Transparent), + stroke = SolidColor(Color.Black), + strokeLineWidth = 2f, + strokeLineCap = StrokeCap.Round, + strokeLineJoin = StrokeJoin.Round + ) { + moveTo(11f, 10f) + horizontalLineToRelative(6f) + } + path( + fill = SolidColor(Color.Transparent), + stroke = SolidColor(Color.Black), + strokeLineWidth = 2f, + strokeLineCap = StrokeCap.Round, + strokeLineJoin = StrokeJoin.Round + ) { + moveTo(14f, 7f) + verticalLineToRelative(6f) + } + }.build() +} + +val Archive: ImageVector by lazy { + ImageVector.Builder( + name = "archive", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 960f, + viewportHeight = 960f + ).apply { + path( + fill = SolidColor(Color.Black) + ) { + moveTo(480f, 720f) + lineToRelative(160f, -160f) + lineToRelative(-56f, -56f) + lineToRelative(-64f, 64f) + verticalLineToRelative(-168f) + horizontalLineToRelative(-80f) + verticalLineToRelative(168f) + lineToRelative(-64f, -64f) + lineToRelative(-56f, 56f) + lineToRelative(160f, 160f) + close() + moveTo(200f, 320f) + verticalLineToRelative(440f) + horizontalLineToRelative(560f) + verticalLineToRelative(-440f) + horizontalLineTo(200f) + close() + moveToRelative(0f, 520f) + quadToRelative(-33f, 0f, -56.5f, -23.5f) + reflectiveQuadTo(120f, 760f) + verticalLineToRelative(-499f) + quadToRelative(0f, -14f, 4.5f, -27f) + reflectiveQuadToRelative(13.5f, -24f) + lineToRelative(50f, -61f) + quadToRelative(11f, -14f, 27.5f, -21.5f) + reflectiveQuadTo(250f, 120f) + horizontalLineToRelative(460f) + quadToRelative(18f, 0f, 34.5f, 7.5f) + reflectiveQuadTo(772f, 149f) + lineToRelative(50f, 61f) + quadToRelative(9f, 11f, 13.5f, 24f) + reflectiveQuadToRelative(4.5f, 27f) + verticalLineToRelative(499f) + quadToRelative(0f, 33f, -23.5f, 56.5f) + reflectiveQuadTo(760f, 840f) + horizontalLineTo(200f) + close() + moveToRelative(16f, -600f) + horizontalLineToRelative(528f) + lineToRelative(-34f, -40f) + horizontalLineTo(250f) + lineToRelative(-34f, 40f) + close() + moveToRelative(264f, 300f) + close() + } + }.build() +} + +val Unarchive: ImageVector by lazy { + ImageVector.Builder( + name = "unarchive", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 24f, + viewportHeight = 24f + ).apply { + path( + fill = SolidColor(Color.Transparent) + ) { + moveTo(0f, 0f) + horizontalLineToRelative(24f) + verticalLineToRelative(24f) + horizontalLineTo(0f) + verticalLineTo(0f) + close() + } + path( + fill = SolidColor(Color.Black) + ) { + moveTo(20.54f, 5.23f) + lineToRelative(-1.39f, -1.68f) + curveTo(18.88f, 3.21f, 18.47f, 3f, 18f, 3f) + horizontalLineTo(6f) + curveToRelative(-0.47f, 0f, -0.88f, 0.21f, -1.16f, 0.55f) + lineTo(3.46f, 5.23f) + curveTo(3.17f, 5.57f, 3f, 6.02f, 3f, 6.5f) + verticalLineTo(19f) + curveToRelative(0f, 1.1f, 0.9f, 2f, 2f, 2f) + horizontalLineToRelative(14f) + curveToRelative(1.1f, 0f, 2f, -0.9f, 2f, -2f) + verticalLineTo(6.5f) + curveToRelative(0f, -0.48f, -0.17f, -0.93f, -0.46f, -1.27f) + close() + moveTo(6.24f, 5f) + horizontalLineToRelative(11.52f) + lineToRelative(0.83f, 1f) + horizontalLineTo(5.42f) + lineToRelative(0.82f, -1f) + close() + moveTo(5f, 19f) + verticalLineTo(8f) + horizontalLineToRelative(14f) + verticalLineToRelative(11f) + horizontalLineTo(5f) + close() + moveToRelative(3f, -5f) + horizontalLineToRelative(2.55f) + verticalLineToRelative(3f) + horizontalLineToRelative(2.9f) + verticalLineToRelative(-3f) + horizontalLineTo(16f) + lineToRelative(-4f, -4f) + close() + } + }.build() +} + +val FormatSize: ImageVector by lazy { + ImageVector.Builder( + name = "format_size", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 24f, + viewportHeight = 24f + ).apply { + path( + fill = SolidColor(Color.Transparent) + ) { + moveTo(0f, 0f) + horizontalLineToRelative(24f) + verticalLineToRelative(24f) + horizontalLineTo(0f) + verticalLineTo(0f) + close() + } + path( + fill = SolidColor(Color.Black) + ) { + moveTo(9f, 4f) + verticalLineToRelative(3f) + horizontalLineToRelative(5f) + verticalLineToRelative(12f) + horizontalLineToRelative(3f) + verticalLineTo(7f) + horizontalLineToRelative(5f) + verticalLineTo(4f) + horizontalLineTo(9f) + close() + moveToRelative(-6f, 8f) + horizontalLineToRelative(3f) + verticalLineToRelative(7f) + horizontalLineToRelative(3f) + verticalLineToRelative(-7f) + horizontalLineToRelative(3f) + verticalLineTo(9f) + horizontalLineTo(3f) + verticalLineToRelative(3f) + close() + } + }.build() +} + +val CircleFilled: ImageVector by lazy { + ImageVector.Builder( + name = "circle-large-filled", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 16f, + viewportHeight = 16f + ).apply { + path( + fill = SolidColor(Color.Black) + ) { + moveTo(8f, 1f) + curveTo(8.64258f, 1f, 9.26237f, 1.08431f, 9.85938f, 1.25293f) + curveTo(10.4564f, 1.41699f, 11.0124f, 1.65169f, 11.5273f, 1.95703f) + curveTo(12.0469f, 2.26237f, 12.5186f, 2.62923f, 12.9424f, 3.05762f) + curveTo(13.3708f, 3.48145f, 13.7376f, 3.95312f, 14.043f, 4.47266f) + curveTo(14.3483f, 4.98763f, 14.583f, 5.54362f, 14.7471f, 6.14062f) + curveTo(14.9157f, 6.73763f, 15f, 7.35742f, 15f, 8f) + curveTo(15f, 8.64258f, 14.9157f, 9.26237f, 14.7471f, 9.85938f) + curveTo(14.583f, 10.4564f, 14.3483f, 11.0146f, 14.043f, 11.5342f) + curveTo(13.7376f, 12.0492f, 13.3708f, 12.5208f, 12.9424f, 12.9492f) + curveTo(12.5186f, 13.373f, 12.0469f, 13.7376f, 11.5273f, 14.043f) + curveTo(11.0124f, 14.3483f, 10.4564f, 14.5853f, 9.85938f, 14.7539f) + curveTo(9.26237f, 14.918f, 8.64258f, 15f, 8f, 15f) + curveTo(7.35742f, 15f, 6.73763f, 14.918f, 6.14062f, 14.7539f) + curveTo(5.54362f, 14.5853f, 4.98535f, 14.3483f, 4.46582f, 14.043f) + curveTo(3.95085f, 13.7376f, 3.47917f, 13.373f, 3.05078f, 12.9492f) + curveTo(2.62695f, 12.5208f, 2.26237f, 12.0492f, 1.95703f, 11.5342f) + curveTo(1.65169f, 11.0146f, 1.41471f, 10.4564f, 1.24609f, 9.85938f) + curveTo(1.08203f, 9.26237f, 1f, 8.64258f, 1f, 8f) + curveTo(1f, 7.35742f, 1.08203f, 6.73763f, 1.24609f, 6.14062f) + curveTo(1.41471f, 5.54362f, 1.65169f, 4.98763f, 1.95703f, 4.47266f) + curveTo(2.26237f, 3.95312f, 2.62695f, 3.48145f, 3.05078f, 3.05762f) + curveTo(3.47917f, 2.62923f, 3.95085f, 2.26237f, 4.46582f, 1.95703f) + curveTo(4.98535f, 1.65169f, 5.54362f, 1.41699f, 6.14062f, 1.25293f) + curveTo(6.73763f, 1.08431f, 7.35742f, 1f, 8f, 1f) + close() + } + }.build() +} + +val CircleOutline: ImageVector by lazy { + ImageVector.Builder( + name = "circle-large", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 16f, + viewportHeight = 16f + ).apply { + path( + fill = SolidColor(Color.Black) + ) { + moveTo(9.58854f, 2.2153f) + lineTo(9.58854f, 2.21528f) + curveTo(9.08311f, 2.07252f, 8.55496f, 2f, 8.00098f, 2f) + curveTo(7.44699f, 2f, 6.91884f, 2.07252f, 6.41341f, 2.21528f) + lineTo(6.40659f, 2.21721f) + lineTo(6.40659f, 2.21718f) + curveTo(5.89259f, 2.35843f, 5.41641f, 2.55904f, 4.97513f, 2.81819f) + curveTo(4.5335f, 3.08023f, 4.12844f, 3.39515f, 3.75886f, 3.76472f) + curveTo(3.39532f, 4.12826f, 3.08274f, 4.53252f, 2.82014f, 4.97935f) + lineTo(2.81818f, 4.98267f) + lineTo(2.81818f, 4.98267f) + curveTo(2.55924f, 5.41938f, 2.35622f, 5.89379f, 2.21039f, 6.409f) + curveTo(2.07155f, 6.91543f, 2.00098f, 7.44479f, 2.00098f, 8f) + curveTo(2.00098f, 8.5552f, 2.07155f, 9.08455f, 2.21038f, 9.59097f) + curveTo(2.35622f, 10.1062f, 2.55946f, 10.5836f, 2.81921f, 11.0259f) + curveTo(3.08148f, 11.4679f, 3.39423f, 11.8729f, 3.75887f, 12.2421f) + curveTo(4.12806f, 12.6068f, 4.53308f, 12.9195f, 4.97513f, 13.1818f) + curveTo(5.41737f, 13.4415f, 5.89472f, 13.6447f, 6.40994f, 13.7906f) + curveTo(6.91638f, 13.9294f, 7.44575f, 14f, 8.00098f, 14f) + curveTo(8.55619f, 14f, 9.08555f, 13.9294f, 9.59198f, 13.7906f) + curveTo(10.1072f, 13.6448f, 10.5816f, 13.4417f, 11.0183f, 13.1828f) + lineTo(11.0216f, 13.1808f) + lineTo(11.0216f, 13.1808f) + curveTo(11.4685f, 12.9182f, 11.8727f, 12.6057f, 12.2363f, 12.2421f) + curveTo(12.6058f, 11.8726f, 12.9207f, 11.4675f, 13.1827f, 11.0259f) + curveTo(13.4419f, 10.5846f, 13.6425f, 10.1084f, 13.7838f, 9.59439f) + lineTo(13.7857f, 9.58756f) + lineTo(13.7857f, 9.58757f) + curveTo(13.9285f, 9.08213f, 14.001f, 8.55398f, 14.001f, 8f) + curveTo(14.001f, 7.44602f, 13.9285f, 6.91787f, 13.7857f, 6.41243f) + lineTo(13.7838f, 6.40562f) + lineTo(13.7838f, 6.40561f) + curveTo(13.6425f, 5.8916f, 13.4421f, 5.41838f, 13.1838f, 4.98267f) + lineTo(13.1818f, 4.97935f) + lineTo(13.1818f, 4.97935f) + curveTo(12.9204f, 4.53447f, 12.6069f, 4.13142f, 12.24f, 3.7685f) + lineTo(12.2324f, 3.76097f) + lineTo(12.2325f, 3.76093f) + curveTo(11.8696f, 3.3941f, 11.4665f, 3.08062f, 11.0216f, 2.81916f) + lineTo(11.0183f, 2.81721f) + lineTo(11.0183f, 2.8172f) + curveTo(10.5826f, 2.55885f, 10.1094f, 2.35844f, 9.59537f, 2.21718f) + lineTo(9.58854f, 2.2153f) + close() + moveTo(14.0439f, 11.5342f) + curveTo(13.7386f, 12.0492f, 13.3717f, 12.5208f, 12.9434f, 12.9492f) + curveTo(12.5195f, 13.373f, 12.0479f, 13.7376f, 11.5283f, 14.043f) + curveTo(11.0133f, 14.3483f, 10.4574f, 14.5853f, 9.86035f, 14.7539f) + curveTo(9.26335f, 14.918f, 8.64355f, 15f, 8.00098f, 15f) + curveTo(7.3584f, 15f, 6.73861f, 14.918f, 6.1416f, 14.7539f) + curveTo(5.5446f, 14.5853f, 4.98633f, 14.3483f, 4.4668f, 14.043f) + curveTo(3.95182f, 13.7376f, 3.48014f, 13.373f, 3.05176f, 12.9492f) + curveTo(2.62793f, 12.5208f, 2.26335f, 12.0492f, 1.95801f, 11.5342f) + curveTo(1.65267f, 11.0146f, 1.41569f, 10.4564f, 1.24707f, 9.85938f) + curveTo(1.08301f, 9.26237f, 1.00098f, 8.64258f, 1.00098f, 8f) + curveTo(1.00098f, 7.35742f, 1.08301f, 6.73763f, 1.24707f, 6.14062f) + curveTo(1.41569f, 5.54362f, 1.65267f, 4.98763f, 1.95801f, 4.47266f) + curveTo(2.26335f, 3.95312f, 2.62793f, 3.48145f, 3.05176f, 3.05762f) + curveTo(3.48014f, 2.62923f, 3.95182f, 2.26237f, 4.4668f, 1.95703f) + curveTo(4.98633f, 1.65169f, 5.5446f, 1.41699f, 6.1416f, 1.25293f) + curveTo(6.73861f, 1.08431f, 7.3584f, 1f, 8.00098f, 1f) + curveTo(8.64355f, 1f, 9.26335f, 1.08431f, 9.86035f, 1.25293f) + curveTo(10.4574f, 1.41699f, 11.0133f, 1.65169f, 11.5283f, 1.95703f) + curveTo(12.0479f, 2.26237f, 12.5195f, 2.62923f, 12.9434f, 3.05762f) + curveTo(13.3717f, 3.48145f, 13.7386f, 3.95312f, 14.0439f, 4.47266f) + curveTo(14.3493f, 4.98763f, 14.584f, 5.54362f, 14.748f, 6.14062f) + curveTo(14.9167f, 6.73763f, 15.001f, 7.35742f, 15.001f, 8f) + curveTo(15.001f, 8.64258f, 14.9167f, 9.26237f, 14.748f, 9.85938f) + curveTo(14.584f, 10.4564f, 14.3493f, 11.0146f, 14.0439f, 11.5342f) + close() + } + }.build() +} + +val FormatListBullet: ImageVector by lazy { + ImageVector.Builder( + name = "format_list_bulleted", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 24f, + viewportHeight = 24f + ).apply { + path( + fill = SolidColor(Color.Transparent) + ) { + moveTo(0f, 0f) + horizontalLineToRelative(24f) + verticalLineToRelative(24f) + horizontalLineTo(0f) + verticalLineTo(0f) + close() + } + path( + fill = SolidColor(Color.Black) + ) { + moveTo(4f, 10.5f) + curveToRelative(-0.83f, 0f, -1.5f, 0.67f, -1.5f, 1.5f) + reflectiveCurveToRelative(0.67f, 1.5f, 1.5f, 1.5f) + reflectiveCurveToRelative(1.5f, -0.67f, 1.5f, -1.5f) + reflectiveCurveToRelative(-0.67f, -1.5f, -1.5f, -1.5f) + close() + moveToRelative(0f, -6f) + curveToRelative(-0.83f, 0f, -1.5f, 0.67f, -1.5f, 1.5f) + reflectiveCurveTo(3.17f, 7.5f, 4f, 7.5f) + reflectiveCurveTo(5.5f, 6.83f, 5.5f, 6f) + reflectiveCurveTo(4.83f, 4.5f, 4f, 4.5f) + close() + moveToRelative(0f, 12f) + curveToRelative(-0.83f, 0f, -1.5f, 0.68f, -1.5f, 1.5f) + reflectiveCurveToRelative(0.68f, 1.5f, 1.5f, 1.5f) + reflectiveCurveToRelative(1.5f, -0.68f, 1.5f, -1.5f) + reflectiveCurveToRelative(-0.67f, -1.5f, -1.5f, -1.5f) + close() + moveTo(7f, 19f) + horizontalLineToRelative(14f) + verticalLineToRelative(-2f) + horizontalLineTo(7f) + verticalLineToRelative(2f) + close() + moveToRelative(0f, -6f) + horizontalLineToRelative(14f) + verticalLineToRelative(-2f) + horizontalLineTo(7f) + verticalLineToRelative(2f) + close() + moveToRelative(0f, -8f) + verticalLineToRelative(2f) + horizontalLineToRelative(14f) + verticalLineTo(5f) + horizontalLineTo(7f) + close() + } + }.build() +} + +val FormatListNumber: ImageVector by lazy { + ImageVector.Builder( + name = "format_list_numbered", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 24f, + viewportHeight = 24f + ).apply { + path( + fill = SolidColor(Color.Transparent) + ) { + moveTo(0f, 0f) + horizontalLineToRelative(24f) + verticalLineToRelative(24f) + horizontalLineTo(0f) + verticalLineTo(0f) + close() + } + path( + fill = SolidColor(Color.Black) + ) { + moveTo(2f, 17f) + horizontalLineToRelative(2f) + verticalLineToRelative(0.5f) + horizontalLineTo(3f) + verticalLineToRelative(1f) + horizontalLineToRelative(1f) + verticalLineToRelative(0.5f) + horizontalLineTo(2f) + verticalLineToRelative(1f) + horizontalLineToRelative(3f) + verticalLineToRelative(-4f) + horizontalLineTo(2f) + verticalLineToRelative(1f) + close() + moveToRelative(1f, -9f) + horizontalLineToRelative(1f) + verticalLineTo(4f) + horizontalLineTo(2f) + verticalLineToRelative(1f) + horizontalLineToRelative(1f) + verticalLineToRelative(3f) + close() + moveToRelative(-1f, 3f) + horizontalLineToRelative(1.8f) + lineTo(2f, 13.1f) + verticalLineToRelative(0.9f) + horizontalLineToRelative(3f) + verticalLineToRelative(-1f) + horizontalLineTo(3.2f) + lineTo(5f, 10.9f) + verticalLineTo(10f) + horizontalLineTo(2f) + verticalLineToRelative(1f) + close() + moveToRelative(5f, -6f) + verticalLineToRelative(2f) + horizontalLineToRelative(14f) + verticalLineTo(5f) + horizontalLineTo(7f) + close() + moveToRelative(0f, 14f) + horizontalLineToRelative(14f) + verticalLineToRelative(-2f) + horizontalLineTo(7f) + verticalLineToRelative(2f) + close() + moveToRelative(0f, -6f) + horizontalLineToRelative(14f) + verticalLineToRelative(-2f) + horizontalLineTo(7f) + verticalLineToRelative(2f) + close() + } + }.build() +} + +val FormatCode: ImageVector by lazy { + ImageVector.Builder( + name = "code", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 640f, + viewportHeight = 512f + ).apply { + path( + fill = SolidColor(Color.Black) + ) { + moveTo(278.9f, 511.5f) + lineToRelative(-61f, -17.7f) + curveToRelative(-6.4f, -1.8f, -10f, -8.5f, -8.2f, -14.9f) + lineTo(346.2f, 8.7f) + curveToRelative(1.8f, -6.4f, 8.5f, -10f, 14.9f, -8.2f) + lineToRelative(61f, 17.7f) + curveToRelative(6.4f, 1.8f, 10f, 8.5f, 8.2f, 14.9f) + lineTo(293.8f, 503.3f) + curveToRelative(-1.9f, 6.4f, -8.5f, 10.1f, -14.9f, 8.2f) + close() + moveToRelative(-114f, -112.2f) + lineToRelative(43.5f, -46.4f) + curveToRelative(4.6f, -4.9f, 4.3f, -12.7f, -0.8f, -17.2f) + lineTo(117f, 256f) + lineToRelative(90.6f, -79.7f) + curveToRelative(5.1f, -4.5f, 5.5f, -12.3f, 0.8f, -17.2f) + lineToRelative(-43.5f, -46.4f) + curveToRelative(-4.5f, -4.8f, -12.1f, -5.1f, -17f, -0.5f) + lineTo(3.8f, 247.2f) + curveToRelative(-5.1f, 4.7f, -5.1f, 12.8f, 0f, 17.5f) + lineToRelative(144.1f, 135.1f) + curveToRelative(4.9f, 4.6f, 12.5f, 4.4f, 17f, -0.5f) + close() + moveToRelative(327.2f, 0.6f) + lineToRelative(144.1f, -135.1f) + curveToRelative(5.1f, -4.7f, 5.1f, -12.8f, 0f, -17.5f) + lineTo(492.1f, 112.1f) + curveToRelative(-4.8f, -4.5f, -12.4f, -4.3f, -17f, 0.5f) + lineTo(431.6f, 159f) + curveToRelative(-4.6f, 4.9f, -4.3f, 12.7f, 0.8f, 17.2f) + lineTo(523f, 256f) + lineToRelative(-90.6f, 79.7f) + curveToRelative(-5.1f, 4.5f, -5.5f, 12.3f, -0.8f, 17.2f) + lineToRelative(43.5f, 46.4f) + curveToRelative(4.5f, 4.9f, 12.1f, 5.1f, 17f, 0.6f) + close() + } + }.build() +} + +val ContentCopy: ImageVector by lazy { + ImageVector.Builder( + name = "content_copy", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 24f, + viewportHeight = 24f + ).apply { + path( + fill = SolidColor(Color.Transparent) + ) { + moveTo(0f, 0f) + horizontalLineToRelative(24f) + verticalLineToRelative(24f) + horizontalLineTo(0f) + verticalLineTo(0f) + close() + } + path( + fill = SolidColor(Color.Black) + ) { + moveTo(16f, 1f) + horizontalLineTo(4f) + curveToRelative(-1.1f, 0f, -2f, 0.9f, -2f, 2f) + verticalLineToRelative(14f) + horizontalLineToRelative(2f) + verticalLineTo(3f) + horizontalLineToRelative(12f) + verticalLineTo(1f) + close() + moveToRelative(3f, 4f) + horizontalLineTo(8f) + curveToRelative(-1.1f, 0f, -2f, 0.9f, -2f, 2f) + verticalLineToRelative(14f) + curveToRelative(0f, 1.1f, 0.9f, 2f, 2f, 2f) + horizontalLineToRelative(11f) + curveToRelative(1.1f, 0f, 2f, -0.9f, 2f, -2f) + verticalLineTo(7f) + curveToRelative(0f, -1.1f, -0.9f, -2f, -2f, -2f) + close() + moveToRelative(0f, 16f) + horizontalLineTo(8f) + verticalLineTo(7f) + horizontalLineToRelative(11f) + verticalLineToRelative(14f) + close() + } + }.build() +} + +val ContentPaste: ImageVector by lazy { + ImageVector.Builder( + name = "content_paste", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 24f, + viewportHeight = 24f + ).apply { + path( + fill = SolidColor(Color.Transparent) + ) { + moveTo(0f, 0f) + horizontalLineToRelative(24f) + verticalLineToRelative(24f) + horizontalLineTo(0f) + verticalLineTo(0f) + close() + } + path( + fill = SolidColor(Color.Black) + ) { + moveTo(19f, 2f) + horizontalLineToRelative(-4.18f) + curveTo(14.4f, 0.84f, 13.3f, 0f, 12f, 0f) + reflectiveCurveTo(9.6f, 0.84f, 9.18f, 2f) + horizontalLineTo(5f) + curveToRelative(-1.1f, 0f, -2f, 0.9f, -2f, 2f) + verticalLineToRelative(16f) + curveToRelative(0f, 1.1f, 0.9f, 2f, 2f, 2f) + horizontalLineToRelative(14f) + curveToRelative(1.1f, 0f, 2f, -0.9f, 2f, -2f) + verticalLineTo(4f) + curveToRelative(0f, -1.1f, -0.9f, -2f, -2f, -2f) + close() + moveToRelative(-7f, 0f) + curveToRelative(0.55f, 0f, 1f, 0.45f, 1f, 1f) + reflectiveCurveToRelative(-0.45f, 1f, -1f, 1f) + reflectiveCurveToRelative(-1f, -0.45f, -1f, -1f) + reflectiveCurveToRelative(0.45f, -1f, 1f, -1f) + close() + moveToRelative(7f, 18f) + horizontalLineTo(5f) + verticalLineTo(4f) + horizontalLineToRelative(2f) + verticalLineToRelative(3f) + horizontalLineToRelative(10f) + verticalLineTo(4f) + horizontalLineToRelative(2f) + verticalLineToRelative(16f) + close() + } + }.build() +} + +val FormatItalic: ImageVector by lazy { + ImageVector.Builder( + name = "italic", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 320f, + viewportHeight = 512f + ).apply { + path( + fill = SolidColor(Color.Black) + ) { + moveTo(320f, 48f) + verticalLineToRelative(32f) + arcToRelative(16f, 16f, 0f, false, true, -16f, 16f) + horizontalLineToRelative(-62.76f) + lineToRelative(-80f, 320f) + horizontalLineTo(208f) + arcToRelative(16f, 16f, 0f, false, true, 16f, 16f) + verticalLineToRelative(32f) + arcToRelative(16f, 16f, 0f, false, true, -16f, 16f) + horizontalLineTo(16f) + arcToRelative(16f, 16f, 0f, false, true, -16f, -16f) + verticalLineToRelative(-32f) + arcToRelative(16f, 16f, 0f, false, true, 16f, -16f) + horizontalLineToRelative(62.76f) + lineToRelative(80f, -320f) + horizontalLineTo(112f) + arcToRelative(16f, 16f, 0f, false, true, -16f, -16f) + verticalLineTo(48f) + arcToRelative(16f, 16f, 0f, false, true, 16f, -16f) + horizontalLineToRelative(192f) + arcToRelative(16f, 16f, 0f, false, true, 16f, 16f) + close() + } + }.build() +} + +val FormatBold: ImageVector by lazy { + ImageVector.Builder( + name = "bold", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 384f, + viewportHeight = 512f + ).apply { + path( + fill = SolidColor(Color.Black) + ) { + moveTo(333.49f, 238f) + arcToRelative(122f, 122f, 0f, false, false, 27f, -65.21f) + curveTo(367.87f, 96.49f, 308f, 32f, 233.42f, 32f) + horizontalLineTo(34f) + arcToRelative(16f, 16f, 0f, false, false, -16f, 16f) + verticalLineToRelative(48f) + arcToRelative(16f, 16f, 0f, false, false, 16f, 16f) + horizontalLineToRelative(31.87f) + verticalLineToRelative(288f) + horizontalLineTo(34f) + arcToRelative(16f, 16f, 0f, false, false, -16f, 16f) + verticalLineToRelative(48f) + arcToRelative(16f, 16f, 0f, false, false, 16f, 16f) + horizontalLineToRelative(209.32f) + curveToRelative(70.8f, 0f, 134.14f, -51.75f, 141f, -122.4f) + curveToRelative(4.74f, -48.45f, -16.39f, -92.06f, -50.83f, -119.6f) + close() + moveTo(145.66f, 112f) + horizontalLineToRelative(87.76f) + arcToRelative(48f, 48f, 0f, false, true, 0f, 96f) + horizontalLineToRelative(-87.76f) + close() + moveToRelative(87.76f, 288f) + horizontalLineToRelative(-87.76f) + verticalLineTo(288f) + horizontalLineToRelative(87.76f) + arcToRelative(56f, 56f, 0f, false, true, 0f, 112f) + close() + } + }.build() +} + +val FormatUnderline: ImageVector by lazy { + ImageVector.Builder( + name = "underline", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 448f, + viewportHeight = 512f + ).apply { + path( + fill = SolidColor(Color.Black) + ) { + moveTo(32f, 64f) + horizontalLineToRelative(32f) + verticalLineToRelative(160f) + curveToRelative(0f, 88.22f, 71.78f, 160f, 160f, 160f) + reflectiveCurveToRelative(160f, -71.78f, 160f, -160f) + verticalLineTo(64f) + horizontalLineToRelative(32f) + arcToRelative(16f, 16f, 0f, false, false, 16f, -16f) + verticalLineTo(16f) + arcToRelative(16f, 16f, 0f, false, false, -16f, -16f) + horizontalLineTo(272f) + arcToRelative(16f, 16f, 0f, false, false, -16f, 16f) + verticalLineToRelative(32f) + arcToRelative(16f, 16f, 0f, false, false, 16f, 16f) + horizontalLineToRelative(32f) + verticalLineToRelative(160f) + arcToRelative(80f, 80f, 0f, false, true, -160f, 0f) + verticalLineTo(64f) + horizontalLineToRelative(32f) + arcToRelative(16f, 16f, 0f, false, false, 16f, -16f) + verticalLineTo(16f) + arcToRelative(16f, 16f, 0f, false, false, -16f, -16f) + horizontalLineTo(32f) + arcToRelative(16f, 16f, 0f, false, false, -16f, 16f) + verticalLineToRelative(32f) + arcToRelative(16f, 16f, 0f, false, false, 16f, 16f) + close() + moveToRelative(400f, 384f) + horizontalLineTo(16f) + arcToRelative(16f, 16f, 0f, false, false, -16f, 16f) + verticalLineToRelative(32f) + arcToRelative(16f, 16f, 0f, false, false, 16f, 16f) + horizontalLineToRelative(416f) + arcToRelative(16f, 16f, 0f, false, false, 16f, -16f) + verticalLineToRelative(-32f) + arcToRelative(16f, 16f, 0f, false, false, -16f, -16f) + close() + } + }.build() +} + +val FormatStrikethrough: ImageVector by lazy { + ImageVector.Builder( + name = "strikethrough", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 512f, + viewportHeight = 512f + ).apply { + path( + fill = SolidColor(Color.Black) + ) { + moveTo(496f, 224f) + horizontalLineTo(293.9f) + lineToRelative(-87.17f, -26.83f) + arcTo(43.55f, 43.55f, 0f, false, true, 219.55f, 112f) + horizontalLineToRelative(66.79f) + arcTo(49.89f, 49.89f, 0f, false, true, 331f, 139.58f) + arcToRelative(16f, 16f, 0f, false, false, 21.46f, 7.15f) + lineToRelative(42.94f, -21.47f) + arcToRelative(16f, 16f, 0f, false, false, 7.16f, -21.46f) + lineToRelative(-0.53f, -1f) + arcTo(128f, 128f, 0f, false, false, 287.51f, 32f) + horizontalLineToRelative(-68f) + arcToRelative(123.68f, 123.68f, 0f, false, false, -123f, 135.64f) + curveToRelative(2f, 20.89f, 10.1f, 39.83f, 21.78f, 56.36f) + horizontalLineTo(16f) + arcToRelative(16f, 16f, 0f, false, false, -16f, 16f) + verticalLineToRelative(32f) + arcToRelative(16f, 16f, 0f, false, false, 16f, 16f) + horizontalLineToRelative(480f) + arcToRelative(16f, 16f, 0f, false, false, 16f, -16f) + verticalLineToRelative(-32f) + arcToRelative(16f, 16f, 0f, false, false, -16f, -16f) + close() + moveToRelative(-180.24f, 96f) + arcTo(43f, 43f, 0f, false, true, 336f, 356.45f) + arcTo(43.59f, 43.59f, 0f, false, true, 292.45f, 400f) + horizontalLineToRelative(-66.79f) + arcTo(49.89f, 49.89f, 0f, false, true, 181f, 372.42f) + arcToRelative(16f, 16f, 0f, false, false, -21.46f, -7.15f) + lineToRelative(-42.94f, 21.47f) + arcToRelative(16f, 16f, 0f, false, false, -7.16f, 21.46f) + lineToRelative(0.53f, 1f) + arcTo(128f, 128f, 0f, false, false, 224.49f, 480f) + horizontalLineToRelative(68f) + arcToRelative(123.68f, 123.68f, 0f, false, false, 123f, -135.64f) + arcToRelative(114.25f, 114.25f, 0f, false, false, -5.34f, -24.36f) + close() + } + }.build() +} + +val UserIcon: ImageVector by lazy { + ImageVector.Builder( + name = "user", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 24f, + viewportHeight = 24f + ).apply { + path( + fill = SolidColor(Color.Transparent), + stroke = SolidColor(Color.Black), + strokeLineWidth = 1.5f, + strokeLineJoin = StrokeJoin.Miter + ) { + moveTo(15.75f, 6f) + arcToRelative(3.75f, 3.75f, 0f, true, true, -7.5f, 0f) + arcToRelative(3.75f, 3.75f, 0f, false, true, 7.5f, 0f) + close() + moveTo(4.501f, 20.118f) + arcToRelative(7.5f, 7.5f, 0f, false, true, 14.998f, 0f) + arcTo(17.933f, 17.933f, 0f, false, true, 12f, 21.75f) + curveToRelative(-2.676f, 0f, -5.216f, -0.584f, -7.499f, -1.632f) + close() + } + }.build() +} + +val UserGroupIcon: ImageVector by lazy { + ImageVector.Builder( + name = "user-group", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 24f, + viewportHeight = 24f + ).apply { + path( + fill = SolidColor(Color.Transparent), + stroke = SolidColor(Color.Black), + strokeLineWidth = 1.5f, + strokeLineJoin = StrokeJoin.Miter + ) { + moveTo(18f, 18.72f) + arcToRelative(9.094f, 9.094f, 0f, false, false, 3.741f, -0.479f) + arcToRelative(3f, 3f, 0f, false, false, -4.682f, -2.72f) + moveToRelative(0.94f, 3.198f) + lineToRelative(0.001f, 0.031f) + curveToRelative(0f, 0.225f, -0.012f, 0.447f, -0.037f, 0.666f) + arcTo(11.944f, 11.944f, 0f, false, true, 12f, 21f) + curveToRelative(-2.17f, 0f, -4.207f, -0.576f, -5.963f, -1.584f) + arcTo(6.062f, 6.062f, 0f, false, true, 6f, 18.719f) + moveToRelative(12f, 0f) + arcToRelative(5.971f, 5.971f, 0f, false, false, -0.941f, -3.197f) + moveToRelative(0f, 0f) + arcTo(5.995f, 5.995f, 0f, false, false, 12f, 12.75f) + arcToRelative(5.995f, 5.995f, 0f, false, false, -5.058f, 2.772f) + moveToRelative(0f, 0f) + arcToRelative(3f, 3f, 0f, false, false, -4.681f, 2.72f) + arcToRelative(8.986f, 8.986f, 0f, false, false, 3.74f, 0.477f) + moveToRelative(0.94f, -3.197f) + arcToRelative(5.971f, 5.971f, 0f, false, false, -0.94f, 3.197f) + moveTo(15f, 6.75f) + arcToRelative(3f, 3f, 0f, true, true, -6f, 0f) + arcToRelative(3f, 3f, 0f, false, true, 6f, 0f) + close() + moveToRelative(6f, 3f) + arcToRelative(2.25f, 2.25f, 0f, true, true, -4.5f, 0f) + arcToRelative(2.25f, 2.25f, 0f, false, true, 4.5f, 0f) + close() + moveToRelative(-13.5f, 0f) + arcToRelative(2.25f, 2.25f, 0f, true, true, -4.5f, 0f) + arcToRelative(2.25f, 2.25f, 0f, false, true, 4.5f, 0f) + close() + } + }.build() +} + +val AssignmentIcon: ImageVector by lazy { + ImageVector.Builder( + name = "assignment", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 960f, + viewportHeight = 960f + ).apply { + path( + fill = SolidColor(Color.Black) + ) { + moveTo(200f, 840f) + quadToRelative(-33f, 0f, -56.5f, -23.5f) + reflectiveQuadTo(120f, 760f) + verticalLineToRelative(-560f) + quadToRelative(0f, -33f, 23.5f, -56.5f) + reflectiveQuadTo(200f, 120f) + horizontalLineToRelative(168f) + quadToRelative(13f, -36f, 43.5f, -58f) + reflectiveQuadToRelative(68.5f, -22f) + quadToRelative(38f, 0f, 68.5f, 22f) + reflectiveQuadToRelative(43.5f, 58f) + horizontalLineToRelative(168f) + quadToRelative(33f, 0f, 56.5f, 23.5f) + reflectiveQuadTo(840f, 200f) + verticalLineToRelative(560f) + quadToRelative(0f, 33f, -23.5f, 56.5f) + reflectiveQuadTo(760f, 840f) + horizontalLineTo(200f) + close() + moveToRelative(0f, -80f) + horizontalLineToRelative(560f) + verticalLineToRelative(-560f) + horizontalLineTo(200f) + verticalLineToRelative(560f) + close() + moveToRelative(80f, -80f) + horizontalLineToRelative(280f) + verticalLineToRelative(-80f) + horizontalLineTo(280f) + verticalLineToRelative(80f) + close() + moveToRelative(0f, -160f) + horizontalLineToRelative(400f) + verticalLineToRelative(-80f) + horizontalLineTo(280f) + verticalLineToRelative(80f) + close() + moveToRelative(0f, -160f) + horizontalLineToRelative(400f) + verticalLineToRelative(-80f) + horizontalLineTo(280f) + verticalLineToRelative(80f) + close() + moveToRelative(200f, -190f) + quadToRelative(13f, 0f, 21.5f, -8.5f) + reflectiveQuadTo(510f, 140f) + quadToRelative(0f, -13f, -8.5f, -21.5f) + reflectiveQuadTo(480f, 110f) + quadToRelative(-13f, 0f, -21.5f, 8.5f) + reflectiveQuadTo(450f, 140f) + quadToRelative(0f, 13f, 8.5f, 21.5f) + reflectiveQuadTo(480f, 170f) + close() + moveTo(200f, 760f) + verticalLineToRelative(-560f) + verticalLineToRelative(560f) + close() + } + }.build() +} + +val Edit: ImageVector by lazy { + ImageVector.Builder( + name = "edit", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 24f, + viewportHeight = 24f + ).apply { + path( + fill = SolidColor(Color.Transparent), + stroke = SolidColor(Color.Black), + strokeLineWidth = 2f, + strokeLineCap = StrokeCap.Round, + strokeLineJoin = StrokeJoin.Round + ) { + moveTo(11f, 4f) + horizontalLineTo(4f) + arcToRelative(2f, 2f, 0f, false, false, -2f, 2f) + verticalLineToRelative(14f) + arcToRelative(2f, 2f, 0f, false, false, 2f, 2f) + horizontalLineToRelative(14f) + arcToRelative(2f, 2f, 0f, false, false, 2f, -2f) + verticalLineToRelative(-7f) + } + path( + fill = SolidColor(Color.Transparent), + stroke = SolidColor(Color.Black), + strokeLineWidth = 2f, + strokeLineCap = StrokeCap.Round, + strokeLineJoin = StrokeJoin.Round + ) { + moveTo(18.5f, 2.5f) + arcToRelative(2.121f, 2.121f, 0f, false, true, 3f, 3f) + lineTo(12f, 15f) + lineToRelative(-4f, 1f) + lineToRelative(1f, -4f) + lineToRelative(9.5f, -9.5f) + close() + } + }.build() +} + +val Check: ImageVector by lazy { + ImageVector.Builder( + name = "check", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 24f, + viewportHeight = 24f + ).apply { + path( + fill = SolidColor(Color.Transparent), + stroke = SolidColor(Color.Black), + strokeLineWidth = 2f, + strokeLineCap = StrokeCap.Round, + strokeLineJoin = StrokeJoin.Round + ) { + moveTo(20f, 6f) + lineTo(9f, 17f) + lineToRelative(-5f, -5f) + } + }.build() +} + +val Close: ImageVector by lazy { + ImageVector.Builder( + name = "close", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 16f, + viewportHeight = 16f + ).apply { + path( + fill = SolidColor(Color.Black) + ) { + moveTo(8.70701f, 8.00001f) + lineTo(12.353f, 4.35401f) + curveTo(12.548f, 4.15901f, 12.548f, 3.84201f, 12.353f, 3.64701f) + curveTo(12.158f, 3.45201f, 11.841f, 3.45201f, 11.646f, 3.64701f) + lineTo(8.00001f, 7.29301f) + lineTo(4.35401f, 3.64701f) + curveTo(4.15901f, 3.45201f, 3.84201f, 3.45201f, 3.64701f, 3.64701f) + curveTo(3.45201f, 3.84201f, 3.45201f, 4.15901f, 3.64701f, 4.35401f) + lineTo(7.29301f, 8.00001f) + lineTo(3.64701f, 11.646f) + curveTo(3.45201f, 11.841f, 3.45201f, 12.158f, 3.64701f, 12.353f) + curveTo(3.74501f, 12.451f, 3.87301f, 12.499f, 4.00101f, 12.499f) + curveTo(4.12901f, 12.499f, 4.25701f, 12.45f, 4.35501f, 12.353f) + lineTo(8.00101f, 8.70701f) + lineTo(11.647f, 12.353f) + curveTo(11.745f, 12.451f, 11.873f, 12.499f, 12.001f, 12.499f) + curveTo(12.129f, 12.499f, 12.257f, 12.45f, 12.355f, 12.353f) + curveTo(12.55f, 12.158f, 12.55f, 11.841f, 12.355f, 11.646f) + lineTo(8.70901f, 8.00001f) + horizontalLineTo(8.70701f) + close() + } + }.build() +} + +val PersonMinus: ImageVector by lazy { + ImageVector.Builder( + name = "person-dash", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 16f, + viewportHeight = 16f + ).apply { + path( + fill = SolidColor(Color.Black) + ) { + moveTo(12.5f, 16f) + arcToRelative(3.5f, 3.5f, 0f, true, false, 0f, -7f) + arcToRelative(3.5f, 3.5f, 0f, false, false, 0f, 7f) + moveTo(11f, 12f) + horizontalLineToRelative(3f) + arcToRelative(0.5f, 0.5f, 0f, false, true, 0f, 1f) + horizontalLineToRelative(-3f) + arcToRelative(0.5f, 0.5f, 0f, false, true, 0f, -1f) + moveToRelative(0f, -7f) + arcToRelative(3f, 3f, 0f, true, true, -6f, 0f) + arcToRelative(3f, 3f, 0f, false, true, 6f, 0f) + moveTo(8f, 7f) + arcToRelative(2f, 2f, 0f, true, false, 0f, -4f) + arcToRelative(2f, 2f, 0f, false, false, 0f, 4f) + } + path( + fill = SolidColor(Color.Black) + ) { + moveTo(8.256f, 14f) + arcToRelative(4.5f, 4.5f, 0f, false, true, -0.229f, -1.004f) + horizontalLineTo(3f) + curveToRelative(0.001f, -0.246f, 0.154f, -0.986f, 0.832f, -1.664f) + curveTo(4.484f, 10.68f, 5.711f, 10f, 8f, 10f) + quadToRelative(0.39f, 0f, 0.74f, 0.025f) + curveToRelative(0.226f, -0.341f, 0.496f, -0.65f, 0.804f, -0.918f) + quadTo(8.844f, 9.002f, 8f, 9f) + curveToRelative(-5f, 0f, -6f, 3f, -6f, 4f) + reflectiveCurveToRelative(1f, 1f, 1f, 1f) + close() + } + }.build() +} + +val DoubleBack: ImageVector by lazy { + ImageVector.Builder( + name = "angle-double-left", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 448f, + viewportHeight = 512f + ).apply { + path( + fill = SolidColor(Color.Black) + ) { + moveTo(223.7f, 239f) + lineToRelative(136f, -136f) + curveToRelative(9.4f, -9.4f, 24.6f, -9.4f, 33.9f, 0f) + lineToRelative(22.6f, 22.6f) + curveToRelative(9.4f, 9.4f, 9.4f, 24.6f, 0f, 33.9f) + lineTo(319.9f, 256f) + lineToRelative(96.4f, 96.4f) + curveToRelative(9.4f, 9.4f, 9.4f, 24.6f, 0f, 33.9f) + lineTo(393.7f, 409f) + curveToRelative(-9.4f, 9.4f, -24.6f, 9.4f, -33.9f, 0f) + lineToRelative(-136f, -136f) + curveToRelative(-9.5f, -9.4f, -9.5f, -24.6f, -0.1f, -34f) + close() + moveToRelative(-192f, 34f) + lineToRelative(136f, 136f) + curveToRelative(9.4f, 9.4f, 24.6f, 9.4f, 33.9f, 0f) + lineToRelative(22.6f, -22.6f) + curveToRelative(9.4f, -9.4f, 9.4f, -24.6f, 0f, -33.9f) + lineTo(127.9f, 256f) + lineToRelative(96.4f, -96.4f) + curveToRelative(9.4f, -9.4f, 9.4f, -24.6f, 0f, -33.9f) + lineTo(201.7f, 103f) + curveToRelative(-9.4f, -9.4f, -24.6f, -9.4f, -33.9f, 0f) + lineToRelative(-136f, 136f) + curveToRelative(-9.5f, 9.4f, -9.5f, 24.6f, -0.1f, 34f) + close() + } + }.build() +} + +val DoubleForward: ImageVector by lazy { + ImageVector.Builder( + name = "angle-double-right", + defaultWidth = 24.dp, + defaultHeight = 24.dp, + viewportWidth = 448f, + viewportHeight = 512f + ).apply { + path( + fill = SolidColor(Color.Black) + ) { + moveTo(224.3f, 273f) + lineToRelative(-136f, 136f) + curveToRelative(-9.4f, 9.4f, -24.6f, 9.4f, -33.9f, 0f) + lineToRelative(-22.6f, -22.6f) + curveToRelative(-9.4f, -9.4f, -9.4f, -24.6f, 0f, -33.9f) + lineToRelative(96.4f, -96.4f) + lineToRelative(-96.4f, -96.4f) + curveToRelative(-9.4f, -9.4f, -9.4f, -24.6f, 0f, -33.9f) + lineTo(54.3f, 103f) + curveToRelative(9.4f, -9.4f, 24.6f, -9.4f, 33.9f, 0f) + lineToRelative(136f, 136f) + curveToRelative(9.5f, 9.4f, 9.5f, 24.6f, 0.1f, 34f) + close() + moveToRelative(192f, -34f) + lineToRelative(-136f, -136f) + curveToRelative(-9.4f, -9.4f, -24.6f, -9.4f, -33.9f, 0f) + lineToRelative(-22.6f, 22.6f) + curveToRelative(-9.4f, 9.4f, -9.4f, 24.6f, 0f, 33.9f) + lineToRelative(96.4f, 96.4f) + lineToRelative(-96.4f, 96.4f) + curveToRelative(-9.4f, 9.4f, -9.4f, 24.6f, 0f, 33.9f) + lineToRelative(22.6f, 22.6f) + curveToRelative(9.4f, 9.4f, 24.6f, 9.4f, 33.9f, 0f) + lineToRelative(136f, -136f) + curveToRelative(9.4f, -9.2f, 9.4f, -24.4f, 0f, -33.8f) + close() + } + }.build() +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/PeerEvalsGradingView.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/PeerEvalsGradingView.kt new file mode 100644 index 0000000..777a345 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/PeerEvalsGradingView.kt @@ -0,0 +1,20 @@ +package com.jaytux.grader.ui + +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.lifecycle.viewmodel.compose.viewModel +import com.jaytux.grader.GroupGrading +import com.jaytux.grader.PeerEvalGrading +import com.jaytux.grader.viewmodel.GroupsGradingVM +import com.jaytux.grader.viewmodel.Navigator +import com.jaytux.grader.viewmodel.PeerEvalsGradingVM + +@Composable +fun PeerEvalsGradingTitle(data: PeerEvalGrading) = Text("Courses / ${data.course.name} / ${data.edition.name} / Peer Evaluations / ${data.assignment.name} / Grading") + +@Composable +fun PeerEvalsGradingView(data: PeerEvalGrading, token: Navigator.NavToken) { + val vm = viewModel(key = data.assignment.id.toString()) { + PeerEvalsGradingVM(data.course, data.edition, data.assignment) + } +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/RichText.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/RichText.kt index d4c878a..0a5ef5d 100644 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/RichText.kt +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/RichText.kt @@ -4,12 +4,6 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.* import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.automirrored.outlined.FormatListBulleted -import androidx.compose.material.icons.filled.Circle -import androidx.compose.material.icons.filled.ContentCopy -import androidx.compose.material.icons.filled.ContentPaste -import androidx.compose.material.icons.outlined.* import androidx.compose.material3.* import androidx.compose.runtime.Composable import androidx.compose.runtime.rememberCoroutineScope @@ -18,6 +12,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.focus.focusProperties import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalClipboard import androidx.compose.ui.platform.LocalClipboardManager import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.font.FontStyle @@ -29,13 +24,14 @@ import com.jaytux.grader.loadClipboard import com.jaytux.grader.toClipboard import com.mohamedrejeb.richeditor.model.RichTextState import com.mohamedrejeb.richeditor.ui.material.OutlinedRichTextEditor +import kotlinx.coroutines.launch @Composable fun RichTextStyleRow( modifier: Modifier = Modifier, state: RichTextState, ) { - val clip = LocalClipboardManager.current + val clip = LocalClipboardManager.current // I know this is deprecated, but I won't figure out the Clipboard API now val scope = rememberCoroutineScope() Row(modifier.fillMaxWidth()) { @@ -53,7 +49,7 @@ fun RichTextStyleRow( ) }, isSelected = state.currentSpanStyle.fontWeight == FontWeight.Bold, - icon = Icons.Outlined.FormatBold + icon = FormatBold ) } @@ -67,7 +63,7 @@ fun RichTextStyleRow( ) }, isSelected = state.currentSpanStyle.fontStyle == FontStyle.Italic, - icon = Icons.Outlined.FormatItalic + icon = FormatItalic ) } @@ -81,7 +77,7 @@ fun RichTextStyleRow( ) }, isSelected = state.currentSpanStyle.textDecoration?.contains(TextDecoration.Underline) == true, - icon = Icons.Outlined.FormatUnderlined + icon = FormatUnderline ) } @@ -95,7 +91,7 @@ fun RichTextStyleRow( ) }, isSelected = state.currentSpanStyle.textDecoration?.contains(TextDecoration.LineThrough) == true, - icon = Icons.Outlined.FormatStrikethrough + icon = FormatStrikethrough ) } @@ -109,7 +105,7 @@ fun RichTextStyleRow( ) }, isSelected = state.currentSpanStyle.fontSize == 28.sp, - icon = Icons.Outlined.FormatSize + icon = FormatSize ) } @@ -123,7 +119,7 @@ fun RichTextStyleRow( ) }, isSelected = state.currentSpanStyle.color == Color.Red, - icon = Icons.Filled.Circle, + icon = CircleFilled, tint = Color.Red ) } @@ -138,7 +134,7 @@ fun RichTextStyleRow( ) }, isSelected = state.currentSpanStyle.background == Color.Yellow, - icon = Icons.Outlined.Circle, + icon = CircleOutline, tint = Color.Yellow ) } @@ -158,7 +154,7 @@ fun RichTextStyleRow( state.toggleUnorderedList() }, isSelected = state.isUnorderedList, - icon = Icons.AutoMirrored.Outlined.FormatListBulleted, + icon = FormatListBullet, ) } @@ -168,7 +164,7 @@ fun RichTextStyleRow( state.toggleOrderedList() }, isSelected = state.isOrderedList, - icon = Icons.Outlined.FormatListNumbered, + icon = FormatListNumber, ) } @@ -187,16 +183,16 @@ fun RichTextStyleRow( state.toggleCodeSpan() }, isSelected = state.isCodeSpan, - icon = Icons.Outlined.Code, + icon = FormatCode, ) } } - IconButton({ state.toClipboard(clip) }) { - Icon(Icons.Default.ContentCopy, contentDescription = "Copy markdown") + IconButton({ scope.launch { state.toClipboard(clip) } }) { + Icon(ContentCopy, contentDescription = "Copy markdown") } - IconButton({ state.loadClipboard(clip, scope) }) { - Icon(Icons.Default.ContentPaste, contentDescription = "Paste markdown") + IconButton({ scope.launch { state.loadClipboard(clip, scope) } }) { + Icon(ContentPaste, contentDescription = "Paste markdown") } } } diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/SolosGradingView.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/SolosGradingView.kt new file mode 100644 index 0000000..42b185a --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/SolosGradingView.kt @@ -0,0 +1,20 @@ +package com.jaytux.grader.ui + +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.lifecycle.viewmodel.compose.viewModel +import com.jaytux.grader.GroupGrading +import com.jaytux.grader.SoloGrading +import com.jaytux.grader.viewmodel.GroupsGradingVM +import com.jaytux.grader.viewmodel.Navigator +import com.jaytux.grader.viewmodel.SolosGradingVM + +@Composable +fun SolosGradingTitle(data: SoloGrading) = Text("Courses / ${data.course.name} / ${data.edition.name} / Individual Assignments / ${data.assignment.name} / Grading") + +@Composable +fun SolosGradingView(data: SoloGrading, token: Navigator.NavToken) { + val vm = viewModel(key = data.assignment.id.toString()) { + SolosGradingVM(data.course, data.edition, data.assignment) + } +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/StudentsView.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/StudentsView.kt new file mode 100644 index 0000000..f2b5c5a --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/StudentsView.kt @@ -0,0 +1,193 @@ +package com.jaytux.grader.ui + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.material3.Button +import androidx.compose.material3.Icon +import androidx.compose.material3.LocalTextStyle +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +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.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import com.jaytux.grader.data.v2.Edition +import com.jaytux.grader.data.v2.Student +import com.jaytux.grader.viewmodel.EditionVM + +@Composable +fun StudentsView(vm: EditionVM) = Row(Modifier.fillMaxSize()) { + val students by vm.studentList.entities + val focus by vm.focusIndex + + Surface(Modifier.weight(0.25f).fillMaxHeight(), tonalElevation = 7.dp) { + ListOrEmpty(students, { Text("No students yet.") }) { idx, it -> + QuickStudent(idx, it, vm) + } + } + + Surface(Modifier.weight(0.75f).fillMaxHeight(), tonalElevation = 1.dp) { + if(focus == -1) { + Box(Modifier.weight(0.75f).fillMaxHeight()) { + Text("Select a student to view details.", Modifier.align(Alignment.Center)) + } + } + else { + val groups by vm.studentGroups.entities + val grades by vm.studentGrades.entities + + Column(Modifier.weight(0.75f).padding(15.dp)) { + Surface(Modifier.padding(10.dp).fillMaxWidth(), tonalElevation = 10.dp, shadowElevation = 2.dp, shape = MaterialTheme.shapes.medium) { + Column(Modifier.padding(10.dp)) { + Text(students[focus].name, style = MaterialTheme.typography.headlineSmall) + Row { + var editing by remember { mutableStateOf(false) } + + Text("Contact: ", Modifier.align(Alignment.CenterVertically).padding(start = 15.dp)) + if(!editing) { + if (students[focus].contact.isBlank()) Text( + "No contact info.", + Modifier.padding(start = 5.dp), + fontStyle = FontStyle.Italic, + color = LocalTextStyle.current.color.copy(alpha = 0.5f) + ) + else Text(students[focus].contact, Modifier.padding(start = 5.dp)) + Spacer(Modifier.width(5.dp)) + Icon(Edit, "Edit contact info", Modifier.clickable { editing = true }) + } + else { + var mod by remember(focus, students[focus].contact, students[focus].id.value) { mutableStateOf(students[focus].contact) } + OutlinedTextField(mod, { mod = it }) + Spacer(Modifier.width(5.dp)) + Icon(Check, "Confirm edit", Modifier.align(Alignment.CenterVertically).clickable { + vm.modStudent(students[focus], null, mod, null) + editing = false + }) + Spacer(Modifier.width(5.dp)) + Icon(Close, "Cancel edit", Modifier.align(Alignment.CenterVertically).clickable { editing = false }) + } + } + + Column { + Text("Groups:", style = MaterialTheme.typography.headlineSmall) + groups?.let { gList -> + if(gList.isEmpty()) null + else { + FlowRow(Modifier.padding(start = 10.dp), horizontalArrangement = Arrangement.SpaceEvenly) { + gList.forEach { group -> + Surface(tonalElevation = 15.dp, shadowElevation = 1.dp, shape = MaterialTheme.shapes.small) { + Box(Modifier.padding(5.dp).clickable { vm.focus(group.first) }) { + Text("${group.first.name} (${group.second ?: "no role"})", Modifier.padding(5.dp)) + } + } + } + } + } + } ?: Text("Not a member of any group.", Modifier.padding(start = 15.dp), fontStyle = FontStyle.Italic, color = LocalTextStyle.current.color.copy(alpha = 0.5f)) + } + } + } + Row { + Column(Modifier.weight(0.33f)) { + var mod by remember(focus, students[focus].note, students[focus].id.value) { mutableStateOf(students[focus].note) } + + Text("Internal Note:") + OutlinedTextField( + mod, + { mod = it }, + singleLine = false, + minLines = 5, + modifier = Modifier.fillMaxWidth() + ) + if(mod != students[focus].note) { + Row { + Spacer(Modifier.weight(1f)) + Button({ vm.modStudent(students[focus], null, null, mod) }) { + Text("Update note") + } + } + } + } + Spacer(Modifier.width(10.dp)) + Column(Modifier.weight(0.66f)) { + Text("Grade Summary: ", style = MaterialTheme.typography.headlineSmall) + Surface(shape = MaterialTheme.shapes.medium, color = Color.White) { + LazyColumn { + item { + Surface(tonalElevation = 15.dp) { + Row(Modifier.padding(10.dp)) { + Text("Assignment", Modifier.weight(0.66f)) + Text("Grade", Modifier.weight(0.33f)) + } + } + } + + items(grades ?: listOf()) { + Column(Modifier.padding(10.dp)) { + Row { + Text(it.assignment.name, Modifier.weight(0.66f)) + it.grade?.render(Modifier.weight(0.33f)) + ?: Text("---", Modifier.weight(0.33f), color = LocalTextStyle.current.color.copy(alpha = 0.5f)) + } + + it.asMember?.let { g -> + Row(Modifier.padding(start = 10.dp)) { + Text("As member of ${g.name}", fontStyle = FontStyle.Italic) + if (it.overridden) Text(" (overridden)", fontStyle = FontStyle.Italic) + } + } + } + } + + if((grades ?: listOf()).isEmpty()) { + item { + Box(Modifier.fillMaxWidth().padding(vertical = 5.dp)) { + Text("No grades yet.", Modifier.align(Alignment.Center), fontStyle = FontStyle.Italic, color = LocalTextStyle.current.color.copy(alpha = 0.5f)) + } + } + } + } + } + } + } + } + } + } +} + +@Composable +fun QuickStudent(idx: Int, student: Student, vm: EditionVM) { + val focus by vm.focusIndex + Surface(tonalElevation = if(focus == idx) 15.dp else 0.dp, shape = MaterialTheme.shapes.small) { + Column(Modifier.fillMaxWidth().clickable { vm.focus(idx) }.padding(10.dp)) { + Text(student.name, fontWeight = FontWeight.Bold) + if(student.contact.isBlank()) + Text("No contact info.", fontStyle = FontStyle.Italic, color = LocalTextStyle.current.color.copy(alpha = 0.5f)) + else Text(student.contact) + } + } +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Views.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Views.kt index 8b0e379..a2f935b 100644 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Views.kt +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Views.kt @@ -1,220 +1,200 @@ package com.jaytux.grader.ui -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.items -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Delete -import androidx.compose.material.icons.filled.Edit -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.DpSize -import androidx.compose.ui.unit.dp -import androidx.compose.ui.window.DialogWindow -import androidx.compose.ui.window.WindowPosition -import androidx.compose.ui.window.rememberDialogState -import com.jaytux.grader.maxN -import com.jaytux.grader.viewmodel.GroupState -import com.jaytux.grader.viewmodel.StudentState -@Composable -fun StudentView(state: StudentState, nav: Navigators) { - val groups by state.groups.entities - val courses by state.courseEditions.entities - val groupGrades by state.groupGrades.entities - val soloGrades by state.soloGrades.entities - - Column(Modifier.padding(10.dp)) { - Row { - Column(Modifier.weight(0.45f)) { - Column(Modifier.padding(10.dp).weight(0.35f)) { - Spacer(Modifier.height(10.dp)) - InteractToEdit(state.student.name, { state.update { this.name = it } }, "Name") - InteractToEdit(state.student.contact, { state.update { this.contact = it } }, "Contact") - InteractToEdit(state.student.note, { state.update { this.note = it } }, "Note", singleLine = false) - } - Column(Modifier.weight(0.20f)) { - Text("Courses", style = MaterialTheme.typography.headlineSmall) - ListOrEmpty(courses, { Text("Not a member of any course") }) { _, it -> - val (ed, course) = it - Text("${course.name} (${ed.name})", style = MaterialTheme.typography.bodyMedium) - } - } - Column(Modifier.weight(0.45f)) { - Text("Groups", style = MaterialTheme.typography.headlineSmall) - ListOrEmpty(groups, { Text("Not a member of any group") }) { _, it -> - val (group, c) = it - val (course, ed) = c - Row(Modifier.clickable { nav.group(group) }) { - Text(group.name, style = MaterialTheme.typography.bodyMedium) - Spacer(Modifier.width(5.dp)) - Text( - "(in course $course ($ed))", - Modifier.align(Alignment.Bottom), - style = MaterialTheme.typography.bodySmall - ) - } - - } - } - } - Column(Modifier.weight(0.55f)) { - Text("Courses", style = MaterialTheme.typography.headlineSmall) - LazyColumn { - item { - Text("As group member", fontWeight = FontWeight.Bold) - } - items(groupGrades) { - groupGradeWidget(it) - } - - item { - Text("Solo assignments", fontWeight = FontWeight.Bold) - } - items(soloGrades) { - soloGradeWidget(it) - } - } - } - } - } -} - -@Composable -fun groupGradeWidget(gg: StudentState.LocalGroupGrade) { - val (group, assignment, gGrade, iGrade) = gg - var expanded by remember { mutableStateOf(false) } - Row(Modifier.padding(5.dp)) { - Spacer(Modifier.width(10.dp)) - Surface( - Modifier.clickable { expanded = !expanded }.fillMaxWidth(), - tonalElevation = 5.dp, - shape = MaterialTheme.shapes.medium - ) { - Column(Modifier.padding(5.dp)) { - Text("${assignment.maxN(25)} (${iGrade ?: gGrade ?: "no grade yet"})") - - if (expanded) { - Row { - Spacer(Modifier.width(10.dp)) - Column { - ItalicAndNormal("Assignment: ", assignment) - ItalicAndNormal("Group name: ", group) - ItalicAndNormal("Group grade: ", gGrade ?: "no grade yet") - ItalicAndNormal("Individual grade: ", iGrade ?: "no individual grade") - } - } - } - } - } - } -} - -@Composable -fun soloGradeWidget(sg: StudentState.LocalSoloGrade) { - val (assignment, grade) = sg - var expanded by remember { mutableStateOf(false) } - Row(Modifier.padding(5.dp)) { - Spacer(Modifier.width(10.dp)) - Surface( - Modifier.clickable { expanded = !expanded }.fillMaxWidth(), - tonalElevation = 5.dp, - shape = MaterialTheme.shapes.medium - ) { - Column(Modifier.padding(5.dp)) { - Text("${assignment.maxN(25)} (${grade ?: "no grade yet"})") - - if (expanded) { - Row { - Spacer(Modifier.width(10.dp)) - Column { - ItalicAndNormal("Assignment: ", assignment) - ItalicAndNormal("Individual grade: ", grade ?: "no grade yet") - } - } - } - } - } - } -} - -@Composable -fun GroupView(state: GroupState, nav: Navigators) { - val members by state.members.entities - val available by state.availableStudents.entities - val allRoles by state.roles.entities - - var pickRole: Pair Unit>? by remember { mutableStateOf(null) } - - Column(Modifier.padding(10.dp)) { - Row { - Column(Modifier.weight(0.5f)) { - Text("Students", style = MaterialTheme.typography.headlineSmall) - ListOrEmpty(members, { Text("No students in this group") }) { _, it -> - val (student, role) = it - Row(Modifier.clickable { nav.student(student) }) { - Text( - "${student.name} (${role ?: "no role"})", - Modifier.weight(0.75f).align(Alignment.CenterVertically), - style = MaterialTheme.typography.bodyMedium - ) - IconButton({ pickRole = role to { r -> state.updateRole(student, r) } }, Modifier.weight(0.12f)) { - Icon(Icons.Default.Edit, "Change role") - } - IconButton({ state.removeStudent(student) }, Modifier.weight(0.12f)) { - Icon(Icons.Default.Delete, "Remove student") - } - } - } - } - Column(Modifier.weight(0.5f)) { - Text("Available students", style = MaterialTheme.typography.headlineSmall) - ListOrEmpty(available, { Text("No students available") }) { _, it -> - Row(Modifier.padding(5.dp).clickable { nav.student(it) }) { - IconButton({ state.addStudent(it) }) { - Icon(ChevronLeft, "Add student") - } - Text(it.name, Modifier.weight(0.75f).align(Alignment.CenterVertically), style = MaterialTheme.typography.bodyMedium) - } - } - } - } - } - - pickRole?.let { - val (curr, onPick) = it - RolePicker(allRoles, curr, { pickRole = null }, { role -> onPick(role); pickRole = null }) - } -} - -@Composable -fun RolePicker(used: List, curr: String?, onClose: () -> Unit, onSave: (String?) -> Unit) = DialogWindow( - onCloseRequest = onClose, - state = rememberDialogState(size = DpSize(400.dp, 500.dp), position = WindowPosition(Alignment.Center)) -) { - Surface(Modifier.fillMaxSize().padding(10.dp)) { - Box(Modifier.fillMaxSize()) { - var role by remember { mutableStateOf(curr ?: "") } - Column { - Text("Used roles:") - LazyColumn(Modifier.weight(1.0f).padding(5.dp)) { - items(used) { - Surface(Modifier.fillMaxWidth().clickable { role = it }, tonalElevation = 5.dp) { - Text(it, Modifier.padding(5.dp)) - } - Spacer(Modifier.height(5.dp)) - } - } - OutlinedTextField(role, { role = it }, Modifier.fillMaxWidth()) - CancelSaveRow(true, onClose) { - onSave(role.ifBlank { null }) - onClose() - } - } - } - } -} \ No newline at end of file +//@Composable +//fun StudentView(state: StudentState, nav: Navigators) { +// val groups by state.groups.entities +// val courses by state.courseEditions.entities +// val groupGrades by state.groupGrades.entities +// val soloGrades by state.soloGrades.entities +// +// Column(Modifier.padding(10.dp)) { +// Row { +// Column(Modifier.weight(0.45f)) { +// Column(Modifier.padding(10.dp).weight(0.35f)) { +// Spacer(Modifier.height(10.dp)) +// InteractToEdit(state.student.name, { state.update { this.name = it } }, "Name") +// InteractToEdit(state.student.contact, { state.update { this.contact = it } }, "Contact") +// InteractToEdit(state.student.note, { state.update { this.note = it } }, "Note", singleLine = false) +// } +// Column(Modifier.weight(0.20f)) { +// Text("Courses", style = MaterialTheme.typography.headlineSmall) +// ListOrEmpty(courses, { Text("Not a member of any course") }) { _, it -> +// val (ed, course) = it +// Text("${course.name} (${ed.name})", style = MaterialTheme.typography.bodyMedium) +// } +// } +// Column(Modifier.weight(0.45f)) { +// Text("Groups", style = MaterialTheme.typography.headlineSmall) +// ListOrEmpty(groups, { Text("Not a member of any group") }) { _, it -> +// val (group, c) = it +// val (course, ed) = c +// Row(Modifier.clickable { nav.group(group) }) { +// Text(group.name, style = MaterialTheme.typography.bodyMedium) +// Spacer(Modifier.width(5.dp)) +// Text( +// "(in course $course ($ed))", +// Modifier.align(Alignment.Bottom), +// style = MaterialTheme.typography.bodySmall +// ) +// } +// +// } +// } +// } +// Column(Modifier.weight(0.55f)) { +// Text("Courses", style = MaterialTheme.typography.headlineSmall) +// LazyColumn { +// item { +// Text("As group member", fontWeight = FontWeight.Bold) +// } +// items(groupGrades) { +// groupGradeWidget(it) +// } +// +// item { +// Text("Solo assignments", fontWeight = FontWeight.Bold) +// } +// items(soloGrades) { +// soloGradeWidget(it) +// } +// } +// } +// } +// } +//} +// +//@Composable +//fun groupGradeWidget(gg: StudentState.LocalGroupGrade) { +// val (group, assignment, gGrade, iGrade) = gg +// var expanded by remember { mutableStateOf(false) } +// Row(Modifier.padding(5.dp)) { +// Spacer(Modifier.width(10.dp)) +// Surface( +// Modifier.clickable { expanded = !expanded }.fillMaxWidth(), +// tonalElevation = 5.dp, +// shape = MaterialTheme.shapes.medium +// ) { +// Column(Modifier.padding(5.dp)) { +// Text("${assignment.maxN(25)} (${iGrade ?: gGrade ?: "no grade yet"})") +// +// if (expanded) { +// Row { +// Spacer(Modifier.width(10.dp)) +// Column { +// ItalicAndNormal("Assignment: ", assignment) +// ItalicAndNormal("Group name: ", group) +// ItalicAndNormal("Group grade: ", gGrade ?: "no grade yet") +// ItalicAndNormal("Individual grade: ", iGrade ?: "no individual grade") +// } +// } +// } +// } +// } +// } +//} +// +//@Composable +//fun soloGradeWidget(sg: StudentState.LocalSoloGrade) { +// val (assignment, grade) = sg +// var expanded by remember { mutableStateOf(false) } +// Row(Modifier.padding(5.dp)) { +// Spacer(Modifier.width(10.dp)) +// Surface( +// Modifier.clickable { expanded = !expanded }.fillMaxWidth(), +// tonalElevation = 5.dp, +// shape = MaterialTheme.shapes.medium +// ) { +// Column(Modifier.padding(5.dp)) { +// Text("${assignment.maxN(25)} (${grade ?: "no grade yet"})") +// +// if (expanded) { +// Row { +// Spacer(Modifier.width(10.dp)) +// Column { +// ItalicAndNormal("Assignment: ", assignment) +// ItalicAndNormal("Individual grade: ", grade ?: "no grade yet") +// } +// } +// } +// } +// } +// } +//} +// +//@Composable +//fun GroupView(state: GroupState, nav: Navigators) { +// val members by state.members.entities +// val available by state.availableStudents.entities +// val allRoles by state.roles.entities +// +// var pickRole: Pair Unit>? by remember { mutableStateOf(null) } +// +// Column(Modifier.padding(10.dp)) { +// Row { +// Column(Modifier.weight(0.5f)) { +// Text("Students", style = MaterialTheme.typography.headlineSmall) +// ListOrEmpty(members, { Text("No students in this group") }) { _, it -> +// val (student, role) = it +// Row(Modifier.clickable { nav.student(student) }) { +// Text( +// "${student.name} (${role ?: "no role"})", +// Modifier.weight(0.75f).align(Alignment.CenterVertically), +// style = MaterialTheme.typography.bodyMedium +// ) +// IconButton({ pickRole = role to { r -> state.updateRole(student, r) } }, Modifier.weight(0.12f)) { +// Icon(Icons.Default.Edit, "Change role") +// } +// IconButton({ state.removeStudent(student) }, Modifier.weight(0.12f)) { +// Icon(Icons.Default.Delete, "Remove student") +// } +// } +// } +// } +// Column(Modifier.weight(0.5f)) { +// Text("Available students", style = MaterialTheme.typography.headlineSmall) +// ListOrEmpty(available, { Text("No students available") }) { _, it -> +// Row(Modifier.padding(5.dp).clickable { nav.student(it) }) { +// IconButton({ state.addStudent(it) }) { +// Icon(ChevronLeft, "Add student") +// } +// Text(it.name, Modifier.weight(0.75f).align(Alignment.CenterVertically), style = MaterialTheme.typography.bodyMedium) +// } +// } +// } +// } +// } +// +// pickRole?.let { +// val (curr, onPick) = it +// RolePicker(allRoles, curr, { pickRole = null }, { role -> onPick(role); pickRole = null }) +// } +//} +// +//@Composable +//fun RolePicker(used: List, curr: String?, onClose: () -> Unit, onSave: (String?) -> Unit) = DialogWindow( +// onCloseRequest = onClose, +// state = rememberDialogState(size = DpSize(400.dp, 500.dp), position = WindowPosition(Alignment.Center)) +//) { +// Surface(Modifier.fillMaxSize().padding(10.dp)) { +// Box(Modifier.fillMaxSize()) { +// var role by remember { mutableStateOf(curr ?: "") } +// Column { +// Text("Used roles:") +// LazyColumn(Modifier.weight(1.0f).padding(5.dp)) { +// items(used) { +// Surface(Modifier.fillMaxWidth().clickable { role = it }, tonalElevation = 5.dp) { +// Text(it, Modifier.padding(5.dp)) +// } +// Spacer(Modifier.height(5.dp)) +// } +// } +// OutlinedTextField(role, { role = it }, Modifier.fillMaxWidth()) +// CancelSaveRow(true, onClose) { +// onSave(role.ifBlank { null }) +// onClose() +// } +// } +// } +// } +//} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Widgets.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Widgets.kt index 475427a..db82f45 100644 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Widgets.kt +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/ui/Widgets.kt @@ -1,45 +1,34 @@ package com.jaytux.grader.ui -import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.* -import androidx.compose.foundation.lazy.* -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Check -import androidx.compose.material.icons.filled.Delete -import androidx.compose.material.icons.filled.Edit +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.LazyItemScope +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.TransformOrigin import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.input.key.Key -import androidx.compose.ui.input.key.KeyEvent -import androidx.compose.ui.input.key.key -import androidx.compose.ui.input.key.onKeyEvent -import androidx.compose.ui.layout.SubcomposeLayout -import androidx.compose.ui.layout.layout import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.text.TextRange -import androidx.compose.ui.text.capitalize import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.TextFieldValue -import androidx.compose.ui.text.intl.Locale -import androidx.compose.ui.unit.* +import androidx.compose.ui.unit.Dp +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.data.Edition -import com.jaytux.grader.viewmodel.PeerEvaluationState -import com.mohamedrejeb.richeditor.model.RichTextState -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch +import com.jaytux.grader.maxN +import com.jaytux.grader.viewmodel.Grade import kotlinx.datetime.* import kotlinx.datetime.TimeZone import java.util.* +import kotlin.time.toJavaInstant @Composable fun CancelSaveRow(canSave: Boolean, onCancel: () -> Unit, cancelText: String = "Cancel", saveText: String = "Save", onSave: () -> Unit) { @@ -50,37 +39,18 @@ fun CancelSaveRow(canSave: Boolean, onCancel: () -> Unit, cancelText: String = " } } -@Composable -fun TabLayout( - options: List, - currentIndex: Int, - onSelect: (Int) -> Unit, - optionContent: @Composable (T) -> Unit, - modifier: Modifier = Modifier, - content: @Composable () -> Unit -) = Column(modifier) { - TabRow(currentIndex) { - options.forEachIndexed { idx, it -> - Tab( - selected = idx == currentIndex, - onClick = { onSelect(idx) }, - text = { optionContent(it) } - ) - } - } - content() -} - @Composable fun AddStringDialog(label: String, taken: List, onClose: () -> Unit, current: String = "", onSave: (String) -> Unit) = DialogWindow( onCloseRequest = onClose, state = rememberDialogState(size = DpSize(400.dp, 300.dp), position = WindowPosition(Alignment.Center)) ) { + val focus = remember { FocusRequester() } + Surface(Modifier.fillMaxSize()) { Box(Modifier.fillMaxSize().padding(10.dp)) { var name by remember(current) { mutableStateOf(current) } Column(Modifier.align(Alignment.Center)) { - OutlinedTextField(name, { name = it }, Modifier.fillMaxWidth(), label = { Text(label) }, isError = name in taken) + OutlinedTextField(name, { name = it }, Modifier.fillMaxWidth().focusRequester(focus), label = { Text(label) }, isError = name in taken) CancelSaveRow(name.isNotBlank() && name !in taken, onClose) { onSave(name) onClose() @@ -88,6 +58,8 @@ fun AddStringDialog(label: String, taken: List, onClose: () -> Unit, cur } } } + + LaunchedEffect(Unit) { focus.requestFocus() } } @Composable @@ -118,299 +90,25 @@ fun ConfirmDeleteDialog( fun ListOrEmpty( data: List, onEmpty: @Composable ColumnScope.() -> Unit, - addOptions: @Composable ColumnScope.() -> Unit, - addAfterLazy: Boolean = true, + modifier: Modifier = Modifier, item: @Composable LazyItemScope.(idx: Int, it: T) -> Unit ) { if(data.isEmpty()) { - Box(Modifier.fillMaxSize()) { - Column(Modifier.align(Alignment.Center)) { - onEmpty() - addOptions() + Box(modifier) { + Box(Modifier.fillMaxSize()) { + Column(Modifier.align(Alignment.Center)) { + onEmpty() + } } } } else { - Column { + Column(modifier) { LazyColumn(Modifier.weight(1f)) { itemsIndexed(data) { idx, it -> item(idx, it) } - - if(!addAfterLazy) item { addOptions() } } - if(addAfterLazy) addOptions() - } - } -} - -@Composable -fun ListOrEmpty( - data: List, - emptyText: @Composable ColumnScope.() -> Unit, - addText: @Composable RowScope.() -> Unit, - onAdd: () -> Unit, - addAfterLazy: Boolean = true, - item: @Composable LazyItemScope.(idx: Int, it: T) -> Unit -) = ListOrEmpty( - data, emptyText, - { Button(onAdd, Modifier.align(Alignment.CenterHorizontally).fillMaxWidth()) { addText() } }, - addAfterLazy, - item -) - -@Composable -fun ListOrEmpty( - data: List, - emptyText: @Composable ColumnScope.() -> Unit, - item: @Composable LazyItemScope.(idx: Int, it: T) -> Unit -) { - if(data.isEmpty()) { - Box(Modifier.fillMaxSize()) { - Column(Modifier.align(Alignment.Center)) { - emptyText() - } - } - } - else { - Column { - LazyColumn(Modifier.padding(5.dp).weight(1f)) { - itemsIndexed(data) { idx, it -> - item(idx, it) - } - } - } - } -} - -@Composable -fun InteractToEdit( - content: String, onSave: (String) -> Unit, pre: String, modifier: Modifier = Modifier, - w1: Float = 0.75f, w2: Float = 0.25f, - singleLine: Boolean = true -) { - var text by remember(content) { mutableStateOf(content) } - - Row(modifier.padding(5.dp)) { - val base = if(singleLine) Modifier.align(Alignment.CenterVertically) else Modifier - OutlinedTextField( - text, { text = it }, base.weight(w1), label = { Text(pre) }, - singleLine = singleLine, minLines = if(singleLine) 1 else 5 - ) - IconButton({ onSave(text) }, base.weight(w2)) { Icon(Icons.Default.Check, "Save") } - } -} - -@Composable -fun PaneHeader(name: String, type: String, course: Course, edition: Edition) = Column { - Text(name, style = MaterialTheme.typography.headlineMedium) - Text("${type.capitalize(Locale.current)} in ${course.name} (${edition.name})", fontStyle = FontStyle.Italic) -} - -@Composable -fun PaneHeader(name: String, type: String, courseEdition: Pair) = PaneHeader(name, type, courseEdition.first, courseEdition.second) - -@OptIn(ExperimentalFoundationApi::class) -@Composable -fun AutocompleteLineField__( -// state: RichTextState, - value: TextFieldValue, onValueChange: (TextFieldValue) -> Unit, - modifier: Modifier = Modifier, label: @Composable (() -> Unit)? = null, - onFilter: (String) -> List -) = Column(modifier) { - var suggestions by remember { mutableStateOf(listOf()) } - var selected by remember { mutableStateOf(0) } - val scope = rememberCoroutineScope() - val scrollState = rememberLazyListState() - - val posToLine = { pos: Int -> - (value.text.take(pos).count { it == '\n' }) to (value.text.take(pos).lastIndexOf('\n')) - } - - val autoComplete = { str: String -> - val pos = value.selection.start - val lines = value.text.split("\n").toMutableList() - val (lineno, lineStart) = posToLine(pos) - - lines[lineno] = str - onValueChange(value.copy(text = lines.joinToString("\n"), selection = TextRange(lineStart + str.length + 1))) - } - - val currentLine = { - value.text.split('\n')[posToLine(value.selection.start).first] - } - - val gotoOption = { idx: Int -> - selected = if(suggestions.isEmpty()) 0 else ((idx + suggestions.size) % suggestions.size) - scope.launch { - scrollState.animateScrollToItem(if(suggestions.isNotEmpty()) (selected + 1) else 0) - } - Unit - } - - val onKey = { kev: KeyEvent -> - var res = true - if(suggestions.isNotEmpty()) { - when (kev.key) { - Key.Tab -> autoComplete(suggestions[selected]) - Key.DirectionUp -> gotoOption(selected - 1) - Key.DirectionDown -> gotoOption(selected + 1) - Key.Escape -> suggestions = listOf() - else -> res = false - } - } - else res = false - - res - } - - LaunchedEffect(value.text) { - delay(300) - suggestions = onFilter(currentLine()) - gotoOption(if(suggestions.isEmpty()) 0 else selected % suggestions.size) - } - - OutlinedTextField( - value, onValueChange, - Modifier.fillMaxWidth().weight(0.75f).onKeyEvent(onKey), label = label, singleLine = false, minLines = 5 - ) - - if(suggestions.isNotEmpty()) { - LazyColumn(Modifier.weight(0.25f), state = scrollState) { - stickyHeader { - Surface(tonalElevation = 5.dp) { - Text("Suggestions", Modifier.padding(5.dp).fillMaxWidth(), fontStyle = FontStyle.Italic) - } - } - itemsIndexed(suggestions) { idx, it -> - Surface(Modifier.padding(5.dp).fillMaxWidth(), tonalElevation = if(selected == idx) 50.dp else 0.dp) { - Text(it, Modifier.clickable { autoComplete(it) }) - } - } - } - } -} - -@OptIn(ExperimentalMaterial3Api::class) -@Composable -fun DateTimePicker( - value: LocalDateTime, - onPick: (LocalDateTime) -> Unit, - formatter: (LocalDateTime) -> String = { java.text.DateFormat.getDateTimeInstance().format(Date.from(it.toInstant(TimeZone.currentSystemDefault()).toJavaInstant())) }, - modifier: Modifier = Modifier, -) { - var showPicker by remember { mutableStateOf(false) } - - Row(modifier) { - Text( - formatter(value), - Modifier.align(Alignment.CenterVertically) - ) - Spacer(Modifier.width(10.dp)) - Button({ showPicker = true }) { Text("Change") } - - if (showPicker) { - val dateState = rememberDatePickerState(value.toInstant(TimeZone.currentSystemDefault()).toEpochMilliseconds()) - val timeState = rememberTimePickerState(value.hour, value.minute) - - Dialog( - { showPicker = false }, - properties = DialogProperties(usePlatformDefaultWidth = false) - ) { - Surface( - shape = MaterialTheme.shapes.extraLarge, tonalElevation = 6.dp, - modifier = Modifier.width(800.dp).height(600.dp) - ) { - val colors = TimePickerDefaults.colors( - selectorColor = MaterialTheme.colorScheme.primary, - timeSelectorSelectedContainerColor = MaterialTheme.colorScheme.primary, - timeSelectorSelectedContentColor = MaterialTheme.colorScheme.onPrimary, - clockDialSelectedContentColor = MaterialTheme.colorScheme.onPrimary, - ) // the colors are fucked, and I don't get why :( - - Column(Modifier.padding(10.dp)) { - Row { - DatePicker( - dateState, - Modifier.padding(10.dp).weight(0.5f), - ) - TimePicker( - timeState, - Modifier.weight(0.5f).align(Alignment.CenterVertically), - layoutType = TimePickerLayoutType.Vertical, - colors = colors - ) - } - CancelSaveRow(true, { showPicker = false }) { - val date = (dateState.selectedDateMillis?.let { Instant.fromEpochMilliseconds(it).toLocalDateTime(TimeZone.currentSystemDefault()) } ?: value).date - val time = LocalTime(timeState.hour, timeState.minute) - - onPick(LocalDateTime(date, time)) - showPicker = false - } - } - } - } - } - - -// DatePickerDialog( -// { showPicker = false }, -// { -// Button({ -// showPicker = false; dateState.selectedDateMillis?.let { state.updateDeadline(it) } -// }) { Text("Set deadline") } -// }, -// Modifier, -// { Button({ showPicker = false }) { Text("Cancel") } }, -// shape = MaterialTheme.shapes.medium, -// tonalElevation = 10.dp, -// colors = DatePickerDefaults.colors(), -// properties = DialogProperties() -// ) { -// DatePicker( -// dateState, -// Modifier.fillMaxWidth().padding(10.dp), -// ) -// } - } -} - -@Composable -fun ItalicAndNormal(italic: String, normal: String) = Row{ - Text(italic, fontStyle = FontStyle.Italic) - Text(normal) -} - -@Composable -fun Selectable( - isSelected: Boolean, - onSelect: () -> Unit, onDeselect: () -> Unit, - unselectedElevation: Dp = 0.dp, selectedElevation: Dp = 50.dp, - content: @Composable () -> Unit -) { - Surface( - Modifier.fillMaxWidth().clickable { if(isSelected) onDeselect() else onSelect() }, - tonalElevation = if (isSelected) selectedElevation else unselectedElevation, - shape = MaterialTheme.shapes.medium - ) { - content() - } -} - -@Composable -fun SelectEditDeleteRow( - isSelected: Boolean, - onSelect: () -> Unit, onDeselect: () -> Unit, onEdit: () -> Unit, onDelete: () -> Unit, - content: @Composable BoxScope.() -> Unit -) = Selectable(isSelected, onSelect, onDeselect) { - Row { - Box(Modifier.weight(1f).align(Alignment.CenterVertically)) { content() } - IconButton(onEdit, Modifier.align(Alignment.CenterVertically)) { - Icon(Icons.Default.Edit, "Edit") - } - IconButton(onDelete, Modifier.align(Alignment.CenterVertically)) { - Icon(Icons.Default.Delete, "Delete") } } } @@ -438,19 +136,19 @@ fun FromTo(size: Dp) { } } -@Composable -fun PEGradeWidget( - grade: PeerEvaluationState.Student2StudentEntry?, - onSelect: () -> Unit, onDeselect: () -> Unit, - isSelected: Boolean, - modifier: Modifier = Modifier -) = Box(modifier.padding(2.dp)) { - Selectable(isSelected, onSelect, onDeselect) { - Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { - Text(grade?.let { if(it.grade.isNotBlank()) it.grade else if(it.feedback.isNotBlank()) "(other)" else null } ?: "none") - } - } -} +//@Composable +//fun PEGradeWidget( +// grade: PeerEvaluationState.Student2StudentEntry?, +// onSelect: () -> Unit, onDeselect: () -> Unit, +// isSelected: Boolean, +// modifier: Modifier = Modifier +//) = Box(modifier.padding(2.dp)) { +// Selectable(isSelected, onSelect, onDeselect) { +// Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) { +// Text(grade?.let { if(it.grade.isNotBlank()) it.grade else if(it.feedback.isNotBlank()) "(other)" else null } ?: "none") +// } +// } +//} @Composable fun VLine(width: Dp = 1.dp, color: Color = Color.Black) = Spacer(Modifier.fillMaxHeight().width(width).background(color)) @@ -459,4 +157,103 @@ fun VLine(width: Dp = 1.dp, color: Color = Color.Black) = Spacer(Modifier.fillMa fun MeasuredLazyItemScope.HLine(height: Dp = 1.dp, color: Color = Color.Black) { val width by measuredWidth() Spacer(Modifier.width(width).height(height).background(color)) +} + +@Composable +fun RolePicker(used: List, curr: String?, onClose: () -> Unit, onSave: (String?) -> Unit) = DialogWindow( + onCloseRequest = onClose, + state = rememberDialogState(size = DpSize(400.dp, 500.dp), position = WindowPosition(Alignment.Center)) +) { + Surface(Modifier.fillMaxSize().padding(10.dp)) { + Box(Modifier.fillMaxSize()) { + var role by remember { mutableStateOf(curr ?: "") } + Column { + Text("Used roles:") + LazyColumn(Modifier.weight(1.0f).padding(5.dp)) { + items(used) { + Surface(Modifier.fillMaxWidth().clickable { role = it }, tonalElevation = 5.dp) { + Text(it, Modifier.padding(5.dp)) + } + Spacer(Modifier.height(5.dp)) + } + } + OutlinedTextField(role, { role = it }, Modifier.fillMaxWidth()) + CancelSaveRow(true, onClose) { + onSave(role.ifBlank { null }) + onClose() + } + } + } + } +} + +@Composable +fun GradePicker(grade: Grade, modifier: Modifier = Modifier, key: Any = Unit, onUpdate: (Grade) -> Unit) = Row(modifier) { // TODO: fix UI to remove save-buttons (instead wait fo end of editing) + Text("Grade: ", Modifier.align(Alignment.CenterVertically)) + + when(grade) { + is Grade.Categoric -> { + if(grade.options.size <= 5) { + Column { + SingleChoiceSegmentedButtonRow(Modifier.fillMaxWidth()) { + grade.options.forEachIndexed { idx, opt -> + println("Rendering opt ${opt.option} (index $idx) ~ current value: ${grade.value.option})") + SegmentedButton( + grade.value.option == opt.option, { onUpdate(Grade.Categoric(opt, grade.options, grade.grade)) }, + shape = SegmentedButtonDefaults.itemShape(idx, grade.options.size) + ) { Text(opt.option.maxN(15)) } + } + } + Row { + Spacer(Modifier.weight(1f)) + Text(grade.value.option, fontStyle = FontStyle.Italic, style = MaterialTheme.typography.bodySmall) + } + } + } + else { + var slider by remember(grade, key) { mutableStateOf(maxOf(0, grade.options.indexOfFirst { it.option == grade.value.option })) } + Row { + Column(Modifier.weight(1f)) { + Slider( + slider.toFloat(), + onValueChange = { onUpdate(grade.copy(value = grade.options[slider])) }, + steps = grade.options.size, + valueRange = 0f..(grade.options.size - 1).toFloat() + ) + Row { + Spacer(Modifier.weight(1f)) + Text(grade.options[slider].option, fontStyle = FontStyle.Italic, style = MaterialTheme.typography.bodySmall) + } + } + } + } + } + is Grade.FreeText -> { + var text by remember(grade, key) { mutableStateOf(grade.text) } + + OutlinedTextField(grade.text, { onUpdate(grade.copy(text = it)) }, Modifier.weight(1f), singleLine = true) + Button({ onUpdate(Grade.FreeText(text)) }, enabled = text != grade.text) { + Text("Save") + } + } + is Grade.Numeric -> { + var num by remember(grade, key) { mutableStateOf(grade.value.toString()) } + + OutlinedTextField( + num, { num = it.filter { c -> c.isDigit() || c == '.' || c == ',' }.ifEmpty { "0" } }, + Modifier.weight(1f), singleLine = true, isError = (num.toDoubleOrNull() ?: 0.0) > grade.grade.max + ) + Button({ onUpdate(Grade.Numeric(num.toDoubleOrNull() ?: 0.0, grade.grade)) }, enabled = (num.toDoubleOrNull() ?: 0.0) <= grade.grade.max) { + Text("Save") + } + } + is Grade.Percentage -> { + var perc by remember(grade, key) { mutableStateOf(grade.percentage.toString()) } + + OutlinedTextField("$perc%", { perc = it.filter { c -> c.isDigit() || c == '.' || c == ',' }.ifEmpty { "0" } }, Modifier.weight(1f), singleLine = true) + Button({ onUpdate(Grade.Percentage(perc.toDoubleOrNull() ?: 0.0)) }) { + Text("Save") + } + } + } } \ 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 index 38260c3..120c698 100644 --- a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/DbState.kt +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/DbState.kt @@ -3,821 +3,64 @@ 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.* -import com.jaytux.grader.data.EditionStudents.editionId -import com.jaytux.grader.data.EditionStudents.studentId -import com.jaytux.grader.viewmodel.GroupAssignmentState.* -import kotlinx.datetime.* -import kotlinx.datetime.TimeZone -import org.jetbrains.exposed.dao.id.EntityID -import org.jetbrains.exposed.sql.* -import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq -import org.jetbrains.exposed.sql.transactions.transaction -import java.util.* -import kotlin.math.max +import org.jetbrains.exposed.v1.core.Transaction +import org.jetbrains.exposed.v1.jdbc.transactions.transaction fun MutableState.immutable(): State = this -fun SizedIterable.sortAsc(vararg columns: Expression<*>) = this.orderBy(*(columns.map { it to SortOrder.ASC }.toTypedArray())) - -enum class AssignmentType(val show: String) { Solo("Solo Assignment"), Group("Group Assignment"), Peer("Peer Evaluation") } -sealed class Assignment { - class GAssignment(val assignment: GroupAssignment) : Assignment() { - override fun name(): String = assignment.name - override fun id(): EntityID = assignment.id - override fun index(): Int? = assignment.number - } - class SAssignment(val assignment: SoloAssignment) : Assignment() { - override fun name(): String = assignment.name - override fun id(): EntityID = assignment.id - override fun index(): Int? = assignment.number - } - class PeerEval(val evaluation: com.jaytux.grader.data.PeerEvaluation) : Assignment() { - override fun name(): String = evaluation.name - override fun id(): EntityID = evaluation.id - override fun index(): Int? = evaluation.number - } - - abstract fun name(): String - abstract fun id(): EntityID - abstract fun index(): Int? - - companion object { - fun from(assignment: GroupAssignment) = GAssignment(assignment) - fun from(assignment: SoloAssignment) = SAssignment(assignment) - fun from(pEval: PeerEvaluation) = PeerEval(pEval) - - fun merge(groups: List, solos: List, peers: List): List { - val g = groups.map { from(it) } - val s = solos.map { from(it) } - val p = peers.map { from(it) } - return (g + s + p).sortedWith(compareBy { it.index() }.thenBy { it.name() }) - } - } -} class RawDbState(private val loader: (Transaction.() -> List)) { - private val rawEntities by lazy { mutableStateOf(transaction { loader() }) } - val entities = rawEntities.immutable() + val entities = rawEntities.immutable() fun refresh() { rawEntities.value = transaction { loader() } } } -class CourseListState { - val courses = RawDbState { Course.all().sortAsc(Courses.name).toList() } - - fun new(name: String) { - transaction { Course.new { this.name = name } } - courses.refresh() +class RawDbFocusableSingleState(private val loader: (Transaction.(TIn) -> TOut?)) { + private var _input: TIn? = null + private val rawEntity by lazy { + mutableStateOf(null) } - fun delete(course: Course) { - transaction { course.delete() } - courses.refresh() + val entity: State = rawEntity.immutable() + + fun focus(input: TIn) { + _input = input + rawEntity.value = transaction { loader(input) } } - fun getEditions(course: Course) = EditionListState(course) -} - -class EditionListState(val course: Course) { - val editions = RawDbState { Edition.find { Editions.courseId eq course.id }.sortAsc(Editions.name).toList() } - - fun new(name: String) { - transaction { Edition.new { this.name = name; this.course = this@EditionListState.course } } - editions.refresh() + fun unfocus() { + _input = null + rawEntity.value = null } - fun delete(edition: Edition) { - transaction { edition.delete() } - editions.refresh() + fun refresh() { + rawEntity.value = transaction { _input?.let { loader(it) } } } } -enum class OpenPanel(val tabName: String) { - Student("Students"), Group("Groups"), Assignment("Assignments") -} - -class EditionState(val edition: Edition) { - val course = transaction { edition.course } - val students = RawDbState { edition.soloStudents.sortAsc(Students.name).toList() } - val groups = RawDbState { edition.groups.sortAsc(Groups.name).toList() } - val solo = RawDbState { edition.soloAssignments.sortAsc(SoloAssignments.name).toList() } - val groupAs = RawDbState { edition.groupAssignments.sortAsc(GroupAssignments.name).toList() } - val peer = RawDbState { edition.peerEvaluations.sortAsc(PeerEvaluations.name).toList() } - private val _history = mutableStateOf(listOf(-1 to OpenPanel.Assignment)) - val history = _history.immutable() - - val availableStudents = RawDbState { - Student.find { - (Students.id notInList edition.soloStudents.map { it.id }) - }.toList() +class RawDbFocusableState(private val loader: (Transaction.(TIn) -> List)) { + private var _input: TIn? = null + private val rawEntities by lazy { + mutableStateOf?>(null) } - fun newStudent(name: String, contact: String, note: String, addToEdition: Boolean) { - transaction { - val student = Student.new { this.name = name; this.contact = contact; this.note = note } - if(addToEdition) EditionStudents.insert { - it[editionId] = edition.id - it[studentId] = student.id - } - } + val entities: State?> = rawEntities.immutable() - if(addToEdition) students.refresh() - else availableStudents.refresh() - } - fun setStudentName(student: Student, name: String) { - transaction { - student.name = name - } - students.refresh() - } - fun addToCourse(students: List) { - transaction { - EditionStudents.batchInsert(students) { - this[editionId] = edition.id - this[studentId] = it.id - } - } - availableStudents.refresh() - this.students.refresh() + fun focus(input: TIn) { + _input = input + rawEntities.value = transaction { loader(input) } } - fun newGroup(name: String) { - transaction { - Group.new { this.name = name; this.edition = this@EditionState.edition } - groups.refresh() - } - } - fun setGroupName(group: Group, name: String) { - transaction { - group.name = name - } - groups.refresh() + fun unfocus() { + _input = null + rawEntities.value = null } - private fun now(): LocalDateTime { - val instant = Instant.fromEpochMilliseconds(System.currentTimeMillis()) - return instant.toLocalDateTime(TimeZone.currentSystemDefault()) + fun refresh() { + rawEntities.value = transaction { _input?.let { loader(it) } } } - - private fun nextIdx(): Int = max( - solo.entities.value.maxOfOrNull { it.number ?: 0 } ?: 0, - groupAs.entities.value.maxOfOrNull { it.number ?: 0 } ?: 0 - ) + 1 - - fun newSoloAssignment(name: String) { - transaction { - val assign = SoloAssignment.new { - this.name = name; this.edition = this@EditionState.edition; assignment = ""; deadline = now() - this.number = nextIdx() - } - val global = SoloAssignmentCriterion.new { - this.name = "_global"; this.description = "[Global] Meta-criterion for $name"; this.assignment = assign - } - assign.globalCriterion = global - solo.refresh() - } - } - fun setSoloAssignmentTitle(assignment: SoloAssignment, title: String) { - transaction { - assignment.name = title - } - solo.refresh() - } - fun newGroupAssignment(name: String) { - transaction { - val assign = GroupAssignment.new { - this.name = name; this.edition = this@EditionState.edition; assignment = ""; deadline = now() - this.number = nextIdx() - } - val global = GroupAssignmentCriterion.new { - this.name = "_global"; this.description = "[Global] Meta-criterion for $name"; this.assignment = assign - } - assign.globalCriterion = global - groupAs.refresh() - } - } - fun setGroupAssignmentTitle(assignment: GroupAssignment, title: String) { - transaction { - assignment.name = title - } - groupAs.refresh() - } - fun newPeerEvaluation(name: String) { - transaction { - PeerEvaluation.new { - this.name = name; this.edition = this@EditionState.edition - this.number = nextIdx() - } - peer.refresh() - } - } - fun setPeerEvaluationTitle(assignment: PeerEvaluation, title: String) { - transaction { - assignment.name = title - } - peer.refresh() - } - - fun newAssignment(type: AssignmentType, name: String) = when(type) { - AssignmentType.Solo -> newSoloAssignment(name) - AssignmentType.Group -> newGroupAssignment(name) - AssignmentType.Peer -> newPeerEvaluation(name) - } - fun setAssignmentTitle(assignment: Assignment, title: String) = when(assignment) { - is Assignment.GAssignment -> setGroupAssignmentTitle(assignment.assignment, title) - is Assignment.SAssignment -> setSoloAssignmentTitle(assignment.assignment, title) - is Assignment.PeerEval -> setPeerEvaluationTitle(assignment.evaluation, title) - } - - fun swapOrder(a1: Assignment, a2: Assignment) { - transaction { - when(a1) { - is Assignment.GAssignment -> { - when(a2) { - is Assignment.GAssignment -> { - val temp = a1.assignment.number - a1.assignment.number = a2.assignment.number - a2.assignment.number = temp - } - is Assignment.SAssignment -> { - val temp = a1.assignment.number - a1.assignment.number = nextIdx() - a2.assignment.number = temp - } - is Assignment.PeerEval -> { - val temp = a1.assignment.number - a1.assignment.number = nextIdx() - a2.evaluation.number = temp - } - } - } - is Assignment.SAssignment -> { - when(a2) { - is Assignment.GAssignment -> { - val temp = a1.assignment.number - a1.assignment.number = a2.assignment.number - a2.assignment.number = temp - } - is Assignment.SAssignment -> { - val temp = a1.assignment.number - a1.assignment.number = a2.assignment.number - a2.assignment.number = temp - } - is Assignment.PeerEval -> { - val temp = a1.assignment.number - a1.assignment.number = nextIdx() - a2.evaluation.number = temp - } - } - } - is Assignment.PeerEval -> { - when(a2) { - is Assignment.GAssignment -> { - val temp = a1.evaluation.number - a1.evaluation.number = a2.assignment.number - a2.assignment.number = temp - } - is Assignment.SAssignment -> { - val temp = a1.evaluation.number - a1.evaluation.number = a2.assignment.number - a2.assignment.number = temp - } - is Assignment.PeerEval -> { - val temp = a1.evaluation.number - a1.evaluation.number = a2.evaluation.number - a2.evaluation.number = temp - } - } - } - } - } - solo.refresh(); groupAs.refresh() - } - - fun delete(s: Student) { - transaction { - EditionStudents.deleteWhere { studentId eq s.id } - GroupStudents.deleteWhere { studentId eq s.id } - IndividualFeedbacks.deleteWhere { studentId eq s.id } - } - students.refresh(); availableStudents.refresh() - } - fun delete(g: Group) { - transaction { - GroupFeedbacks.deleteWhere { groupId eq g.id } - IndividualFeedbacks.deleteWhere { groupId eq g.id } - GroupStudents.deleteWhere { groupId eq g.id } - g.delete() - } - groups.refresh(); groupAs.refresh() - } - fun delete(sa: SoloAssignment) { - transaction { - SoloAssignmentCriteria.selectAll().where { SoloAssignmentCriteria.assignmentId eq sa.id }.forEach { it -> - val id = it[SoloAssignmentCriteria.assignmentId] - SoloFeedbacks.deleteWhere { criterionId eq id } - } - SoloAssignmentCriteria.deleteWhere { assignmentId eq sa.id } - sa.delete() - } - solo.refresh() - } - fun delete(ga: GroupAssignment) { - transaction { - GroupAssignmentCriteria.selectAll().where { GroupAssignmentCriteria.assignmentId eq ga.id }.forEach { it -> - val id = it[GroupAssignmentCriteria.assignmentId] - GroupFeedbacks.deleteWhere { criterionId eq id } - IndividualFeedbacks.deleteWhere { criterionId eq id } - } - GroupAssignmentCriteria.deleteWhere { assignmentId eq ga.id } - ga.delete() - } - groupAs.refresh() - } - fun delete(pe: PeerEvaluation) { - transaction { - PeerEvaluationContents.deleteWhere { peerEvaluationId eq pe.id } - StudentToStudentEvaluation.deleteWhere { peerEvaluationId eq pe.id } - pe.delete() - } - peer.refresh() - } - fun delete(assignment: Assignment) = when(assignment) { - is Assignment.GAssignment -> delete(assignment.assignment) - is Assignment.SAssignment -> delete(assignment.assignment) - is Assignment.PeerEval -> delete(assignment.evaluation) - } - - fun navTo(panel: OpenPanel, id: Int = -1) { - _history.value += (id to panel) - } - fun navTo(id: Int) = navTo(_history.value.last().second, id) - fun back() { - var temp = _history.value.dropLast(1) - while(temp.last().first == -1 && temp.size >= 2) temp = temp.dropLast(1) - _history.value = temp - } - fun clearHistoryIndex() { - val last = _history.value.lastOrNull() ?: return - _history.value = _history.value.filter { (i, panel) -> panel != last.second || i != last.first } + (-1 to last.second) - } -} - -class StudentState(val student: Student, edition: Edition) { - data class LocalGroupGrade(val groupName: String, val assignmentName: String, val groupGrade: String?, val indivGrade: String?) - data class LocalSoloGrade(val assignmentName: String, val grade: String) - - val editionCourse = transaction { edition.course to edition } - val groups = RawDbState { student.groups.sortAsc(Groups.name).map { it to (it.edition.course.name to it.edition.name) }.toList() } - val courseEditions = RawDbState { student.courses.map{ it to it.course }.sortedWith { - (e1, c1), (e2, c2) -> c1.name.compareTo(c2.name).let { if(it == 0) e1.name.compareTo(e2.name) else it } - }.toList() } - - val groupGrades = RawDbState { - val groupsForEdition = Group.find { - (Groups.editionId eq edition.id) and (Groups.id inList student.groups.map { it.id }) - }.associate { it.id to it.name } - - val asGroup = (GroupAssignments innerJoin GroupAssignmentCriteria innerJoin GroupFeedbacks innerJoin Groups).selectAll().where { - (GroupFeedbacks.groupId inList groupsForEdition.keys.toList()) and - (GroupAssignmentCriteria.id eq GroupAssignments.globalCriterion) - }.map { it[GroupAssignments.id] to it } - - val asIndividual = (GroupAssignments innerJoin GroupAssignmentCriteria innerJoin IndividualFeedbacks innerJoin Groups).selectAll().where { - (IndividualFeedbacks.studentId eq student.id) and - (GroupAssignmentCriteria.id eq GroupAssignments.globalCriterion) - }.map { it[GroupAssignments.id] to it } - - val res = mutableMapOf, LocalGroupGrade>() - asGroup.forEach { - val (gAId, gRow) = it - - res[gAId] = LocalGroupGrade( - gRow[Groups.name], gRow[GroupAssignments.name], gRow[GroupFeedbacks.grade], null - ) - } - - asIndividual.forEach { - val (gAId, iRow) = it - - val og = res[gAId] ?: LocalGroupGrade(iRow[Groups.name], iRow[GroupAssignments.name], null, null) - res[gAId] = og.copy(indivGrade = iRow[IndividualFeedbacks.grade]) - } - - res.values.toList() - } - - val soloGrades = RawDbState { - (SoloAssignments innerJoin SoloAssignmentCriteria innerJoin SoloFeedbacks).selectAll().where { - (SoloFeedbacks.studentId eq student.id) and - (SoloAssignmentCriteria.name eq "") - }.map { LocalSoloGrade(it[SoloAssignments.name], it[SoloFeedbacks.grade]) }.toList() - } - - fun update(f: Student.() -> Unit) { - transaction { - student.f() - } - } -} - -class GroupState(val group: Group) { - val members = RawDbState { group.studentRoles.map{ it.student to it.role }.sortedBy { it.first.name }.toList() } - val availableStudents = RawDbState { Student.find { - // not yet in the group - (Students.id notInList group.students.map { it.id }) and - // but in the same course (edition) - (Students.id inList group.edition.soloStudents.map { it.id }) - }.sortAsc(Students.name).toList() } - val course = transaction { group.edition.course to group.edition } - val roles = RawDbState { - GroupStudents.select(GroupStudents.role).where{ GroupStudents.role.isNotNull() } - .withDistinct(true).sortAsc(GroupStudents.role).map{ it[GroupStudents.role] ?: "" }.toList() - } - - fun addStudent(student: Student) { - transaction { - GroupStudents.insert { - it[groupId] = group.id - it[studentId] = student.id - } - } - members.refresh(); availableStudents.refresh() - } - - fun removeStudent(student: Student) { - transaction { - GroupStudents.deleteWhere { groupId eq group.id and (studentId eq student.id) } - } - members.refresh(); availableStudents.refresh() - } - - fun updateRole(student: Student, role: String?) { - transaction { - GroupStudents.update({ GroupStudents.groupId eq group.id and (GroupStudents.studentId eq student.id) }) { - it[this.role] = role - } - members.refresh() - roles.refresh() - } - } -} - -class GroupAssignmentState(val assignment: GroupAssignment) { - data class FeedbackEntry(val feedback: String, val grade: String) - data class LocalCriterionFeedback( - val criterion: GroupAssignmentCriterion, val entry: FeedbackEntry? - ) - data class LocalFeedback( - val global: FeedbackEntry?, val byCriterion: List - ) - data class LocalGFeedback( - val group: Group, - val feedback: LocalFeedback, - val individuals: List>> // Student -> (Role, Feedback) - ) - - val editionCourse = transaction { assignment.edition.course to assignment.edition } - private val _name = mutableStateOf(assignment.name); val name = _name.immutable() - private val _task = mutableStateOf(assignment.assignment); val task = _task.immutable() - private val _deadline = mutableStateOf(assignment.deadline); val deadline = _deadline.immutable() - val criteria = RawDbState { - assignment.criteria.orderBy(GroupAssignmentCriteria.name to SortOrder.ASC).filter { it.id != assignment.globalCriterion.id } - } - val feedback = RawDbState { loadFeedback() } - - val autofill = RawDbState { - val forGroups = (GroupFeedbacks innerJoin GroupAssignmentCriteria).selectAll().where { GroupAssignmentCriteria.assignmentId eq assignment.id }.flatMap { - it[GroupFeedbacks.feedback].split('\n') - } - - val forIndividuals = (IndividualFeedbacks innerJoin GroupAssignmentCriteria).selectAll().where { GroupAssignmentCriteria.assignmentId eq assignment.id }.flatMap { - it[IndividualFeedbacks.feedback].split('\n') - } - - (forGroups + forIndividuals).distinct().sorted() - } - - private fun Transaction.loadFeedback(): List> { - val allCrit = GroupAssignmentCriterion.find { - GroupAssignmentCriteria.assignmentId eq assignment.id - }.orderBy(GroupAssignmentCriteria.name to SortOrder.ASC).filter { it.id != assignment.globalCriterion.id } - - return Group.find { - (Groups.editionId eq assignment.edition.id) - }.sortAsc(Groups.name).map { group -> - val forGroup = (GroupFeedbacks innerJoin Groups).selectAll().where { - (GroupFeedbacks.assignmentId eq assignment.id) and (Groups.id eq group.id) - }.map { row -> - val crit = GroupAssignmentCriterion[row[GroupFeedbacks.criterionId]] - val fdbk = row[GroupFeedbacks.feedback] - val grade = row[GroupFeedbacks.grade] - - crit to FeedbackEntry(fdbk, grade) - } - - val global = forGroup.firstOrNull { it.first.id == assignment.globalCriterion.id }?.second - val byCrit_ = forGroup - .filter{ it.first.id != assignment.globalCriterion.id } - .map { LocalCriterionFeedback(it.first, it.second) } - .associateBy { it.criterion.id } - - val byCrit = allCrit.map { c -> - byCrit_[c.id] ?: LocalCriterionFeedback(c, null) - } - - val byGroup = LocalFeedback(global, byCrit) - - val indiv = group.studentRoles.map { - val student = it.student - val role = it.role - - val forSt = (IndividualFeedbacks innerJoin Groups) - .selectAll().where { - (IndividualFeedbacks.assignmentId eq assignment.id) and - (IndividualFeedbacks.studentId eq student.id) and (Groups.id eq group.id) - }.map { row -> - val stdId = row[IndividualFeedbacks.studentId] - val crit = GroupAssignmentCriterion[row[IndividualFeedbacks.criterionId]] - val fdbk = row[IndividualFeedbacks.feedback] - val grade = row[IndividualFeedbacks.grade] - - crit to FeedbackEntry(fdbk, grade) - } - - val global = forSt.firstOrNull { it.first.id == assignment.globalCriterion.id }?.second - val byCrit_ = forSt - .filter { it.first != assignment.globalCriterion.id } - .map { LocalCriterionFeedback(it.first, it.second) } - .associateBy { it.criterion.id } - - val byCrit = allCrit.map { c -> - byCrit_[c.id] ?: LocalCriterionFeedback(c, null) - } - val byStudent = LocalFeedback(global, byCrit) - - student to (role to byStudent) - } - - group to LocalGFeedback(group, byGroup, indiv) - } - } - - fun upsertGroupFeedback(group: Group, msg: String, grd: String, criterion: GroupAssignmentCriterion? = null) { - transaction { - GroupFeedbacks.upsert { - it[assignmentId] = assignment.id - it[groupId] = group.id - it[this.feedback] = msg - it[this.grade] = grd - it[criterionId] = criterion?.id ?: assignment.globalCriterion.id - } - } - feedback.refresh(); autofill.refresh() - } - - fun upsertIndividualFeedback(student: Student, group: Group, msg: String, grd: String, criterion: GroupAssignmentCriterion? = null) { - transaction { - IndividualFeedbacks.upsert { - it[assignmentId] = assignment.id - it[groupId] = group.id - it[studentId] = student.id - it[this.feedback] = msg - it[this.grade] = grd - it[criterionId] = criterion?.id ?: assignment.globalCriterion.id - } - } - feedback.refresh(); autofill.refresh() - } - - fun updateTask(t: String) { - transaction { - assignment.assignment = t - } - _task.value = t - } - - fun updateDeadline(d: LocalDateTime) { - transaction { - assignment.deadline = d - } - _deadline.value = d - } - - fun addCriterion(name: String) { - transaction { - GroupAssignmentCriterion.new { - this.name = name; - this.description = ""; - this.assignment = this@GroupAssignmentState.assignment - } - criteria.refresh() - } - } - - fun updateCriterion(criterion: GroupAssignmentCriterion, name: String, desc: String) { - transaction { - criterion.name = name - criterion.description = desc - } - criteria.refresh() - } - - fun deleteCriterion(criterion: GroupAssignmentCriterion) { - transaction { - GroupFeedbacks.deleteWhere { criterionId eq criterion.id } - IndividualFeedbacks.deleteWhere { criterionId eq criterion.id } - criterion.delete() - } - criteria.refresh() - } -} - -class SoloAssignmentState(val assignment: SoloAssignment) { - data class LocalFeedback(val feedback: String, val grade: String) - data class FullFeedback(val global: LocalFeedback?, val byCriterion: List>) - - val editionCourse = transaction { assignment.edition.course to assignment.edition } - private val _name = mutableStateOf(assignment.name); val name = _name.immutable() - private val _task = mutableStateOf(assignment.assignment); val task = _task.immutable() - private val _deadline = mutableStateOf(assignment.deadline); val deadline = _deadline.immutable() - val criteria = RawDbState { - assignment.criteria.orderBy(SoloAssignmentCriteria.name to SortOrder.ASC).filter { it.id != assignment.globalCriterion.id } - } - val feedback = RawDbState { loadFeedback() } - - val autofill = RawDbState { - SoloFeedbacks.selectAll().where { SoloFeedbacks.assignmentId eq assignment.id }.map { - it[SoloFeedbacks.feedback].split('\n') - }.flatten().distinct().sorted() - } - - private fun Transaction.loadFeedback(): List> {3 - val allCrit = SoloAssignmentCriterion.find { - SoloAssignmentCriteria.assignmentId eq assignment.id - }.orderBy(SoloAssignmentCriteria.name to SortOrder.ASC).filter { it.id != assignment.globalCriterion.id } - - return editionCourse.second.soloStudents.sortAsc(Students.name).map { student -> - val forStudent = (IndividualFeedbacks innerJoin Students).selectAll().where { - (IndividualFeedbacks.assignmentId eq assignment.id) and (Students.id eq student.id) - }.map { row -> - val crit = SoloAssignmentCriterion[row[IndividualFeedbacks.criterionId]] - val fdbk = row[IndividualFeedbacks.feedback] - val grade = row[IndividualFeedbacks.grade] - - crit to LocalFeedback(fdbk, grade) - } - - val global = forStudent.firstOrNull { it.first == assignment.globalCriterion.id }?.second - val byCrit_ = forStudent - .filter { it.first != assignment.globalCriterion.id } - .map { Pair(it.first, it.second) } - .associateBy { it.first.id } - - val byCrit = allCrit.map { c -> - byCrit_[c.id] ?: Pair(c, null) - } - - student to FullFeedback(global, byCrit) - } - } - - fun upsertFeedback(student: Student, msg: String?, grd: String?, criterion: SoloAssignmentCriterion? = null) { - transaction { - SoloFeedbacks.upsert { - it[assignmentId] = assignment.id - it[studentId] = student.id - it[this.feedback] = msg ?: "" - it[this.grade] = grd ?: "" - it[criterionId] = criterion?.id ?: assignment.globalCriterion.id - } - } - feedback.refresh(); autofill.refresh() - } - - fun updateTask(t: String) { - transaction { - assignment.assignment = t - } - _task.value = t - } - - fun updateDeadline(d: LocalDateTime) { - transaction { - assignment.deadline = d - } - _deadline.value = d - } - - fun addCriterion(name: String) { - transaction { - SoloAssignmentCriterion.new { - this.name = name; - this.description = ""; - this.assignment = this@SoloAssignmentState.assignment - } - criteria.refresh() - } - } - - fun updateCriterion(criterion: SoloAssignmentCriterion, name: String, desc: String) { - transaction { - criterion.name = name - criterion.description = desc - } - criteria.refresh() - } - - fun deleteCriterion(criterion: SoloAssignmentCriterion) { - transaction { - SoloFeedbacks.deleteWhere { criterionId eq criterion.id } - criterion.delete() - } - criteria.refresh() - } -} - -class PeerEvaluationState(val evaluation: PeerEvaluation) { - data class Student2StudentEntry(val grade: String, val feedback: String) - data class StudentEntry(val student: Student, val role: String?, val global: Student2StudentEntry?, val others: List>) - data class GroupEntry(val group: Group, val content: String, val students: List) - val editionCourse = transaction { evaluation.edition.course to evaluation.edition } - private val _name = mutableStateOf(evaluation.name); val name = _name.immutable() - val contents = RawDbState { loadContents() } - - private fun Transaction.loadContents(): List { - return evaluation.edition.groups.map { group -> - val globalNotes = PeerEvaluationContents.selectAll() - .where { - (PeerEvaluationContents.groupId eq group.id) and - (PeerEvaluationContents.peerEvaluationId eq evaluation.id) - }.firstOrNull()?.let { - it[PeerEvaluationContents.content] - } - - val students = group.students.map { from -> - val role = GroupStudents.selectAll().where { (GroupStudents.studentId eq from.id) and (GroupStudents.groupId eq group.id) }.firstOrNull()?.let { - it[GroupStudents.role] - } - val s2g = StudentToGroupEvaluation.selectAll().where { - (StudentToGroupEvaluation.peerEvaluationId eq evaluation.id) and - (StudentToGroupEvaluation.studentId eq from.id) - }.firstOrNull()?.let { - Student2StudentEntry(it[StudentToGroupEvaluation.grade], it[StudentToGroupEvaluation.note]) - } - - val others = group.students.map { other -> - val eval = StudentToStudentEvaluation.selectAll().where { - (StudentToStudentEvaluation.peerEvaluationId eq evaluation.id) and - (StudentToStudentEvaluation.studentIdFrom eq from.id) and - (StudentToStudentEvaluation.studentIdTo eq other.id) - }.firstOrNull()?.let { - Student2StudentEntry(it[StudentToStudentEvaluation.grade], it[StudentToStudentEvaluation.note]) - } - - other to eval - } - - StudentEntry(from, role, s2g, others) - } - - GroupEntry(group, globalNotes ?: "", students) - } - } - - fun upsertGroupFeedback(group: Group, feedback: String) { - transaction { - PeerEvaluationContents.upsert { - it[peerEvaluationId] = evaluation.id - it[groupId] = group.id - it[this.content] = feedback - } - } - contents.refresh() - } - - fun upsertIndividualFeedback(from: Student, to: Student?, grade: String, feedback: String) { - transaction { - to?.let { - StudentToStudentEvaluation.upsert { - it[peerEvaluationId] = evaluation.id - it[studentIdFrom] = from.id - it[studentIdTo] = to.id - it[this.grade] = grade - it[this.note] = feedback - } - } ?: StudentToGroupEvaluation.upsert { - it[peerEvaluationId] = evaluation.id - it[studentId] = from.id - it[this.grade] = grade - it[this.note] = feedback - } - } - contents.refresh() - } -} +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/EditionVM.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/EditionVM.kt new file mode 100644 index 0000000..e7168a0 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/EditionVM.kt @@ -0,0 +1,419 @@ +package com.jaytux.grader.viewmodel + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.lifecycle.ViewModel +import com.jaytux.grader.app +import com.jaytux.grader.data.v2.* +import com.jaytux.grader.ui.AssignmentsTabHeader +import com.jaytux.grader.ui.GroupsTabHeader +import com.jaytux.grader.ui.StudentsTabHeader +import kotlinx.datetime.LocalDateTime +import kotlinx.datetime.TimeZone +import kotlinx.datetime.toLocalDateTime +import org.jetbrains.exposed.v1.core.Expression +import org.jetbrains.exposed.v1.core.SortOrder +import org.jetbrains.exposed.v1.core.Transaction +import org.jetbrains.exposed.v1.core.and +import org.jetbrains.exposed.v1.core.eq +import org.jetbrains.exposed.v1.dao.with +import org.jetbrains.exposed.v1.jdbc.insert +import org.jetbrains.exposed.v1.jdbc.select +import org.jetbrains.exposed.v1.jdbc.transactions.transaction +import kotlin.time.Clock + +class EditionVM(val edition: Edition, val course: Course) : ViewModel() { + data class GroupData(val group: Group, val members: List>) + data class CriterionData(val criterion: Criterion, val gradeType: UiGradeType) { + companion object { + context(trns: Transaction) + fun from(c: Criterion) = CriterionData(c, when(c.gradeType) { + GradeType.CATEGORIC -> UiGradeType.Categoric(c.categoricGrade!!.options.toList(), c.categoricGrade!!) + GradeType.NUMERIC -> UiGradeType.Numeric(c.numericGrade!!) + GradeType.PERCENTAGE -> UiGradeType.Percentage + GradeType.NONE -> UiGradeType.FreeText + }) + } + } + data class AssignmentData(val assignment: BaseAssignment, val global: CriterionData, val criteria: List) + data class GradeSummary(val assignment: BaseAssignment, val asMember: Group?, val overridden: Boolean, val grade: Grade?) + enum class Tab(val renderTab: @Composable () -> Unit, val addText: String) { + STUDENTS(::StudentsTabHeader, "Student"), + GROUPS(::GroupsTabHeader, "Group"), + ASSIGNMENTS(::AssignmentsTabHeader, "Assignment") + } + + val studentList = RawDbState { edition.students.sortedBy { it.name }.toList() } + val groupList = RawDbState { + edition.groups.with(Group::students, GroupStudent::student).sortedBy { it.name }.map { + GroupData(it, it.students.map { gs -> gs.student to gs.role }.sortedBy { it.first.name }) + } + } + val assignmentList = RawDbState { + edition.assignments.sortedBy { it.number }.map { + AssignmentData(it, CriterionData.from(it.globalCriterion), it.nonBaseCriteria.map { c -> + CriterionData.from(c) + }) + } + } + val usedRoles = RawDbState { + GroupStudents.select(GroupStudents.role).mapNotNull { it[GroupStudents.role] }.distinct() + } + + val categoricGrades = RawDbState { + CategoricGrade.all().map { + UiGradeType.Categoric(it.options.toList(), it) + } + } + + val numericGrades = RawDbState { + NumericGrade.all().map { UiGradeType.Numeric(it) } + } + + val studentGrades = RawDbFocusableState { st: Student -> + val groupIds = st.groups.map { it.group.id }.toSet() + + edition.assignments.map { asg -> + val (grade, memberOf, override) = when(asg.type) { + AssignmentType.GROUP -> { + val asGroup = asg.globalCriterion.feedbacks.find { it.asGroupFeedback?.id in groupIds } + val solo = null // asg.globalCriterion.feedbacks.find { it.forStudentsOverrideIfGroup.any { over -> over.student == st } } // TODO + val gr = (solo ?: asGroup)?.let { Grade.fromAssignment(asg.globalCriterion, it) } + gr to asGroup?.asGroupFeedback app (solo != null) + } + AssignmentType.SOLO -> { + val gr = asg.globalCriterion.feedbacks.find { it.asSoloFeedback == st } + ?.let { Grade.fromAssignment(asg.globalCriterion, it) } + gr to null app false + } + AssignmentType.PEER_EVALUATION -> { + val asGroup = asg.globalCriterion.feedbacks.find { it.asPeerEvaluationFeedback?.id in groupIds } + val solo = asg.globalCriterion.feedbacks.find { it.forStudentsOverrideIfPeer.any { over -> over.student == st } } + val gr = (solo ?: asGroup)?.let { Grade.fromAssignment(asg.globalCriterion, it) } + gr to asGroup?.asPeerEvaluationFeedback app (solo != null) + } + } + + GradeSummary(asg, memberOf, override, grade) + } + } + val studentGroups = RawDbFocusableState { st: Student -> + st.groups.map { it.group to it.role } + } + + val groupAvailableStudents = RawDbFocusableState { grp: Group -> + val exclude = grp.students.map { it.student.id }.toSet() + edition.students.filterNot { it.id in exclude } + } + val groupGrades = RawDbFocusableState { g: Group -> + edition.assignments.filter{ it.type != AssignmentType.SOLO }.map { asg -> + val grade = when(asg.type) { + AssignmentType.GROUP -> { + val asGroup = asg.globalCriterion.feedbacks.find { it.asGroupFeedback?.id == g.id } + asGroup?.let { Grade.fromAssignment(asg.globalCriterion, it) } + } + AssignmentType.PEER_EVALUATION -> { + val asGroup = asg.globalCriterion.feedbacks.find { it.asPeerEvaluationFeedback?.id == g.id } + asGroup?.let { Grade.fromAssignment(asg.globalCriterion, it) } + } + else -> null + } + + asg to grade + } + } + + private val _selectedTab = mutableStateOf(Tab.STUDENTS) + private val _focusIndex = mutableStateOf(-1) + val selectedTab = _selectedTab.immutable() + val focusIndex = _focusIndex.immutable() + + fun switchTo(tab: Tab) { + _selectedTab.value = tab + _focusIndex.value = -1 + } + + fun focus(idx: Int) { + _focusIndex.value = idx + + when(_selectedTab.value) { + Tab.STUDENTS -> { + val st = studentList.entities.value[idx] + studentGrades.focus(st) + studentGroups.focus(st) + } + Tab.GROUPS -> { + val grp = groupList.entities.value[idx].group + groupAvailableStudents.focus(grp) + groupGrades.focus(grp) + } + Tab.ASSIGNMENTS -> {} + } + } + + fun focus(group: Group) { + val idx = groupList.entities.value.indexOfFirst { it.group.id == group.id } + if(idx != -1) { + switchTo(Tab.GROUPS) + focus(idx) + } + } + + fun focus(student: Student) { + val idx = studentList.entities.value.indexOfFirst { it.id == student.id } + if(idx != -1) { + switchTo(Tab.STUDENTS) + focus(idx) + } + } + + fun unfocus() { + _focusIndex.value = -1 + + studentGrades.unfocus() + studentGroups.unfocus() + } + + fun mkStudent(name: String, contact: String, note: String) { + transaction { + val s = Student.new { + this.name = name + this.contact = contact + this.note = note + } + EditionStudents.insert { + it[EditionStudents.editionId] = edition.id + it[EditionStudents.studentId] = s.id + } + } + unfocus() + studentList.refresh() + } + + fun modStudent(student: Student, name: String?, contact: String?, note: String?) { + transaction { + student.name = name ?: student.name + student.contact = contact ?: student.contact + student.note = note ?: student.note + } + studentList.refresh() + studentGroups.refresh() + studentGrades.refresh() + } + + fun rmStudent(student: Student) { + transaction { + student.delete() + } + unfocus() + studentList.refresh() + } + + fun mkGroup(name: String) { + transaction { + Group.new { + this.name = name + this.edition = this@EditionVM.edition + } + } + unfocus() + groupList.refresh() + } + + fun modGroup(group: Group, name: String?) { + transaction { + group.name = name ?: group.name + } + groupList.refresh() + } + + fun addStudentToGroup(student: Student, group: Group, role: String?) { + transaction { + GroupStudent.new { + this.student = student + this.group = group + this.role = role + } + } + groupList.refresh() + studentGroups.refresh() + groupAvailableStudents.refresh() + } + + fun setStudentRole(student: Student, group: Group, role: String?) { + transaction { + GroupStudent.find { (GroupStudents.studentId eq student.id) and (GroupStudents.groupId eq group.id) }.firstOrNull()?.let { + it.role = role + } + } + groupList.refresh() + groupAvailableStudents.refresh() + usedRoles.refresh() + } + + fun rmStudentFromGroup(student: Student, group: Group) { + transaction { + GroupStudent.find { (GroupStudents.studentId eq student.id) and (GroupStudents.groupId eq group.id) }.firstOrNull()?.delete() + } + groupList.refresh() + groupAvailableStudents.refresh() + } + + fun rmGroup(group: Group) { + transaction { + group.delete() + } + unfocus() + groupList.refresh() + } + + private fun Transaction.mkBaseAssignment(name: String, type: AssignmentType): BaseAssignment { + val asg = BaseAssignment.new { + this.name = name + this.assignment = "" + this.deadline = Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()) + this.number = assignmentList.entities.value.size + this.edition = this@EditionVM.edition + this.type = type + } + + val crit = Criterion.new { + this.assignment = asg + this.name = "(Default Criterion)" + this.desc = "Default criterion for assignment ${asg.name}" + this.gradeType = GradeType.NONE + } + + asg.globalCriterion = crit + return asg + } + + private fun postCreateAsg() { + focus(assignmentList.entities.value.size) + assignmentList.refresh() + } + + fun mkGroupAssignment(name: String) { + transaction { + val asg = mkBaseAssignment(name, AssignmentType.GROUP) + GroupAssignment.new { this.base = asg } + } + postCreateAsg() + } + + fun mkSoloAssignment(name: String) { + transaction { + val asg = mkBaseAssignment(name, AssignmentType.SOLO) + SoloAssignment.new { this.base = asg } + } + postCreateAsg() + } + + fun mkPeerEvaluation(name: String) { + transaction { + val asg = mkBaseAssignment(name, AssignmentType.PEER_EVALUATION) + PeerEvaluation.new { this.base = asg } + } + postCreateAsg() + } + + fun mkAssignment(name: String, type: AssignmentType) { + when(type) { + AssignmentType.GROUP -> mkGroupAssignment(name) + AssignmentType.SOLO -> mkSoloAssignment(name) + AssignmentType.PEER_EVALUATION -> mkPeerEvaluation(name) + } + } + + fun modAssignment(assignment: BaseAssignment, name: String?, deadline: LocalDateTime?) { + transaction { + assignment.name = name ?: assignment.name + assignment.deadline = deadline ?: assignment.deadline + } + assignmentList.refresh() + } + + fun setDesc(assignment: AssignmentData, desc: String) { + transaction { + assignment.global.criterion.desc = desc + } + assignmentList.refresh() + } + + fun mkCriterion(assignment: BaseAssignment, name: String, desc: String, gradeType: UiGradeType) { + transaction { + val crit = Criterion.new { + this.assignment = assignment + this.name = name + this.desc = desc + this.gradeType = when(gradeType) { + is UiGradeType.Categoric -> GradeType.CATEGORIC + is UiGradeType.Numeric -> GradeType.NUMERIC + UiGradeType.Percentage -> GradeType.PERCENTAGE + UiGradeType.FreeText -> GradeType.NONE + } + } + + when(gradeType) { + is UiGradeType.Categoric -> crit.categoricGrade = gradeType.grade + is UiGradeType.Numeric -> crit.numericGrade = gradeType.grade + else -> {} + } + } + assignmentList.refresh() + } + + fun modCriterion(crit: Criterion, name: String?, desc: String?, gradeType: UiGradeType?) { + transaction { + crit.name = name ?: crit.name + crit.desc = desc ?: crit.desc + crit.gradeType = when(gradeType) { + null -> crit.gradeType + is UiGradeType.Categoric -> GradeType.CATEGORIC + is UiGradeType.Numeric -> GradeType.NUMERIC + UiGradeType.Percentage -> GradeType.PERCENTAGE + UiGradeType.FreeText -> GradeType.NONE + } + + when(gradeType) { + is UiGradeType.Categoric -> crit.categoricGrade = gradeType.grade + is UiGradeType.Numeric -> crit.numericGrade = gradeType.grade + else -> {} + } + } + assignmentList.refresh() + } + + fun mkScale(name: String, options: List) { + transaction { + val grade = CategoricGrade.new { this.name = name } + options.forEachIndexed { idx, opt -> + CategoricGradeOption.new { + this.grade = grade + this.option = opt + this.index = idx + } + } + } + categoricGrades.refresh() + } + + fun mkNumericScale(name: String, max: Double) { + transaction { + NumericGrade.new { + this.name = name + this.max = max + } + } + numericGrades.refresh() + } + + fun rmAssignment(assignment: BaseAssignment) { + transaction { + assignment.delete() + (assignment.asPeerEvaluation ?: assignment.asGroupAssignment ?: assignment.asSoloAssignment)?.delete() + } + unfocus() + assignmentList.refresh() + } +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/Grade.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/Grade.kt new file mode 100644 index 0000000..b97d78a --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/Grade.kt @@ -0,0 +1,57 @@ +package com.jaytux.grader.viewmodel + +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.jaytux.grader.data.v2.BaseFeedback +import com.jaytux.grader.data.v2.CategoricGrade +import com.jaytux.grader.data.v2.CategoricGradeOption +import com.jaytux.grader.data.v2.CategoricGradeOptions +import com.jaytux.grader.data.v2.Criterion +import com.jaytux.grader.data.v2.GradeType +import com.jaytux.grader.data.v2.NumericGrade +import com.jaytux.grader.maxN +import org.jetbrains.exposed.v1.core.Transaction +import org.jetbrains.exposed.v1.jdbc.transactions.transaction + +sealed class Grade { + data class FreeText(val text: String) : Grade() + data class Percentage(val percentage: Double) : Grade() + data class Numeric(val value: Double, val grade: NumericGrade) : Grade() + data class Categoric(val value: CategoricGradeOption, val options: List, val grade: CategoricGrade) : Grade() + + @Composable + fun render(modifier: Modifier = Modifier) = when(this) { + is FreeText -> Text(text.maxN(15), modifier) + is Categoric -> Text(value.option, modifier) + is Numeric -> Text("$value / ${grade.max}", modifier) + is Percentage -> Text("$percentage%", modifier) + } + + companion object { + context(trns: Transaction) + fun fromAssignment(asg: Criterion, fdb: BaseFeedback): Grade = when(asg.gradeType) { + GradeType.CATEGORIC -> + Categoric(fdb.gradeCategoric!!, asg.categoricGrade!!.options.toList(), asg.categoricGrade!!) + + GradeType.NUMERIC -> Numeric(fdb.gradeNumeric!!, asg.numericGrade!!) + GradeType.PERCENTAGE -> Percentage(fdb.gradeNumeric!!) + GradeType.NONE -> FreeText(fdb.gradeFreeText!!) + } + + fun defaultFreeText() = FreeText("") + fun defaultPercentage() = Percentage(0.0) + fun defaultNumeric(grade: NumericGrade) = Numeric(0.0, grade) + fun defaultCategoric(grade: CategoricGrade, options: List) = Categoric(options.first(), options, grade) + + fun default(type: GradeType, cat: CategoricGrade?, num: NumericGrade?) = when(type) { + GradeType.CATEGORIC -> transaction { + cat!! + defaultCategoric(cat, cat.options.toList()) + } + GradeType.NUMERIC -> defaultNumeric(num!!) + GradeType.PERCENTAGE -> defaultPercentage() + GradeType.NONE -> defaultFreeText() + } + } +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/GroupsGradingVM.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/GroupsGradingVM.kt new file mode 100644 index 0000000..775df17 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/GroupsGradingVM.kt @@ -0,0 +1,174 @@ +package com.jaytux.grader.viewmodel + +import androidx.compose.runtime.mutableStateOf +import androidx.lifecycle.ViewModel +import com.jaytux.grader.data.v2.BaseAssignment +import com.jaytux.grader.data.v2.BaseFeedback +import com.jaytux.grader.data.v2.BaseFeedbacks +import com.jaytux.grader.data.v2.CategoricGrade +import com.jaytux.grader.data.v2.Course +import com.jaytux.grader.data.v2.Criterion +import com.jaytux.grader.data.v2.Edition +import com.jaytux.grader.data.v2.GradeType +import com.jaytux.grader.data.v2.Group +import com.jaytux.grader.data.v2.GroupAssignment +import com.jaytux.grader.data.v2.GroupFeedbacks +import com.jaytux.grader.data.v2.GroupStudent +import com.jaytux.grader.data.v2.NumericGrade +import com.jaytux.grader.data.v2.Student +import com.jaytux.grader.data.v2.StudentOverrideFeedback +import com.jaytux.grader.data.v2.StudentOverrideFeedbacks +import org.jetbrains.exposed.v1.core.Transaction +import org.jetbrains.exposed.v1.core.and +import org.jetbrains.exposed.v1.core.eq +import org.jetbrains.exposed.v1.dao.with +import org.jetbrains.exposed.v1.jdbc.insert +import org.jetbrains.exposed.v1.jdbc.transactions.transaction +import org.jetbrains.exposed.v1.jdbc.upsertReturning + +class GroupsGradingVM(val course: Course, val edition: Edition, val base: BaseAssignment) : ViewModel() { + data class GroupData(val group: Group, val students: List>) + data class FeedbackItem(val base: BaseFeedback, val grade: Grade, val feedback: String) { + companion object { + context(trns: Transaction) + fun fromDb(f: BaseFeedback): FeedbackItem = when(f.criterion.gradeType) { + GradeType.CATEGORIC -> { + val categoric = f.criterion.categoricGrade!! + val options = categoric.options.toList() + Grade.Categoric(f.gradeCategoric ?: options.first(), options, categoric) + } + GradeType.NUMERIC -> Grade.Numeric(f.gradeNumeric ?: 0.0, f.criterion.numericGrade!!) + GradeType.PERCENTAGE -> Grade.Percentage(f.gradeNumeric ?: 0.0) + GradeType.NONE -> Grade.FreeText(f.gradeFreeText ?: "") + }.let { FeedbackItem(f, it, f.feedback) } + } + } + data class FeedbackData(val groupLevel: FeedbackItem?, val overrides: List>) + data class CritData(val criterion: Criterion, val cat: CategoricGrade?, val num: NumericGrade?) { + companion object { + context(trns: Transaction) + fun fromDb(c: Criterion) = CritData(c, c.categoricGrade, c.numericGrade) + } + } + + private val _focus = mutableStateOf(-1) + val focus = _focus.immutable() + + val asGroup = transaction { base.asGroupAssignment!! } + val global = transaction { CritData.fromDb(base.globalCriterion) } + val groupList = RawDbState { + edition.groups.with(Group::students, GroupStudent::student).map { group -> + GroupData(group, group.students.map { Pair(it.student, it.role) }) + } + } + + val globalGrade = RawDbFocusableSingleState { group: Group -> + val g = base.globalCriterion.feedbacks.find { it.asGroupFeedback?.id == group.id }?.let { FeedbackItem.fromDb(it) } + val overrides = g?.let { gl -> getOverrides(group, gl.base) } ?: group.students.map { it.student to null } + FeedbackData(g, overrides) + } + + val gradeList = RawDbFocusableState { group: Group -> + base.nonBaseCriteria.map { crit -> + val groupLevel = crit.feedbacks.find { it.asGroupFeedback?.id == group.id }?.let { FeedbackItem.fromDb(it) } + val overrides = groupLevel?.let { gl -> getOverrides(group, gl.base) } ?: group.students.map { it.student to null } + + CritData.fromDb(crit) to FeedbackData(groupLevel, overrides) + } + } + + private fun Transaction.getOverrides(group: Group, fd: BaseFeedback): List> { +// val feedbacks = fd.forStudentsOverrideIfGroup.filter { it.group.id == group.id }.associateBy { it.student.id } +// +// return group.students.map { +// it.student to feedbacks[it.student.id]?.let { sof -> FeedbackItem.fromDb(sof.feedback) } +// } + return listOf() // TODO!!! + } + + fun focusGroup(idx: Int) { + _focus.value = idx + val group = groupList.entities.value[idx].group + globalGrade.focus(group) + gradeList.focus(group) + } + + fun focusPrev() { + if (focus.value > 0) { + focusGroup(focus.value - 1) + } + } + + fun focusNext() { + if (focus.value < groupList.entities.value.size - 1) { + focusGroup(focus.value + 1) + } + } + + context(trns: Transaction) + private fun BaseFeedback.set(grade: Grade, feedback: String) { + this.feedback = feedback + when(grade) { + is Grade.Categoric -> this.gradeCategoric = grade.value + is Grade.FreeText -> this.gradeFreeText = grade.text + is Grade.Numeric -> this.gradeNumeric = grade.value + is Grade.Percentage -> this.gradeNumeric = grade.percentage + } + } + + fun modGroupFeedback(crit: Criterion, group: Group, grade: Grade, feedback: String) { + transaction { + val existing = group.feedbacks.find { f -> f.criterion.id == crit.id } + if(existing != null) { + existing.set(grade, feedback) + } + else { + val fdb = BaseFeedback.new { + criterion = crit + set(grade, feedback) + } + GroupFeedbacks.insert { + it[GroupFeedbacks.feedbackId] = fdb.id + it[GroupFeedbacks.groupId] = group.id + } + } + } + globalGrade.refresh() + gradeList.refresh() + } + + fun modOverrideFeedback(crit: Criterion, group: Group, student: Student, groupLevel: FeedbackItem, grade: Grade, feedback: String) { + transaction { + val existing = groupLevel.base.forStudentsOverrideIfGroup.find { it.student.id == student.id } + if(existing != null) { + existing.feedback.set(grade, feedback) + } + else { + val fdb = BaseFeedback.new { + criterion = crit + set(grade, feedback) + } + StudentOverrideFeedback.new { + this.group = group + this.student = student + this.feedback = fdb + this.overrides = groupLevel.base + } + } + } + globalGrade.refresh() + gradeList.refresh() + } + + fun rmOverrideFeedback(crit: Criterion, group: Group, student: Student) { + transaction { + crit.feedbacks.find { + it.asGroupFeedback!!.id == group.id // find relevant group-level feedback + }?.forStudentsOverrideIfGroup?.find { + it.student.id == student.id // find override for the student + }?.delete() + } + globalGrade.refresh() + gradeList.refresh() + } +} diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/HomeVM.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/HomeVM.kt new file mode 100644 index 0000000..f2224d8 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/HomeVM.kt @@ -0,0 +1,70 @@ +package com.jaytux.grader.viewmodel + +import androidx.lifecycle.ViewModel +import com.jaytux.grader.data.v2.BaseAssignment +import com.jaytux.grader.data.v2.Course +import com.jaytux.grader.data.v2.Edition +import com.jaytux.grader.data.v2.Group +import com.jaytux.grader.data.v2.Student +import org.jetbrains.exposed.v1.dao.with +import org.jetbrains.exposed.v1.jdbc.transactions.transaction + +class HomeVM : ViewModel() { + data class EditionData(val edition: Edition, val students: List, val groups: List, val assignments: List) + data class CourseData(val course: Course, val editions: List, val archived: List) + + val courses = RawDbState { + Course.all().with(Course::editions, Edition::students, Edition::groups, Edition::assignments).map { + val mkEditionData = { e: Edition -> + EditionData(e, e.students.toList(), e.groups.toList(), e.assignments.toList()) + } + + CourseData(it, it.editions.filter { e -> !e.archived }.map(mkEditionData), it.editions.filter { e -> e.archived }.map(mkEditionData)) + } + } + + fun mkCourse(name: String) { + transaction { + Course.new { this.name = name } + } + courses.refresh() + } + + fun rmCourse(course: Course) { + transaction { + course.delete() + } + courses.refresh() + } + + fun mkEdition(course: Course, name: String) { + transaction { + Edition.new { + this.course = course + this.name = name + } + } + courses.refresh() + } + + fun rmEdition(edition: Edition) { + transaction { + edition.delete() + } + courses.refresh() + } + + fun archiveEdition(edition: Edition) { + transaction { + edition.archived = true + } + courses.refresh() + } + + fun unarchiveEdition(edition: Edition) { + transaction { + edition.archived = false + } + courses.refresh() + } +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/Navigator.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/Navigator.kt new file mode 100644 index 0000000..d535d15 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/Navigator.kt @@ -0,0 +1,152 @@ +package com.jaytux.grader.viewmodel + +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.Modifier +import androidx.compose.ui.backhandler.BackHandler +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewmodel.compose.viewModel +import com.jaytux.grader.ui.ChevronLeft +import kotlin.reflect.KClass + +class Navigator private constructor( + private var _start: IDestination, + private val _typeMap: Map, RenderData> +) : ViewModel() { + interface IDestination + + private data class Entry(val dest: T, val token: NavToken) + inner class NavToken { + fun navTo(target: IDestination) { this@Navigator.navTo(target) } + fun back() { this@Navigator.back() } + inline fun backTo() { this@Navigator.backTo() } + fun rewriteHistory(t: IDestination) { this@Navigator.rewriteHistory(t) } + } + internal data class RenderData( + val header: @Composable (IDestination) -> Unit, + val renderer: @Composable (IDestination, NavToken) -> Unit + ) + + private val _stack = mutableStateOf(listOf>(Entry(_start, NavToken()))) + + fun navTo(target: IDestination) { + _stack.value += Entry(target, NavToken()) + } + + fun back() { + if(_stack.value.size > 1) _stack.value = _stack.value.dropLast(1) + } + + fun backTo(cls: KClass) { + val idx = _stack.value.indexOfLast { entry -> cls.isInstance(entry.dest) } + if(idx != -1 && idx != _stack.value.lastIndex) { + _stack.value = _stack.value.take(idx + 1) + } + } + + fun rewriteHistory(t: IDestination) { + _stack.value = listOf(Entry(t, NavToken())) + _start = t + } + + inline fun backTo() = backTo(T::class) + + @OptIn(ExperimentalMaterial3Api::class, ExperimentalComposeUiApi::class) + @Composable + fun DisplayScaffold() { + val state = remember { SnackbarHostState() } + val stack by _stack + val (top, render) = remember(stack) { + val top = stack.last() + val render = _typeMap[top.dest::class] + ?: throw IllegalStateException("No renderer for destination of type ${top.dest::class.simpleName}") + top to render + } + val snackVM = viewModel() + snackVM.Launcher(state) + + BackHandler { back() } + Scaffold( + topBar = { + TopAppBar( + colors = TopAppBarDefaults.topAppBarColors(containerColor = MaterialTheme.colorScheme.primaryContainer), + title = { render.header(top.dest) }, + navigationIcon = { + IconButton({ back() }, enabled = top != _start) { + Icon(ChevronLeft, contentDescription = "Back") + } + } + ) + }, + snackbarHost = { + SnackbarHost(state) + } + ) { insets -> + Surface(Modifier.padding(insets), color = MaterialTheme.colorScheme.surface) { + render.renderer(top.dest, top.token) + } + } + } + + @DslMarker + annotation class NavigatorDslMarker + + @NavigatorDslMarker + class Builder internal constructor( + private val _onBuild: (IDestination, Map, RenderData>) -> Navigator + ) { + private val _typeMap = mutableMapOf, RenderData>() + private lateinit var _start: IDestination + + fun composable(cls: KClass, title: @Composable (T) -> Unit, renderer: @Composable (T, NavToken) -> Unit) { + _typeMap[cls]?.let { + throw IllegalArgumentException("Destination of type ${cls.simpleName} is already registered.") + } ?: run { + _typeMap[cls] = RenderData({ + @Suppress("UNCHECKED_CAST") + title(it as T) + }) { d, t -> + @Suppress("UNCHECKED_CAST") + renderer(d as T, t) + } + } + } + + inline fun composable(noinline title: @Composable (T) -> Unit, noinline renderer: @Composable (T, NavToken) -> Unit) { + composable(T::class, title, renderer) + } + + fun start(start: IDestination) { + if(this::_start.isInitialized) throw IllegalStateException("Start destination is already set.") + _start = start + } + + internal fun build(): Navigator { + if(!this::_start.isInitialized) throw IllegalStateException("Start destination is not set.") + return _onBuild(_start, _typeMap) + } + } + + companion object { + fun build(block: Builder.() -> Unit): Navigator = + Builder { start, map -> Navigator(start, map) } + .apply { block() }.build() + + @Composable + fun NavHost(initial: IDestination, block: Builder.() -> Unit) { + val vm = viewModel { + build { + block() + start(initial) + } + } + + vm.DisplayScaffold() + } + } +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/PeerEvalsGradingVM.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/PeerEvalsGradingVM.kt new file mode 100644 index 0000000..07d5d99 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/PeerEvalsGradingVM.kt @@ -0,0 +1,9 @@ +package com.jaytux.grader.viewmodel + +import androidx.lifecycle.ViewModel +import com.jaytux.grader.data.v2.BaseAssignment +import com.jaytux.grader.data.v2.Course +import com.jaytux.grader.data.v2.Edition + +class PeerEvalsGradingVM(val course: Course, val edition: Edition, val base: BaseAssignment) : ViewModel() { +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/SnackVM.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/SnackVM.kt new file mode 100644 index 0000000..8e2cf86 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/SnackVM.kt @@ -0,0 +1,28 @@ +package com.jaytux.grader.viewmodel + +import androidx.compose.material3.SnackbarHostState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.launch + +class SnackVM : ViewModel() { + private val _snacks = Channel() + val snacks = _snacks.receiveAsFlow() + + fun show(msg: String): Unit { + viewModelScope.launch { + _snacks.send(msg) + } + } + + @Composable + fun Launcher(state: SnackbarHostState) { + LaunchedEffect(Unit) { + snacks.collect { snack -> state.showSnackbar(snack) } + } + } +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/SolosGradingVM.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/SolosGradingVM.kt new file mode 100644 index 0000000..c7b9b2d --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/SolosGradingVM.kt @@ -0,0 +1,9 @@ +package com.jaytux.grader.viewmodel + +import androidx.lifecycle.ViewModel +import com.jaytux.grader.data.v2.BaseAssignment +import com.jaytux.grader.data.v2.Course +import com.jaytux.grader.data.v2.Edition + +class SolosGradingVM(val course: Course, val edition: Edition, val base: BaseAssignment) : ViewModel() { +} \ No newline at end of file diff --git a/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/UiGradeType.kt b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/UiGradeType.kt new file mode 100644 index 0000000..3e5a013 --- /dev/null +++ b/composeApp/src/desktopMain/kotlin/com/jaytux/grader/viewmodel/UiGradeType.kt @@ -0,0 +1,20 @@ +package com.jaytux.grader.viewmodel + +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.jaytux.grader.data.v2.BaseFeedback +import com.jaytux.grader.data.v2.CategoricGrade +import com.jaytux.grader.data.v2.CategoricGradeOption +import com.jaytux.grader.data.v2.Criterion +import com.jaytux.grader.data.v2.GradeType +import com.jaytux.grader.data.v2.NumericGrade +import com.jaytux.grader.maxN +import org.jetbrains.exposed.v1.core.Transaction + +sealed class UiGradeType { + object FreeText : UiGradeType() + object Percentage : UiGradeType() + data class Numeric(val grade: NumericGrade) : UiGradeType() + data class Categoric(val options: List, val grade: CategoricGrade) : UiGradeType() +} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 914e2fc..c0a9bf2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,33 +1,38 @@ [versions] -androidx-lifecycle = "2.8.4" -compose-multiplatform = "1.8.1" +androidx-lifecycle = "2.9.6" +compose-multiplatform = "1.9.0" junit = "4.13.2" -kotlin = "2.1.0" +kotlin = "2.3.0" kotlinx-coroutines = "1.10.1" -exposed = "0.59.0" -material3 = "1.7.3" +exposed = "1.1.1" +material3 = "1.9.0" ui-android = "1.7.8" foundation-layout-android = "1.7.8" rtf = "1.0.0-rc11" filekit = "0.10.0-beta04" +directories = "26" +androidx-activity-compose = "1.12.2" [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-viewmodel-compose = { group = "org.jetbrains.androidx.lifecycle", name = "lifecycle-viewmodel-compose", version.ref = "androidx-lifecycle" } +androidx-activity-compose = { module = "androidx.activity:activity-compose", version.ref = "androidx-activity-compose" } +compose-backhandler = { module = "org.jetbrains.compose.ui:ui-backhandler", version.ref = "compose-multiplatform" } 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-migration = { group = "org.jetbrains.exposed", name = "exposed-migration", version.ref = "exposed" } +exposed-migration = { group = "org.jetbrains.exposed", name = "exposed-migration-core", version.ref = "exposed" } +exposed-migration-jdbc = { group = "org.jetbrains.exposed", name = "exposed-migration-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" } -material-icons = { group = "org.jetbrains.compose.material", name = "material-icons-extended", version.ref = "material3" } androidx-ui-android = { group = "androidx.compose.ui", name = "ui-android", version.ref = "ui-android" } androidx-foundation-layout-android = { group = "androidx.compose.foundation", name = "foundation-layout-android", version.ref = "foundation-layout-android" } rtfield = { group = "com.mohamedrejeb.richeditor", name = "richeditor-compose", version.ref = "rtf" } @@ -35,6 +40,7 @@ filekit-core = { group = "io.github.vinceglb", name = "filekit-core", version.re filekit-dialogs = { group = "io.github.vinceglb", name = "filekit-dialogs", version.ref = "filekit" } filekit-dialogs-compose = { group = "io.github.vinceglb", name = "filekit-dialogs-compose", version.ref = "filekit" } filekit-coil = { group = "io.github.vinceglb", name = "filekit-coil", version.ref = "filekit" } +directories = { group = "dev.dirs", name = "directories", version.ref = "directories" } [plugins] composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "compose-multiplatform" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 2c3521197d7c4586c843d1d3e9090525f1898cde..61285a659d17295f1de7c53e24fdf13ad755c379 100644 GIT binary patch delta 38044 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 delta 35286 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 09523c0..48b43d3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.0.0-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index f5feea6..adff685 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 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. @@ -86,8 +86,7 @@ done # 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 +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -115,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -173,7 +171,6 @@ fi # 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" ) @@ -206,15 +203,14 @@ fi 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, +# * DEFAULT_JVM_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 \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 9b42019..e509b2d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -70,11 +70,10 @@ 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 %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell