Move SSD PDF name helper to typed Kotlin

ober

2ce158319dc087283f65fc319ef16eff8313a8f6

diff --git a/templates/ssd-review.ss b/templates/ssd-review.ss
index c347b74..303a7e1 100644
--- a/templates/ssd-review.ss
+++ b/templates/ssd-review.ss
@@ -439,7 +439,7 @@
 
     (typed-kotlin-file "com/sfb/ssdreview/UiTextHelpers.kt"
       (typed-library (com sfb ssdreview)
-        (export normalizeFiringArc normalizeLabel isGenericGuessLabel)
+        (export normalizeFiringArc normalizeLabel isGenericGuessLabel isSsdPdfName)
         (def (normalizeFiringArc (value : String)) : String
           (string-uppercase (string-trim value)))
         (def (normalizeLabel (value : String)) : String
@@ -454,7 +454,11 @@
             (or (string-matches-regex? normalized "^\\d+\\s+boxes$")
                 (or (or (equal? normalized "boxes")
                         (equal? normalized "unknown"))
-                    (equal? normalized "unclassified")))))))
+                    (equal? normalized "unclassified")))))
+        (def (isSsdPdfName (name : String)) : Bool
+          (let ((lower (string-lowercase name)))
+            (and (string-ends-with? lower ".pdf")
+                 (string-contains? lower "ssd"))))))
 
     (kotlin-file-lines "com/sfb/ssdreview/BoxTypes.kt"
       (
@@ -2067,9 +2071,6 @@
        "            }"
        "    }"
        ""
-       "    private fun isSsdPdfName(name: String): Boolean ="
-       "        name.endsWith(\".pdf\", ignoreCase = true) && name.contains(\"ssd\", ignoreCase = true)"
-       ""
        "    private fun uniquePdfChoices(choices: List<SsdPdfChoice>): List<SsdPdfChoice> {"
        "        val unique = linkedMapOf<String, SsdPdfChoice>()"
        "        choices.forEach { choice ->"