diff --git a/src/jsMain/kotlin/PekDelay.kt b/src/jsMain/kotlin/PekDelay.kt
new file mode 100644
index 0000000000000000000000000000000000000000..f0525dad9ec2e653fb61eb2a027cc038b4d5f202
--- /dev/null
+++ b/src/jsMain/kotlin/PekDelay.kt
@@ -0,0 +1,49 @@
+import kotlinx.atomicfu.AtomicInt
+import kotlinx.browser.document
+import kotlinx.coroutines.delay
+import org.w3c.dom.HTMLDivElement
+import org.w3c.dom.MutationObserver
+import org.w3c.dom.MutationObserverInit
+import kotlin.coroutines.Continuation
+import kotlin.coroutines.resume
+import kotlin.coroutines.suspendCoroutine
+
+object PekDelay {
+    private val saveIconElem = document.getElementById("save-icon") as HTMLDivElement
+    private val isUpdating get() = saveIconElem.style.display == "block"
+
+    private val continuations = mutableListOf<Continuation<Unit>>()
+    private var skips = 0
+
+    fun skipNext() {
+        skips++
+    }
+
+    private val observer = MutationObserver { _, _ ->
+        if (!isUpdating) {
+            println("run called")
+            val conts = continuations.toList()
+            conts.forEach { it.resume(Unit) }
+            continuations.removeAll(conts)
+        }
+    }
+
+    init {
+        observer.observe(
+            saveIconElem, MutationObserverInit(
+                attributes = true,
+                attributeFilter = arrayOf("style")
+            )
+        )
+    }
+
+    suspend operator fun invoke() = suspendCoroutine<Unit> { cont ->
+        if (skips > 0) {
+            cont.resume(Unit)
+            skips--
+            return@suspendCoroutine
+        }
+        continuations += cont
+    }
+
+}
\ No newline at end of file
diff --git a/src/jsMain/kotlin/PekTable.kt b/src/jsMain/kotlin/PekTable.kt
index 5de79ea82b1eefdf59d8645e2a71e28ad8559eaf..d656b0cd143ea37feb80f429521da9b3d0c1bc4a 100644
--- a/src/jsMain/kotlin/PekTable.kt
+++ b/src/jsMain/kotlin/PekTable.kt
@@ -57,7 +57,11 @@ object PekTable {
             elem.style.background = origBg
         }
 
-        if (elem.value.toIntOrNull() == value) return
+        if (elem.value.toIntOrNull() == value) { // don't update if up-to-date
+            // sort of ugly workaround, meh.
+            PekDelay.skipNext()
+            return
+        }
 
         elem.click()
         elem.value = value.toString()
diff --git a/src/jsMain/kotlin/Process.kt b/src/jsMain/kotlin/Process.kt
index 46ad42610c883ce1d13dff41c5ecfa23a8c04f42..df0c4ece41ec0fea664a7e8623440b292523855d 100644
--- a/src/jsMain/kotlin/Process.kt
+++ b/src/jsMain/kotlin/Process.kt
@@ -1,9 +1,9 @@
 import kotlin.math.max
 
-class ProcessingError(val errors: List<String>): Exception(errors.toString()) {
+class ProcessingError(private val errors: List<String>): Exception(errors.toString()) {
     override fun toString(): String {
-        return "Hiba történt az importálás közben:\n"+
-            errors.joinToString("\n")
+        return "${errors.size} hiba történt az importálás közben:\n\n"+
+            errors.joinToString("\n\n")
     }
 }
 
@@ -29,7 +29,7 @@ suspend fun CSVTable.process(
             val pekPrinciple = principleMappings[principle]!!
 
             PekTable[pekPerson, pekPrinciple] = point
-            pekDelay()
+            PekDelay()
             progress(calcProgress(i, j, people.size, principles.size))
 
             if (person != pekPerson) {
diff --git a/src/jsMain/kotlin/Utils.kt b/src/jsMain/kotlin/Utils.kt
index 50b67b3b199c41a6e7957acb88cdb86832dc9b47..ed2f64c767f36a0a66c0ac84c26cf00ae91d4aa7 100644
--- a/src/jsMain/kotlin/Utils.kt
+++ b/src/jsMain/kotlin/Utils.kt
@@ -1,6 +1,4 @@
 import kotlinx.browser.document
-import kotlinx.browser.window
-import kotlinx.coroutines.delay
 import org.w3c.dom.*
 import org.w3c.files.Blob
 import org.w3c.files.FileReader
@@ -86,41 +84,13 @@ suspend fun PekTable.clear(
     people.forEachIndexed { i, person ->
         principles.forEachIndexed { j, principle ->
             PekTable[person, principle] = 0
-            pekDelay()
+            PekDelay()
 
             progress(calcProgress(i, j, people.size, principles.size))
         }
     }
 }
 
-private val saveIconElem = document.getElementById("save-icon") as HTMLDivElement
-val isUpdating get() = saveIconElem.style.display == "block"
-
-fun observeSaveChange(changed: () -> Unit): MutationObserver {
-    val observer = MutationObserver { _, _ ->
-        changed()
-    }
-    observer.observe(saveIconElem, MutationObserverInit(
-        attributes = true,
-        attributeFilter = arrayOf("style")
-    ))
-    return observer
-}
-
-suspend fun pekDelay() = suspendCoroutine<Unit> { cont ->
-    lateinit var observer: MutationObserver
-    observer = observeSaveChange {
-        if (!isUpdating) {
-            cont.resume(Unit)
-            observer.disconnect()
-        }
-    }
-    if (!isUpdating) {
-        cont.resume(Unit)
-        observer.disconnect()
-    }
-}
-
 fun Double.format() = this.asDynamic().toFixed(1) as String
 
 fun calcProgress(i: Int, j: Int, iMax: Int, jMax: Int) =