string-fn
Version:
String manipulation library
1,125 lines (1,040 loc) • 29 kB
JavaScript
function between(str, left, rightRaw) {
const right = rightRaw === undefined ? left : rightRaw;
const rightIndex = str.lastIndexOf(right);
const leftIndex = str.indexOf(left);
return rightIndex === -1 ? str : str.substring(leftIndex + left.length, rightIndex).trim();
}
function type(input){
if (input === null){
return 'Null'
} else if (input === undefined){
return 'Undefined'
} else if (Number.isNaN(input)){
return 'NaN'
}
const typeResult = Object.prototype.toString.call(input).slice(8, -1);
return typeResult === 'AsyncFunction' ? 'Promise' : typeResult
}
const { isArray } = Array;
const cloneList = list => Array.prototype.slice.call(list);
function curry(fn, args = []){
return (..._args) =>
(rest => rest.length >= fn.length ? fn(...rest) : curry(fn, rest))([
...args,
..._args,
])
}
class ReduceStopper{
constructor(value){
this.value = value;
}
}
function reduceFn(
reducer, acc, list
){
if (list == null){
return acc
}
if (!isArray(list)){
throw new TypeError('reduce: list must be array or iterable')
}
let index = 0;
const len = list.length;
while (index < len){
acc = reducer(
acc, list[ index ], index, list
);
if (acc instanceof ReduceStopper){
return acc.value
}
index++;
}
return acc
}
function _indexOf(valueToFind, list){
if (!isArray(list))
throw new Error(`Cannot read property 'indexOf' of ${ list }`)
const typeOfValue = type(valueToFind);
if (![ 'Array', 'NaN', 'Object', 'RegExp' ].includes(typeOfValue))
return list.indexOf(valueToFind)
let index = -1;
let foundIndex = -1;
const { length } = list;
while (++index < length && foundIndex === -1)
if (equals(list[ index ], valueToFind))
foundIndex = index;
return foundIndex
}
function _arrayFromIterator(iter){
const list = [];
let next;
while (!(next = iter.next()).done)
list.push(next.value);
return list
}
function _compareSets(a, b){
if (a.size !== b.size)
return false
const aList = _arrayFromIterator(a.values());
const bList = _arrayFromIterator(b.values());
const filtered = aList.filter(aInstance => _indexOf(aInstance, bList) === -1);
return filtered.length === 0
}
function compareErrors(a, b){
if (a.message !== b.message) return false
if (a.toString !== b.toString) return false
return a.toString() === b.toString()
}
function parseDate(maybeDate){
if (!maybeDate.toDateString) return [ false ]
return [ true, maybeDate.getTime() ]
}
function parseRegex(maybeRegex){
if (maybeRegex.constructor !== RegExp) return [ false ]
return [ true, maybeRegex.toString() ]
}
function equals(a, b){
if (arguments.length === 1) return _b => equals(a, _b)
if (Object.is(a, b)) return true
const aType = type(a);
if (aType !== type(b)) return false
if (aType === 'Function')
return a.name === undefined ? false : a.name === b.name
if ([ 'NaN', 'Null', 'Undefined' ].includes(aType)) return true
if ([ 'BigInt', 'Number' ].includes(aType)){
if (Object.is(-0, a) !== Object.is(-0, b)) return false
return a.toString() === b.toString()
}
if ([ 'Boolean', 'String' ].includes(aType))
return a.toString() === b.toString()
if (aType === 'Array'){
const aClone = Array.from(a);
const bClone = Array.from(b);
if (aClone.toString() !== bClone.toString())
return false
let loopArrayFlag = true;
aClone.forEach((aCloneInstance, aCloneIndex) => {
if (loopArrayFlag)
if (
aCloneInstance !== bClone[ aCloneIndex ] &&
!equals(aCloneInstance, bClone[ aCloneIndex ])
)
loopArrayFlag = false;
});
return loopArrayFlag
}
const aRegex = parseRegex(a);
const bRegex = parseRegex(b);
if (aRegex[ 0 ])
return bRegex[ 0 ] ? aRegex[ 1 ] === bRegex[ 1 ] : false
else if (bRegex[ 0 ]) return false
const aDate = parseDate(a);
const bDate = parseDate(b);
if (aDate[ 0 ])
return bDate[ 0 ] ? aDate[ 1 ] === bDate[ 1 ] : false
else if (bDate[ 0 ]) return false
if (a instanceof Error){
if (!(b instanceof Error)) return false
return compareErrors(a, b)
}
if (aType === 'Set')
return _compareSets(a, b)
if (aType === 'Object'){
const aKeys = Object.keys(a);
if (aKeys.length !== Object.keys(b).length)
return false
let loopObjectFlag = true;
aKeys.forEach(aKeyInstance => {
if (loopObjectFlag){
const aValue = a[ aKeyInstance ];
const bValue = b[ aKeyInstance ];
if (aValue !== bValue && !equals(aValue, bValue))
loopObjectFlag = false;
}
});
return loopObjectFlag
}
return false
}
function filterObject(predicate, obj){
const willReturn = {};
for (const prop in obj){
if (predicate(
obj[ prop ], prop, obj
)){
willReturn[ prop ] = obj[ prop ];
}
}
return willReturn
}
function filterArray(
predicate, list, indexed = false
){
let index = 0;
const len = list.length;
const willReturn = [];
while (index < len){
const predicateResult = indexed ?
predicate(list[ index ], index) :
predicate(list[ index ]);
if (predicateResult){
willReturn.push(list[ index ]);
}
index++;
}
return willReturn
}
function filter(predicate, iterable){
if (arguments.length === 1)
return _iterable => filter(predicate, _iterable)
if (!iterable){
throw new Error('Incorrect iterable input')
}
if (isArray(iterable)) return filterArray(
predicate, iterable, false
)
return filterObject(predicate, iterable)
}
const INCORRECT_ITERABLE_INPUT = 'Incorrect iterable input';
const { keys } = Object;
function mapArray(
fn, list, isIndexed = false
){
let index = 0;
const willReturn = Array(list.length);
while (index < list.length){
willReturn[ index ] = isIndexed ? fn(list[ index ], index) : fn(list[ index ]);
index++;
}
return willReturn
}
function mapObject(fn, obj){
if (arguments.length === 1){
return _obj => mapObject(fn, _obj)
}
let index = 0;
const objKeys = keys(obj);
const len = objKeys.length;
const willReturn = {};
while (index < len){
const key = objKeys[ index ];
willReturn[ key ] = fn(
obj[ key ], key, obj
);
index++;
}
return willReturn
}
function map(fn, iterable){
if (arguments.length === 1) return _iterable => map(fn, _iterable)
if (!iterable){
throw new Error(INCORRECT_ITERABLE_INPUT)
}
if (isArray(iterable)) return mapArray(fn, iterable)
return mapObject(fn, iterable)
}
function mapIndexed(fn, iterable){
if (arguments.length === 1){
return _iterable => mapIndexed(fn, _iterable)
}
if (iterable === undefined) return []
if (isArray(iterable)) return mapArray(
fn, iterable, true
)
return mapObject(fn, iterable)
}
function mergeRight(target, newProps){
if (arguments.length === 1)
return _newProps => mergeRight(target, _newProps)
return Object.assign(
{}, target || {}, newProps || {}
)
}
function baseSlice(
array, start, end
){
let index = -1;
let { length } = array;
end = end > length ? length : end;
if (end < 0){
end += length;
}
length = start > end ? 0 : end - start >>> 0;
start >>>= 0;
const result = Array(length);
while (++index < length){
result[ index ] = array[ index + start ];
}
return result
}
function init(listOrString){
if (typeof listOrString === 'string') return listOrString.slice(0, -1)
return listOrString.length ?
baseSlice(
listOrString, 0, -1
) :
[]
}
function test(pattern, str){
if (arguments.length === 1) return _str => test(pattern, _str)
if (typeof pattern === 'string'){
throw new TypeError(`R.test requires a value of type RegExp as its first argument; received "${ pattern }"`)
}
return str.search(pattern) !== -1
}
function toLower(str){
return str.toLowerCase()
}
function _arity(n, fn){
switch (n){
case 0:
return function (){
return fn.apply(this, arguments)
}
case 1:
return function (_1){
return fn.apply(this, arguments)
}
case 2:
return function (_1, _2){
return fn.apply(this, arguments)
}
case 3:
return function (
_1, _2, _3
){
return fn.apply(this, arguments)
}
case 4:
return function (
_1, _2, _3, _4
){
return fn.apply(this, arguments)
}
case 5:
return function (
_1, _2, _3, _4, _5
){
return fn.apply(this, arguments)
}
case 6:
return function (
_1, _2, _3, _4, _5, _6
){
return fn.apply(this, arguments)
}
case 7:
return function (
_1, _2, _3, _4, _5, _6, _7
){
return fn.apply(this, arguments)
}
case 8:
return function (
_1, _2, _3, _4, _5, _6, _7, _8
){
return fn.apply(this, arguments)
}
case 9:
return function (
_1, _2, _3, _4, _5, _6, _7, _8, _9
){
return fn.apply(this, arguments)
}
default:
return function (
_1, _2, _3, _4, _5, _6, _7, _8, _9, _10
){
return fn.apply(this, arguments)
}
}
}
function _pipe(f, g){
return function (){
return g.call(this, f.apply(this, arguments))
}
}
function pipe(){
if (arguments.length === 0){
throw new Error('pipe requires at least one argument')
}
return _arity(arguments[ 0 ].length,
reduceFn(
_pipe,
arguments[ 0 ],
Array.prototype.slice.call(
arguments, 1, Infinity
)
))
}
function compose(){
if (arguments.length === 0){
throw new Error('compose requires at least one argument')
}
return pipe.apply(this, Array.prototype.slice.call(arguments, 0).reverse())
}
function replaceFn(
pattern, replacer, str
){
return str.replace(pattern, replacer)
}
const replace = curry(replaceFn);
function sort(sortFn, list){
if (arguments.length === 1) return _list => sort(sortFn, _list)
return cloneList(list).sort(sortFn)
}
function take(howMany, listOrString){
if (arguments.length === 1)
return _listOrString => take(howMany, _listOrString)
if (typeof listOrString === 'string') return listOrString.slice(0, howMany)
return baseSlice(
listOrString, 0, howMany
)
}
function clone(input){
const out = isArray(input) ? Array(input.length) : {};
if (input && input.getTime) return new Date(input.getTime())
for (const key in input){
const v = input[ key ];
out[ key ] =
typeof v === 'object' && v !== null ?
v.getTime ?
new Date(v.getTime()) :
clone(v) :
v;
}
return out
}
function mergeDeepRight(target, source){
if (arguments.length === 1){
return sourceHolder => mergeDeepRight(target, sourceHolder)
}
const willReturn = clone(target);
Object.keys(source).forEach(key => {
if (type(source[ key ]) === 'Object'){
if (type(target[ key ]) === 'Object'){
willReturn[ key ] = mergeDeepRight(target[ key ], source[ key ]);
} else {
willReturn[ key ] = source[ key ];
}
} else {
willReturn[ key ] = source[ key ];
}
});
return willReturn
}
function partialObject(fn, input){
return nextInput => fn(mergeDeepRight(nextInput, input))
}
function piped(...inputs){
const [ input, ...fnList ] = inputs;
return pipe(...fnList)(input)
}
function shuffle$1(arrayRaw){
const array = arrayRaw.concat();
let counter = array.length;
while (counter > 0){
const index = Math.floor(Math.random() * counter);
counter--;
const temp = array[ counter ];
array[ counter ] = array[ index ];
array[ index ] = temp;
}
return array
}
const NO_MATCH_FOUND = Symbol ? Symbol('NO_MATCH_FOUND') : undefined;
const getMatchingKeyValuePair = (
cases, testValue, defaultValue
) => {
let iterationValue;
for (let index = 0; index < cases.length; index++){
iterationValue = cases[ index ].test(testValue);
if (iterationValue !== NO_MATCH_FOUND){
return iterationValue
}
}
return defaultValue
};
const isEqual = (testValue, matchValue) => {
const willReturn =
typeof testValue === 'function' ?
testValue(matchValue) :
equals(testValue, matchValue);
return willReturn
};
const is = (testValue, matchResult = true) => ({
key : testValue,
test : matchValue =>
isEqual(testValue, matchValue) ? matchResult : NO_MATCH_FOUND,
});
class Switchem{
constructor(
defaultValue, cases, willMatch
){
if (cases === undefined && willMatch === undefined){
this.cases = [];
this.defaultValue = undefined;
this.willMatch = defaultValue;
} else {
this.cases = cases;
this.defaultValue = defaultValue;
this.willMatch = willMatch;
}
return this
}
default(defaultValue){
const holder = new Switchem(
defaultValue, this.cases, this.willMatch
);
return holder.match(this.willMatch)
}
is(testValue, matchResult){
return new Switchem(
this.defaultValue,
[ ...this.cases, is(testValue, matchResult) ],
this.willMatch
)
}
match(matchValue){
return getMatchingKeyValuePair(
this.cases, matchValue, this.defaultValue
)
}
}
function switcher(input){
return new Switchem(input)
}
function toDecimal(number, charsAfterDecimalPoint = 2){
return Number(parseFloat(String(number)).toFixed(charsAfterDecimalPoint))
}
function range(start, end){
if (arguments.length === 1) return _end => range(start, _end)
if (Number.isNaN(Number(start)) || Number.isNaN(Number(end))){
throw new TypeError('Both arguments to range must be numbers')
}
if (end < start) return []
const len = end - start;
const willReturn = Array(len);
for (let i = 0; i < len; i++){
willReturn[ i ] = start + i;
}
return willReturn
}
function head(listOrString){
if (typeof listOrString === 'string') return listOrString[ 0 ] || ''
return listOrString[ 0 ]
}
function drop(howManyToDrop, listOrString){
if (arguments.length === 1) return _list => drop(howManyToDrop, _list)
return listOrString.slice(howManyToDrop )
}
function tail(listOrString){
return drop(1, listOrString)
}
function dropLast(howManyToDrop, listOrString){
if (arguments.length === 1){
return _listOrString => dropLast(howManyToDrop, _listOrString)
}
return howManyToDrop > 0 ?
listOrString.slice(0, -howManyToDrop) :
listOrString.slice()
}
function join(glue, list){
if (arguments.length === 1) return _list => join(glue, _list)
return list.join(glue)
}
function last(listOrString){
if (typeof listOrString === 'string'){
return listOrString[ listOrString.length - 1 ] || ''
}
return listOrString[ listOrString.length - 1 ]
}
function length(x){
if (isArray(x)) return x.length
if (typeof x === 'string') return x.length
return NaN
}
function match(pattern, input){
if (arguments.length === 1) return _input => match(pattern, _input)
const willReturn = input.match(pattern);
return willReturn === null ? [] : willReturn
}
function split(separator, str){
if (arguments.length === 1) return _str => split(separator, _str)
return str.split(separator)
}
function toUpper(str){
return str.toUpperCase()
}
function trim$1(str){
return str.trim()
}
const WORDS = /[A-Z]?[a-z]+|[A-Z]+(?![a-z])+/g;
const WORDS_EXTENDED = /[A-Z\xC0-\xD6\xD8-\xDEА-Я]?[a-z\xDF-\xF6\xF8-\xFFа-я]+|[A-Z\xC0-\xD6\xD8-\xDE]+(?![a-z\xDF-\xF6\xF8-\xFF])/g;
const PUNCTUATIONSX = /[",.?]/g;
const PUNCTUATIONS = /[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,\-./:;<=>?@[\]^_`{|}~]/g;
const HTML_TAGS = /<[^>]*>/g;
function words(str) {
return match(WORDS, str);
}
function wordsX(str) {
return match(WORDS_EXTENDED, str);
}
const capitalize = str => str[0].toUpperCase() + str.slice(1).toLowerCase();
const createMethodWithAdditionalSupport = (transformFn, separator) => (str, extraLatin) => compose(join(separator), mapIndexed(transformFn), extraLatin ? wordsX : words)(str);
const camelCaseTransform = (x, i) => i === 0 ? x.toLowerCase() : capitalize(x);
const camelCase = createMethodWithAdditionalSupport(camelCaseTransform, '');
const constantCase = createMethodWithAdditionalSupport(toUpper, '_');
const dotCase = createMethodWithAdditionalSupport(toLower, '.');
const kebabCase = createMethodWithAdditionalSupport(toLower, '-');
const pascalCaseTransform = x => head(x).toUpperCase() + tail(x).toLowerCase();
const pascalCase = createMethodWithAdditionalSupport(pascalCaseTransform, '');
const snakeCase = createMethodWithAdditionalSupport(toLower, '_');
const titleCase = createMethodWithAdditionalSupport(pascalCaseTransform, ' ');
function checkCase(transformFn) {
return input => transformFn(input) === input;
}
const isTitleCase = checkCase(titleCase);
const isKebabCase = checkCase(kebabCase);
const isCamelCase = checkCase(camelCase);
const isConstantCase = checkCase(constantCase);
const isDotCase = checkCase(dotCase);
const isSnakeCase = checkCase(snakeCase);
const isPascalCase = checkCase(pascalCase);
function count(str, substr) {
return length(split(substr, str)) - 1;
}
const MAX_LENGTH = 35;
function replaceUmlauts(str) {
return str.replace(/ä/g, 'ae').replace(/ö/g, 'oe').replace(/ü/g, 'ue').replace(/ß/g, 'ss');
}
function createIdFromSentence(str) {
const removed = [];
const initialResult = piped(str, wordsX, map(toLower), filter(x => {
if (x.length >= 3) {
return true;
}
removed.push(x);
return false;
}), map(replaceUmlauts), map(x => {
if (removed.length < 7) {
removed.push(x);
}
return head(x) + last(x);
}), join(''));
if (initialResult.length >= MAX_LENGTH || removed.length === 0) {
return initialResult.slice(0, MAX_LENGTH);
}
return take(MAX_LENGTH, initialResult + removed.join(''));
}
function distance(a, b) {
if (a.length === 0) {
return b.length;
}
if (b.length === 0) {
return a.length;
}
let i;
let j;
let prev;
let tmp;
let val;
if (a.length > b.length) {
tmp = a;
a = b;
b = tmp;
}
const row = Array(a.length + 1);
for (i = 0; i <= a.length; i++) {
row[i] = i;
}
for (i = 1; i <= b.length; i++) {
prev = i;
for (j = 1; j <= a.length; j++) {
if (b[i - 1] === a[j - 1]) {
val = row[j - 1];
} else {
val = Math.min(row[j - 1] + 1, Math.min(prev + 1, row[j] + 1));
}
row[j - 1] = prev;
prev = val;
}
row[a.length] = prev;
}
return row[a.length];
}
const normalizeGermanChar = char => {
const arr = ['ä', 'ö', 'ü', 'ß'];
const normalizedArr = ['a', 'o', 'u', 'ss'];
const foundIndex = arr.indexOf(char);
if (foundIndex === -1) {
return char;
}
return normalizedArr[foundIndex];
};
const normalizeGermanWord = str => join('', map(val => normalizeGermanChar(val), split('', toLower(str))));
function distanceGerman(a, b) {
return distance(normalizeGermanWord(a), normalizeGermanWord(b));
}
function splitPerLine({
text,
perLine = 30,
splitChar = ' '
}) {
const words = text.split(splitChar);
const toReturn = [];
let line = '';
words.forEach(word => {
const newLine = line + (line === '' ? '' : ' ') + word;
if (newLine.length >= perLine) {
toReturn.push(line);
line = word;
} else {
line = newLine;
}
});
if (line !== '') {
toReturn.push(line);
}
return toReturn;
}
const BUFFER = 3;
function fitWithinLines({
limit,
perLine = 30,
text
}) {
let counter = perLine;
const len = text.length;
let answer;
while (counter < len) {
counter++;
const maybeAnswer = splitPerLine({
text,
perLine: counter
});
if (maybeAnswer.length <= limit) {
answer = maybeAnswer;
counter = len;
}
}
if (!answer) {
const partial = trim$1(dropLast(BUFFER, text));
if (partial.length < BUFFER * 2) {
throw new Error(`such text cannot fit within ${limit} lines`);
}
return fitWithinLines({
text: partial,
perLine,
limit
});
}
return answer;
}
function getIndent(str) {
if (str.trim() === '') return 0;
return str.split('').findIndex(char => char !== ' ');
}
const getMaxLength = lines => {
const [max] = sort((a, b) => a.length < b.length ? 1 : -1)(lines);
return max.length;
};
function glob(str, globStr) {
const numGlobs = count(globStr, '*');
if (numGlobs === 1) {
if (head(globStr) === '*') {
return str.endsWith(tail(globStr));
}
if (last(globStr) === '*') {
return str.startsWith(init(globStr));
}
} else if (numGlobs === 2 && head(globStr) === '*' && last(globStr) === '*') {
globStr = init(tail(globStr));
const foundIndex = str.indexOf(globStr);
return foundIndex > 0 && foundIndex + globStr.length < str.length;
}
return false;
}
const flatCase = createMethodWithAdditionalSupport(toLower, '');
function indent(str, indentCount) {
return join('\n', map(val => `${' '.repeat(indentCount)}${val}`, split('\n', str)));
}
function isLetter(char) {
return test(WORDS_EXTENDED, char);
}
function isPunctuation(char) {
return test(PUNCTUATIONS, char);
}
const humanLengths = {
5: 'Five',
6: 'Six',
7: 'Seven',
8: 'Eight'
};
const globs = {
easyFive: '*123*',
easySix: '*123**',
easySixR: '**234*',
easierSix: '*123**',
easierSixR: '**234*',
easySeven: '*1234**',
easySevenR: '**2345*',
easierSeven: '**234**',
easyEight: '**2345**',
easierEight: '**234***',
easierEightR: '***345**',
easyAny: len => `**${'-'.repeat(len - 5)}***`,
easierAny: len => `***${'-'.repeat(len - 6)}***`
};
function chance() {
return Math.random() > 0.49;
}
function getGlob(len, mode, random) {
if (len > 8) return globs[`${mode}Any`](len);
if (len === 5) return globs.easyFive;
const base = `${mode}${humanLengths[len]}`;
const maybeKey = globs[base];
if (!random) {
return maybeKey === undefined ? globs[`easy${humanLengths[len]}`] : maybeKey;
}
return globs[`${base}R`] === undefined ? maybeKey : chance() ? globs[`${base}R`] : maybeKey;
}
function ant(word, glob, replacer) {
const chars = [...word];
return chars.map((char, i) => glob[i] === '*' ? char : replacer).join('');
}
function maskWordHelper(word, replacer, charLimit = 4) {
if (test(PUNCTUATIONSX, word) || word.length <= 1) {
return word;
}
if (word.length < charLimit) {
return `${head(word)}${replacer.repeat(word.length - 1)}`;
}
return `${head(word)}${replacer.repeat(word.length - 2)}${last(word)}`;
}
function maskWordHelperX({
word,
replacer = '_',
easyMode = false,
randomMode = false,
easierMode = false,
charLimit = 4
}) {
const len = word.length;
if (!easyMode && !easierMode || len <= 4) return maskWordHelper(word, replacer, charLimit);
const glob = getGlob(len, easyMode ? 'easy' : 'easier', randomMode);
return ant(word, glob, replacer);
}
function trim(str) {
return replace(/\s+/g, ' ', str).trim();
}
const addSpaceAroundPunctuation$1 = sentence => sentence.replace(PUNCTUATIONSX, x => ` ${x} `);
function maskSentence({
charLimit = 4,
easyMode = false,
easierMode = false,
randomMode = false,
replacer = '_',
sentence,
words = []
}) {
const parsed = trim(addSpaceAroundPunctuation$1(sentence));
const hidden = [];
const visible = [];
const input = {
replacer,
easyMode,
randomMode,
easierMode,
charLimit
};
const easyFn = partialObject(maskWordHelperX, input);
const ant = easierMode || easyMode ? word => easyFn({
word
}) : word => maskWordHelper(word, replacer, charLimit);
map(word => {
const ok = words.length === 0 || words.includes(word);
const visiblePart = ok ? ant(word) : word;
hidden.push(word);
visible.push(visiblePart);
}, split(' ', parsed));
return {
hidden,
visible
};
}
function maskWords({
words,
replacer = '_',
charLimit = 3
}) {
const result = map(val => maskWordHelper(val, replacer, charLimit), split(' ', words));
return join(' ', result);
}
function parseInput(inputRaw) {
if (typeof inputRaw !== 'string') throw new Error('inputRaw !== string');
const numbers = [];
const chars = [];
let flag = false;
inputRaw.split('').forEach(x => {
if (flag && x) {
chars.push(x);
} else if (!flag) {
const isNumber = Number(x) === Number(x);
if (isNumber) {
numbers.push(x);
} else {
chars.push(x);
flag = true;
}
} else {
flag = true;
}
});
return {
numbers: Number(numbers.join('')),
chars: chars.join('')
};
}
const hash = {
1: ['s', 'seconds', 'second', 'sec'],
60: ['m', 'minutes', 'minute', 'min'],
3600: ['h', 'hours', 'hour'],
86400: ['d', 'days', 'day']
};
function findInHash(hashKey) {
const [found] = Object.keys(hash).filter(singleKey => hash[singleKey].includes(hashKey));
if (!found) throw new Error('no numbers passed to `ms`');
return found;
}
function ms(inputRaw) {
const input = parseInput(inputRaw);
const miliseconds = findInHash(input.chars);
return Math.floor(Number(miliseconds) * 1000 * input.numbers);
}
const SECONDS = 'seconds';
const MINUTES = 'minutes';
const HOURS = 'hours';
const DAYS = 'days';
function findLargestUnit(seconds) {
return switcher(seconds).is(x => x < 60, {
label: SECONDS,
scale: 1
}).is(x => x < 3600, {
label: MINUTES,
scale: 60
}).is(x => x < 3600 * 24 * 7, {
label: HOURS,
scale: 3600
}).default({
label: DAYS,
scale: 3600 * 24
});
}
function msToText(msInput) {
if (typeof msInput !== 'number') {
throw new Error(`${msInput} is not a number`);
}
const seconds = toDecimal(msInput / 1000, 0);
const {
label,
scale
} = findLargestUnit(seconds);
return `${toDecimal(seconds / scale, 1)} ${label}`;
}
const charCodesString = [...range(65, 90), ...range(97, 122)];
const charCodes = [...charCodesString, ...range(49, 57)];
function randomString(length = 8, stringTag = false) {
const loops = range(0, length);
const charSet = stringTag ? charCodesString : charCodes;
return loops.map(x => String.fromCharCode(head(shuffle$1(charSet)))).join('');
}
function removeIndent(str) {
return join('\n', map(val => val.trimLeft(), split('\n', str)));
}
function reverse(str) {
return [...str].reverse().join('');
}
const seoTitle = createMethodWithAdditionalSupport((x, i) => x.length >= 3 ? capitalize(x) : x, ' ');
const shuffleArr = arr => {
let counter = arr.length;
while (counter > 0) {
const index = Math.floor(Math.random() * counter);
counter--;
const temp = arr[counter];
arr[counter] = arr[index];
arr[index] = temp;
}
return arr;
};
function shuffle(str) {
return join('', shuffleArr(split('', str)));
}
const addSpaceAroundPunctuation = sentence => sentence.replace(PUNCTUATIONS, match => ` ${match} `);
function splitSentence(sentence) {
return split(' ', trim(addSpaceAroundPunctuation(sentence)));
}
function splitWhen(text, predicate) {
const result = [];
let current = '';
for (let i = 0; i < text.length; i++) {
current += text[i];
if (predicate(text[i])) {
result.push(current);
current = '';
}
}
return result;
}
function stripPunctuation(str) {
return replace(PUNCTUATIONS, '', str);
}
function stripTags(str) {
return replace(/\s+/g, ' ', replace(HTML_TAGS, ' ', str)).trim();
}
function mergeAll(arr) {
let willReturn = {};
map(val => {
willReturn = mergeRight(willReturn, val);
}, arr);
return willReturn;
}
function mapToObject(fn, list) {
return mergeAll(map(fn, list));
}
function takeArguments(url, sep = '?', rawFlag = false) {
const [, ...rawArguments] = url.split(sep);
if (rawArguments.length === 0) return {};
return mapToObject(x => {
const [keyRaw, value] = x.split('=');
const key = rawFlag ? keyRaw : camelCase(keyRaw);
if (value === undefined || value === 'true') {
return {
[key]: true
};
}
if (value === 'false') {
return {
[key]: false
};
}
if (Number.isNaN(Number(value))) {
return {
[key]: value
};
}
return {
[key]: Number(value)
};
}, rawArguments);
}
function toFixedLineLength(str, lineLength) {
return piped(str, split('\n'), map(x => {
if (x.length > lineLength) {
console.warn(`line \`${x}\` is too long`);
return x;
}
return `${x}${' '.repeat(lineLength - x.length)}`;
}), join('\n'));
}
export { between, camelCase, camelCaseTransform, constantCase, count, createIdFromSentence, distance, distanceGerman, dotCase, fitWithinLines, flatCase, getIndent, getMaxLength, glob, indent, isCamelCase, isConstantCase, isDotCase, isKebabCase, isLetter, isPascalCase, isPunctuation, isSnakeCase, isTitleCase, kebabCase, maskSentence, maskWords, ms, msToText, pascalCase, pascalCaseTransform, randomString, removeIndent, reverse, seoTitle, shuffle, snakeCase, splitPerLine, splitSentence, splitWhen, stripPunctuation, stripTags, takeArguments, titleCase, toFixedLineLength, trim, words, wordsX };