Move SSD page index clamping to typed Kotlin

ober

861a54624f4f57604c772654cd5f8ad77b9482bd

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index 78d69d7..df336fa 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -3586,7 +3586,8 @@
                 sourceBaseName canonicalSourceName isUsefulGuessLabel isErrorStatus
                 formatActivityDuration groupDisplayLabel appendModeStatus
                 selectedGroupStatus sessionCountsStatus rotatedPageStatus
-                manualGroupLabel manualCellCount editedGroupCount)
+                manualGroupLabel manualCellCount editedGroupCount
+                clampPageIndex shiftPageIndex)
         (type Int32)
         (def (normalizeFiringArc (value : String)) : String
           (string-uppercase (string-trim value)))
@@ -3716,6 +3717,21 @@
               (if (< value (int32 0))
                 (int32 0)
                 value))))
+        (def (lastPageIndex (pageCount : Int32)) : Int32
+          (if (<= pageCount (int32 1))
+            (int32 0)
+            (- pageCount (int32 1))))
+        (def (clampPageIndex (index : Int32) (pageCount : Int32)) : Int32
+          (if (< index (int32 0))
+            (int32 0)
+            (let ((last (lastPageIndex pageCount)))
+              (if (> index last)
+                last
+                index))))
+        (def (shiftPageIndex (index : Int32)
+                             (pageCount : Int32)
+                             (delta : Int32)) : Int32
+          (clampPageIndex (+ index delta) pageCount))
         (def (appendModeStatus (group : SsdGroup)) : String
           (string-append
             "Append mode: drag boxes to add to "
@@ -4910,7 +4926,7 @@
        ""
        "    private fun changePage(delta: Int) {"
        "        if (pdfUri == null || pageCount <= 0) return"
-       "        pageIndex = (pageIndex + delta).coerceIn(0, pageCount - 1)"
+       "        pageIndex = shiftPageIndex(pageIndex, pageCount, delta)"
        "        persistCurrentPdfState(includeViewport = false)"
        "        renderCurrentPage()"
        "    }"
@@ -5898,7 +5914,7 @@
        "                runOnUiThread {"
        "                    pdfSha1 = hash"
        "                    pageCount = count"
-       "                    pageIndex = initialPageIndex.coerceIn(0, maxOf(0, count - 1))"
+       "                    pageIndex = clampPageIndex(initialPageIndex, count)"
        "                    if (!restoring) persistCurrentPdfState(includeViewport = false)"
        "                    setStatus(\"Loaded $pdfName ($pageCount pages)\")"
        "                    renderCurrentPage()"