{"version":3,"sources":["../../src/index.ts"],"names":[],"mappings":";;;;AAgBO,SAAS,WAAW,KAAqC;AAC/D,SAAO,OAAO,QAAQ,WAAW,CAAC,GAAG,GAAG,IAAI;AAC7C;AAFgB;AAWT,SAAS,YAAY,eAAoC,mBAAwC;AACvG,QAAM,KAAK,WAAW,aAAa;AACnC,QAAM,KAAK,WAAW,iBAAiB;AAEvC,QAAM,KAAK,GAAG;AACd,QAAM,KAAK,GAAG;AAId,QAAM,WAAW,IAAI,WAAW,EAAE;AAClC,QAAM,WAAW,IAAI,WAAW,EAAE;AAElC,QAAM,UAAU,YAAY,IAAI,IAAI,UAAU,QAAQ;AACtD,MAAI,WAAW;AAAG,WAAO;AAGzB,QAAM,iBAAiB,kBAAkB,IAAI,IAAI,UAAU,QAAQ;AACnE,QAAM,cAAc,UAAU,KAAK,UAAU,MAAM,UAAU,kBAAkB,WAAW;AAI1F,QAAM,cAAc;AACpB,QAAM,SAAS,UAAU,IAAI,EAAE;AAC/B,SAAO,aAAa,SAAS,eAAe,IAAI;AACjD;AAxBgB;AAmChB,SAAS,YAAY,IAAe,IAAe,UAAsB,UAAsB;AAC9F,QAAM,cAAc,KAAK,MAAM,KAAK,IAAI,GAAG,QAAQ,GAAG,MAAM,IAAI,CAAC;AAEjE,MAAI,UAAU;AACd,MAAI,SAAS;AACb,MAAI,SAAS;AAGb,OAAK,SAAS,GAAG,SAAS,GAAG,QAAQ,UAAU;AAE9C,UAAM,QAAQ,KAAK,IAAI,GAAG,SAAS,WAAW;AAC9C,UAAM,MAAM,KAAK,IAAI,SAAS,cAAc,GAAG,GAAG,MAAM;AAGxD,SAAK,SAAS,OAAO,SAAS,KAAK,UAAU;AAE5C,UAAI,SAAS,MAAM,GAAG;AACrB;AAAA,MACD;AAGA,UAAI,GAAG,MAAM,MAAM,GAAG,MAAM,GAAG;AAC9B;AAAA,MACD;AAGA,eAAS,MAAM,IAAI;AACnB,eAAS,MAAM,IAAI;AAGnB,QAAE;AACF;AAAA,IACD;AAAA,EACD;AAEA,SAAO;AACR;AApCS;AA2CT,SAAS,kBAAkB,IAAe,IAAe,UAAsB,UAAsB;AACpG,MAAI,iBAAiB;AAGrB,WAAS,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,QAAQ,MAAM;AAE9C,QAAI,SAAS,EAAE,MAAM;AAAG;AAGxB,WAAO,KAAK,SAAS,UAAU,SAAS,EAAE,MAAM;AAAG;AAGnD,QAAI,GAAG,EAAE,MAAM,GAAG,EAAE;AAAG;AAGvB;AAAA,EACD;AAEA,SAAO,KAAK,MAAM,iBAAiB,CAAC;AACrC;AAnBS;AA2BT,SAAS,UAAU,IAAe,IAAe;AAChD,QAAM,cAAc;AACpB,MAAI,IAAI;AAER,SAAO,IAAI,aAAa,KAAK;AAC5B,QAAI,GAAG,CAAC,MAAM,GAAG,CAAC;AAAG,aAAO;AAAA,EAC7B;AAEA,SAAO,EAAE;AACV;AATS","sourcesContent":["/**\n * Represents an array of characters.\n */\nexport type CharArray = readonly string[];\n\n/**\n * Represents a type that can be resolved to a string or a CharArray.\n */\nexport type CharArrayResolvable = string | CharArray;\n\n/**\n * Decodes a UTF-8 string into a character array.\n *\n * @param str The UTF-8 string to decode.\n * @returns The decoded character array.\n */\nexport function decodeUtf8(str: CharArrayResolvable): CharArray {\n\treturn typeof str === 'string' ? [...str] : str;\n}\n\n/**\n * Calculates the {@link https://en.wikipedia.org/wiki/Jaro%E2%80%93Winkler_distance Jaro-Winkler similarity} between two strings.\n *\n * @param stringCompare - The first string to compare.\n * @param stringCompareWith - The second string to compare.\n * @returns The {@link https://en.wikipedia.org/wiki/Jaro%E2%80%93Winkler_distance Jaro-Winkler} between the two strings.\n */\nexport function jaroWinkler(stringCompare: CharArrayResolvable, stringCompareWith: CharArrayResolvable) {\n\tconst a1 = decodeUtf8(stringCompare);\n\tconst a2 = decodeUtf8(stringCompareWith);\n\n\tconst l1 = a1.length;\n\tconst l2 = a2.length;\n\n\t// We use Uint8Array here because they are the most compact packed arrays,\n\t// and they initialize with 0's, which in this function equal to `false`:\n\tconst matches1 = new Uint8Array(l1);\n\tconst matches2 = new Uint8Array(l2);\n\n\tconst matches = getMatching(a1, a2, matches1, matches2);\n\tif (matches <= 0) return 0;\n\n\t// Calculate the Jaro distance:\n\tconst transpositions = getTranspositions(a1, a2, matches1, matches2);\n\tconst similarity = (matches / l1 + matches / l2 + (matches - transpositions) / matches) / 3;\n\n\t// Transform to Jaro-Winkler:\n\t// Prefix scale gives more favourable ratings to strings that share common prefixes:\n\tconst prefixScale = 0.1;\n\tconst prefix = getPrefix(a1, a2);\n\treturn similarity + prefix * prefixScale * (1 - similarity);\n}\n\n/**\n * Calculates the number of matching characters between two character arrays.\n *\n * @param a1 - The first character array.\n * @param a2 - The second character array.\n * @param matches1 - An array to store the matches for characters in `a1`.\n * @param matches2 - An array to store the matches for characters in `a2`.\n * @returns The number of matching characters between `a1` and `a2`.\n */\nfunction getMatching(a1: CharArray, a2: CharArray, matches1: Uint8Array, matches2: Uint8Array) {\n\tconst matchWindow = Math.floor(Math.max(a1.length, a2.length) / 2);\n\n\tlet matches = 0;\n\tlet index1 = 0;\n\tlet index2 = 0;\n\n\t// Loop to find matched characters:\n\tfor (index1 = 0; index1 < a1.length; index1++) {\n\t\t// Use the higher of the window diff and the min of the window and string 2 length:\n\t\tconst start = Math.max(0, index1 - matchWindow);\n\t\tconst end = Math.min(index1 + matchWindow + 1, a2.length);\n\n\t\t// Iterate second string index:\n\t\tfor (index2 = start; index2 < end; index2++) {\n\t\t\t// If second string character already matched, skip:\n\t\t\tif (matches2[index2]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If the characters don't match, skip:\n\t\t\tif (a1[index1] !== a2[index2]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Assume match if the above 2 checks don't continue:\n\t\t\tmatches1[index1] = 1;\n\t\t\tmatches2[index2] = 1;\n\n\t\t\t// Add matches by 1, break inner loop:\n\t\t\t++matches;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn matches;\n}\n\n/**\n * Calculate the number of transpositions between the two words\n * @param a1 The first string to compare\n * @param a2 The second string to compare\n */\nfunction getTranspositions(a1: CharArray, a2: CharArray, matches1: Uint8Array, matches2: Uint8Array) {\n\tlet transpositions = 0;\n\n\t// Loop to find transpositions:\n\tfor (let i1 = 0, i2 = 0; i1 < a1.length; i1++) {\n\t\t// If a non-matching character was found, skip:\n\t\tif (matches1[i1] === 0) continue;\n\n\t\t// Move i2 index to the next match:\n\t\twhile (i2 < matches2.length && matches2[i2] === 0) i2++;\n\n\t\t// If the characters don't match, increase transposition:\n\t\tif (a1[i1] !== a2[i2]) transpositions++;\n\n\t\t// Iterate i2 index normally:\n\t\ti2++;\n\t}\n\n\treturn Math.floor(transpositions / 2);\n}\n\n/**\n * Counts the number of common characters at the beginning\n * of each word up to a maximum of 4\n * @param a1 The first string to compare\n * @param a2 The second string to compare\n */\nfunction getPrefix(a1: CharArray, a2: CharArray) {\n\tconst prefixLimit = 4;\n\tlet p = 0;\n\n\tfor (; p < prefixLimit; p++) {\n\t\tif (a1[p] !== a2[p]) return p;\n\t}\n\n\treturn ++p;\n}\n"]}