{"ScriptPreparationCode":"// Natural sort\r\nfunction isNumeric(value) {\r\n return !isNaN(value - parseFloat(value))\r\n}\r\n\r\nconst MAX_INT = Math.pow(2, 53)\r\nconst SAFE_STRING_INT_LENGTH = MAX_INT.toString().length - 1\r\n\r\n\r\nfunction naturalSort(strA, strB) {\r\n const digitSplit = /(\\d\u002B)|(\\D\u002B)/g;\r\n\r\n // Ignore case.\r\n strA = strA.toLowerCase()\r\n strB = strB.toLowerCase()\r\n\r\n // Check if they\u0027re the same.\r\n if (strA === strB) {\r\n return 0;\r\n }\r\n\r\n // Split digit and non-digit sections.\r\n const splitA = strA.match(digitSplit)\r\n const splitB = strB.match(digitSplit)\r\n\r\n // Check every section.\r\n let i = 0\r\n while (true) {\r\n // Get the current section of each item.\r\n let splitASection = splitA[i]\r\n let splitBSection = splitB[i]\r\n\r\n // Check if we\u0027ve reached the end of either string.\r\n let splitASecEmpty = splitASection === undefined\r\n let splitBSecEmpty = splitBSection === undefined\r\n\r\n if (splitASecEmpty \u0026\u0026 splitBSecEmpty) {\r\n return 0\r\n } else if (splitASecEmpty) {\r\n return -1\r\n } else if (splitBSecEmpty) {\r\n return 1\r\n }\r\n\r\n // If either section is too long to be represented as a safe integer\r\n // then split it and put the rest back into the array.\r\n if (splitASection.length \u003E SAFE_STRING_INT_LENGTH) {\r\n let nextSplitA = splitASection.slice(SAFE_STRING_INT_LENGTH)\r\n splitASection = splitASection.slice(0, SAFE_STRING_INT_LENGTH)\r\n //splitA.splice(i, 1, splitASection)\r\n splitA.splice(i \u002B 1, 0, nextSplitA)\r\n }\r\n if (splitBSection.length \u003E SAFE_STRING_INT_LENGTH) {\r\n let nextSplitB = splitBSection.slice(SAFE_STRING_INT_LENGTH)\r\n splitBSection = splitBSection.slice(0, SAFE_STRING_INT_LENGTH)\r\n splitB.splice(i \u002B 1, 0, nextSplitB)\r\n }\r\n\r\n // Check if either section is a number.\r\n let splitASecNumeric = isNumeric(splitASection)\r\n let splitBSecNumeric = isNumeric(splitBSection)\r\n\r\n if (splitASecNumeric \u0026\u0026 splitBSecNumeric) {\r\n splitASection = parseInt(splitASection)\r\n splitBSection = parseInt(splitBSection)\r\n } else if (splitASecNumeric) {\r\n return -1\r\n } else if (splitBSecNumeric) {\r\n return 1\r\n }\r\n\r\n // Compare values directly.\r\n if (splitASection \u003C splitBSection) {\r\n return -1\r\n } else if (splitASection \u003E splitBSection) {\r\n return 1\r\n }\r\n\r\n i\u002B\u002B\r\n }\r\n}\r\n\r\n// Natural Compare\r\nvar naturalCompare = function(a, b) {\r\n var i, codeA, codeB = 1,\r\n posA = 0,\r\n posB = 0,\r\n alphabet = String.alphabet\r\n\r\n function getCode(str, pos, code) {\r\n if (code) {\r\n for (i = pos; code = getCode(str, i), code \u003C 76 \u0026\u0026 code \u003E 65;) \u002B\u002Bi;\r\n return \u002Bstr.slice(pos - 1, i)\r\n }\r\n code = alphabet \u0026\u0026 alphabet.indexOf(str.charAt(pos))\r\n return code \u003E -1 ? code \u002B 76 : ((code = str.charCodeAt(pos) || 0), code \u003C 45 || code \u003E 127) ? code :\r\n code \u003C 46 ? 65 // -\r\n :\r\n code \u003C 48 ? code - 1 :\r\n code \u003C 58 ? code \u002B 18 // 0-9\r\n :\r\n code \u003C 65 ? code - 11 :\r\n code \u003C 91 ? code \u002B 11 // A-Z\r\n :\r\n code \u003C 97 ? code - 37 :\r\n code \u003C 123 ? code \u002B 5 // a-z\r\n :\r\n code - 63\r\n }\r\n\r\n\r\n if ((a \u002B= \u0022\u0022) != (b \u002B= \u0022\u0022))\r\n for (; codeB;) {\r\n codeA = getCode(a, posA\u002B\u002B)\r\n codeB = getCode(b, posB\u002B\u002B)\r\n\r\n if (codeA \u003C 76 \u0026\u0026 codeB \u003C 76 \u0026\u0026 codeA \u003E 66 \u0026\u0026 codeB \u003E 66) {\r\n codeA = getCode(a, posA, posA)\r\n codeB = getCode(b, posB, posA = i)\r\n posB = i\r\n }\r\n\r\n if (codeA != codeB) return (codeA \u003C codeB) ? -1 : 1\r\n }\r\n return 0\r\n}\r\n\r\n\r\n// JavaScript Natural Sort\r\nfunction javascriptNaturalSort(a, b) {\r\n \u0022use strict\u0022;\r\n var re = /(^([\u002B\\-]?(?:0|[1-9]\\d*)(?:\\.\\d*)?(?:[eE][\u002B\\-]?\\d\u002B)?)?$|^0x[0-9a-f]\u002B$|\\d\u002B)/gi,\r\n sre = /(^[ ]*|[ ]*$)/g,\r\n dre = /(^([\\w ]\u002B,?[\\w ]\u002B)?[\\w ]\u002B,?[\\w ]\u002B\\d\u002B:\\d\u002B(:\\d\u002B)?[\\w ]?|^\\d{1,4}[\\/\\-]\\d{1,4}[\\/\\-]\\d{1,4}|^\\w\u002B, \\w\u002B \\d\u002B, \\d{4})/,\r\n hre = /^0x[0-9a-f]\u002B$/i,\r\n ore = /^0/,\r\n i = function(s) {\r\n return naturalSort.insensitive \u0026\u0026 (\u0027\u0027 \u002B s).toLowerCase() || \u0027\u0027 \u002B s;\r\n },\r\n // convert all to strings strip whitespace\r\n x = i(a).replace(sre, \u0027\u0027) || \u0027\u0027,\r\n y = i(b).replace(sre, \u0027\u0027) || \u0027\u0027,\r\n // chunk/tokenize\r\n xN = x.replace(re, \u0027\\0$1\\0\u0027).replace(/\\0$/, \u0027\u0027).replace(/^\\0/, \u0027\u0027).split(\u0027\\0\u0027),\r\n yN = y.replace(re, \u0027\\0$1\\0\u0027).replace(/\\0$/, \u0027\u0027).replace(/^\\0/, \u0027\u0027).split(\u0027\\0\u0027),\r\n // numeric, hex or date detection\r\n xD = parseInt(x.match(hre), 16) || (xN.length !== 1 \u0026\u0026 x.match(dre) \u0026\u0026 Date.parse(x)),\r\n yD = parseInt(y.match(hre), 16) || xD \u0026\u0026 y.match(dre) \u0026\u0026 Date.parse(y) || null,\r\n oFxNcL, oFyNcL;\r\n // first try and sort Hex codes or Dates\r\n if (yD) {\r\n if (xD \u003C yD) {\r\n return -1;\r\n } else if (xD \u003E yD) {\r\n return 1;\r\n }\r\n }\r\n // natural sorting through split numeric strings and default strings\r\n for (var cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc \u003C numS; cLoc\u002B\u002B) {\r\n // find floats not starting with \u00270\u0027, string or 0 if not defined (Clint Priest)\r\n oFxNcL = !(xN[cLoc] || \u0027\u0027).match(ore) \u0026\u0026 parseFloat(xN[cLoc]) || xN[cLoc] || 0;\r\n oFyNcL = !(yN[cLoc] || \u0027\u0027).match(ore) \u0026\u0026 parseFloat(yN[cLoc]) || yN[cLoc] || 0;\r\n // handle numeric vs string comparison - number \u003C string - (Kyle Adams)\r\n if (isNaN(oFxNcL) !== isNaN(oFyNcL)) {\r\n return (isNaN(oFxNcL)) ? 1 : -1;\r\n }\r\n // rely on string comparison if different types - i.e. \u002702\u0027 \u003C 2 != \u002702\u0027 \u003C \u00272\u0027\r\n else if (typeof oFxNcL !== typeof oFyNcL) {\r\n oFxNcL \u002B= \u0027\u0027;\r\n oFyNcL \u002B= \u0027\u0027;\r\n }\r\n if (oFxNcL \u003C oFyNcL) {\r\n return -1;\r\n }\r\n if (oFxNcL \u003E oFyNcL) {\r\n return 1;\r\n }\r\n }\r\n return 0;\r\n};\r\n\r\n\r\n// String Natural Compare\r\nconst defaultAlphabetIndexMap = [];\r\n\r\nfunction isNumberCode(code) {\r\n return code \u003E= 48 /* \u00270\u0027 */ \u0026\u0026 code \u003C= 57 /* \u00279\u0027 */ ;\r\n}\r\n\r\nfunction stringNaturalCompare(a, b, opts) {\r\n if (typeof a !== \u0027string\u0027) {\r\n throw new TypeError(\u0060The first argument must be a string. Received type \u0027${typeof a}\u0027\u0060);\r\n }\r\n if (typeof b !== \u0027string\u0027) {\r\n throw new TypeError(\u0060The second argument must be a string. Received type \u0027${typeof b}\u0027\u0060);\r\n }\r\n\r\n const lengthA = a.length;\r\n const lengthB = b.length;\r\n let indexA = 0;\r\n let indexB = 0;\r\n let alphabetIndexMap = defaultAlphabetIndexMap;\r\n let firstDifferenceInLeadingZeros = 0;\r\n\r\n if (opts) {\r\n if (opts.caseInsensitive) {\r\n a = a.toLowerCase();\r\n b = b.toLowerCase();\r\n }\r\n\r\n if (opts.alphabet) {\r\n alphabetIndexMap = buildAlphabetIndexMap(opts.alphabet);\r\n }\r\n }\r\n\r\n while (indexA \u003C lengthA \u0026\u0026 indexB \u003C lengthB) {\r\n let charCodeA = a.charCodeAt(indexA);\r\n let charCodeB = b.charCodeAt(indexB);\r\n\r\n if (isNumberCode(charCodeA)) {\r\n if (!isNumberCode(charCodeB)) {\r\n return charCodeA - charCodeB;\r\n }\r\n\r\n let numStartA = indexA;\r\n let numStartB = indexB;\r\n\r\n while (charCodeA === 48 /* \u00270\u0027 */ \u0026\u0026 \u002B\u002BnumStartA \u003C lengthA) {\r\n charCodeA = a.charCodeAt(numStartA);\r\n }\r\n while (charCodeB === 48 /* \u00270\u0027 */ \u0026\u0026 \u002B\u002BnumStartB \u003C lengthB) {\r\n charCodeB = b.charCodeAt(numStartB);\r\n }\r\n\r\n if (numStartA !== numStartB \u0026\u0026 firstDifferenceInLeadingZeros === 0) {\r\n firstDifferenceInLeadingZeros = numStartA - numStartB;\r\n }\r\n\r\n let numEndA = numStartA;\r\n let numEndB = numStartB;\r\n\r\n while (numEndA \u003C lengthA \u0026\u0026 isNumberCode(a.charCodeAt(numEndA))) {\r\n \u002B\u002BnumEndA;\r\n }\r\n while (numEndB \u003C lengthB \u0026\u0026 isNumberCode(b.charCodeAt(numEndB))) {\r\n \u002B\u002BnumEndB;\r\n }\r\n\r\n let difference = numEndA - numStartA - numEndB \u002B numStartB; // numA length - numB length\r\n if (difference !== 0) {\r\n return difference;\r\n }\r\n\r\n while (numStartA \u003C numEndA) {\r\n difference = a.charCodeAt(numStartA\u002B\u002B) - b.charCodeAt(numStartB\u002B\u002B);\r\n if (difference !== 0) {\r\n return difference;\r\n }\r\n }\r\n\r\n indexA = numEndA;\r\n indexB = numEndB;\r\n continue;\r\n }\r\n\r\n if (charCodeA !== charCodeB) {\r\n if (\r\n charCodeA \u003C alphabetIndexMap.length \u0026\u0026\r\n charCodeB \u003C alphabetIndexMap.length \u0026\u0026\r\n alphabetIndexMap[charCodeA] !== -1 \u0026\u0026\r\n alphabetIndexMap[charCodeB] !== -1\r\n ) {\r\n return alphabetIndexMap[charCodeA] - alphabetIndexMap[charCodeB];\r\n }\r\n\r\n return charCodeA - charCodeB;\r\n }\r\n\r\n \u002B\u002BindexA;\r\n \u002B\u002BindexB;\r\n }\r\n\r\n if (indexA \u003C lengthA) { // \u0060b\u0060 is a substring of \u0060a\u0060\r\n return 1;\r\n }\r\n\r\n if (indexB \u003C lengthB) { // \u0060a\u0060 is a substring of \u0060b\u0060\r\n return -1;\r\n }\r\n\r\n return firstDifferenceInLeadingZeros;\r\n}\r\n\r\nconst alphabetIndexMapCache = {};\r\n\r\nfunction buildAlphabetIndexMap(alphabet) {\r\n const existingMap = alphabetIndexMapCache[alphabet];\r\n if (existingMap !== undefined) {\r\n return existingMap;\r\n }\r\n\r\n const indexMap = [];\r\n const maxCharCode = alphabet.split(\u0027\u0027).reduce((maxCode, char) =\u003E {\r\n return Math.max(maxCode, char.charCodeAt(0));\r\n }, 0);\r\n\r\n for (let i = 0; i \u003C= maxCharCode; i\u002B\u002B) {\r\n indexMap.push(-1);\r\n }\r\n\r\n for (let i = 0; i \u003C alphabet.length; i\u002B\u002B) {\r\n indexMap[alphabet.charCodeAt(i)] = i;\r\n }\r\n\r\n alphabetIndexMapCache[alphabet] = indexMap;\r\n\r\n return indexMap;\r\n}\r\n\r\nfunction stringNaturalCompareCI(a, b) {\r\n stringNaturalCompare(a, b, { caseInsensitive: true });\r\n}\r\n\r\n\r\n// Alphanum-sort\r\nvar zero = \u00270\u0027.charCodeAt(0);\r\nvar plus = \u0027\u002B\u0027.charCodeAt(0);\r\nvar minus = \u0027-\u0027.charCodeAt(0);\r\n\r\nfunction isWhitespace(code) {\r\n return code \u003C= 32;\r\n}\r\n\r\nfunction isDigit(code) {\r\n return 48 \u003C= code \u0026\u0026 code \u003C= 57;\r\n}\r\n\r\nfunction isSign(code) {\r\n return code === minus || code === plus;\r\n}\r\n\r\nfunction compare(opts, a, b) {\r\n var checkSign = opts.sign;\r\n var ia = 0;\r\n var ib = 0;\r\n var ma = a.length;\r\n var mb = b.length;\r\n var ca, cb; // character code\r\n var za, zb; // leading zero count\r\n var na, nb; // number length\r\n var sa, sb; // number sign\r\n var ta, tb; // temporary\r\n var bias;\r\n\r\n while (ia \u003C ma \u0026\u0026 ib \u003C mb) {\r\n ca = a.charCodeAt(ia);\r\n cb = b.charCodeAt(ib);\r\n za = zb = 0;\r\n na = nb = 0;\r\n sa = sb = true;\r\n bias = 0;\r\n\r\n // skip over leading spaces\r\n while (isWhitespace(ca)) {\r\n ia \u002B= 1;\r\n ca = a.charCodeAt(ia);\r\n }\r\n while (isWhitespace(cb)) {\r\n ib \u002B= 1;\r\n cb = b.charCodeAt(ib);\r\n }\r\n\r\n // skip and save sign\r\n if (checkSign) {\r\n ta = a.charCodeAt(ia \u002B 1);\r\n if (isSign(ca) \u0026\u0026 isDigit(ta)) {\r\n if (ca === minus) {\r\n sa = false;\r\n }\r\n ia \u002B= 1;\r\n ca = ta;\r\n }\r\n tb = b.charCodeAt(ib \u002B 1);\r\n if (isSign(cb) \u0026\u0026 isDigit(tb)) {\r\n if (cb === minus) {\r\n sb = false;\r\n }\r\n ib \u002B= 1;\r\n cb = tb;\r\n }\r\n }\r\n\r\n // compare digits with other symbols\r\n if (isDigit(ca) \u0026\u0026 !isDigit(cb)) {\r\n return -1;\r\n }\r\n if (!isDigit(ca) \u0026\u0026 isDigit(cb)) {\r\n return 1;\r\n }\r\n\r\n // compare negative and positive\r\n if (!sa \u0026\u0026 sb) {\r\n return -1;\r\n }\r\n if (sa \u0026\u0026 !sb) {\r\n return 1;\r\n }\r\n\r\n // count leading zeros\r\n while (ca === zero) {\r\n za \u002B= 1;\r\n ia \u002B= 1;\r\n ca = a.charCodeAt(ia);\r\n }\r\n while (cb === zero) {\r\n zb \u002B= 1;\r\n ib \u002B= 1;\r\n cb = b.charCodeAt(ib);\r\n }\r\n\r\n // count numbers\r\n while (isDigit(ca) || isDigit(cb)) {\r\n if (isDigit(ca) \u0026\u0026 isDigit(cb) \u0026\u0026 bias === 0) {\r\n if (sa) {\r\n if (ca \u003C cb) {\r\n bias = -1;\r\n } else if (ca \u003E cb) {\r\n bias = 1;\r\n }\r\n } else {\r\n if (ca \u003E cb) {\r\n bias = -1;\r\n } else if (ca \u003C cb) {\r\n bias = 1;\r\n }\r\n }\r\n }\r\n if (isDigit(ca)) {\r\n ia \u002B= 1;\r\n na \u002B= 1;\r\n ca = a.charCodeAt(ia);\r\n }\r\n if (isDigit(cb)) {\r\n ib \u002B= 1;\r\n nb \u002B= 1;\r\n cb = b.charCodeAt(ib);\r\n }\r\n }\r\n\r\n // compare number length\r\n if (sa) {\r\n if (na \u003C nb) {\r\n return -1;\r\n }\r\n if (na \u003E nb) {\r\n return 1;\r\n }\r\n } else {\r\n if (na \u003E nb) {\r\n return -1;\r\n }\r\n if (na \u003C nb) {\r\n return 1;\r\n }\r\n }\r\n\r\n // compare numbers\r\n if (bias) {\r\n return bias;\r\n }\r\n\r\n // compare leading zeros\r\n if (sa) {\r\n if (za \u003E zb) {\r\n return -1;\r\n }\r\n if (za \u003C zb) {\r\n return 1;\r\n }\r\n } else {\r\n if (za \u003C zb) {\r\n return -1;\r\n }\r\n if (za \u003E zb) {\r\n return 1;\r\n }\r\n }\r\n\r\n // compare ascii codes\r\n if (ca \u003C cb) {\r\n return -1;\r\n }\r\n if (ca \u003E cb) {\r\n return 1;\r\n }\r\n\r\n ia \u002B= 1;\r\n ib \u002B= 1;\r\n }\r\n\r\n // compare length\r\n if (ma \u003C mb) {\r\n return -1;\r\n }\r\n if (ma \u003E mb) {\r\n return 1;\r\n }\r\n};\r\n\r\nfunction mediator(a, b) {\r\n return compare(this, a.converted, b.converted);\r\n}\r\n\r\nfunction alphanumSort(array, opts) {\r\n if (!Array.isArray(array) || array.length \u003C 2) {\r\n return array;\r\n }\r\n if (typeof opts !== \u0027object\u0027) {\r\n opts = {};\r\n }\r\n opts.sign = !!opts.sign;\r\n var insensitive = !!opts.insensitive;\r\n var result = Array(array.length);\r\n var i, max, value;\r\n\r\n for (i = 0, max = array.length; i \u003C max; i \u002B= 1) {\r\n value = String(array[i]);\r\n result[i] = {\r\n value: array[i],\r\n converted: insensitive ? value.toLowerCase() : value\r\n };\r\n }\r\n\r\n result.sort(mediator.bind(opts));\r\n\r\n for (i = result.length - 1; ~i; i -= 1) {\r\n result[i] = result[i].value;\r\n }\r\n\r\n return result;\r\n};","TestCases":[{"Name":"Natural Sort","Code":"const arr = [\u002720\u0027, \u00272c\u0027, \u00272a\u0027, \u00271-3bench\u0027, \u0027test12\u0027, \u0027test5\u0027, \u0027TEST9\u0027, \u00271.6\u0027, \u00271.A6\u0027, \u002290071992547400029999\u0022, \u002290071992547400021111\u0022, \u0022Test42\u0022]\r\n\r\nconsole.log(arr.sort(naturalSort))","IsDeferred":false},{"Name":"Natural Compare","Code":"const arr = [\u002720\u0027, \u00272c\u0027, \u00272a\u0027, \u00271-3bench\u0027, \u0027test12\u0027, \u0027test5\u0027, \u0027TEST9\u0027, \u00271.6\u0027, \u00271.A6\u0027, \u002290071992547400029999\u0022, \u002290071992547400021111\u0022, \u0022Test42\u0022]\r\n\r\nconsole.log(arr.sort(naturalCompare))","IsDeferred":false},{"Name":"JavaScript Natural Sort","Code":"const arr = [\u002720\u0027, \u00272c\u0027, \u00272a\u0027, \u00271-3bench\u0027, \u0027test12\u0027, \u0027test5\u0027, \u0027TEST9\u0027, \u00271.6\u0027, \u00271.A6\u0027, \u002290071992547400029999\u0022, \u002290071992547400021111\u0022, \u0022Test42\u0022]\r\n\r\nconsole.log(arr.sort(javascriptNaturalSort))","IsDeferred":false},{"Name":"String Natural Compare","Code":"const arr = [\u002720\u0027, \u00272c\u0027, \u00272a\u0027, \u00271-3bench\u0027, \u0027test12\u0027, \u0027test5\u0027, \u0027TEST9\u0027, \u00271.6\u0027, \u00271.A6\u0027, \u002290071992547400029999\u0022, \u002290071992547400021111\u0022, \u0022Test42\u0022]\r\n\r\nconsole.log(arr.sort(stringNaturalCompareCI))","IsDeferred":false},{"Name":"Alphanum-Sort","Code":"const arr = [\u002720\u0027, \u00272c\u0027, \u00272a\u0027, \u00271-3bench\u0027, \u0027test12\u0027, \u0027test5\u0027, \u0027TEST9\u0027, \u00271.6\u0027, \u00271.A6\u0027, \u002290071992547400029999\u0022, \u002290071992547400021111\u0022, \u0022Test42\u0022]\r\n\r\nconsole.log(alphanumSort([].concat(arr), { insensitive: true }))","IsDeferred":false}]}