UNPKG

string-fn

Version:
1,125 lines (1,040 loc) 29 kB
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 };