Project Init

This commit is contained in:
Muluhabt
2026-05-29 15:23:46 +03:00
commit 2fbc557aac
67387 changed files with 6063341 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
/**
* @name match-sorter
* @license MIT license.
* @copyright (c) 2099 Kent C. Dodds
* @author Kent C. Dodds <me@kentcdodds.com> (https://kentcdodds.com)
*/
export type AccessorAttributes = {
threshold?: Ranking;
maxRanking: Ranking;
minRanking: Ranking;
};
export interface RankingInfo {
rankedValue: any;
rank: Ranking;
accessorIndex: number;
accessorThreshold: Ranking | undefined;
passed: boolean;
}
export interface AccessorOptions<TItem> {
accessor: AccessorFn<TItem>;
threshold?: Ranking;
maxRanking?: Ranking;
minRanking?: Ranking;
}
export type AccessorFn<TItem> = (item: TItem) => string | Array<string>;
export type Accessor<TItem> = AccessorFn<TItem> | AccessorOptions<TItem>;
export interface RankItemOptions<TItem = unknown> {
accessors?: ReadonlyArray<Accessor<TItem>>;
threshold?: Ranking;
keepDiacritics?: boolean;
}
export declare const rankings: {
readonly CASE_SENSITIVE_EQUAL: 7;
readonly EQUAL: 6;
readonly STARTS_WITH: 5;
readonly WORD_STARTS_WITH: 4;
readonly CONTAINS: 3;
readonly ACRONYM: 2;
readonly MATCHES: 1;
readonly NO_MATCH: 0;
};
export type Ranking = (typeof rankings)[keyof typeof rankings];
/**
* Gets the highest ranking for value for the given item based on its values for the given keys
* @param {*} item - the item to rank
* @param {String} value - the value to rank against
* @param {Object} options - options to control the ranking
* @return {{rank: Number, accessorIndex: Number, accessorThreshold: Number}} - the highest ranking
*/
export declare function rankItem<TItem>(item: TItem, value: string, options?: RankItemOptions<TItem>): RankingInfo;
/**
* Sorts items that have a rank, index, and accessorIndex
* @param {Object} a - the first item to sort
* @param {Object} b - the second item to sort
* @return {Number} -1 if a should come first, 1 if b should come first, 0 if equal
*/
export declare function compareItems<TItem>(a: RankingInfo, b: RankingInfo): number;

View File

@@ -0,0 +1,710 @@
/**
* match-sorter-utils
*
* Copyright (c) TanStack
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
const characterMap = {
À: 'A',
Á: 'A',
Â: 'A',
Ã: 'A',
Ä: 'A',
Å: 'A',
: 'A',
: 'A',
: 'A',
: 'A',
: 'A',
Æ: 'AE',
: 'A',
: 'A',
Ȃ: 'A',
Ç: 'C',
: 'C',
È: 'E',
É: 'E',
Ê: 'E',
Ë: 'E',
: 'E',
: 'E',
: 'E',
: 'E',
: 'E',
Ȇ: 'E',
Ì: 'I',
Í: 'I',
Î: 'I',
Ï: 'I',
: 'I',
Ȋ: 'I',
Ð: 'D',
Ñ: 'N',
Ò: 'O',
Ó: 'O',
Ô: 'O',
Õ: 'O',
Ö: 'O',
Ø: 'O',
: 'O',
: 'O',
: 'O',
Ȏ: 'O',
Ù: 'U',
Ú: 'U',
Û: 'U',
Ü: 'U',
Ý: 'Y',
à: 'a',
á: 'a',
â: 'a',
ã: 'a',
ä: 'a',
å: 'a',
: 'a',
: 'a',
: 'a',
: 'a',
: 'a',
æ: 'ae',
: 'a',
: 'a',
ȃ: 'a',
ç: 'c',
: 'c',
è: 'e',
é: 'e',
ê: 'e',
ë: 'e',
ế: 'e',
: 'e',
: 'e',
: 'e',
: 'e',
ȇ: 'e',
ì: 'i',
í: 'i',
î: 'i',
ï: 'i',
: 'i',
ȋ: 'i',
ð: 'd',
ñ: 'n',
ò: 'o',
ó: 'o',
ô: 'o',
õ: 'o',
ö: 'o',
ø: 'o',
: 'o',
: 'o',
: 'o',
ȏ: 'o',
ù: 'u',
ú: 'u',
û: 'u',
ü: 'u',
ý: 'y',
ÿ: 'y',
Ā: 'A',
ā: 'a',
Ă: 'A',
ă: 'a',
Ą: 'A',
ą: 'a',
Ć: 'C',
ć: 'c',
Ĉ: 'C',
ĉ: 'c',
Ċ: 'C',
ċ: 'c',
Č: 'C',
č: 'c',
C̆: 'C',
c̆: 'c',
Ď: 'D',
ď: 'd',
Đ: 'D',
đ: 'd',
Ē: 'E',
ē: 'e',
Ĕ: 'E',
ĕ: 'e',
Ė: 'E',
ė: 'e',
Ę: 'E',
ę: 'e',
Ě: 'E',
ě: 'e',
Ĝ: 'G',
Ǵ: 'G',
ĝ: 'g',
ǵ: 'g',
Ğ: 'G',
ğ: 'g',
Ġ: 'G',
ġ: 'g',
Ģ: 'G',
ģ: 'g',
Ĥ: 'H',
ĥ: 'h',
Ħ: 'H',
ħ: 'h',
: 'H',
: 'h',
Ĩ: 'I',
ĩ: 'i',
Ī: 'I',
ī: 'i',
Ĭ: 'I',
ĭ: 'i',
Į: 'I',
į: 'i',
İ: 'I',
ı: 'i',
IJ: 'IJ',
ij: 'ij',
Ĵ: 'J',
ĵ: 'j',
Ķ: 'K',
ķ: 'k',
: 'K',
: 'k',
K̆: 'K',
k̆: 'k',
Ĺ: 'L',
ĺ: 'l',
Ļ: 'L',
ļ: 'l',
Ľ: 'L',
ľ: 'l',
Ŀ: 'L',
ŀ: 'l',
Ł: 'l',
ł: 'l',
: 'M',
ḿ: 'm',
M̆: 'M',
m̆: 'm',
Ń: 'N',
ń: 'n',
Ņ: 'N',
ņ: 'n',
Ň: 'N',
ň: 'n',
ʼn: 'n',
N̆: 'N',
n̆: 'n',
Ō: 'O',
ō: 'o',
Ŏ: 'O',
ŏ: 'o',
Ő: 'O',
ő: 'o',
Œ: 'OE',
œ: 'oe',
P̆: 'P',
p̆: 'p',
Ŕ: 'R',
ŕ: 'r',
Ŗ: 'R',
ŗ: 'r',
Ř: 'R',
ř: 'r',
R̆: 'R',
r̆: 'r',
Ȓ: 'R',
ȓ: 'r',
Ś: 'S',
ś: 's',
Ŝ: 'S',
ŝ: 's',
Ş: 'S',
Ș: 'S',
ș: 's',
ş: 's',
Š: 'S',
š: 's',
Ţ: 'T',
ţ: 't',
ț: 't',
Ț: 'T',
Ť: 'T',
ť: 't',
Ŧ: 'T',
ŧ: 't',
T̆: 'T',
t̆: 't',
Ũ: 'U',
ũ: 'u',
Ū: 'U',
ū: 'u',
Ŭ: 'U',
ŭ: 'u',
Ů: 'U',
ů: 'u',
Ű: 'U',
ű: 'u',
Ų: 'U',
ų: 'u',
Ȗ: 'U',
ȗ: 'u',
V̆: 'V',
v̆: 'v',
Ŵ: 'W',
ŵ: 'w',
: 'W',
: 'w',
X̆: 'X',
x̆: 'x',
Ŷ: 'Y',
ŷ: 'y',
Ÿ: 'Y',
Y̆: 'Y',
y̆: 'y',
Ź: 'Z',
ź: 'z',
Ż: 'Z',
ż: 'z',
Ž: 'Z',
ž: 'z',
ſ: 's',
ƒ: 'f',
Ơ: 'O',
ơ: 'o',
Ư: 'U',
ư: 'u',
Ǎ: 'A',
ǎ: 'a',
Ǐ: 'I',
ǐ: 'i',
Ǒ: 'O',
ǒ: 'o',
Ǔ: 'U',
ǔ: 'u',
Ǖ: 'U',
ǖ: 'u',
Ǘ: 'U',
ǘ: 'u',
Ǚ: 'U',
ǚ: 'u',
Ǜ: 'U',
ǜ: 'u',
: 'U',
: 'u',
: 'U',
: 'u',
Ǻ: 'A',
ǻ: 'a',
Ǽ: 'AE',
ǽ: 'ae',
Ǿ: 'O',
ǿ: 'o',
Þ: 'TH',
þ: 'th',
: 'P',
: 'p',
: 'S',
: 's',
X́: 'X',
x́: 'x',
Ѓ: 'Г',
ѓ: 'г',
Ќ: 'К',
ќ: 'к',
A̋: 'A',
a̋: 'a',
E̋: 'E',
e̋: 'e',
I̋: 'I',
i̋: 'i',
Ǹ: 'N',
ǹ: 'n',
: 'O',
: 'o',
: 'O',
: 'o',
: 'U',
: 'u',
: 'W',
: 'w',
: 'Y',
: 'y',
Ȁ: 'A',
ȁ: 'a',
Ȅ: 'E',
ȅ: 'e',
Ȉ: 'I',
ȉ: 'i',
Ȍ: 'O',
ȍ: 'o',
Ȑ: 'R',
ȑ: 'r',
Ȕ: 'U',
ȕ: 'u',
B̌: 'B',
b̌: 'b',
Č̣: 'C',
č̣: 'c',
Ê̌: 'E',
ê̌: 'e',
F̌: 'F',
f̌: 'f',
Ǧ: 'G',
ǧ: 'g',
Ȟ: 'H',
ȟ: 'h',
J̌: 'J',
ǰ: 'j',
Ǩ: 'K',
ǩ: 'k',
M̌: 'M',
m̌: 'm',
P̌: 'P',
p̌: 'p',
Q̌: 'Q',
q̌: 'q',
Ř̩: 'R',
ř̩: 'r',
: 'S',
: 's',
V̌: 'V',
v̌: 'v',
W̌: 'W',
w̌: 'w',
X̌: 'X',
x̌: 'x',
Y̌: 'Y',
y̌: 'y',
A̧: 'A',
a̧: 'a',
B̧: 'B',
b̧: 'b',
: 'D',
: 'd',
Ȩ: 'E',
ȩ: 'e',
Ɛ̧: 'E',
ɛ̧: 'e',
: 'H',
: 'h',
I̧: 'I',
i̧: 'i',
Ɨ̧: 'I',
ɨ̧: 'i',
M̧: 'M',
m̧: 'm',
O̧: 'O',
o̧: 'o',
Q̧: 'Q',
q̧: 'q',
U̧: 'U',
u̧: 'u',
X̧: 'X',
x̧: 'x',
Z̧: 'Z',
z̧: 'z'
};
const chars = Object.keys(characterMap).join('|');
const allAccents = new RegExp(chars, 'g');
function removeAccents(str) {
return str.replace(allAccents, match => {
return characterMap[match];
});
}
/**
* @name match-sorter
* @license MIT license.
* @copyright (c) 2099 Kent C. Dodds
* @author Kent C. Dodds <me@kentcdodds.com> (https://kentcdodds.com)
*/
const rankings = {
CASE_SENSITIVE_EQUAL: 7,
EQUAL: 6,
STARTS_WITH: 5,
WORD_STARTS_WITH: 4,
CONTAINS: 3,
ACRONYM: 2,
MATCHES: 1,
NO_MATCH: 0
};
/**
* Gets the highest ranking for value for the given item based on its values for the given keys
* @param {*} item - the item to rank
* @param {String} value - the value to rank against
* @param {Object} options - options to control the ranking
* @return {{rank: Number, accessorIndex: Number, accessorThreshold: Number}} - the highest ranking
*/
function rankItem(item, value, options) {
var _options$threshold;
options = options || {};
options.threshold = (_options$threshold = options.threshold) != null ? _options$threshold : rankings.MATCHES;
if (!options.accessors) {
// if keys is not specified, then we assume the item given is ready to be matched
const rank = getMatchRanking(item, value, options);
return {
// ends up being duplicate of 'item' in matches but consistent
rankedValue: item,
rank,
accessorIndex: -1,
accessorThreshold: options.threshold,
passed: rank >= options.threshold
};
}
const valuesToRank = getAllValuesToRank(item, options.accessors);
const rankingInfo = {
rankedValue: item,
rank: rankings.NO_MATCH,
accessorIndex: -1,
accessorThreshold: options.threshold,
passed: false
};
for (let i = 0; i < valuesToRank.length; i++) {
const rankValue = valuesToRank[i];
let newRank = getMatchRanking(rankValue.itemValue, value, options);
const {
minRanking,
maxRanking,
threshold = options.threshold
} = rankValue.attributes;
if (newRank < minRanking && newRank >= rankings.MATCHES) {
newRank = minRanking;
} else if (newRank > maxRanking) {
newRank = maxRanking;
}
newRank = Math.min(newRank, maxRanking);
if (newRank >= threshold && newRank > rankingInfo.rank) {
rankingInfo.rank = newRank;
rankingInfo.passed = true;
rankingInfo.accessorIndex = i;
rankingInfo.accessorThreshold = threshold;
rankingInfo.rankedValue = rankValue.itemValue;
}
}
return rankingInfo;
}
/**
* Gives a rankings score based on how well the two strings match.
* @param {String} testString - the string to test against
* @param {String} stringToRank - the string to rank
* @param {Object} options - options for the match (like keepDiacritics for comparison)
* @returns {Number} the ranking for how well stringToRank matches testString
*/
function getMatchRanking(testString, stringToRank, options) {
testString = prepareValueForComparison(testString, options);
stringToRank = prepareValueForComparison(stringToRank, options);
// too long
if (stringToRank.length > testString.length) {
return rankings.NO_MATCH;
}
// case sensitive equals
if (testString === stringToRank) {
return rankings.CASE_SENSITIVE_EQUAL;
}
// Lower casing before further comparison
testString = testString.toLowerCase();
stringToRank = stringToRank.toLowerCase();
// case insensitive equals
if (testString === stringToRank) {
return rankings.EQUAL;
}
// starts with
if (testString.startsWith(stringToRank)) {
return rankings.STARTS_WITH;
}
// word starts with
if (testString.includes(` ${stringToRank}`)) {
return rankings.WORD_STARTS_WITH;
}
// contains
if (testString.includes(stringToRank)) {
return rankings.CONTAINS;
} else if (stringToRank.length === 1) {
// If the only character in the given stringToRank
// isn't even contained in the testString, then
// it's definitely not a match.
return rankings.NO_MATCH;
}
// acronym
if (getAcronym(testString).includes(stringToRank)) {
return rankings.ACRONYM;
}
// will return a number between rankings.MATCHES and
// rankings.MATCHES + 1 depending on how close of a match it is.
return getClosenessRanking(testString, stringToRank);
}
/**
* Generates an acronym for a string.
*
* @param {String} string the string for which to produce the acronym
* @returns {String} the acronym
*/
function getAcronym(string) {
let acronym = '';
const wordsInString = string.split(' ');
wordsInString.forEach(wordInString => {
const splitByHyphenWords = wordInString.split('-');
splitByHyphenWords.forEach(splitByHyphenWord => {
acronym += splitByHyphenWord.substr(0, 1);
});
});
return acronym;
}
/**
* Returns a score based on how spread apart the
* characters from the stringToRank are within the testString.
* A number close to rankings.MATCHES represents a loose match. A number close
* to rankings.MATCHES + 1 represents a tighter match.
* @param {String} testString - the string to test against
* @param {String} stringToRank - the string to rank
* @returns {Number} the number between rankings.MATCHES and
* rankings.MATCHES + 1 for how well stringToRank matches testString
*/
function getClosenessRanking(testString, stringToRank) {
let matchingInOrderCharCount = 0;
let charNumber = 0;
function findMatchingCharacter(matchChar, string, index) {
for (let j = index, J = string.length; j < J; j++) {
const stringChar = string[j];
if (stringChar === matchChar) {
matchingInOrderCharCount += 1;
return j + 1;
}
}
return -1;
}
function getRanking(spread) {
const spreadPercentage = 1 / spread;
const inOrderPercentage = matchingInOrderCharCount / stringToRank.length;
const ranking = rankings.MATCHES + inOrderPercentage * spreadPercentage;
return ranking;
}
const firstIndex = findMatchingCharacter(stringToRank[0], testString, 0);
if (firstIndex < 0) {
return rankings.NO_MATCH;
}
charNumber = firstIndex;
for (let i = 1, I = stringToRank.length; i < I; i++) {
const matchChar = stringToRank[i];
charNumber = findMatchingCharacter(matchChar, testString, charNumber);
const found = charNumber > -1;
if (!found) {
return rankings.NO_MATCH;
}
}
const spread = charNumber - firstIndex;
return getRanking(spread);
}
/**
* Sorts items that have a rank, index, and accessorIndex
* @param {Object} a - the first item to sort
* @param {Object} b - the second item to sort
* @return {Number} -1 if a should come first, 1 if b should come first, 0 if equal
*/
function compareItems(a, b) {
return a.rank === b.rank ? 0 : a.rank > b.rank ? -1 : 1;
}
/**
* Prepares value for comparison by stringifying it, removing diacritics (if specified)
* @param {String} value - the value to clean
* @param {Object} options - {keepDiacritics: whether to remove diacritics}
* @return {String} the prepared value
*/
function prepareValueForComparison(value, _ref) {
let {
keepDiacritics
} = _ref;
// value might not actually be a string at this point (we don't get to choose)
// so part of preparing the value for comparison is ensure that it is a string
value = `${value}`; // toString
if (!keepDiacritics) {
value = removeAccents(value);
}
return value;
}
/**
* Gets value for key in item at arbitrarily nested keypath
* @param {Object} item - the item
* @param {Object|Function} key - the potentially nested keypath or property callback
* @return {Array} - an array containing the value(s) at the nested keypath
*/
function getItemValues(item, accessor) {
let accessorFn = accessor;
if (typeof accessor === 'object') {
accessorFn = accessor.accessor;
}
const value = accessorFn(item);
// because `value` can also be undefined
if (value == null) {
return [];
}
if (Array.isArray(value)) {
return value;
}
return [String(value)];
}
/**
* Gets all the values for the given keys in the given item and returns an array of those values
* @param item - the item from which the values will be retrieved
* @param keys - the keys to use to retrieve the values
* @return objects with {itemValue, attributes}
*/
function getAllValuesToRank(item, accessors) {
const allValues = [];
for (let j = 0, J = accessors.length; j < J; j++) {
const accessor = accessors[j];
const attributes = getAccessorAttributes(accessor);
const itemValues = getItemValues(item, accessor);
for (let i = 0, I = itemValues.length; i < I; i++) {
allValues.push({
itemValue: itemValues[i],
attributes
});
}
}
return allValues;
}
const defaultKeyAttributes = {
maxRanking: Infinity,
minRanking: -Infinity
};
/**
* Gets all the attributes for the given accessor
* @param accessor - the accessor from which the attributes will be retrieved
* @return object containing the accessor's attributes
*/
function getAccessorAttributes(accessor) {
if (typeof accessor === 'function') {
return defaultKeyAttributes;
}
return {
...defaultKeyAttributes,
...accessor
};
}
export { compareItems, rankItem, rankings };
//# sourceMappingURL=index.esm.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,307 @@
/**
* match-sorter-utils
*
* Copyright (c) TanStack
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
'use strict';
var removeAccents = require('./remove-accents.js');
/**
* @name match-sorter
* @license MIT license.
* @copyright (c) 2099 Kent C. Dodds
* @author Kent C. Dodds <me@kentcdodds.com> (https://kentcdodds.com)
*/
const rankings = {
CASE_SENSITIVE_EQUAL: 7,
EQUAL: 6,
STARTS_WITH: 5,
WORD_STARTS_WITH: 4,
CONTAINS: 3,
ACRONYM: 2,
MATCHES: 1,
NO_MATCH: 0
};
/**
* Gets the highest ranking for value for the given item based on its values for the given keys
* @param {*} item - the item to rank
* @param {String} value - the value to rank against
* @param {Object} options - options to control the ranking
* @return {{rank: Number, accessorIndex: Number, accessorThreshold: Number}} - the highest ranking
*/
function rankItem(item, value, options) {
var _options$threshold;
options = options || {};
options.threshold = (_options$threshold = options.threshold) != null ? _options$threshold : rankings.MATCHES;
if (!options.accessors) {
// if keys is not specified, then we assume the item given is ready to be matched
const rank = getMatchRanking(item, value, options);
return {
// ends up being duplicate of 'item' in matches but consistent
rankedValue: item,
rank,
accessorIndex: -1,
accessorThreshold: options.threshold,
passed: rank >= options.threshold
};
}
const valuesToRank = getAllValuesToRank(item, options.accessors);
const rankingInfo = {
rankedValue: item,
rank: rankings.NO_MATCH,
accessorIndex: -1,
accessorThreshold: options.threshold,
passed: false
};
for (let i = 0; i < valuesToRank.length; i++) {
const rankValue = valuesToRank[i];
let newRank = getMatchRanking(rankValue.itemValue, value, options);
const {
minRanking,
maxRanking,
threshold = options.threshold
} = rankValue.attributes;
if (newRank < minRanking && newRank >= rankings.MATCHES) {
newRank = minRanking;
} else if (newRank > maxRanking) {
newRank = maxRanking;
}
newRank = Math.min(newRank, maxRanking);
if (newRank >= threshold && newRank > rankingInfo.rank) {
rankingInfo.rank = newRank;
rankingInfo.passed = true;
rankingInfo.accessorIndex = i;
rankingInfo.accessorThreshold = threshold;
rankingInfo.rankedValue = rankValue.itemValue;
}
}
return rankingInfo;
}
/**
* Gives a rankings score based on how well the two strings match.
* @param {String} testString - the string to test against
* @param {String} stringToRank - the string to rank
* @param {Object} options - options for the match (like keepDiacritics for comparison)
* @returns {Number} the ranking for how well stringToRank matches testString
*/
function getMatchRanking(testString, stringToRank, options) {
testString = prepareValueForComparison(testString, options);
stringToRank = prepareValueForComparison(stringToRank, options);
// too long
if (stringToRank.length > testString.length) {
return rankings.NO_MATCH;
}
// case sensitive equals
if (testString === stringToRank) {
return rankings.CASE_SENSITIVE_EQUAL;
}
// Lower casing before further comparison
testString = testString.toLowerCase();
stringToRank = stringToRank.toLowerCase();
// case insensitive equals
if (testString === stringToRank) {
return rankings.EQUAL;
}
// starts with
if (testString.startsWith(stringToRank)) {
return rankings.STARTS_WITH;
}
// word starts with
if (testString.includes(` ${stringToRank}`)) {
return rankings.WORD_STARTS_WITH;
}
// contains
if (testString.includes(stringToRank)) {
return rankings.CONTAINS;
} else if (stringToRank.length === 1) {
// If the only character in the given stringToRank
// isn't even contained in the testString, then
// it's definitely not a match.
return rankings.NO_MATCH;
}
// acronym
if (getAcronym(testString).includes(stringToRank)) {
return rankings.ACRONYM;
}
// will return a number between rankings.MATCHES and
// rankings.MATCHES + 1 depending on how close of a match it is.
return getClosenessRanking(testString, stringToRank);
}
/**
* Generates an acronym for a string.
*
* @param {String} string the string for which to produce the acronym
* @returns {String} the acronym
*/
function getAcronym(string) {
let acronym = '';
const wordsInString = string.split(' ');
wordsInString.forEach(wordInString => {
const splitByHyphenWords = wordInString.split('-');
splitByHyphenWords.forEach(splitByHyphenWord => {
acronym += splitByHyphenWord.substr(0, 1);
});
});
return acronym;
}
/**
* Returns a score based on how spread apart the
* characters from the stringToRank are within the testString.
* A number close to rankings.MATCHES represents a loose match. A number close
* to rankings.MATCHES + 1 represents a tighter match.
* @param {String} testString - the string to test against
* @param {String} stringToRank - the string to rank
* @returns {Number} the number between rankings.MATCHES and
* rankings.MATCHES + 1 for how well stringToRank matches testString
*/
function getClosenessRanking(testString, stringToRank) {
let matchingInOrderCharCount = 0;
let charNumber = 0;
function findMatchingCharacter(matchChar, string, index) {
for (let j = index, J = string.length; j < J; j++) {
const stringChar = string[j];
if (stringChar === matchChar) {
matchingInOrderCharCount += 1;
return j + 1;
}
}
return -1;
}
function getRanking(spread) {
const spreadPercentage = 1 / spread;
const inOrderPercentage = matchingInOrderCharCount / stringToRank.length;
const ranking = rankings.MATCHES + inOrderPercentage * spreadPercentage;
return ranking;
}
const firstIndex = findMatchingCharacter(stringToRank[0], testString, 0);
if (firstIndex < 0) {
return rankings.NO_MATCH;
}
charNumber = firstIndex;
for (let i = 1, I = stringToRank.length; i < I; i++) {
const matchChar = stringToRank[i];
charNumber = findMatchingCharacter(matchChar, testString, charNumber);
const found = charNumber > -1;
if (!found) {
return rankings.NO_MATCH;
}
}
const spread = charNumber - firstIndex;
return getRanking(spread);
}
/**
* Sorts items that have a rank, index, and accessorIndex
* @param {Object} a - the first item to sort
* @param {Object} b - the second item to sort
* @return {Number} -1 if a should come first, 1 if b should come first, 0 if equal
*/
function compareItems(a, b) {
return a.rank === b.rank ? 0 : a.rank > b.rank ? -1 : 1;
}
/**
* Prepares value for comparison by stringifying it, removing diacritics (if specified)
* @param {String} value - the value to clean
* @param {Object} options - {keepDiacritics: whether to remove diacritics}
* @return {String} the prepared value
*/
function prepareValueForComparison(value, _ref) {
let {
keepDiacritics
} = _ref;
// value might not actually be a string at this point (we don't get to choose)
// so part of preparing the value for comparison is ensure that it is a string
value = `${value}`; // toString
if (!keepDiacritics) {
value = removeAccents.removeAccents(value);
}
return value;
}
/**
* Gets value for key in item at arbitrarily nested keypath
* @param {Object} item - the item
* @param {Object|Function} key - the potentially nested keypath or property callback
* @return {Array} - an array containing the value(s) at the nested keypath
*/
function getItemValues(item, accessor) {
let accessorFn = accessor;
if (typeof accessor === 'object') {
accessorFn = accessor.accessor;
}
const value = accessorFn(item);
// because `value` can also be undefined
if (value == null) {
return [];
}
if (Array.isArray(value)) {
return value;
}
return [String(value)];
}
/**
* Gets all the values for the given keys in the given item and returns an array of those values
* @param item - the item from which the values will be retrieved
* @param keys - the keys to use to retrieve the values
* @return objects with {itemValue, attributes}
*/
function getAllValuesToRank(item, accessors) {
const allValues = [];
for (let j = 0, J = accessors.length; j < J; j++) {
const accessor = accessors[j];
const attributes = getAccessorAttributes(accessor);
const itemValues = getItemValues(item, accessor);
for (let i = 0, I = itemValues.length; i < I; i++) {
allValues.push({
itemValue: itemValues[i],
attributes
});
}
}
return allValues;
}
const defaultKeyAttributes = {
maxRanking: Infinity,
minRanking: -Infinity
};
/**
* Gets all the attributes for the given accessor
* @param accessor - the accessor from which the attributes will be retrieved
* @return object containing the accessor's attributes
*/
function getAccessorAttributes(accessor) {
if (typeof accessor === 'function') {
return defaultKeyAttributes;
}
return {
...defaultKeyAttributes,
...accessor
};
}
exports.compareItems = compareItems;
exports.rankItem = rankItem;
exports.rankings = rankings;
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,710 @@
/**
* match-sorter-utils
*
* Copyright (c) TanStack
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
const characterMap = {
À: 'A',
Á: 'A',
Â: 'A',
Ã: 'A',
Ä: 'A',
Å: 'A',
: 'A',
: 'A',
: 'A',
: 'A',
: 'A',
Æ: 'AE',
: 'A',
: 'A',
Ȃ: 'A',
Ç: 'C',
: 'C',
È: 'E',
É: 'E',
Ê: 'E',
Ë: 'E',
: 'E',
: 'E',
: 'E',
: 'E',
: 'E',
Ȇ: 'E',
Ì: 'I',
Í: 'I',
Î: 'I',
Ï: 'I',
: 'I',
Ȋ: 'I',
Ð: 'D',
Ñ: 'N',
Ò: 'O',
Ó: 'O',
Ô: 'O',
Õ: 'O',
Ö: 'O',
Ø: 'O',
: 'O',
: 'O',
: 'O',
Ȏ: 'O',
Ù: 'U',
Ú: 'U',
Û: 'U',
Ü: 'U',
Ý: 'Y',
à: 'a',
á: 'a',
â: 'a',
ã: 'a',
ä: 'a',
å: 'a',
: 'a',
: 'a',
: 'a',
: 'a',
: 'a',
æ: 'ae',
: 'a',
: 'a',
ȃ: 'a',
ç: 'c',
: 'c',
è: 'e',
é: 'e',
ê: 'e',
ë: 'e',
ế: 'e',
: 'e',
: 'e',
: 'e',
: 'e',
ȇ: 'e',
ì: 'i',
í: 'i',
î: 'i',
ï: 'i',
: 'i',
ȋ: 'i',
ð: 'd',
ñ: 'n',
ò: 'o',
ó: 'o',
ô: 'o',
õ: 'o',
ö: 'o',
ø: 'o',
: 'o',
: 'o',
: 'o',
ȏ: 'o',
ù: 'u',
ú: 'u',
û: 'u',
ü: 'u',
ý: 'y',
ÿ: 'y',
Ā: 'A',
ā: 'a',
Ă: 'A',
ă: 'a',
Ą: 'A',
ą: 'a',
Ć: 'C',
ć: 'c',
Ĉ: 'C',
ĉ: 'c',
Ċ: 'C',
ċ: 'c',
Č: 'C',
č: 'c',
C̆: 'C',
c̆: 'c',
Ď: 'D',
ď: 'd',
Đ: 'D',
đ: 'd',
Ē: 'E',
ē: 'e',
Ĕ: 'E',
ĕ: 'e',
Ė: 'E',
ė: 'e',
Ę: 'E',
ę: 'e',
Ě: 'E',
ě: 'e',
Ĝ: 'G',
Ǵ: 'G',
ĝ: 'g',
ǵ: 'g',
Ğ: 'G',
ğ: 'g',
Ġ: 'G',
ġ: 'g',
Ģ: 'G',
ģ: 'g',
Ĥ: 'H',
ĥ: 'h',
Ħ: 'H',
ħ: 'h',
: 'H',
: 'h',
Ĩ: 'I',
ĩ: 'i',
Ī: 'I',
ī: 'i',
Ĭ: 'I',
ĭ: 'i',
Į: 'I',
į: 'i',
İ: 'I',
ı: 'i',
IJ: 'IJ',
ij: 'ij',
Ĵ: 'J',
ĵ: 'j',
Ķ: 'K',
ķ: 'k',
: 'K',
: 'k',
K̆: 'K',
k̆: 'k',
Ĺ: 'L',
ĺ: 'l',
Ļ: 'L',
ļ: 'l',
Ľ: 'L',
ľ: 'l',
Ŀ: 'L',
ŀ: 'l',
Ł: 'l',
ł: 'l',
: 'M',
ḿ: 'm',
M̆: 'M',
m̆: 'm',
Ń: 'N',
ń: 'n',
Ņ: 'N',
ņ: 'n',
Ň: 'N',
ň: 'n',
ʼn: 'n',
N̆: 'N',
n̆: 'n',
Ō: 'O',
ō: 'o',
Ŏ: 'O',
ŏ: 'o',
Ő: 'O',
ő: 'o',
Œ: 'OE',
œ: 'oe',
P̆: 'P',
p̆: 'p',
Ŕ: 'R',
ŕ: 'r',
Ŗ: 'R',
ŗ: 'r',
Ř: 'R',
ř: 'r',
R̆: 'R',
r̆: 'r',
Ȓ: 'R',
ȓ: 'r',
Ś: 'S',
ś: 's',
Ŝ: 'S',
ŝ: 's',
Ş: 'S',
Ș: 'S',
ș: 's',
ş: 's',
Š: 'S',
š: 's',
Ţ: 'T',
ţ: 't',
ț: 't',
Ț: 'T',
Ť: 'T',
ť: 't',
Ŧ: 'T',
ŧ: 't',
T̆: 'T',
t̆: 't',
Ũ: 'U',
ũ: 'u',
Ū: 'U',
ū: 'u',
Ŭ: 'U',
ŭ: 'u',
Ů: 'U',
ů: 'u',
Ű: 'U',
ű: 'u',
Ų: 'U',
ų: 'u',
Ȗ: 'U',
ȗ: 'u',
V̆: 'V',
v̆: 'v',
Ŵ: 'W',
ŵ: 'w',
: 'W',
: 'w',
X̆: 'X',
x̆: 'x',
Ŷ: 'Y',
ŷ: 'y',
Ÿ: 'Y',
Y̆: 'Y',
y̆: 'y',
Ź: 'Z',
ź: 'z',
Ż: 'Z',
ż: 'z',
Ž: 'Z',
ž: 'z',
ſ: 's',
ƒ: 'f',
Ơ: 'O',
ơ: 'o',
Ư: 'U',
ư: 'u',
Ǎ: 'A',
ǎ: 'a',
Ǐ: 'I',
ǐ: 'i',
Ǒ: 'O',
ǒ: 'o',
Ǔ: 'U',
ǔ: 'u',
Ǖ: 'U',
ǖ: 'u',
Ǘ: 'U',
ǘ: 'u',
Ǚ: 'U',
ǚ: 'u',
Ǜ: 'U',
ǜ: 'u',
: 'U',
: 'u',
: 'U',
: 'u',
Ǻ: 'A',
ǻ: 'a',
Ǽ: 'AE',
ǽ: 'ae',
Ǿ: 'O',
ǿ: 'o',
Þ: 'TH',
þ: 'th',
: 'P',
: 'p',
: 'S',
: 's',
X́: 'X',
x́: 'x',
Ѓ: 'Г',
ѓ: 'г',
Ќ: 'К',
ќ: 'к',
A̋: 'A',
a̋: 'a',
E̋: 'E',
e̋: 'e',
I̋: 'I',
i̋: 'i',
Ǹ: 'N',
ǹ: 'n',
: 'O',
: 'o',
: 'O',
: 'o',
: 'U',
: 'u',
: 'W',
: 'w',
: 'Y',
: 'y',
Ȁ: 'A',
ȁ: 'a',
Ȅ: 'E',
ȅ: 'e',
Ȉ: 'I',
ȉ: 'i',
Ȍ: 'O',
ȍ: 'o',
Ȑ: 'R',
ȑ: 'r',
Ȕ: 'U',
ȕ: 'u',
B̌: 'B',
b̌: 'b',
Č̣: 'C',
č̣: 'c',
Ê̌: 'E',
ê̌: 'e',
F̌: 'F',
f̌: 'f',
Ǧ: 'G',
ǧ: 'g',
Ȟ: 'H',
ȟ: 'h',
J̌: 'J',
ǰ: 'j',
Ǩ: 'K',
ǩ: 'k',
M̌: 'M',
m̌: 'm',
P̌: 'P',
p̌: 'p',
Q̌: 'Q',
q̌: 'q',
Ř̩: 'R',
ř̩: 'r',
: 'S',
: 's',
V̌: 'V',
v̌: 'v',
W̌: 'W',
w̌: 'w',
X̌: 'X',
x̌: 'x',
Y̌: 'Y',
y̌: 'y',
A̧: 'A',
a̧: 'a',
B̧: 'B',
b̧: 'b',
: 'D',
: 'd',
Ȩ: 'E',
ȩ: 'e',
Ɛ̧: 'E',
ɛ̧: 'e',
: 'H',
: 'h',
I̧: 'I',
i̧: 'i',
Ɨ̧: 'I',
ɨ̧: 'i',
M̧: 'M',
m̧: 'm',
O̧: 'O',
o̧: 'o',
Q̧: 'Q',
q̧: 'q',
U̧: 'U',
u̧: 'u',
X̧: 'X',
x̧: 'x',
Z̧: 'Z',
z̧: 'z'
};
const chars = Object.keys(characterMap).join('|');
const allAccents = new RegExp(chars, 'g');
function removeAccents(str) {
return str.replace(allAccents, match => {
return characterMap[match];
});
}
/**
* @name match-sorter
* @license MIT license.
* @copyright (c) 2099 Kent C. Dodds
* @author Kent C. Dodds <me@kentcdodds.com> (https://kentcdodds.com)
*/
const rankings = {
CASE_SENSITIVE_EQUAL: 7,
EQUAL: 6,
STARTS_WITH: 5,
WORD_STARTS_WITH: 4,
CONTAINS: 3,
ACRONYM: 2,
MATCHES: 1,
NO_MATCH: 0
};
/**
* Gets the highest ranking for value for the given item based on its values for the given keys
* @param {*} item - the item to rank
* @param {String} value - the value to rank against
* @param {Object} options - options to control the ranking
* @return {{rank: Number, accessorIndex: Number, accessorThreshold: Number}} - the highest ranking
*/
function rankItem(item, value, options) {
var _options$threshold;
options = options || {};
options.threshold = (_options$threshold = options.threshold) != null ? _options$threshold : rankings.MATCHES;
if (!options.accessors) {
// if keys is not specified, then we assume the item given is ready to be matched
const rank = getMatchRanking(item, value, options);
return {
// ends up being duplicate of 'item' in matches but consistent
rankedValue: item,
rank,
accessorIndex: -1,
accessorThreshold: options.threshold,
passed: rank >= options.threshold
};
}
const valuesToRank = getAllValuesToRank(item, options.accessors);
const rankingInfo = {
rankedValue: item,
rank: rankings.NO_MATCH,
accessorIndex: -1,
accessorThreshold: options.threshold,
passed: false
};
for (let i = 0; i < valuesToRank.length; i++) {
const rankValue = valuesToRank[i];
let newRank = getMatchRanking(rankValue.itemValue, value, options);
const {
minRanking,
maxRanking,
threshold = options.threshold
} = rankValue.attributes;
if (newRank < minRanking && newRank >= rankings.MATCHES) {
newRank = minRanking;
} else if (newRank > maxRanking) {
newRank = maxRanking;
}
newRank = Math.min(newRank, maxRanking);
if (newRank >= threshold && newRank > rankingInfo.rank) {
rankingInfo.rank = newRank;
rankingInfo.passed = true;
rankingInfo.accessorIndex = i;
rankingInfo.accessorThreshold = threshold;
rankingInfo.rankedValue = rankValue.itemValue;
}
}
return rankingInfo;
}
/**
* Gives a rankings score based on how well the two strings match.
* @param {String} testString - the string to test against
* @param {String} stringToRank - the string to rank
* @param {Object} options - options for the match (like keepDiacritics for comparison)
* @returns {Number} the ranking for how well stringToRank matches testString
*/
function getMatchRanking(testString, stringToRank, options) {
testString = prepareValueForComparison(testString, options);
stringToRank = prepareValueForComparison(stringToRank, options);
// too long
if (stringToRank.length > testString.length) {
return rankings.NO_MATCH;
}
// case sensitive equals
if (testString === stringToRank) {
return rankings.CASE_SENSITIVE_EQUAL;
}
// Lower casing before further comparison
testString = testString.toLowerCase();
stringToRank = stringToRank.toLowerCase();
// case insensitive equals
if (testString === stringToRank) {
return rankings.EQUAL;
}
// starts with
if (testString.startsWith(stringToRank)) {
return rankings.STARTS_WITH;
}
// word starts with
if (testString.includes(` ${stringToRank}`)) {
return rankings.WORD_STARTS_WITH;
}
// contains
if (testString.includes(stringToRank)) {
return rankings.CONTAINS;
} else if (stringToRank.length === 1) {
// If the only character in the given stringToRank
// isn't even contained in the testString, then
// it's definitely not a match.
return rankings.NO_MATCH;
}
// acronym
if (getAcronym(testString).includes(stringToRank)) {
return rankings.ACRONYM;
}
// will return a number between rankings.MATCHES and
// rankings.MATCHES + 1 depending on how close of a match it is.
return getClosenessRanking(testString, stringToRank);
}
/**
* Generates an acronym for a string.
*
* @param {String} string the string for which to produce the acronym
* @returns {String} the acronym
*/
function getAcronym(string) {
let acronym = '';
const wordsInString = string.split(' ');
wordsInString.forEach(wordInString => {
const splitByHyphenWords = wordInString.split('-');
splitByHyphenWords.forEach(splitByHyphenWord => {
acronym += splitByHyphenWord.substr(0, 1);
});
});
return acronym;
}
/**
* Returns a score based on how spread apart the
* characters from the stringToRank are within the testString.
* A number close to rankings.MATCHES represents a loose match. A number close
* to rankings.MATCHES + 1 represents a tighter match.
* @param {String} testString - the string to test against
* @param {String} stringToRank - the string to rank
* @returns {Number} the number between rankings.MATCHES and
* rankings.MATCHES + 1 for how well stringToRank matches testString
*/
function getClosenessRanking(testString, stringToRank) {
let matchingInOrderCharCount = 0;
let charNumber = 0;
function findMatchingCharacter(matchChar, string, index) {
for (let j = index, J = string.length; j < J; j++) {
const stringChar = string[j];
if (stringChar === matchChar) {
matchingInOrderCharCount += 1;
return j + 1;
}
}
return -1;
}
function getRanking(spread) {
const spreadPercentage = 1 / spread;
const inOrderPercentage = matchingInOrderCharCount / stringToRank.length;
const ranking = rankings.MATCHES + inOrderPercentage * spreadPercentage;
return ranking;
}
const firstIndex = findMatchingCharacter(stringToRank[0], testString, 0);
if (firstIndex < 0) {
return rankings.NO_MATCH;
}
charNumber = firstIndex;
for (let i = 1, I = stringToRank.length; i < I; i++) {
const matchChar = stringToRank[i];
charNumber = findMatchingCharacter(matchChar, testString, charNumber);
const found = charNumber > -1;
if (!found) {
return rankings.NO_MATCH;
}
}
const spread = charNumber - firstIndex;
return getRanking(spread);
}
/**
* Sorts items that have a rank, index, and accessorIndex
* @param {Object} a - the first item to sort
* @param {Object} b - the second item to sort
* @return {Number} -1 if a should come first, 1 if b should come first, 0 if equal
*/
function compareItems(a, b) {
return a.rank === b.rank ? 0 : a.rank > b.rank ? -1 : 1;
}
/**
* Prepares value for comparison by stringifying it, removing diacritics (if specified)
* @param {String} value - the value to clean
* @param {Object} options - {keepDiacritics: whether to remove diacritics}
* @return {String} the prepared value
*/
function prepareValueForComparison(value, _ref) {
let {
keepDiacritics
} = _ref;
// value might not actually be a string at this point (we don't get to choose)
// so part of preparing the value for comparison is ensure that it is a string
value = `${value}`; // toString
if (!keepDiacritics) {
value = removeAccents(value);
}
return value;
}
/**
* Gets value for key in item at arbitrarily nested keypath
* @param {Object} item - the item
* @param {Object|Function} key - the potentially nested keypath or property callback
* @return {Array} - an array containing the value(s) at the nested keypath
*/
function getItemValues(item, accessor) {
let accessorFn = accessor;
if (typeof accessor === 'object') {
accessorFn = accessor.accessor;
}
const value = accessorFn(item);
// because `value` can also be undefined
if (value == null) {
return [];
}
if (Array.isArray(value)) {
return value;
}
return [String(value)];
}
/**
* Gets all the values for the given keys in the given item and returns an array of those values
* @param item - the item from which the values will be retrieved
* @param keys - the keys to use to retrieve the values
* @return objects with {itemValue, attributes}
*/
function getAllValuesToRank(item, accessors) {
const allValues = [];
for (let j = 0, J = accessors.length; j < J; j++) {
const accessor = accessors[j];
const attributes = getAccessorAttributes(accessor);
const itemValues = getItemValues(item, accessor);
for (let i = 0, I = itemValues.length; i < I; i++) {
allValues.push({
itemValue: itemValues[i],
attributes
});
}
}
return allValues;
}
const defaultKeyAttributes = {
maxRanking: Infinity,
minRanking: -Infinity
};
/**
* Gets all the attributes for the given accessor
* @param accessor - the accessor from which the attributes will be retrieved
* @return object containing the accessor's attributes
*/
function getAccessorAttributes(accessor) {
if (typeof accessor === 'function') {
return defaultKeyAttributes;
}
return {
...defaultKeyAttributes,
...accessor
};
}
export { compareItems, rankItem, rankings };
//# sourceMappingURL=index.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
export declare function removeAccents(str: string): string;

View File

@@ -0,0 +1,423 @@
/**
* match-sorter-utils
*
* Copyright (c) TanStack
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
'use strict';
const characterMap = {
À: 'A',
Á: 'A',
Â: 'A',
Ã: 'A',
Ä: 'A',
Å: 'A',
: 'A',
: 'A',
: 'A',
: 'A',
: 'A',
Æ: 'AE',
: 'A',
: 'A',
Ȃ: 'A',
Ç: 'C',
: 'C',
È: 'E',
É: 'E',
Ê: 'E',
Ë: 'E',
: 'E',
: 'E',
: 'E',
: 'E',
: 'E',
Ȇ: 'E',
Ì: 'I',
Í: 'I',
Î: 'I',
Ï: 'I',
: 'I',
Ȋ: 'I',
Ð: 'D',
Ñ: 'N',
Ò: 'O',
Ó: 'O',
Ô: 'O',
Õ: 'O',
Ö: 'O',
Ø: 'O',
: 'O',
: 'O',
: 'O',
Ȏ: 'O',
Ù: 'U',
Ú: 'U',
Û: 'U',
Ü: 'U',
Ý: 'Y',
à: 'a',
á: 'a',
â: 'a',
ã: 'a',
ä: 'a',
å: 'a',
: 'a',
: 'a',
: 'a',
: 'a',
: 'a',
æ: 'ae',
: 'a',
: 'a',
ȃ: 'a',
ç: 'c',
: 'c',
è: 'e',
é: 'e',
ê: 'e',
ë: 'e',
ế: 'e',
: 'e',
: 'e',
: 'e',
: 'e',
ȇ: 'e',
ì: 'i',
í: 'i',
î: 'i',
ï: 'i',
: 'i',
ȋ: 'i',
ð: 'd',
ñ: 'n',
ò: 'o',
ó: 'o',
ô: 'o',
õ: 'o',
ö: 'o',
ø: 'o',
: 'o',
: 'o',
: 'o',
ȏ: 'o',
ù: 'u',
ú: 'u',
û: 'u',
ü: 'u',
ý: 'y',
ÿ: 'y',
Ā: 'A',
ā: 'a',
Ă: 'A',
ă: 'a',
Ą: 'A',
ą: 'a',
Ć: 'C',
ć: 'c',
Ĉ: 'C',
ĉ: 'c',
Ċ: 'C',
ċ: 'c',
Č: 'C',
č: 'c',
C̆: 'C',
c̆: 'c',
Ď: 'D',
ď: 'd',
Đ: 'D',
đ: 'd',
Ē: 'E',
ē: 'e',
Ĕ: 'E',
ĕ: 'e',
Ė: 'E',
ė: 'e',
Ę: 'E',
ę: 'e',
Ě: 'E',
ě: 'e',
Ĝ: 'G',
Ǵ: 'G',
ĝ: 'g',
ǵ: 'g',
Ğ: 'G',
ğ: 'g',
Ġ: 'G',
ġ: 'g',
Ģ: 'G',
ģ: 'g',
Ĥ: 'H',
ĥ: 'h',
Ħ: 'H',
ħ: 'h',
: 'H',
: 'h',
Ĩ: 'I',
ĩ: 'i',
Ī: 'I',
ī: 'i',
Ĭ: 'I',
ĭ: 'i',
Į: 'I',
į: 'i',
İ: 'I',
ı: 'i',
IJ: 'IJ',
ij: 'ij',
Ĵ: 'J',
ĵ: 'j',
Ķ: 'K',
ķ: 'k',
: 'K',
: 'k',
K̆: 'K',
k̆: 'k',
Ĺ: 'L',
ĺ: 'l',
Ļ: 'L',
ļ: 'l',
Ľ: 'L',
ľ: 'l',
Ŀ: 'L',
ŀ: 'l',
Ł: 'l',
ł: 'l',
: 'M',
ḿ: 'm',
M̆: 'M',
m̆: 'm',
Ń: 'N',
ń: 'n',
Ņ: 'N',
ņ: 'n',
Ň: 'N',
ň: 'n',
ʼn: 'n',
N̆: 'N',
n̆: 'n',
Ō: 'O',
ō: 'o',
Ŏ: 'O',
ŏ: 'o',
Ő: 'O',
ő: 'o',
Œ: 'OE',
œ: 'oe',
P̆: 'P',
p̆: 'p',
Ŕ: 'R',
ŕ: 'r',
Ŗ: 'R',
ŗ: 'r',
Ř: 'R',
ř: 'r',
R̆: 'R',
r̆: 'r',
Ȓ: 'R',
ȓ: 'r',
Ś: 'S',
ś: 's',
Ŝ: 'S',
ŝ: 's',
Ş: 'S',
Ș: 'S',
ș: 's',
ş: 's',
Š: 'S',
š: 's',
Ţ: 'T',
ţ: 't',
ț: 't',
Ț: 'T',
Ť: 'T',
ť: 't',
Ŧ: 'T',
ŧ: 't',
T̆: 'T',
t̆: 't',
Ũ: 'U',
ũ: 'u',
Ū: 'U',
ū: 'u',
Ŭ: 'U',
ŭ: 'u',
Ů: 'U',
ů: 'u',
Ű: 'U',
ű: 'u',
Ų: 'U',
ų: 'u',
Ȗ: 'U',
ȗ: 'u',
V̆: 'V',
v̆: 'v',
Ŵ: 'W',
ŵ: 'w',
: 'W',
: 'w',
X̆: 'X',
x̆: 'x',
Ŷ: 'Y',
ŷ: 'y',
Ÿ: 'Y',
Y̆: 'Y',
y̆: 'y',
Ź: 'Z',
ź: 'z',
Ż: 'Z',
ż: 'z',
Ž: 'Z',
ž: 'z',
ſ: 's',
ƒ: 'f',
Ơ: 'O',
ơ: 'o',
Ư: 'U',
ư: 'u',
Ǎ: 'A',
ǎ: 'a',
Ǐ: 'I',
ǐ: 'i',
Ǒ: 'O',
ǒ: 'o',
Ǔ: 'U',
ǔ: 'u',
Ǖ: 'U',
ǖ: 'u',
Ǘ: 'U',
ǘ: 'u',
Ǚ: 'U',
ǚ: 'u',
Ǜ: 'U',
ǜ: 'u',
: 'U',
: 'u',
: 'U',
: 'u',
Ǻ: 'A',
ǻ: 'a',
Ǽ: 'AE',
ǽ: 'ae',
Ǿ: 'O',
ǿ: 'o',
Þ: 'TH',
þ: 'th',
: 'P',
: 'p',
: 'S',
: 's',
X́: 'X',
x́: 'x',
Ѓ: 'Г',
ѓ: 'г',
Ќ: 'К',
ќ: 'к',
A̋: 'A',
a̋: 'a',
E̋: 'E',
e̋: 'e',
I̋: 'I',
i̋: 'i',
Ǹ: 'N',
ǹ: 'n',
: 'O',
: 'o',
: 'O',
: 'o',
: 'U',
: 'u',
: 'W',
: 'w',
: 'Y',
: 'y',
Ȁ: 'A',
ȁ: 'a',
Ȅ: 'E',
ȅ: 'e',
Ȉ: 'I',
ȉ: 'i',
Ȍ: 'O',
ȍ: 'o',
Ȑ: 'R',
ȑ: 'r',
Ȕ: 'U',
ȕ: 'u',
B̌: 'B',
b̌: 'b',
Č̣: 'C',
č̣: 'c',
Ê̌: 'E',
ê̌: 'e',
F̌: 'F',
f̌: 'f',
Ǧ: 'G',
ǧ: 'g',
Ȟ: 'H',
ȟ: 'h',
J̌: 'J',
ǰ: 'j',
Ǩ: 'K',
ǩ: 'k',
M̌: 'M',
m̌: 'm',
P̌: 'P',
p̌: 'p',
Q̌: 'Q',
q̌: 'q',
Ř̩: 'R',
ř̩: 'r',
: 'S',
: 's',
V̌: 'V',
v̌: 'v',
W̌: 'W',
w̌: 'w',
X̌: 'X',
x̌: 'x',
Y̌: 'Y',
y̌: 'y',
A̧: 'A',
a̧: 'a',
B̧: 'B',
b̧: 'b',
: 'D',
: 'd',
Ȩ: 'E',
ȩ: 'e',
Ɛ̧: 'E',
ɛ̧: 'e',
: 'H',
: 'h',
I̧: 'I',
i̧: 'i',
Ɨ̧: 'I',
ɨ̧: 'i',
M̧: 'M',
m̧: 'm',
O̧: 'O',
o̧: 'o',
Q̧: 'Q',
q̧: 'q',
U̧: 'U',
u̧: 'u',
X̧: 'X',
x̧: 'x',
Z̧: 'Z',
z̧: 'z'
};
const chars = Object.keys(characterMap).join('|');
const allAccents = new RegExp(chars, 'g');
function removeAccents(str) {
return str.replace(allAccents, match => {
return characterMap[match];
});
}
exports.removeAccents = removeAccents;
//# sourceMappingURL=remove-accents.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,720 @@
/**
* match-sorter-utils
*
* Copyright (c) TanStack
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.MatchSorterUtils = {}));
})(this, (function (exports) { 'use strict';
const characterMap = {
À: 'A',
Á: 'A',
Â: 'A',
Ã: 'A',
Ä: 'A',
Å: 'A',
: 'A',
: 'A',
: 'A',
: 'A',
: 'A',
Æ: 'AE',
: 'A',
: 'A',
Ȃ: 'A',
Ç: 'C',
: 'C',
È: 'E',
É: 'E',
Ê: 'E',
Ë: 'E',
: 'E',
: 'E',
: 'E',
: 'E',
: 'E',
Ȇ: 'E',
Ì: 'I',
Í: 'I',
Î: 'I',
Ï: 'I',
: 'I',
Ȋ: 'I',
Ð: 'D',
Ñ: 'N',
Ò: 'O',
Ó: 'O',
Ô: 'O',
Õ: 'O',
Ö: 'O',
Ø: 'O',
: 'O',
: 'O',
: 'O',
Ȏ: 'O',
Ù: 'U',
Ú: 'U',
Û: 'U',
Ü: 'U',
Ý: 'Y',
à: 'a',
á: 'a',
â: 'a',
ã: 'a',
ä: 'a',
å: 'a',
: 'a',
: 'a',
: 'a',
: 'a',
: 'a',
æ: 'ae',
: 'a',
: 'a',
ȃ: 'a',
ç: 'c',
: 'c',
è: 'e',
é: 'e',
ê: 'e',
ë: 'e',
ế: 'e',
: 'e',
: 'e',
: 'e',
: 'e',
ȇ: 'e',
ì: 'i',
í: 'i',
î: 'i',
ï: 'i',
: 'i',
ȋ: 'i',
ð: 'd',
ñ: 'n',
ò: 'o',
ó: 'o',
ô: 'o',
õ: 'o',
ö: 'o',
ø: 'o',
: 'o',
: 'o',
: 'o',
ȏ: 'o',
ù: 'u',
ú: 'u',
û: 'u',
ü: 'u',
ý: 'y',
ÿ: 'y',
Ā: 'A',
ā: 'a',
Ă: 'A',
ă: 'a',
Ą: 'A',
ą: 'a',
Ć: 'C',
ć: 'c',
Ĉ: 'C',
ĉ: 'c',
Ċ: 'C',
ċ: 'c',
Č: 'C',
č: 'c',
C̆: 'C',
c̆: 'c',
Ď: 'D',
ď: 'd',
Đ: 'D',
đ: 'd',
Ē: 'E',
ē: 'e',
Ĕ: 'E',
ĕ: 'e',
Ė: 'E',
ė: 'e',
Ę: 'E',
ę: 'e',
Ě: 'E',
ě: 'e',
Ĝ: 'G',
Ǵ: 'G',
ĝ: 'g',
ǵ: 'g',
Ğ: 'G',
ğ: 'g',
Ġ: 'G',
ġ: 'g',
Ģ: 'G',
ģ: 'g',
Ĥ: 'H',
ĥ: 'h',
Ħ: 'H',
ħ: 'h',
: 'H',
: 'h',
Ĩ: 'I',
ĩ: 'i',
Ī: 'I',
ī: 'i',
Ĭ: 'I',
ĭ: 'i',
Į: 'I',
į: 'i',
İ: 'I',
ı: 'i',
IJ: 'IJ',
ij: 'ij',
Ĵ: 'J',
ĵ: 'j',
Ķ: 'K',
ķ: 'k',
: 'K',
: 'k',
K̆: 'K',
k̆: 'k',
Ĺ: 'L',
ĺ: 'l',
Ļ: 'L',
ļ: 'l',
Ľ: 'L',
ľ: 'l',
Ŀ: 'L',
ŀ: 'l',
Ł: 'l',
ł: 'l',
: 'M',
ḿ: 'm',
M̆: 'M',
m̆: 'm',
Ń: 'N',
ń: 'n',
Ņ: 'N',
ņ: 'n',
Ň: 'N',
ň: 'n',
ʼn: 'n',
N̆: 'N',
n̆: 'n',
Ō: 'O',
ō: 'o',
Ŏ: 'O',
ŏ: 'o',
Ő: 'O',
ő: 'o',
Œ: 'OE',
œ: 'oe',
P̆: 'P',
p̆: 'p',
Ŕ: 'R',
ŕ: 'r',
Ŗ: 'R',
ŗ: 'r',
Ř: 'R',
ř: 'r',
R̆: 'R',
r̆: 'r',
Ȓ: 'R',
ȓ: 'r',
Ś: 'S',
ś: 's',
Ŝ: 'S',
ŝ: 's',
Ş: 'S',
Ș: 'S',
ș: 's',
ş: 's',
Š: 'S',
š: 's',
Ţ: 'T',
ţ: 't',
ț: 't',
Ț: 'T',
Ť: 'T',
ť: 't',
Ŧ: 'T',
ŧ: 't',
T̆: 'T',
t̆: 't',
Ũ: 'U',
ũ: 'u',
Ū: 'U',
ū: 'u',
Ŭ: 'U',
ŭ: 'u',
Ů: 'U',
ů: 'u',
Ű: 'U',
ű: 'u',
Ų: 'U',
ų: 'u',
Ȗ: 'U',
ȗ: 'u',
V̆: 'V',
v̆: 'v',
Ŵ: 'W',
ŵ: 'w',
: 'W',
: 'w',
X̆: 'X',
x̆: 'x',
Ŷ: 'Y',
ŷ: 'y',
Ÿ: 'Y',
Y̆: 'Y',
y̆: 'y',
Ź: 'Z',
ź: 'z',
Ż: 'Z',
ż: 'z',
Ž: 'Z',
ž: 'z',
ſ: 's',
ƒ: 'f',
Ơ: 'O',
ơ: 'o',
Ư: 'U',
ư: 'u',
Ǎ: 'A',
ǎ: 'a',
Ǐ: 'I',
ǐ: 'i',
Ǒ: 'O',
ǒ: 'o',
Ǔ: 'U',
ǔ: 'u',
Ǖ: 'U',
ǖ: 'u',
Ǘ: 'U',
ǘ: 'u',
Ǚ: 'U',
ǚ: 'u',
Ǜ: 'U',
ǜ: 'u',
: 'U',
: 'u',
: 'U',
: 'u',
Ǻ: 'A',
ǻ: 'a',
Ǽ: 'AE',
ǽ: 'ae',
Ǿ: 'O',
ǿ: 'o',
Þ: 'TH',
þ: 'th',
: 'P',
: 'p',
: 'S',
: 's',
X́: 'X',
x́: 'x',
Ѓ: 'Г',
ѓ: 'г',
Ќ: 'К',
ќ: 'к',
A̋: 'A',
a̋: 'a',
E̋: 'E',
e̋: 'e',
I̋: 'I',
i̋: 'i',
Ǹ: 'N',
ǹ: 'n',
: 'O',
: 'o',
: 'O',
: 'o',
: 'U',
: 'u',
: 'W',
: 'w',
: 'Y',
: 'y',
Ȁ: 'A',
ȁ: 'a',
Ȅ: 'E',
ȅ: 'e',
Ȉ: 'I',
ȉ: 'i',
Ȍ: 'O',
ȍ: 'o',
Ȑ: 'R',
ȑ: 'r',
Ȕ: 'U',
ȕ: 'u',
B̌: 'B',
b̌: 'b',
Č̣: 'C',
č̣: 'c',
Ê̌: 'E',
ê̌: 'e',
F̌: 'F',
f̌: 'f',
Ǧ: 'G',
ǧ: 'g',
Ȟ: 'H',
ȟ: 'h',
J̌: 'J',
ǰ: 'j',
Ǩ: 'K',
ǩ: 'k',
M̌: 'M',
m̌: 'm',
P̌: 'P',
p̌: 'p',
Q̌: 'Q',
q̌: 'q',
Ř̩: 'R',
ř̩: 'r',
: 'S',
: 's',
V̌: 'V',
v̌: 'v',
W̌: 'W',
w̌: 'w',
X̌: 'X',
x̌: 'x',
Y̌: 'Y',
y̌: 'y',
A̧: 'A',
a̧: 'a',
B̧: 'B',
b̧: 'b',
: 'D',
: 'd',
Ȩ: 'E',
ȩ: 'e',
Ɛ̧: 'E',
ɛ̧: 'e',
: 'H',
: 'h',
I̧: 'I',
i̧: 'i',
Ɨ̧: 'I',
ɨ̧: 'i',
M̧: 'M',
m̧: 'm',
O̧: 'O',
o̧: 'o',
Q̧: 'Q',
q̧: 'q',
U̧: 'U',
u̧: 'u',
X̧: 'X',
x̧: 'x',
Z̧: 'Z',
z̧: 'z'
};
const chars = Object.keys(characterMap).join('|');
const allAccents = new RegExp(chars, 'g');
function removeAccents(str) {
return str.replace(allAccents, match => {
return characterMap[match];
});
}
/**
* @name match-sorter
* @license MIT license.
* @copyright (c) 2099 Kent C. Dodds
* @author Kent C. Dodds <me@kentcdodds.com> (https://kentcdodds.com)
*/
const rankings = {
CASE_SENSITIVE_EQUAL: 7,
EQUAL: 6,
STARTS_WITH: 5,
WORD_STARTS_WITH: 4,
CONTAINS: 3,
ACRONYM: 2,
MATCHES: 1,
NO_MATCH: 0
};
/**
* Gets the highest ranking for value for the given item based on its values for the given keys
* @param {*} item - the item to rank
* @param {String} value - the value to rank against
* @param {Object} options - options to control the ranking
* @return {{rank: Number, accessorIndex: Number, accessorThreshold: Number}} - the highest ranking
*/
function rankItem(item, value, options) {
var _options$threshold;
options = options || {};
options.threshold = (_options$threshold = options.threshold) != null ? _options$threshold : rankings.MATCHES;
if (!options.accessors) {
// if keys is not specified, then we assume the item given is ready to be matched
const rank = getMatchRanking(item, value, options);
return {
// ends up being duplicate of 'item' in matches but consistent
rankedValue: item,
rank,
accessorIndex: -1,
accessorThreshold: options.threshold,
passed: rank >= options.threshold
};
}
const valuesToRank = getAllValuesToRank(item, options.accessors);
const rankingInfo = {
rankedValue: item,
rank: rankings.NO_MATCH,
accessorIndex: -1,
accessorThreshold: options.threshold,
passed: false
};
for (let i = 0; i < valuesToRank.length; i++) {
const rankValue = valuesToRank[i];
let newRank = getMatchRanking(rankValue.itemValue, value, options);
const {
minRanking,
maxRanking,
threshold = options.threshold
} = rankValue.attributes;
if (newRank < minRanking && newRank >= rankings.MATCHES) {
newRank = minRanking;
} else if (newRank > maxRanking) {
newRank = maxRanking;
}
newRank = Math.min(newRank, maxRanking);
if (newRank >= threshold && newRank > rankingInfo.rank) {
rankingInfo.rank = newRank;
rankingInfo.passed = true;
rankingInfo.accessorIndex = i;
rankingInfo.accessorThreshold = threshold;
rankingInfo.rankedValue = rankValue.itemValue;
}
}
return rankingInfo;
}
/**
* Gives a rankings score based on how well the two strings match.
* @param {String} testString - the string to test against
* @param {String} stringToRank - the string to rank
* @param {Object} options - options for the match (like keepDiacritics for comparison)
* @returns {Number} the ranking for how well stringToRank matches testString
*/
function getMatchRanking(testString, stringToRank, options) {
testString = prepareValueForComparison(testString, options);
stringToRank = prepareValueForComparison(stringToRank, options);
// too long
if (stringToRank.length > testString.length) {
return rankings.NO_MATCH;
}
// case sensitive equals
if (testString === stringToRank) {
return rankings.CASE_SENSITIVE_EQUAL;
}
// Lower casing before further comparison
testString = testString.toLowerCase();
stringToRank = stringToRank.toLowerCase();
// case insensitive equals
if (testString === stringToRank) {
return rankings.EQUAL;
}
// starts with
if (testString.startsWith(stringToRank)) {
return rankings.STARTS_WITH;
}
// word starts with
if (testString.includes(` ${stringToRank}`)) {
return rankings.WORD_STARTS_WITH;
}
// contains
if (testString.includes(stringToRank)) {
return rankings.CONTAINS;
} else if (stringToRank.length === 1) {
// If the only character in the given stringToRank
// isn't even contained in the testString, then
// it's definitely not a match.
return rankings.NO_MATCH;
}
// acronym
if (getAcronym(testString).includes(stringToRank)) {
return rankings.ACRONYM;
}
// will return a number between rankings.MATCHES and
// rankings.MATCHES + 1 depending on how close of a match it is.
return getClosenessRanking(testString, stringToRank);
}
/**
* Generates an acronym for a string.
*
* @param {String} string the string for which to produce the acronym
* @returns {String} the acronym
*/
function getAcronym(string) {
let acronym = '';
const wordsInString = string.split(' ');
wordsInString.forEach(wordInString => {
const splitByHyphenWords = wordInString.split('-');
splitByHyphenWords.forEach(splitByHyphenWord => {
acronym += splitByHyphenWord.substr(0, 1);
});
});
return acronym;
}
/**
* Returns a score based on how spread apart the
* characters from the stringToRank are within the testString.
* A number close to rankings.MATCHES represents a loose match. A number close
* to rankings.MATCHES + 1 represents a tighter match.
* @param {String} testString - the string to test against
* @param {String} stringToRank - the string to rank
* @returns {Number} the number between rankings.MATCHES and
* rankings.MATCHES + 1 for how well stringToRank matches testString
*/
function getClosenessRanking(testString, stringToRank) {
let matchingInOrderCharCount = 0;
let charNumber = 0;
function findMatchingCharacter(matchChar, string, index) {
for (let j = index, J = string.length; j < J; j++) {
const stringChar = string[j];
if (stringChar === matchChar) {
matchingInOrderCharCount += 1;
return j + 1;
}
}
return -1;
}
function getRanking(spread) {
const spreadPercentage = 1 / spread;
const inOrderPercentage = matchingInOrderCharCount / stringToRank.length;
const ranking = rankings.MATCHES + inOrderPercentage * spreadPercentage;
return ranking;
}
const firstIndex = findMatchingCharacter(stringToRank[0], testString, 0);
if (firstIndex < 0) {
return rankings.NO_MATCH;
}
charNumber = firstIndex;
for (let i = 1, I = stringToRank.length; i < I; i++) {
const matchChar = stringToRank[i];
charNumber = findMatchingCharacter(matchChar, testString, charNumber);
const found = charNumber > -1;
if (!found) {
return rankings.NO_MATCH;
}
}
const spread = charNumber - firstIndex;
return getRanking(spread);
}
/**
* Sorts items that have a rank, index, and accessorIndex
* @param {Object} a - the first item to sort
* @param {Object} b - the second item to sort
* @return {Number} -1 if a should come first, 1 if b should come first, 0 if equal
*/
function compareItems(a, b) {
return a.rank === b.rank ? 0 : a.rank > b.rank ? -1 : 1;
}
/**
* Prepares value for comparison by stringifying it, removing diacritics (if specified)
* @param {String} value - the value to clean
* @param {Object} options - {keepDiacritics: whether to remove diacritics}
* @return {String} the prepared value
*/
function prepareValueForComparison(value, _ref) {
let {
keepDiacritics
} = _ref;
// value might not actually be a string at this point (we don't get to choose)
// so part of preparing the value for comparison is ensure that it is a string
value = `${value}`; // toString
if (!keepDiacritics) {
value = removeAccents(value);
}
return value;
}
/**
* Gets value for key in item at arbitrarily nested keypath
* @param {Object} item - the item
* @param {Object|Function} key - the potentially nested keypath or property callback
* @return {Array} - an array containing the value(s) at the nested keypath
*/
function getItemValues(item, accessor) {
let accessorFn = accessor;
if (typeof accessor === 'object') {
accessorFn = accessor.accessor;
}
const value = accessorFn(item);
// because `value` can also be undefined
if (value == null) {
return [];
}
if (Array.isArray(value)) {
return value;
}
return [String(value)];
}
/**
* Gets all the values for the given keys in the given item and returns an array of those values
* @param item - the item from which the values will be retrieved
* @param keys - the keys to use to retrieve the values
* @return objects with {itemValue, attributes}
*/
function getAllValuesToRank(item, accessors) {
const allValues = [];
for (let j = 0, J = accessors.length; j < J; j++) {
const accessor = accessors[j];
const attributes = getAccessorAttributes(accessor);
const itemValues = getItemValues(item, accessor);
for (let i = 0, I = itemValues.length; i < I; i++) {
allValues.push({
itemValue: itemValues[i],
attributes
});
}
}
return allValues;
}
const defaultKeyAttributes = {
maxRanking: Infinity,
minRanking: -Infinity
};
/**
* Gets all the attributes for the given accessor
* @param accessor - the accessor from which the attributes will be retrieved
* @return object containing the accessor's attributes
*/
function getAccessorAttributes(accessor) {
if (typeof accessor === 'function') {
return defaultKeyAttributes;
}
return {
...defaultKeyAttributes,
...accessor
};
}
exports.compareItems = compareItems;
exports.rankItem = rankItem;
exports.rankings = rankings;
}));
//# sourceMappingURL=index.development.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,19 @@
/**
* match-sorter-utils
*
* Copyright (c) TanStack
*
* This source code is licensed under the MIT license found in the
* LICENSE.md file in the root directory of this source tree.
*
* @license MIT
*/
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).MatchSorterUtils={})}(this,(function(e){"use strict";const n={"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","Ấ":"A","Ắ":"A","Ẳ":"A","Ẵ":"A","Ặ":"A","Æ":"AE","Ầ":"A","Ằ":"A","Ȃ":"A","Ç":"C","Ḉ":"C","È":"E","É":"E","Ê":"E","Ë":"E","Ế":"E","Ḗ":"E","Ề":"E","Ḕ":"E","Ḝ":"E","Ȇ":"E","Ì":"I","Í":"I","Î":"I","Ï":"I","Ḯ":"I","Ȋ":"I","Ð":"D","Ñ":"N","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","Ố":"O","Ṍ":"O","Ṓ":"O","Ȏ":"O","Ù":"U","Ú":"U","Û":"U","Ü":"U","Ý":"Y","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","ấ":"a","ắ":"a","ẳ":"a","ẵ":"a","ặ":"a","æ":"ae","ầ":"a","ằ":"a","ȃ":"a","ç":"c","ḉ":"c","è":"e","é":"e","ê":"e","ë":"e","ế":"e","ḗ":"e","ề":"e","ḕ":"e","ḝ":"e","ȇ":"e","ì":"i","í":"i","î":"i","ï":"i","ḯ":"i","ȋ":"i","ð":"d","ñ":"n","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","ố":"o","ṍ":"o","ṓ":"o","ȏ":"o","ù":"u","ú":"u","û":"u","ü":"u","ý":"y","ÿ":"y","Ā":"A","ā":"a","Ă":"A","ă":"a","Ą":"A","ą":"a","Ć":"C","ć":"c","Ĉ":"C","ĉ":"c","Ċ":"C","ċ":"c","Č":"C","č":"c","C̆":"C","c̆":"c","Ď":"D","ď":"d","Đ":"D","đ":"d","Ē":"E","ē":"e","Ĕ":"E","ĕ":"e","Ė":"E","ė":"e","Ę":"E","ę":"e","Ě":"E","ě":"e","Ĝ":"G","Ǵ":"G","ĝ":"g","ǵ":"g","Ğ":"G","ğ":"g","Ġ":"G","ġ":"g","Ģ":"G","ģ":"g","Ĥ":"H","ĥ":"h","Ħ":"H","ħ":"h","Ḫ":"H","ḫ":"h","Ĩ":"I","ĩ":"i","Ī":"I","ī":"i","Ĭ":"I","ĭ":"i","Į":"I","į":"i","İ":"I","ı":"i","IJ":"IJ","ij":"ij","Ĵ":"J","ĵ":"j","Ķ":"K","ķ":"k","Ḱ":"K","ḱ":"k","K̆":"K","k̆":"k","Ĺ":"L","ĺ":"l","Ļ":"L","ļ":"l","Ľ":"L","ľ":"l","Ŀ":"L","ŀ":"l","Ł":"l","ł":"l","Ḿ":"M","ḿ":"m","M̆":"M","m̆":"m","Ń":"N","ń":"n","Ņ":"N","ņ":"n","Ň":"N","ň":"n","ʼn":"n","N̆":"N","n̆":"n","Ō":"O","ō":"o","Ŏ":"O","ŏ":"o","Ő":"O","ő":"o","Œ":"OE","œ":"oe","P̆":"P","p̆":"p","Ŕ":"R","ŕ":"r","Ŗ":"R","ŗ":"r","Ř":"R","ř":"r","R̆":"R","r̆":"r","Ȓ":"R","ȓ":"r","Ś":"S","ś":"s","Ŝ":"S","ŝ":"s","Ş":"S","Ș":"S","ș":"s","ş":"s","Š":"S","š":"s","Ţ":"T","ţ":"t","ț":"t","Ț":"T","Ť":"T","ť":"t","Ŧ":"T","ŧ":"t","T̆":"T","t̆":"t","Ũ":"U","ũ":"u","Ū":"U","ū":"u","Ŭ":"U","ŭ":"u","Ů":"U","ů":"u","Ű":"U","ű":"u","Ų":"U","ų":"u","Ȗ":"U","ȗ":"u","V̆":"V","v̆":"v","Ŵ":"W","ŵ":"w","Ẃ":"W","ẃ":"w","X̆":"X","x̆":"x","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Y̆":"Y","y̆":"y","Ź":"Z","ź":"z","Ż":"Z","ż":"z","Ž":"Z","ž":"z","ſ":"s","ƒ":"f","Ơ":"O","ơ":"o","Ư":"U","ư":"u","Ǎ":"A","ǎ":"a","Ǐ":"I","ǐ":"i","Ǒ":"O","ǒ":"o","Ǔ":"U","ǔ":"u","Ǖ":"U","ǖ":"u","Ǘ":"U","ǘ":"u","Ǚ":"U","ǚ":"u","Ǜ":"U","ǜ":"u","Ứ":"U","ứ":"u","Ṹ":"U","ṹ":"u","Ǻ":"A","ǻ":"a","Ǽ":"AE","ǽ":"ae","Ǿ":"O","ǿ":"o","Þ":"TH","þ":"th","Ṕ":"P","ṕ":"p","Ṥ":"S","ṥ":"s","X́":"X","x́":"x","Ѓ":"Г","ѓ":"г","Ќ":"К","ќ":"к","A̋":"A","a̋":"a","E̋":"E","e̋":"e","I̋":"I","i̋":"i","Ǹ":"N","ǹ":"n","Ồ":"O","ồ":"o","Ṑ":"O","ṑ":"o","Ừ":"U","ừ":"u","Ẁ":"W","ẁ":"w","Ỳ":"Y","ỳ":"y","Ȁ":"A","ȁ":"a","Ȅ":"E","ȅ":"e","Ȉ":"I","ȉ":"i","Ȍ":"O","ȍ":"o","Ȑ":"R","ȑ":"r","Ȕ":"U","ȕ":"u","B̌":"B","b̌":"b","Č̣":"C","č̣":"c","Ê̌":"E","ê̌":"e","F̌":"F","f̌":"f","Ǧ":"G","ǧ":"g","Ȟ":"H","ȟ":"h","J̌":"J","ǰ":"j","Ǩ":"K","ǩ":"k","M̌":"M","m̌":"m","P̌":"P","p̌":"p","Q̌":"Q","q̌":"q","Ř̩":"R","ř̩":"r","Ṧ":"S","ṧ":"s","V̌":"V","v̌":"v","W̌":"W","w̌":"w","X̌":"X","x̌":"x","Y̌":"Y","y̌":"y","A̧":"A","a̧":"a","B̧":"B","b̧":"b","Ḑ":"D","ḑ":"d","Ȩ":"E","ȩ":"e","Ɛ̧":"E","ɛ̧":"e","Ḩ":"H","ḩ":"h","I̧":"I","i̧":"i","Ɨ̧":"I","ɨ̧":"i","M̧":"M","m̧":"m","O̧":"O","o̧":"o","Q̧":"Q","q̧":"q","U̧":"U","u̧":"u","X̧":"X","x̧":"x","Z̧":"Z","z̧":"z"},t=Object.keys(n).join("|"),r=new RegExp(t,"g");
/**
* @name match-sorter
* @license MIT license.
* @copyright (c) 2099 Kent C. Dodds
* @author Kent C. Dodds <me@kentcdodds.com> (https://kentcdodds.com)
*/
const o={CASE_SENSITIVE_EQUAL:7,EQUAL:6,STARTS_WITH:5,WORD_STARTS_WITH:4,CONTAINS:3,ACRONYM:2,MATCHES:1,NO_MATCH:0};function s(e,n,t){return e=a(e,t),(n=a(n,t)).length>e.length?o.NO_MATCH:e===n?o.CASE_SENSITIVE_EQUAL:(e=e.toLowerCase())===(n=n.toLowerCase())?o.EQUAL:e.startsWith(n)?o.STARTS_WITH:e.includes(` ${n}`)?o.WORD_STARTS_WITH:e.includes(n)?o.CONTAINS:1===n.length?o.NO_MATCH:function(e){let n="";return e.split(" ").forEach((e=>{e.split("-").forEach((e=>{n+=e.substr(0,1)}))})),n}(e).includes(n)?o.ACRONYM:function(e,n){let t=0,r=0;function s(e,n,r){for(let o=r,s=n.length;o<s;o++){if(n[o]===e)return t+=1,o+1}return-1}function a(e){const r=1/e,s=t/n.length;return o.MATCHES+s*r}const i=s(n[0],e,0);if(i<0)return o.NO_MATCH;r=i;for(let t=1,a=n.length;t<a;t++){r=s(n[t],e,r);if(!(r>-1))return o.NO_MATCH}return a(r-i)}(e,n)}function a(e,t){let{keepDiacritics:o}=t;return e=`${e}`,o||(e=e.replace(r,(e=>n[e]))),e}function i(e,n){let t=n;"object"==typeof n&&(t=n.accessor);const r=t(e);return null==r?[]:Array.isArray(r)?r:[String(r)]}const u={maxRanking:1/0,minRanking:-1/0};function c(e){return"function"==typeof e?u:{...u,...e}}e.compareItems=function(e,n){return e.rank===n.rank?0:e.rank>n.rank?-1:1},e.rankItem=function(e,n,t){var r;if((t=t||{}).threshold=null!=(r=t.threshold)?r:o.MATCHES,!t.accessors){const r=s(e,n,t);return{rankedValue:e,rank:r,accessorIndex:-1,accessorThreshold:t.threshold,passed:r>=t.threshold}}const a=function(e,n){const t=[];for(let r=0,o=n.length;r<o;r++){const o=n[r],s=c(o),a=i(e,o);for(let e=0,n=a.length;e<n;e++)t.push({itemValue:a[e],attributes:s})}return t}(e,t.accessors),u={rankedValue:e,rank:o.NO_MATCH,accessorIndex:-1,accessorThreshold:t.threshold,passed:!1};for(let e=0;e<a.length;e++){const r=a[e];let i=s(r.itemValue,n,t);const{minRanking:c,maxRanking:l,threshold:A=t.threshold}=r.attributes;i<c&&i>=o.MATCHES?i=c:i>l&&(i=l),i=Math.min(i,l),i>=A&&i>u.rank&&(u.rank=i,u.passed=!0,u.accessorIndex=e,u.accessorThreshold=A,u.rankedValue=r.itemValue)}return u},e.rankings=o}));
//# sourceMappingURL=index.production.js.map

File diff suppressed because one or more lines are too long