From dbdbb32835da410db2d69a5b08243b1988305fb6 Mon Sep 17 00:00:00 2001
From: FCGudder <-@->
Date: Wed, 22 Feb 2017 16:39:30 +0100
Subject: [PATCH] Categorizer utility class

---
 src/js/utilJS.tw | 67 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 src/js/utilJS.tw

diff --git a/src/js/utilJS.tw b/src/js/utilJS.tw
new file mode 100644
index 00000000000..bf939d49397
--- /dev/null
+++ b/src/js/utilJS.tw
@@ -0,0 +1,67 @@
+:: UtilJS [script]
+
+if(!Array.prototype.findIndex) {
+	Array.prototype.findIndex = function(predicate) {
+		if (this == null) {
+			throw new TypeError('Array.prototype.find called on null or undefined');
+		}
+		if (typeof predicate !== 'function') {
+			throw new TypeError('predicate must be a function');
+		}
+		var list = Object(this);
+		var length = list.length >>> 0;
+		var thisArg = arguments[1];
+		var value;
+
+		for (var i = 0; i < length; i++) {
+			value = list[i];
+			if (predicate.call(thisArg, value, i, list)) {
+				return i;
+			}
+		}
+		return -1;
+	};
+};
+
+/*
+A categorizer is used to "slice" a value range into distinct categories in an efficient manner.
+
+--- Example ---
+Original SugarCube code
+<<if _Slave.muscles > 95>>
+	Musc++
+<<elseif _Slave.muscles > 30>>
+	Musc+
+<<elseif _Slave.muscles > 5>>
+	Toned
+<<elseif _Slave.muscles > -6>>
+<<elseif _Slave.muscles > -31>>
+	@@color:red;weak@@
+<<elseif _Slave.muscles > -96>>
+	@@color:red;weak+@@
+<<else>>
+	@@color:red;weak++@@
+<</if>>
+
+As a categorizer
+<<if ndef $cats>><<set $cats = {}>><</if>>
+<<if ndef $cats.muscleCat>>
+	<!-- This only gets set once, skipping much of the code evaluation, and can be set outside of the code in an "init" passage for further optimization -->
+	<<set $cats.muscleCat = new Categorizer([96, 'Musc++'], [31, 'Musc+'], [6, 'Toned'], [-5, ''], [-30, '@@color:red;weak@@'], [-95, '@@color:red;weak+@@'], [-Infinity, '@@color:red;weak++@@'])>>
+<</if>>
+<<print $cats.muscleCat.cat(_Slave.muscles)>>
+*/
+window.Categorizer = function() {
+	this.cats = Array.prototype.slice.call(arguments)
+		.filter(function(e, i, a) {
+			return e instanceof Array && e.length == 2 && typeof e[0] === 'number' && !isNaN(e[0])
+				&& a.findIndex(function(val) { return e[0] === val[0]; }) === i; /* uniqueness test */ })
+		.sort(function(a, b) { return b[0] - a[0]; /* reverse sort */ });
+};
+window.Categorizer.prototype.cat = function(val, def) {
+	if(typeof val !== 'number' || isNaN(val)) {
+		return def;
+	}
+	var result = this.cats.find(function(e) { return val >= e[0]; });
+	return result ? result[1] : def;
+};
-- 
GitLab