Move SSD page dialog parsing to typed Kotlin

ober

723622aabb976ff79810f1f16bb10e310c6a4bda

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 1958159..70b3712 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -3800,7 +3800,8 @@
                 dialogCountValue editedGroupCountText
                 selectionIgnoredLoadingStatus
                 clampPageIndex shiftPageIndex displayGroupCanvasLabel
-                dropdownHeight dialogPageNumber nullableLowercaseOrEmpty
+                dropdownHeight dialogPageNumber dialogPageNumberText
+                pageNumberText sessionIdFromUuid nullableLowercaseOrEmpty
                 selectModeStatus selectionResultStatus detectStartStatus
                 detectorSourceWithTruth detectionTruthNote detectionOcrNote
                 detectionLearnedNote
@@ -4329,6 +4330,13 @@
                   (if (> value last)
                     last
                     value))))))
+        (def (dialogPageNumberText (text : String)
+                                   (pageCount : Int32)) : (Nullable Int32)
+          (dialogPageNumber (string->int32-or-null text) pageCount))
+        (def (pageNumberText (pageIndex : Int32)) : String
+          (int32->string (+ pageIndex (int32 1))))
+        (def (sessionIdFromUuid (uuid : String)) : String
+          (string-take (string-replace-regex uuid "-" "") (int32 16)))
         (def (appendModeStatus (group : SsdGroup)) : String
           (string-append
             "Append mode: drag boxes to add to "
@@ -5606,7 +5614,7 @@
        "        if (pdfUri == null || pageCount <= 0) return"
        "        val input = EditText(this).apply {"
        "            inputType = InputType.TYPE_CLASS_NUMBER"
-       "            setText((pageIndex + 1).toString())"
+       "            setText(pageNumberText(pageIndex))"
        "            selectAll()"
        "        }"
        "        AlertDialog.Builder(this)"
@@ -5614,7 +5622,7 @@
        "            .setView(input)"
        "            .setNegativeButton(\"Cancel\", null)"
        "            .setPositiveButton(\"Load\") { _, _ ->"
-       "                val page = dialogPageNumber(input.text.toString().toIntOrNull(), pageCount) ?: return@setPositiveButton"
+       "                val page = dialogPageNumberText(input.text.toString(), pageCount) ?: return@setPositiveButton"
        "                pageIndex = page - 1"
        "                renderCurrentPage()"
        "            }"
@@ -5752,7 +5760,7 @@
        "                if (!isCurrentLoad(expectedGeneration, uri, expectedPageIndex)) return@thread"
        "                val key = sourceKey(expectedPdfSha1, expectedPageIndex + 1, DPI)"
        "                val session = SsdSession("
-       "                    sessionId = UUID.randomUUID().toString().replace(\"-\", \"\").take(16),"
+       "                    sessionId = sessionIdFromUuid(UUID.randomUUID().toString()),"
        "                    sourceKey = key,"
        "                    sourceName = expectedPdfName,"
        "                    sourceUri = uri.toString(),"