diff --git a/.gitignore b/.gitignore index bdd2045..4ffedfb 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,9 @@ node_modules coverage npm-debug.log docs -/index.js +index.js .tern-project -dist_mod -.vscode \ No newline at end of file +dist_mod/ +.vscode +dist/ +test_runner/test_bundle.js \ No newline at end of file diff --git a/dist/voca.js b/dist/voca.js deleted file mode 100644 index 93d9101..0000000 --- a/dist/voca.js +++ /dev/null @@ -1,3993 +0,0 @@ -/*! - * Voca string library 1.3.0 - * https://vocajs.com - * - * Copyright Dmitri Pavlutin and other contributors - * Released under the MIT license - */ - -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global.v = factory()); -}(this, (function () { 'use strict'; - -/** - * Checks if `value` is `null` or `undefined` - * - * @ignore - * @function isNil - * @param {*} value The object to check - * @return {boolean} Returns `true` is `value` is `undefined` or `null`, `false` otherwise - */ -function isNil(value) { - return value === undefined || value === null; -} - -/** - * Converts the `value` to a boolean. If `value` is `undefined` or `null`, returns `defaultValue`. - * - * @ignore - * @function toBoolean - * @param {*} value The value to convert. - * @param {boolean} [defaultValue=false] The default value. - * @return {boolean} Returns the coercion to boolean. - */ -function coerceToBoolean(value) { - var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - if (isNil(value)) { - return defaultValue; - } - return Boolean(value); -} - -/** - * Checks whether `subject` is a string primitive type. - * - * @function isString - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} subject The value to verify. - * @return {boolean} Returns `true` if `subject` is string primitive type or `false` otherwise. - * @example - * v.isString('vacation'); - * // => true - * - * v.isString(560); - * // => false - */ -function isString(subject) { - return typeof subject === 'string'; -} - -/** - * Get the string representation of the `value`. - * Converts the `value` to string. - * If `value` is `null` or `undefined`, return `defaultValue`. - * - * @ignore - * @function toString - * @param {*} value The value to convert. - * @param {*} [defaultValue=''] The default value to return. - * @return {string|null} Returns the string representation of `value`. Returns `defaultValue` if `value` is - * `null` or `undefined`. - */ -function coerceToString(value) { - var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; - - if (isNil(value)) { - return defaultValue; - } - if (isString(value)) { - return value; - } - return String(value); -} - -/** - * Converts the first character of `subject` to upper case. If `restToLower` is `true`, convert the rest of - * `subject` to lower case. - * - * @function capitalize - * @static - * @since 1.0.0 - * @memberOf Case - * @param {string} [subject=''] The string to capitalize. - * @param {boolean} [restToLower=false] Convert the rest of `subject` to lower case. - * @return {string} Returns the capitalized string. - * @example - * v.capitalize('apple'); - * // => 'Apple' - * - * v.capitalize('aPPle', true); - * // => 'Apple' - */ -function capitalize(subject, restToLower) { - var subjectString = coerceToString(subject); - var restToLowerCaseBoolean = coerceToBoolean(restToLower); - if (subjectString === '') { - return ''; - } - if (restToLowerCaseBoolean) { - subjectString = subjectString.toLowerCase(); - } - return subjectString.substr(0, 1).toUpperCase() + subjectString.substr(1); -} - -/** - * Converts the `subject` to lower case. - * - * @function lowerCase - * @static - * @since 1.0.0 - * @memberOf Case - * @param {string} [subject=''] The string to convert to lower case. - * @return {string} Returns the lower case string. - * @example - * v.lowerCase('Green'); - * // => 'green' - * - * v.lowerCase('BLUE'); - * // => 'blue' - */ -function lowerCase(subject) { - var subjectString = coerceToString(subject, ''); - return subjectString.toLowerCase(); -} - -/** - * A regular expression string matching digits - * - * @type {string} - * @ignore - */ -var digit = '\\d'; - -/** - * A regular expression string matching whitespace - * - * @type {string} - * @ignore - */ -var whitespace = '\\s\\uFEFF\\xA0'; - -/** - * A regular expression string matching high surrogate - * - * @type {string} - * @ignore - */ -var highSurrogate = '\\uD800-\\uDBFF'; - -/** - * A regular expression string matching low surrogate - * - * @type {string} - * @ignore - */ -var lowSurrogate = '\\uDC00-\\uDFFF'; - -/** - * A regular expression string matching diacritical mark - * - * @type {string} - * @ignore - */ -var diacriticalMark = '\\u0300-\\u036F\\u1AB0-\\u1AFF\\u1DC0-\\u1DFF\\u20D0-\\u20FF\\uFE20-\\uFE2F'; - -/** - * A regular expression to match the base character for a combining mark - * - * @type {string} - * @ignore - */ -var base = '\\0-\\u02FF\\u0370-\\u1AAF\\u1B00-\\u1DBF\\u1E00-\\u20CF\\u2100-\\uD7FF\\uE000-\\uFE1F\\uFE30-\\uFFFF'; - -/** - * Regular expression to match combining marks - * - * @see http://unicode.org/faq/char_combmark.html - * @type {RegExp} - * @ignore - */ -var REGEXP_COMBINING_MARKS = new RegExp('([' + base + ']|[' + highSurrogate + '][' + lowSurrogate + ']|[' + highSurrogate + '](?![' + lowSurrogate + '])|(?:[^' + highSurrogate + ']|^)[' + lowSurrogate + '])([' + diacriticalMark + ']+)', 'g'); - -/** - * Regular expression to match surrogate pairs - * - * @see http://www.unicode.org/faq/utf_bom.html#utf16-2 - * @type {RegExp} - * @ignore - */ -var REGEXP_SURROGATE_PAIRS = new RegExp('([' + highSurrogate + '])([' + lowSurrogate + '])', 'g'); - -/** - * Regular expression to match an unicode character - * - * @type {RegExp} - * @ignore - */ -var REGEXP_UNICODE_CHARACTER = new RegExp('((?:[' + base + ']|[' + highSurrogate + '][' + lowSurrogate + ']|[' + highSurrogate + '](?![' + lowSurrogate + '])|(?:[^' + highSurrogate + ']|^)[' + lowSurrogate + '])(?:[' + diacriticalMark + ']+))|\ -([' + highSurrogate + '][' + lowSurrogate + '])|\ -([\\n\\r\\u2028\\u2029])|\ -(.)', 'g'); - -/** - * Regular expression to match whitespaces - * - * @type {RegExp} - * @ignore - */ -var REGEXP_WHITESPACE = new RegExp('[' + whitespace + ']'); - -/** - * Regular expression to match whitespaces from the left side - * - * @type {RegExp} - * @ignore - */ -var REGEXP_TRIM_LEFT = new RegExp('^[' + whitespace + ']+'); - -/** - * Regular expression to match whitespaces from the right side - * - * @type {RegExp} - * @ignore - */ -var REGEXP_TRIM_RIGHT = new RegExp('[' + whitespace + ']+$'); - -/** - * Regular expression to match digit characters - * - * @type {RegExp} - * @ignore - */ -var REGEXP_DIGIT = new RegExp('^' + digit + '+$'); - -/** - * Regular expression to match regular expression special characters - * - * @type {RegExp} - * @ignore - */ -var REGEXP_SPECIAL_CHARACTERS = /[-[\]{}()*+!<=:?.\/\\^$|#,]/g; - -/** - * Regular expression to match not latin characters - * - * @type {RegExp} - * @ignore - */ -var REGEXP_NON_LATIN = /[^A-Za-z0-9]/g; - -/** - * Regular expression to match HTML special characters. - * - * @type {RegExp} - * @ignore - */ -var REGEXP_HTML_SPECIAL_CHARACTERS = /[<>&"'`]/g; - -/** - * Regular expression to match sprintf format string - * - * @type {RegExp} - * @ignore - */ -var REGEXP_CONVERSION_SPECIFICATION = /(%{1,2})(?:(\d+)\$)?(\+)?([ 0]|'.{1})?(-)?(\d+)?(?:\.(\d+))?([bcdiouxXeEfgGs])?/g; - -/** - * Regular expression to match trailing zeros in a number - * - * @type {RegExp} - * @ignore - */ -var REGEXP_TRAILING_ZEROS = /\.?0+$/g; - -/** - * Regular expression to match flags from a regular expression. - * - * @type {RegExp} - * @ignore - */ -var REGEXP_FLAGS = /[gimuy]*$/; - -/** - * Regular expression to match a list of tags. - * - * @see https://html.spec.whatwg.org/multipage/syntax.html#syntax-tag-name - * @type {RegExp} - * @ignore - */ - -var REGEXP_TAG_LIST = /<([A-Za-z0-9]+)>/g; - -/** - * A regular expression to match the General Punctuation Unicode block - * - * @type {string} - * @ignore - */ -var generalPunctuationBlock = '\\u2000-\\u206F'; - -/** - * A regular expression to match non characters from from Basic Latin and Latin-1 Supplement Unicode blocks - * - * @type {string} - * @ignore - */ -var nonCharacter = '\\x00-\\x2F\\x3A-\\x40\\x5B-\\x60\\x7b-\\xBF\\xD7\\xF7'; - -/** - * A regular expression to match the dingbat Unicode block - * - * @type {string} - * @ignore - */ -var dingbatBlock = '\\u2700-\\u27BF'; - -/** - * A regular expression string that matches lower case letters: LATIN - * - * @type {string} - * @ignore - */ -var lowerCaseLetter = 'a-z\\xB5\\xDF-\\xF6\\xF8-\\xFF\\u0101\\u0103\\u0105\\u0107\\u0109\\u010B\\u010D\\u010F\\u0111\\u0113\\u0115\\u0117\\u0119\\u011B\\u011D\\u011F\\u0121\\u0123\\u0125\\u0127\\u0129\\u012B\\u012D\\u012F\\u0131\\u0133\\u0135\\u0137\\u0138\\u013A\\u013C\\u013E\\u0140\\u0142\\u0144\\u0146\\u0148\\u0149\\u014B\\u014D\\u014F\\u0151\\u0153\\u0155\\u0157\\u0159\\u015B\\u015D\\u015F\\u0161\\u0163\\u0165\\u0167\\u0169\\u016B\\u016D\\u016F\\u0171\\u0173\\u0175\\u0177\\u017A\\u017C\\u017E-\\u0180\\u0183\\u0185\\u0188\\u018C\\u018D\\u0192\\u0195\\u0199-\\u019B\\u019E\\u01A1\\u01A3\\u01A5\\u01A8\\u01AA\\u01AB\\u01AD\\u01B0\\u01B4\\u01B6\\u01B9\\u01BA\\u01BD-\\u01BF\\u01C6\\u01C9\\u01CC\\u01CE\\u01D0\\u01D2\\u01D4\\u01D6\\u01D8\\u01DA\\u01DC\\u01DD\\u01DF\\u01E1\\u01E3\\u01E5\\u01E7\\u01E9\\u01EB\\u01ED\\u01EF\\u01F0\\u01F3\\u01F5\\u01F9\\u01FB\\u01FD\\u01FF\\u0201\\u0203\\u0205\\u0207\\u0209\\u020B\\u020D\\u020F\\u0211\\u0213\\u0215\\u0217\\u0219\\u021B\\u021D\\u021F\\u0221\\u0223\\u0225\\u0227\\u0229\\u022B\\u022D\\u022F\\u0231\\u0233-\\u0239\\u023C\\u023F\\u0240\\u0242\\u0247\\u0249\\u024B\\u024D\\u024F'; - -/** - * A regular expression string that matches upper case letters: LATIN - * - * @type {string} - * @ignore - */ -var upperCaseLetter = '\\x41-\\x5a\\xc0-\\xd6\\xd8-\\xde\\u0100\\u0102\\u0104\\u0106\\u0108\\u010a\\u010c\\u010e\\u0110\\u0112\\u0114\\u0116\\u0118\\u011a\\u011c\\u011e\\u0120\\u0122\\u0124\\u0126\\u0128\\u012a\\u012c\\u012e\\u0130\\u0132\\u0134\\u0136\\u0139\\u013b\\u013d\\u013f\\u0141\\u0143\\u0145\\u0147\\u014a\\u014c\\u014e\\u0150\\u0152\\u0154\\u0156\\u0158\\u015a\\u015c\\u015e\\u0160\\u0162\\u0164\\u0166\\u0168\\u016a\\u016c\\u016e\\u0170\\u0172\\u0174\\u0176\\u0178\\u0179\\u017b\\u017d\\u0181\\u0182\\u0184\\u0186\\u0187\\u0189-\\u018b\\u018e-\\u0191\\u0193\\u0194\\u0196-\\u0198\\u019c\\u019d\\u019f\\u01a0\\u01a2\\u01a4\\u01a6\\u01a7\\u01a9\\u01ac\\u01ae\\u01af\\u01b1-\\u01b3\\u01b5\\u01b7\\u01b8\\u01bc\\u01c4\\u01c5\\u01c7\\u01c8\\u01ca\\u01cb\\u01cd\\u01cf\\u01d1\\u01d3\\u01d5\\u01d7\\u01d9\\u01db\\u01de\\u01e0\\u01e2\\u01e4\\u01e6\\u01e8\\u01ea\\u01ec\\u01ee\\u01f1\\u01f2\\u01f4\\u01f6-\\u01f8\\u01fa\\u01fc\\u01fe\\u0200\\u0202\\u0204\\u0206\\u0208\\u020a\\u020c\\u020e\\u0210\\u0212\\u0214\\u0216\\u0218\\u021a\\u021c\\u021e\\u0220\\u0222\\u0224\\u0226\\u0228\\u022a\\u022c\\u022e\\u0230\\u0232\\u023a\\u023b\\u023d\\u023e\\u0241\\u0243-\\u0246\\u0248\\u024a\\u024c\\u024e'; - -/** - * Regular expression to match Unicode words - * - * @type {RegExp} - * @ignore - */ -var REGEXP_WORD = new RegExp('(?:[' + upperCaseLetter + '][' + diacriticalMark + ']*)?(?:[' + lowerCaseLetter + '][' + diacriticalMark + ']*)+|\ -(?:[' + upperCaseLetter + '][' + diacriticalMark + ']*)+(?![' + lowerCaseLetter + '])|\ -[' + digit + ']+|\ -[' + dingbatBlock + ']|\ -[^' + nonCharacter + generalPunctuationBlock + whitespace + ']+', 'g'); - -/** - * Regular expression to match words from Basic Latin and Latin-1 Supplement blocks - * - * @type {RegExp} - * @ignore - */ -var REGEXP_LATIN_WORD = /[A-Z\xC0-\xD6\xD8-\xDE]?[a-z\xDF-\xF6\xF8-\xFF]+|[A-Z\xC0-\xD6\xD8-\xDE]+(?![a-z\xDF-\xF6\xF8-\xFF])|\d+/g; - -/** - * Regular expression to match alpha characters - * - * @see http://stackoverflow.com/a/22075070/1894471 - * @type {RegExp} - * @ignore - */ -var REGEXP_ALPHA = new RegExp('^(?:[' + lowerCaseLetter + upperCaseLetter + '][' + diacriticalMark + ']*)+$'); - -/** - * Regular expression to match alpha and digit characters - * - * @see http://stackoverflow.com/a/22075070/1894471 - * @type {RegExp} - * @ignore - */ -var REGEXP_ALPHA_DIGIT = new RegExp('^((?:[' + lowerCaseLetter + upperCaseLetter + '][' + diacriticalMark + ']*)|[' + digit + '])+$'); - -/** - * Regular expression to match Extended ASCII characters, i.e. the first 255 - * - * @type {RegExp} - * @ignore - */ -var REGEXP_EXTENDED_ASCII = /^[\x00-\xFF]*$/; - -/** - * Verifies if `value` is `undefined` or `null` and returns `defaultValue`. In other case returns `value`. - * - * @ignore - * @function nilDefault - * @param {*} value The value to verify. - * @param {*} defaultValue The default value. - * @return {*} Returns `defaultValue` if `value` is `undefined` or `null`, otherwise `defaultValue`. - */ -function nilDefault(value, defaultValue) { - return value == null ? defaultValue : value; -} - -/** - * Get the string representation of the `value`. - * Converts the `value` to string. - * - * @ignore - * @function toString - * @param {*} value The value to convert. - * @return {string|null} Returns the string representation of `value`. - */ -function toString(value) { - if (isNil(value)) { - return null; - } - if (isString(value)) { - return value; - } - return String(value); -} - -/** - * Splits `subject` into an array of words. - * - * @function words - * @static - * @since 1.0.0 - * @memberOf Split - * @param {string} [subject=''] The string to split into words. - * @param {string|RegExp} [pattern] The pattern to watch words. If `pattern` is not RegExp, it is transformed to `new RegExp(pattern, flags)`. - * @param {string} [flags=''] The regular expression flags. Applies when `pattern` is string type. - * @return {Array} Returns the array of words. - * @example - * v.words('gravity can cross dimensions'); - * // => ['gravity', 'can', 'cross', 'dimensions'] - * - * v.words('GravityCanCrossDimensions'); - * // => ['Gravity', 'Can', 'Cross', 'Dimensions'] - * - * v.words('Gravity - can cross dimensions!'); - * // => ['Gravity', 'can', 'cross', 'dimensions'] - * - * v.words('Earth gravity', /[^\s]+/g); - * // => ['Earth', 'gravity'] - */ -function words(subject, pattern, flags) { - var subjectString = coerceToString(subject); - var patternRegExp = void 0; - if (isNil(pattern)) { - patternRegExp = REGEXP_EXTENDED_ASCII.test(subjectString) ? REGEXP_LATIN_WORD : REGEXP_WORD; - } else if (pattern instanceof RegExp) { - patternRegExp = pattern; - } else { - var flagsString = toString(nilDefault(flags, '')); - patternRegExp = new RegExp(toString(pattern), flagsString); - } - return nilDefault(subjectString.match(patternRegExp), []); -} - -/** - * Transforms the `word` into camel case chunk. - * - * @param {string} word The word string - * @param {number} index The index of the word in phrase. - * @return {string} The transformed word. - * @ignore - */ -function wordToCamel(word, index) { - return index === 0 ? lowerCase(word) : capitalize(word, true); -} - -/** - * Converts the `subject` to camel case. - * - * @function camelCase - * @static - * @since 1.0.0 - * @memberOf Case - * @param {string} [subject=''] The string to convert to camel case. - * @return {string} The camel case string. - * @example - * v.camelCase('bird flight'); - * // => 'birdFlight' - * - * v.camelCase('BirdFlight'); - * // => 'birdFlight' - * - * v.camelCase('-BIRD-FLIGHT-'); - * // => 'birdFlight' - */ -function camelCase(subject) { - var subjectString = coerceToString(subject); - if (subjectString === '') { - return ''; - } - return words(subjectString).map(wordToCamel).join(''); -} - -/** - * Converts the first character of `subject` to lower case. - * - * @function decapitalize - * @static - * @since 1.0.0 - * @memberOf Case - * @param {string} [subject=''] The string to decapitalize. - * @return {string} Returns the decapitalized string. - * @example - * v.decapitalize('Sun'); - * // => 'sun' - * - * v.decapitalize('moon'); - * // => 'moon' - */ -function decapitalize(subject) { - var subjectString = coerceToString(subject); - if (subjectString === '') { - return ''; - } - return subjectString.substr(0, 1).toLowerCase() + subjectString.substr(1); -} - -/** - * Converts the `subject` to kebab case, - * also called spinal case or lisp case. - * - * @function kebabCase - * @static - * @since 1.0.0 - * @memberOf Case - * @param {string} [subject=''] The string to convert to kebab case. - * @return {string} Returns the kebab case string. - * @example - * v.kebabCase('goodbye blue sky'); - * // => 'goodbye-blue-sky' - * - * v.kebabCase('GoodbyeBlueSky'); - * // => 'goodbye-blue-sky' - * - * v.kebabCase('-Goodbye-Blue-Sky-'); - * // => 'goodbye-blue-sky' - */ -function kebabCase(subject) { - var subjectString = coerceToString(subject); - if (subjectString === '') { - return ''; - } - return words(subjectString).map(lowerCase).join('-'); -} - -/** - * Converts the `subject` to snake case. - * - * @function snakeCase - * @static - * @since 1.0.0 - * @memberOf Case - * @param {string} [subject=''] The string to convert to snake case. - * @return {string} Returns the snake case string. - * @example - * v.snakeCase('learning to fly'); - * // => 'learning_to_fly' - * - * v.snakeCase('LearningToFly'); - * // => 'learning_to_fly' - * - * v.snakeCase('-Learning-To-Fly-'); - * // => 'learning_to_fly' - */ -function snakeCase(subject) { - var subjectString = coerceToString(subject); - if (subjectString === '') { - return ''; - } - return words(subjectString).map(lowerCase).join('_'); -} - -/** - * Converts the `subject` to upper case. - * - * @function upperCase - * @static - * @since 1.0.0 - * @memberOf Case - * @param {string} [subject=''] The string to convert to upper case. - * @return {string} Returns the upper case string. - * @example - * v.upperCase('school'); - * // => 'SCHOOL' - */ -function upperCase(subject) { - var subjectString = coerceToString(subject); - return subjectString.toUpperCase(); -} - -/** - * Converts the uppercase alpha caracters of `subject` to lowercase and lowercase - * characters to uppercase. - * - * @function swapCase - * @static - * @since 1.3.0 - * @memberOf Case - * @param {string} [subject=''] The string to swap the case. - * @return {string} Returns the converted string. - * @example - * v.swapCase('League of Shadows'); - * // => 'lEAGE OF sHADOWS' - * - * v.swapCase('2 Bees'); - * // => '2 bEES' - */ -function swapCase(subject) { - var subjectString = coerceToString(subject); - return subjectString.split('').reduce(swapAndConcat, ''); -} - -function swapAndConcat(swapped, character) { - var lowerCase = character.toLowerCase(); - var upperCase = character.toUpperCase(); - return swapped + (character === lowerCase ? upperCase : lowerCase); -} - -/** - * Converts the subject to title case. - * - * @function titleCase - * @static - * @since 1.2.0 - * @memberOf Case - * @param {string} [subject=''] The string to convert to title case. - * @param {Array} [ignoreWords] The words that should not be capitalized. - * @return {string} Returns the title case string. - * @example - * v.titleCase('learning to fly'); - * // => 'Learning To Fly' - * - * v.titleCase('another brick in the wall', ['in', 'the']); - * // => 'Another Brick in the Wall' - */ -function titleCase(subject, ignoreWords) { - var subjectString = coerceToString(subject); - var ignoreWordsArray = Array.isArray(ignoreWords) ? ignoreWords : []; - var wordsRegExp = REGEXP_EXTENDED_ASCII.test(subjectString) ? REGEXP_LATIN_WORD : REGEXP_WORD; - return subjectString.replace(wordsRegExp, function (word) { - var lowerCaseWord = word.toLowerCase(); - return ignoreWordsArray.indexOf(lowerCaseWord) !== -1 ? lowerCaseWord : capitalize(lowerCaseWord, true); - }); -} - -/** - * Clip the number to interval `downLimit` to `upLimit`. - * - * @ignore - * @function clipNumber - * @param {number} value The number to clip - * @param {number} downLimit The down limit - * @param {number} upLimit The upper limit - * @return {number} The clipped number - */ -function clipNumber(value, downLimit, upLimit) { - if (value <= downLimit) { - return downLimit; - } - if (value >= upLimit) { - return upLimit; - } - return value; -} - -/** - * Max save integer value - * - * @ignore - * @type {number} - */ -var MAX_SAFE_INTEGER = 0x1fffffffffffff; - -/** - * Transforms `value` to an integer. - * - * @ignore - * @function toInteger - * @param {number} value The number to transform. - * @returns {number} Returns the transformed integer. - */ -function toInteger(value) { - if (value === Infinity) { - return MAX_SAFE_INTEGER; - } - if (value === -Infinity) { - return -MAX_SAFE_INTEGER; - } - return ~~value; -} - -/** - * Truncates `subject` to a new `length`. - * - * @function truncate - * @static - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to truncate. - * @param {int} length The length to truncate the string. - * @param {string} [end='...'] The string to be added at the end. - * @return {string} Returns the truncated string. - * @example - * v.truncate('Once upon a time', 7); - * // => 'Once...' - * - * v.truncate('Good day, Little Red Riding Hood', 14, ' (...)'); - * // => 'Good day (...)' - * - * v.truncate('Once upon', 10); - * // => 'Once upon' - */ -function truncate(subject, length, end) { - var subjectString = coerceToString(subject); - var lengthInt = isNil(length) ? subjectString.length : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER); - var endString = coerceToString(end, '...'); - if (lengthInt >= subjectString.length) { - return subjectString; - } - return subjectString.substr(0, length - endString.length) + endString; -} - -/** - * Access a character from `subject` at specified `position`. - * - * @function charAt - * @static - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to extract from. - * @param {numbers} position The position to get the character. - * @return {string} Returns the character at specified position. - * @example - * v.charAt('helicopter', 0); - * // => 'h' - * - * v.charAt('helicopter', 1); - * // => 'e' - */ -function charAt(subject, position) { - var subjectString = coerceToString(subject); - return subjectString.charAt(position); -} - -var HIGH_SURROGATE_START = 0xD800; -var HIGH_SURROGATE_END = 0xDBFF; -var LOW_SURROGATE_START = 0xDC00; -var LOW_SURROGATE_END = 0xDFFF; - -/** - * Checks if `codePoint` is a high-surrogate number from range 0xD800 to 0xDBFF. - * - * @ignore - * @param {number} codePoint The code point number to be verified - * @return {boolean} Returns a boolean whether `codePoint` is a high-surrogate number. - */ -function isHighSurrogate(codePoint) { - return codePoint >= HIGH_SURROGATE_START && codePoint <= HIGH_SURROGATE_END; -} - -/** - * Checks if `codePoint` is a low-surrogate number from range 0xDC00 to 0xDFFF. - * - * @ignore - * @param {number} codePoint The code point number to be verified - * @return {boolean} Returns a boolean whether `codePoint` is a low-surrogate number. - */ -function isLowSurrogate(codePoint) { - return codePoint >= LOW_SURROGATE_START && codePoint <= LOW_SURROGATE_END; -} - -/** - * Get the astral code point number based on surrogate pair numbers. - * - * @ignore - * @param {number} highSurrogate The high-surrogate code point number. - * @param {number} lowSurrogate The low-surrogate code point number. - * @return {number} Returns the astral symbol number. - */ -function getAstralNumberFromSurrogatePair(highSurrogate, lowSurrogate) { - return (highSurrogate - HIGH_SURROGATE_START) * 0x400 + lowSurrogate - LOW_SURROGATE_START + 0x10000; -} - -/** - * Get the number representation of the `value`. - * Converts the `value` to number. - * If `value` is `null` or `undefined`, return `defaultValue`. - * - * @ignore - * @function toString - * @param {*} value The value to convert. - * @param {*} [defaultValue=''] The default value to return. - * @return {number|null} Returns the number representation of `value`. Returns `defaultValue` if `value` is - * `null` or `undefined`. - */ -function coerceToNumber(value) { - var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - - if (isNil(value)) { - return defaultValue; - } - if (typeof value === 'number') { - return value; - } - return Number(value); -} - -/** - * If `value` is `NaN`, return `defaultValue`. In other case returns `value`. - * - * @ignore - * @function nanDefault - * @param {*} value The value to verify. - * @param {*} defaultValue The default value. - * @return {*} Returns `defaultValue` if `value` is `NaN`, otherwise `defaultValue`. - */ -function nanDefault(value, defaultValue) { - return value !== value ? defaultValue : value; -} - -/** - * Get the Unicode code point value of the character at `position`.
- * If a valid UTF-16 - * surrogate pair starts at `position`, the - * astral code point - * value at `position` is returned. - * - * @function codePointAt - * @static - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to extract from. - * @param {number} position The position to get the code point number. - * @return {number} Returns a non-negative number less than or equal to `0x10FFFF`. - * @example - * v.codePointAt('rain', 1); - * // => 97, or 0x0061 - * - * v.codePointAt('\uD83D\uDE00 is smile', 0); // or '😀 is smile' - * // => 128512, or 0x1F600 - */ -function codePointAt(subject, position) { - var subjectString = coerceToString(subject); - var subjectStringLength = subjectString.length; - var positionNumber = coerceToNumber(position); - positionNumber = nanDefault(positionNumber, 0); - if (positionNumber < 0 || positionNumber >= subjectStringLength) { - return undefined; - } - var firstCodePoint = subjectString.charCodeAt(positionNumber); - var secondCodePoint = void 0; - if (isHighSurrogate(firstCodePoint) && subjectStringLength > positionNumber + 1) { - secondCodePoint = subjectString.charCodeAt(positionNumber + 1); - if (isLowSurrogate(secondCodePoint)) { - return getAstralNumberFromSurrogatePair(firstCodePoint, secondCodePoint); - } - } - return firstCodePoint; -} - -/** - * Extracts the first `length` characters from `subject`. - * - * @function first - * @static - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to extract from. - * @param {int} [length=1] The number of characters to extract. - * @return {string} Returns the first characters string. - * @example - * v.first('helicopter'); - * // => 'h' - * - * v.first('vehicle', 2); - * // => 've' - * - * v.first('car', 5); - * // => 'car' - */ -function first(subject, length) { - var subjectString = coerceToString(subject); - var lengthInt = isNil(length) ? 1 : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER); - if (subjectString.length <= lengthInt) { - return subjectString; - } - return subjectString.substr(0, lengthInt); -} - -/** - * Get a grapheme from `subject` at specified `position` taking care of - * surrogate pairs and - * combining marks. - * - * @function graphemeAt - * @static - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to extract from. - * @param {number} position The position to get the grapheme. - * @return {string} Returns the grapheme at specified position. - * @example - * v.graphemeAt('\uD835\uDC00\uD835\uDC01', 0); // or '𝐀𝐁' - * // => 'A' - * - * v.graphemeAt('cafe\u0301', 3); // or 'café' - * // => 'é' - */ -function graphemeAt(subject, position) { - var subjectString = coerceToString(subject); - var positionNumber = coerceToNumber(position); - var graphemeMatch = void 0; - var graphemeMatchIndex = 0; - positionNumber = nanDefault(positionNumber, 0); - while ((graphemeMatch = REGEXP_UNICODE_CHARACTER.exec(subjectString)) !== null) { - if (graphemeMatchIndex === positionNumber) { - REGEXP_UNICODE_CHARACTER.lastIndex = 0; - return graphemeMatch[0]; - } - graphemeMatchIndex++; - } - return ''; -} - -/** - * Extracts the last `length` characters from `subject`. - * - * @function last - * @static - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to extract from. - * @param {int} [length=1] The number of characters to extract. - * @return {string} Returns the last characters string. - * @example - * v.last('helicopter'); - * // => 'r' - * - * v.last('vehicle', 2); - * // => 'le' - * - * v.last('car', 5); - * // => 'car' - */ -function last(subject, length) { - var subjectString = coerceToString(subject); - var lengthInt = isNil(length) ? 1 : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER); - if (subjectString.length <= lengthInt) { - return subjectString; - } - return subjectString.substr(subjectString.length - lengthInt, lengthInt); -} - -/** - * Truncates `subject` to a new `length` and does not break the words. Guarantees that the truncated string is no longer - * than `length`. - * - * @static - * @function prune - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to prune. - * @param {int} length The length to prune the string. - * @param {string} [end='...'] The string to be added at the end. - * @return {string} Returns the pruned string. - * @example - * v.prune('Once upon a time', 7); - * // => 'Once...' - * - * v.prune('Good day, Little Red Riding Hood', 16, ' (more)'); - * // => 'Good day (more)' - * - * v.prune('Once upon', 10); - * // => 'Once upon' - */ -function prune(subject, length, end) { - var subjectString = coerceToString(subject); - var lengthInt = isNil(length) ? subjectString.length : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER); - var endString = coerceToString(end, '...'); - if (lengthInt >= subjectString.length) { - return subjectString; - } - var pattern = REGEXP_EXTENDED_ASCII.test(subjectString) ? REGEXP_LATIN_WORD : REGEXP_WORD; - var truncatedLength = 0; - subjectString.replace(pattern, function (word, offset) { - var wordInsertLength = offset + word.length; - if (wordInsertLength <= lengthInt - endString.length) { - truncatedLength = wordInsertLength; - } - }); - return subjectString.substr(0, truncatedLength) + endString; -} - -/** - * Extracts from `subject` a string from `start` position up to `end` position. The character at `end` position is not - * included. - * - * @function slice - * @static - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to extract from. - * @param {number} start The position to start extraction. If negative use `subject.length + start`. - * @param {number} [end=subject.length] The position to end extraction. If negative use `subject.length + end`. - * @return {string} Returns the extracted string. - * @note Uses native `String.prototype.slice()` - * @example - * v.slice('miami', 1); - * // => 'iami' - * - * v.slice('florida', -4); - * // => 'rida' - * - * v.slice('florida', 1, 4); - * // => "lor" - */ -function slice(subject, start, end) { - return coerceToString(subject).slice(start, end); -} - -/** - * Extracts from `subject` a string from `start` position a number of `length` characters. - * - * @function substr - * @static - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to extract from. - * @param {number} start The position to start extraction. - * @param {number} [length=subject.endOfString] The number of characters to extract. If omitted, extract to the end of `subject`. - * @return {string} Returns the extracted string. - * @note Uses native `String.prototype.substr()` - * @example - * v.substr('infinite loop', 9); - * // => 'loop' - * - * v.substr('dreams', 2, 2); - * // => 'ea' - */ -function substr(subject, start, length) { - return coerceToString(subject).substr(start, length); -} - -/** - * Extracts from `subject` a string from `start` position up to `end` position. The character at `end` position is not - * included. - * - * @function substring - * @static - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to extract from. - * @param {number} start The position to start extraction. - * @param {number} [end=subject.length] The position to end extraction. - * @return {string} Returns the extracted string. - * @note Uses native `String.prototype.substring()` - * @example - * v.substring('beach', 1); - * // => 'each' - * - * v.substring('ocean', 1, 3); - * // => 'ea' - */ -function substring(subject, start, end) { - return coerceToString(subject).substring(start, end); -} - -/** - * Counts the characters in `subject`.
- * - * @function count - * @static - * @since 1.0.0 - * @memberOf Count - * @param {string} [subject=''] The string to count characters. - * @return {number} Returns the number of characters in `subject`. - * @example - * v.count('rain'); - * // => 4 - */ -function count(subject) { - return coerceToString(subject).length; -} - -/** - * Counts the graphemes in `subject` taking care of - * surrogate pairs and - * combining marks. - * - * @function countGraphemes - * @static - * @since 1.0.0 - * @memberOf Count - * @param {string} [subject=''] The string to count graphemes. - * @return {number} Returns the number of graphemes in `subject`. - * @example - * v.countGraphemes('cafe\u0301'); // or 'café' - * // => 4 - * - * v.countGraphemes('\uD835\uDC00\uD835\uDC01'); // or '𝐀𝐁' - * // => 2 - * - * v.countGraphemes('rain'); - * // => 4 - */ -function countGrapheme(subject) { - return coerceToString(subject).replace(REGEXP_COMBINING_MARKS, '*').replace(REGEXP_SURROGATE_PAIRS, '*').length; -} - -/** - * Counts the number of `substring` appearances in `subject`. - * - * @function countSubstrings - * @static - * @since 1.0.0 - * @memberOf Count - * @param {string} [subject=''] The string where to count. - * @param {string} substring The substring to be counted. - * @return {number} Returns the number of `substring` appearances. - * @example - * v.countSubstrings('bad boys, bad boys whatcha gonna do?', 'boys'); - * // => 2 - * - * v.countSubstrings('every dog has its day', 'cat'); - * // => 0 - */ -function countSubstrings(subject, substring) { - var subjectString = coerceToString(subject); - var substringString = coerceToString(substring); - var substringLength = substringString.length; - var count = 0; - var matchIndex = 0; - if (subjectString === '' || substringString === '') { - return count; - } - do { - matchIndex = subjectString.indexOf(substringString, matchIndex); - if (matchIndex !== -1) { - count++; - matchIndex += substringLength; - } - } while (matchIndex !== -1); - return count; -} - -var reduce = Array.prototype.reduce; - -/** - * Counts the characters in `subject` for which `predicate` returns truthy. - * - * @function countWhere - * @static - * @since 1.0.0 - * @memberOf Count - * @param {string} [subject=''] The string to count characters. - * @param {Function} predicate The predicate function invoked on each character with parameters `(character, index, string)`. - * @param {Object} [context] The context to invoke the `predicate`. - * @return {number} Returns the number of characters for which `predicate` returns truthy. - * @example - * v.countWhere('hola!', v.isAlpha); - * // => 4 - * - * v.countWhere('2022', function(character, index, str) { - * return character === '2'; - * }); - * // => 3 - */ -function countWhere(subject, predicate, context) { - var subjectString = coerceToString(subject); - if (subjectString === '' || typeof predicate !== 'function') { - return 0; - } - var predicateWithContext = predicate.bind(context); - return reduce.call(subjectString, function (countTruthy, character, index) { - return predicateWithContext(character, index, subjectString) ? countTruthy + 1 : countTruthy; - }, 0); -} - -/** - * Counts the number of words in `subject`. - * - * @function countWords - * @static - * @since 1.0.0 - * @memberOf Count - * @param {string} [subject=''] The string to split into words. - * @param {string|RegExp} [pattern] The pattern to watch words. If `pattern` is not RegExp, it is transformed to `new RegExp(pattern, flags)`. - * @param {string} [flags=''] The regular expression flags. Applies when `pattern` is string type. - * @return {number} Returns the number of words. - * @example - * v.countWords('gravity can cross dimensions'); - * // => 4 - * - * v.countWords('GravityCanCrossDimensions'); - * // => 4 - * - * v.countWords('Gravity - can cross dimensions!'); - * // => 4 - * - * v.words('Earth gravity', /[^\s]+/g); - * // => 2 - */ -function countWords(subject, pattern, flags) { - return words(subject, pattern, flags).length; -} - -/** - * The current index. - * - * @ignore - * @name ReplacementIndex#index - * @type {number} - * @return {ReplacementIndex} ReplacementIndex instance. - */ -function ReplacementIndex() { - this.index = 0; -} - -/** - * Increment the current index. - * - * @ignore - * @return {undefined} - */ -ReplacementIndex.prototype.increment = function () { - this.index++; -}; - -/** - * Increment the current index by position. - * - * @ignore - * @param {number} [position] The replacement position. - * @return {undefined} - */ -ReplacementIndex.prototype.incrementOnEmptyPosition = function (position) { - if (isNil(position)) { - this.increment(); - } -}; - -/** - * Get the replacement index by position. - * - * @ignore - * @param {number} [position] The replacement position. - * @return {number} The replacement index. - */ -ReplacementIndex.prototype.getIndexByPosition = function (position) { - return isNil(position) ? this.index : position - 1; -}; - -var Const = Object.freeze({ - // Type specifiers - TYPE_INTEGER: 'i', - TYPE_INTEGER_BINARY: 'b', - TYPE_INTEGER_ASCII_CHARACTER: 'c', - TYPE_INTEGER_DECIMAL: 'd', - TYPE_INTEGER_OCTAL: 'o', - TYPE_INTEGER_UNSIGNED_DECIMAL: 'u', - TYPE_INTEGER_HEXADECIMAL: 'x', - TYPE_INTEGER_HEXADECIMAL_UPPERCASE: 'X', - TYPE_FLOAT_SCIENTIFIC: 'e', - TYPE_FLOAT_SCIENTIFIC_UPPERCASE: 'E', - TYPE_FLOAT: 'f', - TYPE_FLOAT_SHORT: 'g', - TYPE_FLOAT_SHORT_UPPERCASE: 'G', - TYPE_STRING: 's', - - // Simple literals - LITERAL_PERCENT: '%', - LITERAL_SINGLE_QUOTE: "'", - LITERAL_PLUS: '+', - LITERAL_MINUS: '-', - LITERAL_PERCENT_SPECIFIER: '%%', - - // Radix constants to format numbers - RADIX_BINARY: 2, - RADIX_OCTAL: 8, - RADIX_DECIMAL: 10, - RADIX_HEXADECIMAL: 16 -}); - -/** - * Repeats the `subject` number of `times`. - * - * @function repeat - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to repeat. - * @param {number} [times=1] The number of times to repeat. - * @return {string} Returns the repeated string. - * @example - * v.repeat('w', 3); - * // => 'www' - * - * v.repeat('world', 0); - * // => '' - */ -function repeat(subject, times) { - var subjectString = coerceToString(subject); - var timesInt = isNil(times) ? 1 : clipNumber(toInteger(times), 0, MAX_SAFE_INTEGER); - var repeatString = ''; - while (timesInt) { - if (timesInt & 1) { - repeatString += subjectString; - } - if (timesInt > 1) { - subjectString += subjectString; - } - timesInt >>= 1; - } - return repeatString; -} - -/** - * Creates the padding string. - * - * @ignore - * @param {string} padCharacters The characters to create padding string. - * @param {number} length The padding string length. - * @return {string} The padding string. - */ -function buildPadding(padCharacters, length) { - var padStringRepeat = toInteger(length / padCharacters.length); - var padStringRest = length % padCharacters.length; - return repeat(padCharacters, padStringRepeat + padStringRest).substr(0, length); -} - -/** - * Pads `subject` from left to a new `length`. - * - * @function padLeft - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to pad. - * @param {int} [length=0] The length to left pad the string. No changes are made if `length` is less than `subject.length`. - * @param {string} [pad=' '] The string to be used for padding. - * @return {string} Returns the left padded string. - * @example - * v.padLeft('dog', 5); - * // => ' dog' - * - * v.padLeft('bird', 6, '-'); - * // => '--bird' - * - * v.padLeft('cat', 6, '-='); - * // => '-=-cat' - */ -function padLeft(subject, length, pad) { - var subjectString = coerceToString(subject); - var lengthInt = isNil(length) ? 0 : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER); - var padString = coerceToString(pad, ' '); - if (lengthInt <= subjectString.length) { - return subjectString; - } - return buildPadding(padString, lengthInt - subjectString.length) + subjectString; -} - -/** - * Pads `subject` from right to a new `length`. - * - * @function padRight - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to pad. - * @param {int} [length=0] The length to right pad the string. No changes are made if `length` is less than `subject.length`. - * @param {string} [pad=' '] The string to be used for padding. - * @return {string} Returns the right padded string. - * @example - * v.padRight('dog', 5); - * // => 'dog ' - * - * v.padRight('bird', 6, '-'); - * // => 'bird--' - * - * v.padRight('cat', 6, '-='); - * // => 'cat-=-' - */ -function padRight(subject, length, pad) { - var subjectString = coerceToString(subject); - var lengthInt = isNil(length) ? 0 : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER); - var padString = coerceToString(pad, ' '); - if (lengthInt <= subjectString.length) { - return subjectString; - } - return subjectString + buildPadding(padString, lengthInt - subjectString.length); -} - -/** - * Aligns and pads `subject` string. - * - * @ignore - * @param {string} subject The subject string. - * @param {ConversionSpecification} conversion The conversion specification object. - * @return {string} Returns the aligned and padded string. - */ -function alignAndPad(subject, conversion) { - var width = conversion.width; - if (isNil(width) || subject.length >= width) { - return subject; - } - var padType = conversion.alignmentSpecifier === Const.LITERAL_MINUS ? padRight : padLeft; - return padType(subject, width, conversion.getPaddingCharacter()); -} - -/** - * Add sign to the formatted number. - * - * @ignore - * @name addSignToFormattedNumber - * @param {number} replacementNumber The number to be replaced. - * @param {string} formattedReplacement The formatted version of number. - * @param {ConversionSpecification} conversion The conversion specification object. - * @return {string} Returns the formatted number string with a sign. - */ -function addSignToFormattedNumber(replacementNumber, formattedReplacement, conversion) { - if (conversion.signSpecifier === Const.LITERAL_PLUS && replacementNumber >= 0) { - formattedReplacement = Const.LITERAL_PLUS + formattedReplacement; - } - return formattedReplacement; -} - -/** - * Formats a float type according to specifiers. - * - * @ignore - * @param {string} replacement The string to be formatted. - * @param {ConversionSpecification} conversion The conversion specification object. - * @return {string} Returns the formatted string. - */ - -function float(replacement, conversion) { - var replacementNumber = parseFloat(replacement); - var formattedReplacement = void 0; - if (isNaN(replacementNumber)) { - replacementNumber = 0; - } - var precision = coerceToNumber(conversion.precision, 6); - switch (conversion.typeSpecifier) { - case Const.TYPE_FLOAT: - formattedReplacement = replacementNumber.toFixed(precision); - break; - case Const.TYPE_FLOAT_SCIENTIFIC: - formattedReplacement = replacementNumber.toExponential(precision); - break; - case Const.TYPE_FLOAT_SCIENTIFIC_UPPERCASE: - formattedReplacement = replacementNumber.toExponential(precision).toUpperCase(); - break; - case Const.TYPE_FLOAT_SHORT: - case Const.TYPE_FLOAT_SHORT_UPPERCASE: - formattedReplacement = formatFloatAsShort(replacementNumber, precision, conversion); - break; - } - formattedReplacement = addSignToFormattedNumber(replacementNumber, formattedReplacement, conversion); - return coerceToString(formattedReplacement); -} - -/** - * Formats the short float. - * - * @ignore - * @param {number} replacementNumber The number to format. - * @param {number} precision The precision to format the float. - * @param {ConversionSpecification} conversion The conversion specification object. - * @return {string} Returns the formatted short float. - */ -function formatFloatAsShort(replacementNumber, precision, conversion) { - if (replacementNumber === 0) { - return '0'; - } - var nonZeroPrecision = precision === 0 ? 1 : precision; - var formattedReplacement = replacementNumber.toPrecision(nonZeroPrecision).replace(REGEXP_TRAILING_ZEROS, ''); - if (conversion.typeSpecifier === Const.TYPE_FLOAT_SHORT_UPPERCASE) { - formattedReplacement = formattedReplacement.toUpperCase(); - } - return formattedReplacement; -} - -/** - * Formats an integer type according to specifiers. - * - * @ignore - * @param {string} replacement The string to be formatted. - * @param {ConversionSpecification} conversion The conversion specification object. - * @return {string} Returns the formatted string. - */ - -function integerBase(replacement, conversion) { - var integer = parseInt(replacement); - if (isNaN(integer)) { - integer = 0; - } - integer = integer >>> 0; - switch (conversion.typeSpecifier) { - case Const.TYPE_INTEGER_ASCII_CHARACTER: - integer = String.fromCharCode(integer); - break; - case Const.TYPE_INTEGER_BINARY: - integer = integer.toString(Const.RADIX_BINARY); - break; - case Const.TYPE_INTEGER_OCTAL: - integer = integer.toString(Const.RADIX_OCTAL); - break; - case Const.TYPE_INTEGER_HEXADECIMAL: - integer = integer.toString(Const.RADIX_HEXADECIMAL); - break; - case Const.TYPE_INTEGER_HEXADECIMAL_UPPERCASE: - integer = integer.toString(Const.RADIX_HEXADECIMAL).toUpperCase(); - break; - } - return coerceToString(integer); -} - -/** - * Formats a decimal integer type according to specifiers. - * - * @ignore - * @param {string} replacement The string to be formatted. - * @param {ConversionSpecification} conversion The conversion specification object. - * @return {string} Returns the formatted string. - */ - -function integerDecimal(replacement, conversion) { - var integer = parseInt(replacement); - if (isNaN(integer)) { - integer = 0; - } - return addSignToFormattedNumber(integer, toString(integer), conversion); -} - -/** - * Formats a string type according to specifiers. - * - * @ignore - * @param {string} replacement The string to be formatted. - * @param {ConversionSpecification} conversion The conversion specification object. - * @return {string} Returns the formatted string. - */ -function stringFormat(replacement, conversion) { - var formattedReplacement = replacement; - var precision = conversion.precision; - if (!isNil(precision) && formattedReplacement.length > precision) { - formattedReplacement = truncate(formattedReplacement, precision, ''); - } - return formattedReplacement; -} - -/** - * Returns the computed string based on format specifiers. - * - * @ignore - * @name computeReplacement - * @param {string} replacement The replacement value. - * @param {ConversionSpecification} conversion The conversion specification object. - * @return {string} Returns the computed string. - */ -function compute(replacement, conversion) { - var formatFunction = void 0; - switch (conversion.typeSpecifier) { - case Const.TYPE_STRING: - formatFunction = stringFormat; - break; - case Const.TYPE_INTEGER_DECIMAL: - case Const.TYPE_INTEGER: - formatFunction = integerDecimal; - break; - case Const.TYPE_INTEGER_ASCII_CHARACTER: - case Const.TYPE_INTEGER_BINARY: - case Const.TYPE_INTEGER_OCTAL: - case Const.TYPE_INTEGER_HEXADECIMAL: - case Const.TYPE_INTEGER_HEXADECIMAL_UPPERCASE: - case Const.TYPE_INTEGER_UNSIGNED_DECIMAL: - formatFunction = integerBase; - break; - case Const.TYPE_FLOAT: - case Const.TYPE_FLOAT_SCIENTIFIC: - case Const.TYPE_FLOAT_SCIENTIFIC_UPPERCASE: - case Const.TYPE_FLOAT_SHORT: - case Const.TYPE_FLOAT_SHORT_UPPERCASE: - formatFunction = float; - break; - } - var formattedString = formatFunction(replacement, conversion); - return alignAndPad(formattedString, conversion); -} - -/** - * Construct the new conversion specification object. - * - * @ignore - * @param {Object} properties An object with properties to initialize. - * @return {ConversionSpecification} ConversionSpecification instance. - */ -function ConversionSpecification(properties) { - - /** - * The percent characters from conversion specification. - * - * @ignore - * @name ConversionSpecification#percent - * @type {string} - */ - this.percent = properties.percent; - - /** - * The sign specifier to force a sign to be used on a number. - * - * @ignore - * @name ConversionSpecification#signSpecifier - * @type {string} - */ - this.signSpecifier = properties.signSpecifier; - - /** - * The padding specifier that says what padding character will be used. - * - * @ignore - * @name ConversionSpecification#paddingSpecifier - * @type {string} - */ - this.paddingSpecifier = properties.paddingSpecifier; - - /** - * The alignment specifier that says if the result should be left-justified or right-justified. - * - * @ignore - * @name ConversionSpecification#alignmentSpecifier - * @type {string} - */ - this.alignmentSpecifier = properties.alignmentSpecifier; - - /** - * The width specifier how many characters this conversion should result in. - * - * @ignore - * @name ConversionSpecification#width - * @type {number} - */ - this.width = properties.width; - - /** - * The precision specifier says how many decimal digits should be displayed for floating-point numbers. - * - * @ignore - * @name ConversionSpecification#precision - * @type {number} - */ - this.precision = properties.precision; - - /** - * The type specifier says what type the argument data should be treated as. - * - * @ignore - * @name ConversionSpecification#typeSpecifier - * @type {string} - */ - this.typeSpecifier = properties.typeSpecifier; -} - -/** - * Check if the conversion specification is a percent literal "%%". - * - * @ignore - * @return {boolean} Returns true if the conversion is a percent literal, false otherwise. - */ -ConversionSpecification.prototype.isPercentLiteral = function () { - return Const.LITERAL_PERCENT_SPECIFIER === this.percent; -}; - -/** - * Get the padding character from padding specifier. - * - * @ignore - * @returns {string} Returns the padding character. - */ -ConversionSpecification.prototype.getPaddingCharacter = function () { - var paddingCharacter = nilDefault(this.paddingSpecifier, ' '); - if (paddingCharacter.length === 2 && paddingCharacter[0] === Const.LITERAL_SINGLE_QUOTE) { - paddingCharacter = paddingCharacter[1]; - } - return paddingCharacter; -}; - -/** - * Validates the specifier type and replacement position. - * - * @ignore - * @throws {Error} Throws an exception on insufficient arguments or unknown specifier. - * @param {number} index The index of the matched specifier. - * @param {number} replacementsLength The number of replacements. - * @param {ConversionSpecification} conversion The conversion specification object. - * @return {undefined} - */ -function validate(index, replacementsLength, conversion) { - if (isNil(conversion.typeSpecifier)) { - throw new Error('sprintf(): Unknown type specifier'); - } - if (index > replacementsLength - 1) { - throw new Error('sprintf(): Too few arguments'); - } - if (index < 0) { - throw new Error('sprintf(): Argument number must be greater than zero'); - } -} - -/** - * Return the replacement for regular expression match of the conversion specification. - * - * @ignore - * @name matchReplacement - * @param {ReplacementIndex} replacementIndex The replacement index object. - * @param {string[]} replacements The array of replacements. - * @param {string} conversionSpecification The conversion specification. - * @param {string} percent The percent characters from conversion specification. - * @param {string} position The position to insert the replacement. - * @param {string} signSpecifier The sign specifier to force a sign to be used on a number. - * @param {string} paddingSpecifier The padding specifier that says what padding character will be used. - * @param {string} alignmentSpecifier The alignment specifier that says if the result should be left-justified or right-justified. - * @param {string} widthSpecifier The width specifier how many characters this conversion should result in. - * @param {string} precisionSpecifier The precision specifier says how many decimal digits should be displayed for floating-point numbers. - * @param {string} typeSpecifier The type specifier says what type the argument data should be treated as. - * @return {string} Returns the computed replacement. - */ -function match(replacementIndex, replacements, conversionSpecification, percent, position, signSpecifier, paddingSpecifier, alignmentSpecifier, widthSpecifier, precisionSpecifier, typeSpecifier) { - var conversion = new ConversionSpecification({ - percent: percent, - signSpecifier: signSpecifier, - paddingSpecifier: paddingSpecifier, - alignmentSpecifier: alignmentSpecifier, - width: coerceToNumber(widthSpecifier, null), - precision: coerceToNumber(precisionSpecifier, null), - typeSpecifier: typeSpecifier - }); - if (conversion.isPercentLiteral()) { - return conversionSpecification.slice(1); - } - var actualReplacementIndex = replacementIndex.getIndexByPosition(position); - replacementIndex.incrementOnEmptyPosition(position); - validate(actualReplacementIndex, replacements.length, conversion); - return compute(replacements[actualReplacementIndex], conversion); -} - -/** - * Produces a string according to `format`. - * - *
- * `format` string is composed of zero or more directives: ordinary characters (not %), which are copied unchanged - * to the output string and conversion specifications, each of which results in fetching zero or more subsequent - * arguments.

- * - * Each conversion specification is introduced by the character %, and ends with a conversion - * specifier. In between there may be (in this order) zero or more flags, an optional minimum field width - * and an optional precision.
- * The syntax is: ConversionSpecification = "%" { Flags } - * [ MinimumFieldWidth ] [ Precision ] ConversionSpecifier, where curly braces { } denote repetition - * and square brackets [ ] optionality.

- * - * By default, the arguments are used in the given order.
- * For argument numbering and swapping, `%m$` (where `m` is a number indicating the argument order) - * is used instead of `%` to specify explicitly which argument is taken. For instance `%1$s` fetches the 1st argument, - * `%2$s` the 2nd and so on, no matter what position the conversion specification has in `format`. - *

- * - * The flags
- * The character % is followed by zero or more of the following flags:
- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
+ - * A sign (+ or -) should always be placed before a number produced by a - * signed conversion. By default a sign is used only for negative numbers. - *
0The value should be zero padded.
(a space) The value should be space padded.
'Indicates alternate padding character, specified by prefixing it with a single quote '.
-The converted value is to be left adjusted on the field boundary (the default is right justification).
- * - * The minimum field width
- * An optional decimal digit string (with nonzero first digit) specifying a minimum field width. If the converted - * value has fewer characters than the field width, it will be padded with spaces on the left (or right, if the - * left-adjustment flag has been given).

- * - * The precision
- * An optional precision, in the form of a period `.` followed by an optional decimal digit string.
- * This gives the number of digits to appear after the radix character for `e`, `E`, `f` and `F` conversions, the - * maximum number of significant digits for `g` and `G` conversions or the maximum number of characters to be printed - * from a string for `s` conversion.

- * - * The conversion specifier
- * A specifier that mentions what type the argument should be treated as: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
`s`The string argument is treated as and presented as a string.
`d` `i`The integer argument is converted to signed decimal notation.
`b`The unsigned integer argument is converted to unsigned binary.
`c`The unsigned integer argument is converted to an ASCII character with that number.
`o`The unsigned integer argument is converted to unsigned octal.
`u`The unsigned integer argument is converted to unsigned decimal.
`x` `X`The unsigned integer argument is converted to unsigned hexadecimal. The letters `abcdef` are used for `x` - * conversions; the letters `ABCDEF` are used for `X` conversions.
`f` - * The float argument is rounded and converted to decimal notation in the style `[-]ddd.ddd`, where the number of - * digits after the decimal-point character is equal to the precision specification. If the precision is missing, - * it is taken as 6; if the precision is explicitly zero, no decimal-point character appears. - * If a decimal point appears, at least one digit appears before it. - *
`e` `E` - * The float argument is rounded and converted in the style `[-]d.ddde±dd`, where there is one digit - * before the decimal-point character and the number of digits after it is equal to the precision. If - * the precision is missing, it is taken as `6`; if the precision is zero, no decimal-point character - * appears. An `E` conversion uses the letter `E` (rather than `e`) to introduce the exponent. - *
`g` `G` - * The float argument is converted in style `f` or `e` (or `F` or `E` for `G` conversions). The precision specifies - * the number of significant digits. If the precision is missing, `6` digits are given; if the - * precision is zero, it is treated as `1`. Style `e` is used if the exponent from its conversion is less - * than `-6` or greater than or equal to the precision. Trailing zeros are removed from the fractional - * part of the result; a decimal point appears only if it is followed by at least one digit. - *
`%`A literal `%` is written. No argument is converted. The complete conversion specification is `%%`.
- *
- * - * @function sprintf - * @static - * @since 1.0.0 - * @memberOf Format - * @param {string} [format=''] The format string. - * @param {...*} replacements The replacements to produce the string. - * @return {string} Returns the produced string. - * @example - * v.sprintf('%s, %s!', 'Hello', 'World'); - * // => 'Hello World!' - * - * v.sprintf('%s costs $%d', 'coffee', 2); - * // => 'coffee costs $2' - * - * v.sprintf('%1$s %2$s %1$s %2$s, watcha gonna %3$s', 'bad', 'boys', 'do') - * // => 'bad boys bad boys, watcha gonna do' - * - * v.sprintf('% 6s', 'bird'); - * // => ' bird' - * - * v.sprintf('% -6s', 'crab'); - * // => 'crab ' - * - * v.sprintf("%'*5s", 'cat'); - * // => '**cat' - * - * v.sprintf("%'*-6s", 'duck'); - * // => 'duck**' - * - * v.sprintf('%d %i %+d', 15, -2, 25); - * // => '15 -2 +25' - * - * v.sprintf("%06d", 15); - * // => '000015' - * - * v.sprintf('0b%b 0o%o 0x%X', 12, 9, 155); - * // => '0b1100 0o11 0x9B' - * - * v.sprintf('%.2f', 10.469); - * // => '10.47' - * - * v.sprintf('%.2e %g', 100.5, 0.455); - * // => '1.01e+2 0.455' - * - */ -function sprintf(format) { - var formatString = coerceToString(format); - if (formatString === '') { - return formatString; - } - - for (var _len = arguments.length, replacements = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - replacements[_key - 1] = arguments[_key]; - } - - var boundReplacementMatch = match.bind(undefined, new ReplacementIndex(), replacements); - return formatString.replace(REGEXP_CONVERSION_SPECIFICATION, boundReplacementMatch); -} - -function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } - -/** - * Produces a string according to `format`. Works exactly like sprintf(), - * with the only difference that accepts the formatting arguments in an array `values`.
- * See here `format` string specifications. - * - * @function vprintf - * @static - * @since 1.0.0 - * @memberOf Format - * @param {string} format=''] The format string. - * @param {Array} replacements The array of replacements to produce the string. - * @return {string} Returns the produced string. - * @example - * v.vprintf('%s', ['Welcome']) - * // => 'Welcome' - * - * v.vprintf('%s has %d apples', ['Alexandra', 3]); - * // => 'Alexandra has 3 apples' - */ -function vprintf(format, replacements) { - return sprintf.apply(undefined, [format].concat(_toConsumableArray(nilDefault(replacements, [])))); -} - -var escapeCharactersMap = { - '<': '<', - '>': '>', - '&': '&', - '"': '"', - "'": ''', - '`': '`' -}; - -/** - * Return the escaped version of `character`. - * - * @ignore - * @param {string} character The character to be escape. - * @return {string} The escaped version of character. - */ -function replaceSpecialCharacter(character) { - return escapeCharactersMap[character]; -} - -/** - * Escapes HTML special characters < > & ' " ` in subject. - * - * @function escapeHtml - * @static - * @since 1.0.0 - * @memberOf Escape - * @param {string} [subject=''] The string to escape. - * @return {string} Returns the escaped string. - * @example - * v.escapeHtml('

wonderful world

'); - * // => '<p>wonderful world</p>' - */ -function escapeHtml(subject) { - return coerceToString(subject).replace(REGEXP_HTML_SPECIAL_CHARACTERS, replaceSpecialCharacter); -} - -/** - * Escapes the regular expression special characters `- [ ] / { } ( ) * + ? . \ ^ $ |` in `subject`. - * - * @function escapeRegExp - * @static - * @since 1.0.0 - * @memberOf Escape - * @param {string} [subject=''] The string to escape. - * @return {string} Returns the escaped string. - * @example - * v.escapeRegExp('(hours)[minutes]{seconds}'); - * // => '\(hours\)\[minutes\]\{seconds\}' - */ -function escapeRegExp(subject) { - return coerceToString(subject).replace(REGEXP_SPECIAL_CHARACTERS, '\\$&'); -} - -var unescapeCharactersMap = { - '<': /(<)|(�*3c;)|(�*60;)/gi, - '>': /(>)|(�*3e;)|(�*62;)/gi, - '&': /(&)|(�*26;)|(�*38;)/gi, - '"': /(")|(�*22;)|(�*34;)/gi, - "'": /(�*27;)|(�*39;)/gi, - '`': /(�*60;)|(�*96;)/gi -}; -var characters = Object.keys(unescapeCharactersMap); - -/** - * Replaces the HTML entities with corresponding characters. - * - * @ignore - * @param {string} string The accumulator string. - * @param {string} key The character. - * @return {string} The string with replaced HTML entity - */ -function reduceUnescapedString(string, key) { - return string.replace(unescapeCharactersMap[key], key); -} - -/** - * Unescapes HTML special characters from &lt; &gt; &amp; &quot; &#x27; &#x60; - * to corresponding < > & ' " ` in subject. - * - * @function unescapeHtml - * @static - * @since 1.0.0 - * @memberOf Escape - * @param {string} [subject=''] The string to unescape. - * @return {string} Returns the unescaped string. - * @example - * v.unescapeHtml('<p>wonderful world</p>'); - * // => '

wonderful world

' - */ -function unescapeHtml(subject) { - var subjectString = coerceToString(subject); - return characters.reduce(reduceUnescapedString, subjectString); -} - -/** - * Returns the first occurrence index of `search` in `subject`. - * - * @function indexOf - * @static - * @since 1.0.0 - * @memberOf Index - * @param {string} [subject=''] The string where to search. - * @param {string} search The string to search. - * @param {number} [fromIndex=0] The index to start searching. - * @return {number} Returns the first occurrence index or `-1` if not found. - * @example - * v.indexOf('morning', 'n'); - * // => 3 - * - * v.indexOf('evening', 'o'); - * // => -1 - */ -function indexOf(subject, search, fromIndex) { - var subjectString = coerceToString(subject); - return subjectString.indexOf(search, fromIndex); -} - -/** - * Returns the last occurrence index of `search` in `subject`. - * - * @function lastIndexOf - * @static - * @since 1.0.0 - * @memberOf Index - * @param {string} [subject=''] The string where to search. - * @param {string} search The string to search. - * @param {number} [fromIndex=subject.length - 1] The index to start searching backward in the string. - * @return {number} Returns the last occurrence index or `-1` if not found. - * @example - * v.lastIndexOf('morning', 'n'); - * // => 5 - * - * v.lastIndexOf('evening', 'o'); - * // => -1 - */ -function lastIndexOf(subject, search, fromIndex) { - var subjectString = coerceToString(subject); - return subjectString.lastIndexOf(search, fromIndex); -} - -/** - * Returns the first index of a `pattern` match in `subject`. - * - * @function search - * @static - * @since 1.0.0 - * @memberOf Index - * @param {string} [subject=''] The string where to search. - * @param {string|RegExp} pattern The pattern to match. If `pattern` is not RegExp, it is transformed to `new RegExp(pattern)`. - * @param {number} [fromIndex=0] The index to start searching. - * @return {number} Returns the first match index or `-1` if not found. - * @example - * v.search('morning', /rn/); - * // => 2 - * - * v.search('evening', '/\d/'); - * // => -1 - */ -function search(subject, pattern, fromIndex) { - var subjectString = coerceToString(subject); - var fromIndexNumber = isNil(fromIndex) ? 0 : clipNumber(toInteger(fromIndex), 0, subjectString.length); - var matchIndex = subjectString.substr(fromIndexNumber).search(pattern); - if (matchIndex !== -1 && !isNaN(fromIndexNumber)) { - matchIndex += fromIndexNumber; - } - return matchIndex; -} - -/** - * Inserts into `subject` a string `toInsert` at specified `position`. - * - * @function insert - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string where to insert. - * @param {string} [toInsert=''] The string to be inserted. - * @param {number} [position=0] The position to insert. - * @return {string} Returns the string after insertion. - * @example - * v.insert('ct', 'a', 1); - * // => 'cat' - * - * v.insert('sunny', ' day', 5); - * // => 'sunny day' - */ -function insert(subject, toInsert, position) { - var subjectString = coerceToString(subject); - var toInsertString = coerceToString(toInsert); - var positionNumber = coerceToNumber(position); - if (positionNumber < 0 || positionNumber > subjectString.length || toInsertString === '') { - return subjectString; - } - return subjectString.slice(0, positionNumber) + toInsertString + subjectString.slice(positionNumber); -} - -/** - * Generated diacritics map. See bellow the base code. - * @ignore - * @see http://stackoverflow.com/a/18391901/1894471 - * @type Object - */ - -var diacritics = { - "3": "\u039e\u03be", - "8": "\u0398\u03b8", - "A": "\x41\xc0\xc1\xc2\xc3\xc4\xc5\u0100\u0102\u0104\u01cd\u01de\u01e0\u01fa\u0200\u0202\u0226\u023a\u1e00\u1ea0\u1ea2\u1ea4\u1ea6\u1ea8\u1eaa\u1eac\u1eae\u1eb0\u1eb2\u1eb4\u1eb6\u24b6\u2c6f\uff21\u0386\u0391\u0410", - "B": "\x42\u0181\u0182\u0243\u1e02\u1e04\u1e06\u24b7\uff22\u0392\u0411", - "C": "\x43\xc7\u0106\u0108\u010a\u010c\u0187\u023b\u1e08\u24b8\ua73e\uff23\u0426", - "D": "\x44\u010e\u0110\u0189\u018a\u018b\u1e0a\u1e0c\u1e0e\u1e10\u1e12\u24b9\ua779\uff24\xd0\u0394\u0414", - "E": "\x45\xc8\xc9\xca\xcb\u0112\u0114\u0116\u0118\u011a\u018e\u0190\u0204\u0206\u0228\u1e14\u1e16\u1e18\u1e1a\u1e1c\u1eb8\u1eba\u1ebc\u1ebe\u1ec0\u1ec2\u1ec4\u1ec6\u24ba\uff25\u0388\u0395\u0415\u042d", - "F": "\x46\u0191\u1e1e\u24bb\ua77b\uff26\u03a6\u0424", - "G": "\x47\u011c\u011e\u0120\u0122\u0193\u01e4\u01e6\u01f4\u1e20\u24bc\ua77d\ua77e\ua7a0\uff27\u0393\u0413\u0490", - "H": "\x48\u0124\u0126\u021e\u1e22\u1e24\u1e26\u1e28\u1e2a\u24bd\u2c67\u2c75\ua78d\uff28\u0389\u0397\u0425", - "I": "\x49\xcc\xcd\xce\xcf\u0128\u012a\u012c\u012e\u0130\u0197\u01cf\u0208\u020a\u1e2c\u1e2e\u1ec8\u1eca\u24be\uff29\u038a\u0399\u03aa\u0406\u0418", - "J": "\x4a\u0134\u0248\u24bf\uff2a\u0419", - "K": "\x4b\u0136\u0198\u01e8\u1e30\u1e32\u1e34\u24c0\u2c69\ua740\ua742\ua744\ua7a2\uff2b\u039a\u041a", - "L": "\x4c\u0139\u013b\u013d\u013f\u0141\u023d\u1e36\u1e38\u1e3a\u1e3c\u24c1\u2c60\u2c62\ua746\ua748\ua780\uff2c\u039b\u041b", - "M": "\x4d\u019c\u1e3e\u1e40\u1e42\u24c2\u2c6e\uff2d\u039c\u041c", - "N": "\x4e\xd1\u0143\u0145\u0147\u019d\u01f8\u0220\u1e44\u1e46\u1e48\u1e4a\u24c3\ua790\ua7a4\uff2e\u039d\u041d", - "O": "\x4f\xd2\xd3\xd4\xd5\xd6\xd8\u014c\u014e\u0150\u0186\u019f\u01a0\u01d1\u01ea\u01ec\u01fe\u020c\u020e\u022a\u022c\u022e\u0230\u1e4c\u1e4e\u1e50\u1e52\u1ecc\u1ece\u1ed0\u1ed2\u1ed4\u1ed6\u1ed8\u1eda\u1edc\u1ede\u1ee0\u1ee2\u24c4\ua74a\ua74c\uff2f\u038c\u039f\u041e", - "P": "\x50\u01a4\u1e54\u1e56\u24c5\u2c63\ua750\ua752\ua754\uff30\u03a0\u041f", - "Q": "\x51\u024a\u24c6\ua756\ua758\uff31", - "R": "\x52\u0154\u0156\u0158\u0210\u0212\u024c\u1e58\u1e5a\u1e5c\u1e5e\u24c7\u2c64\ua75a\ua782\ua7a6\uff32\u03a1\u0420", - "S": "\x53\u015a\u015c\u015e\u0160\u0218\u1e60\u1e62\u1e64\u1e66\u1e68\u1e9e\u24c8\u2c7e\ua784\ua7a8\uff33\u03a3\u0421", - "T": "\x54\u0162\u0164\u0166\u01ac\u01ae\u021a\u023e\u1e6a\u1e6c\u1e6e\u1e70\u24c9\ua786\uff34\u03a4\u0422", - "U": "\x55\xd9\xda\xdb\xdc\u0168\u016a\u016c\u016e\u0170\u0172\u01af\u01d3\u01d5\u01d7\u01d9\u01db\u0214\u0216\u0244\u1e72\u1e74\u1e76\u1e78\u1e7a\u1ee4\u1ee6\u1ee8\u1eea\u1eec\u1eee\u1ef0\u24ca\uff35\u0423\u042a", - "V": "\x56\u01b2\u0245\u1e7c\u1e7e\u24cb\ua75e\uff36\u0412", - "W": "\x57\u0174\u1e80\u1e82\u1e84\u1e86\u1e88\u24cc\u2c72\uff37\u038f\u03a9", - "X": "\x58\u1e8a\u1e8c\u24cd\uff38\u03a7", - "Y": "\x59\xdd\u0176\u0178\u01b3\u0232\u024e\u1e8e\u1ef2\u1ef4\u1ef6\u1ef8\u1efe\u24ce\uff39\u038e\u03a5\u03ab\u042b", - "Z": "\x5a\u0179\u017b\u017d\u01b5\u0224\u1e90\u1e92\u1e94\u24cf\u2c6b\u2c7f\ua762\uff3a\u0396\u0417", - "a": "\x61\xe0\xe1\xe2\xe3\xe4\xe5\u0101\u0103\u0105\u01ce\u01df\u01e1\u01fb\u0201\u0203\u0227\u0250\u1e01\u1e9a\u1ea1\u1ea3\u1ea5\u1ea7\u1ea9\u1eab\u1ead\u1eaf\u1eb1\u1eb3\u1eb5\u1eb7\u24d0\u2c65\uff41\u03ac\u03b1\u0430", - "b": "\x62\u0180\u0183\u0253\u1e03\u1e05\u1e07\u24d1\uff42\u03b2\u0431", - "c": "\x63\xe7\u0107\u0109\u010b\u010d\u0188\u023c\u1e09\u2184\u24d2\ua73f\uff43\u0446", - "d": "\x64\u010f\u0111\u018c\u0256\u0257\u1e0b\u1e0d\u1e0f\u1e11\u1e13\u24d3\ua77a\uff44\xf0\u03b4\u0434", - "e": "\x65\xe8\xe9\xea\xeb\u0113\u0115\u0117\u0119\u011b\u01dd\u0205\u0207\u0229\u0247\u025b\u1e15\u1e17\u1e19\u1e1b\u1e1d\u1eb9\u1ebb\u1ebd\u1ebf\u1ec1\u1ec3\u1ec5\u1ec7\u24d4\uff45\u03ad\u03b5\u0435\u044d", - "f": "\x66\u0192\u1e1f\u24d5\ua77c\uff46\u03c6\u0444", - "g": "\x67\u011d\u011f\u0121\u0123\u01e5\u01e7\u01f5\u0260\u1d79\u1e21\u24d6\ua77f\ua7a1\uff47\u03b3\u0433\u0491", - "h": "\x68\u0125\u0127\u021f\u0265\u1e23\u1e25\u1e27\u1e29\u1e2b\u1e96\u24d7\u2c68\u2c76\uff48\u03ae\u03b7\u0445", - "i": "\x69\xec\xed\xee\xef\u0129\u012b\u012d\u012f\u0131\u01d0\u0209\u020b\u0268\u1e2d\u1e2f\u1ec9\u1ecb\u24d8\uff49\u0390\u03af\u03b9\u03ca\u0438\u0456", - "j": "\x6a\u0135\u01f0\u0249\u24d9\uff4a\u0439", - "k": "\x6b\u0137\u0199\u01e9\u1e31\u1e33\u1e35\u24da\u2c6a\ua741\ua743\ua745\ua7a3\uff4b\u03ba\u043a", - "l": "\x6c\u013a\u013c\u013e\u0140\u0142\u017f\u019a\u026b\u1e37\u1e39\u1e3b\u1e3d\u24db\u2c61\ua747\ua749\ua781\uff4c\u03bb\u043b", - "m": "\x6d\u026f\u0271\u1e3f\u1e41\u1e43\u24dc\uff4d\u03bc\u043c", - "n": "\x6e\xf1\u0144\u0146\u0148\u0149\u019e\u01f9\u0272\u1e45\u1e47\u1e49\u1e4b\u24dd\ua791\ua7a5\uff4e\u03bd\u043d", - "o": "\x6f\xf2\xf3\xf4\xf5\xf6\xf8\u014d\u014f\u0151\u01a1\u01d2\u01eb\u01ed\u01ff\u020d\u020f\u022b\u022d\u022f\u0231\u0254\u0275\u1e4d\u1e4f\u1e51\u1e53\u1ecd\u1ecf\u1ed1\u1ed3\u1ed5\u1ed7\u1ed9\u1edb\u1edd\u1edf\u1ee1\u1ee3\u24de\ua74b\ua74d\uff4f\u03bf\u03cc\u043e", - "p": "\x70\u01a5\u1d7d\u1e55\u1e57\u24df\ua751\ua753\ua755\uff50\u03c0\u043f", - "q": "\x71\u024b\u24e0\ua757\ua759\uff51", - "r": "\x72\u0155\u0157\u0159\u0211\u0213\u024d\u027d\u1e59\u1e5b\u1e5d\u1e5f\u24e1\ua75b\ua783\ua7a7\uff52\u03c1\u0440", - "s": "\x73\xdf\u015b\u015d\u015f\u0161\u0219\u023f\u1e61\u1e63\u1e65\u1e67\u1e69\u1e9b\u24e2\ua785\ua7a9\uff53\u03c2\u03c3\u0441", - "t": "\x74\u0163\u0165\u0167\u01ad\u021b\u0288\u1e6b\u1e6d\u1e6f\u1e71\u1e97\u24e3\u2c66\ua787\uff54\u03c4\u0442", - "u": "\x75\xf9\xfa\xfb\xfc\u0169\u016b\u016d\u016f\u0171\u0173\u01b0\u01d4\u01d6\u01d8\u01da\u01dc\u0215\u0217\u0289\u1e73\u1e75\u1e77\u1e79\u1e7b\u1ee5\u1ee7\u1ee9\u1eeb\u1eed\u1eef\u1ef1\u24e4\uff55\u0443\u044a", - "v": "\x76\u028b\u028c\u1e7d\u1e7f\u24e5\ua75f\uff56\u0432", - "w": "\x77\u0175\u1e81\u1e83\u1e85\u1e87\u1e89\u1e98\u24e6\u2c73\uff57\u03c9\u03ce", - "x": "\x78\u1e8b\u1e8d\u24e7\uff58\u03c7", - "y": "\x79\xfd\xff\u0177\u01b4\u0233\u024f\u1e8f\u1e99\u1ef3\u1ef5\u1ef7\u1ef9\u1eff\u24e8\uff59\u03b0\u03c5\u03cb\u03cd\u044b", - "z": "\x7a\u017a\u017c\u017e\u01b6\u0225\u0240\u1e91\u1e93\u1e95\u24e9\u2c6c\ua763\uff5a\u03b6\u0437", - "OE": "\x8c\u0152", - "oe": "\x9c\u0153", - "AE": "\xc6\u01e2\u01fc", - "ae": "\xe6\u01e3\u01fd", - "hv": "\u0195", - "OI": "\u01a2", - "oi": "\u01a3", - "DZ": "\u01c4\u01f1", - "Dz": "\u01c5\u01f2", - "dz": "\u01c6\u01f3", - "LJ": "\u01c7", - "Lj": "\u01c8", - "lj": "\u01c9", - "NJ": "\u01ca", - "Nj": "\u01cb", - "nj": "\u01cc", - "OU": "\u0222", - "ou": "\u0223", - "TZ": "\ua728", - "tz": "\ua729", - "AA": "\ua732", - "aa": "\ua733", - "AO": "\ua734", - "ao": "\ua735", - "AU": "\ua736", - "au": "\ua737", - "AV": "\ua738\ua73a", - "av": "\ua739\ua73b", - "AY": "\ua73c", - "ay": "\ua73d", - "OO": "\ua74e", - "oo": "\ua74f", - "VY": "\ua760", - "vy": "\ua761", - "TH": "\xde", - "th": "\xfe", - "PS": "\u03a8", - "ps": "\u03c8", - "Yo": "\u0401", - "Ye": "\u0404", - "Yi": "\u0407", - "Zh": "\u0416", - "Ch": "\u0427", - "Sh": "\u0428\u0429", - "": "\u042c\u044c", - "Yu": "\u042e", - "Ya": "\u042f", - "zh": "\u0436", - "ch": "\u0447", - "sh": "\u0448\u0449", - "yu": "\u044e", - "ya": "\u044f", - "yo": "\u0451", - "ye": "\u0454", - "yi": "\u0457" -}; - -var diacriticsMap = null; - -/** - * Creates a map of the diacritics. - * - * @ignore - * @returns {Object} Returns the diacritics map. - */ -function getDiacriticsMap() { - if (diacriticsMap !== null) { - return diacriticsMap; - } - diacriticsMap = {}; - Object.keys(diacritics).forEach(function (key) { - var characters = diacritics[key]; - for (var index = 0; index < characters.length; index++) { - var character = characters[index]; - diacriticsMap[character] = key; - } - }); - return diacriticsMap; -} - -/** - * Get the latin character from character with diacritics. - * - * @ignore - * @param {string} character The character with diacritics. - * @returns {string} Returns the character without diacritics. - */ -function getLatinCharacter(character) { - var characterWithoutDiacritic = getDiacriticsMap()[character]; - return characterWithoutDiacritic ? characterWithoutDiacritic : character; -} - -/** - * Returns the `cleanCharacter` from combining marks regular expression match. - * - * @ignore - * @param {string} character The character with combining marks - * @param {string} cleanCharacter The character without combining marks. - * @return {string} The character without combining marks. - */ -function removeCombiningMarks(character, cleanCharacter) { - return cleanCharacter; -} - -/** - * Latinises the `subject` by removing diacritic characters. - * - * @function latinise - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to latinise. - * @return {string} Returns the latinised string. - * @example - * v.latinise('cafe\u0301'); // or 'café' - * // => 'cafe' - * - * v.latinise('août décembre'); - * // => 'aout decembre' - * - * v.latinise('как прекрасен этот мир'); - * // => 'kak prekrasen etot mir' - */ -function latinise(subject) { - var subjectString = coerceToString(subject); - if (subjectString === '') { - return ''; - } - return subjectString.replace(REGEXP_NON_LATIN, getLatinCharacter).replace(REGEXP_COMBINING_MARKS, removeCombiningMarks); -} - -/** - * Pads `subject` to a new `length`. - * - * @function pad - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to pad. - * @param {int} [length=0] The length to pad the string. No changes are made if `length` is less than `subject.length`. - * @param {string} [pad=' '] The string to be used for padding. - * @return {string} Returns the padded string. - * @example - * v.pad('dog', 5); - * // => ' dog ' - * - * v.pad('bird', 6, '-'); - * // => '-bird-' - * - * v.pad('cat', 6, '-='); - * // => '-cat-=' - */ -function pad(subject, length, pad) { - var subjectString = coerceToString(subject); - var lengthInt = isNil(length) ? 0 : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER); - var padString = coerceToString(pad, ' '); - if (lengthInt <= subjectString.length) { - return subjectString; - } - var paddingLength = lengthInt - subjectString.length; - var paddingSideLength = toInteger(paddingLength / 2); - var paddingSideRemainingLength = paddingLength % 2; - return buildPadding(padString, paddingSideLength) + subjectString + buildPadding(padString, paddingSideLength + paddingSideRemainingLength); -} - -/** - * Replaces the matches of `pattern` with `replacement`.
- * - * @function replace - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to verify. - * @param {string|RegExp} pattern The pattern which match is replaced. If `pattern` is a string, - * a simple string match is evaluated and only the first occurrence replaced. - * @param {string|Function} replacement The string or function which invocation result replaces `pattern` match. - * @return {string} Returns the replacement result. - * @example - * v.replace('swan', 'wa', 'u'); - * // => 'sun' - * - * v.replace('domestic duck', /domestic\s/, ''); - * // => 'duck' - * - * v.replace('nice duck', /(nice)(duck)/, function(match, nice, duck) { - * return 'the ' + duck + ' is ' + nice; - * }); - * // => 'the duck is nice' - */ -function replace(subject, pattern, replacement) { - var subjectString = coerceToString(subject); - return subjectString.replace(pattern, replacement); -} - -/** - * Get the flags string from a regular expression object. - * - * @ignore - * @param {RegExp} regExp The regular expression object. - * @return {string} Returns the string with flags chars. - */ -function getRegExpFlags(regExp) { - return regExp.toString().match(REGEXP_FLAGS)[0]; -} - -/** - * Checks whether `subject` includes `search` starting from `position`. - * - * @function includes - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string where to search. - * @param {string} search The string to search. - * @param {number} [position=0] The position to start searching. - * @return {boolean} Returns `true` if `subject` includes `search` or `false` otherwise. - * @example - * v.includes('starship', 'star'); - * // => true - * - * v.includes('galaxy', 'g', 1); - * // => false - */ -function includes(subject, search, position) { - var subjectString = coerceToString(subject); - var searchString = toString(search); - if (searchString === null) { - return false; - } - if (searchString === '') { - return true; - } - position = isNil(position) ? 0 : clipNumber(toInteger(position), 0, subjectString.length); - return subjectString.indexOf(searchString, position) !== -1; -} - -/** - * Append flag to a regular expression. - * - * @ignore - * @param {RegExp} pattern The pattern to coerce. - * @param {string} appendFlag The flag to append to regular expression. - * @return {RegExp} The regular expression with added flag. - */ -function appendFlagToRegExp(pattern, appendFlag) { - var regularExpressionFlags = getRegExpFlags(pattern); - if (!includes(regularExpressionFlags, appendFlag)) { - return new RegExp(pattern.source, regularExpressionFlags + appendFlag); - } - return pattern; -} - -/** - * Replaces all matches of `pattern` with `replacement`.
- * - * @function replaceAll - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to verify. - * @param {string|RegExp} pattern The pattern which match is replaced. If `pattern` is a string, a simple string match is evaluated. - * All matches are replaced. - * @param {string|Function} replacement The string or function which invocation result replaces `pattern` match. - * @return {string} Returns the replacement result. - * @example - * v.replaceAll('good morning', 'o', '*'); - * // => 'g**d m*rning' - * v.replaceAll('evening', /n/, 's'); - * // => 'evesisg' - * - */ -function replaceAll(subject, pattern, replacement) { - var subjectString = coerceToString(subject); - var regExp = pattern; - if (!(pattern instanceof RegExp)) { - regExp = new RegExp(escapeRegExp(pattern), 'g'); - } else if (!pattern.global) { - regExp = appendFlagToRegExp(pattern, 'g'); - } - return subjectString.replace(regExp, replacement); -} - -/** - * Reverses the `subject`. - * - * @function reverse - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to reverse. - * @return {string} Returns the reversed string. - * @example - * v.reverse('winter'); - * // => 'retniw' - */ -function reverse(subject) { - var subjectString = coerceToString(subject); - return subjectString.split('').reverse().join(''); -} - -/** - * Reverses the `subject` taking care of - * surrogate pairs and - * combining marks. - * - * @function reverseGrapheme - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to reverse. - * @return {string} Returns the reversed string. - * @example - * v.reverseGrapheme('summer'); - * // => 'remmus' - * - * v.reverseGrapheme('𝌆 bar mañana mañana'); - * // => 'anañam anañam rab 𝌆' - */ -function reverseGrapheme(subject) { - var subjectString = coerceToString(subject); - /** - * @see https://github.com/mathiasbynens/esrever - */ - subjectString = subjectString.replace(REGEXP_COMBINING_MARKS, function ($0, $1, $2) { - return reverseGrapheme($2) + $1; - }).replace(REGEXP_SURROGATE_PAIRS, '$2$1'); - var reversedString = ''; - var index = subjectString.length; - while (index--) { - reversedString += subjectString.charAt(index); - } - return reversedString; -} - -/** - * Slugifies the `subject`. Cleans the `subject` by replacing diacritics with corresponding latin characters. - * - * @function slugify - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to slugify. - * @return {string} Returns the slugified string. - * @example - * v.slugify('Italian cappuccino drink'); - * // => 'italian-cappuccino-drink' - * - * v.slugify('caffé latté'); - * // => 'caffe-latte' - * - * v.slugify('хорошая погода'); - * // => 'horoshaya-pogoda' - */ -function slugify(subject) { - var subjectString = coerceToString(subject); - if (subjectString === '') { - return ''; - } - var cleanSubjectString = latinise(subjectString).replace(REGEXP_NON_LATIN, '-'); - return kebabCase(cleanSubjectString); -} - -/** - * Changes `subject` by deleting `deleteCount` of characters starting at position `start`. Places a new string - * `toAdd` instead of deleted characters. - * - * @function splice - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string where to insert. - * @param {string} start The position to start changing the string. For a negative position will start from the end of - * the string. - * @param {number} [deleteCount=subject.length-start] The number of characters to delete from string. - * @param {string} [toAdd=''] The string to be added instead of deleted characters. - * @return {string} Returns the modified string. - * @example - * v.splice('new year', 0, 4); - * // => 'year' - * - * v.splice('new year', 0, 3, 'happy'); - * // => 'happy year' - * - * v.splice('new year', -4, 4, 'day'); - * // => 'new day' - */ -function splice(subject, start, deleteCount, toAdd) { - var subjectString = coerceToString(subject); - var toAddString = coerceToString(toAdd); - var startPosition = coerceToNumber(start); - if (startPosition < 0) { - startPosition = subjectString.length + startPosition; - if (startPosition < 0) { - startPosition = 0; - } - } else if (startPosition > subjectString.length) { - startPosition = subjectString.length; - } - var deleteCountNumber = coerceToNumber(deleteCount, subjectString.length - startPosition); - if (deleteCountNumber < 0) { - deleteCountNumber = 0; - } - return subjectString.slice(0, startPosition) + toAddString + subjectString.slice(startPosition + deleteCountNumber); -} - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -/** - * Translates characters or replaces substrings in `subject`. - * - * @function tr - * @static - * @since 1.3.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to translate. - * @param {string|Object} from The string of characters to translate from. Or an object, then the object keys are replaced with corresponding values (longest keys are tried first). - * @param {string} to The string of characters to translate to. Ignored when `from` is an object. - * @return {string} Returns the translated string. - * @example - * v.tr('hello', 'el', 'ip'); - * // => 'hippo' - * - * v.tr('légèreté', 'éè', 'ee'); - * // => 'legerete' - * - * v.tr('Yes. The fire rises.', { - * 'Yes': 'Awesome', - * 'fire': 'flame' - * }) - * // => 'Awesome. The flame rises.' - * - * v.tr(':where is the birthplace of :what', { - * ':where': 'Africa', - * ':what': 'Humanity' - * }); - * // => 'Africa is the birthplace of Humanity' - * - */ -function tr(subject, from, to) { - var subjectString = coerceToString(subject); - var keys = void 0; - var values = void 0; - if (isString(from) && isString(to)) { - keys = from.split(''); - values = to.split(''); - } else { - var _extractKeysAndValues = extractKeysAndValues(nilDefault(from, {})); - - var _extractKeysAndValues2 = _slicedToArray(_extractKeysAndValues, 2); - - keys = _extractKeysAndValues2[0]; - values = _extractKeysAndValues2[1]; - } - if (keys.length === 0) { - return subjectString; - } - var result = ''; - var valuesLength = values.length; - var keysLength = keys.length; - for (var index = 0; index < subjectString.length; index++) { - var isMatch = false; - var matchValue = void 0; - for (var keyIndex = 0; keyIndex < keysLength && keyIndex < valuesLength; keyIndex++) { - var key = keys[keyIndex]; - if (subjectString.substr(index, key.length) === key) { - isMatch = true; - matchValue = values[keyIndex]; - index = index + key.length - 1; - break; - } - } - result += isMatch ? matchValue : subjectString[index]; - } - return result; -} - -function extractKeysAndValues(object) { - var keys = Object.keys(object); - var values = keys.sort(sortStringByLength).map(function (key) { - return object[key]; - }); - return [keys, values]; -} - -function sortStringByLength(str1, str2) { - if (str1.length === str2.length) { - return 0; - } - return str1.length < str2.length ? 1 : -1; -} - -var reduce$1 = Array.prototype.reduce; - -/** - * Removes whitespaces from the left side of the `subject`. - * - * @function trimLeft - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to trim. - * @param {string} [whitespace=whitespace] The whitespace characters to trim. List all characters that you want to be stripped. - * @return {string} Returns the trimmed string. - * @example - * v.trimLeft(' Starship Troopers'); - * // => 'Starship Troopers' - * - * v.trimLeft('***Mobile Infantry', '*'); - * // => 'Mobile Infantry' - */ -function trimLeft(subject, whitespace$$1) { - var subjectString = coerceToString(subject); - if (whitespace$$1 === '' || subjectString === '') { - return subjectString; - } - var whitespaceString = toString(whitespace$$1); - if (isNil(whitespaceString)) { - return subjectString.replace(REGEXP_TRIM_LEFT, ''); - } - var matchWhitespace = true; - return reduce$1.call(subjectString, function (trimmed, character) { - if (matchWhitespace && includes(whitespaceString, character)) { - return trimmed; - } - matchWhitespace = false; - return trimmed + character; - }, ''); -} - -var reduceRight = Array.prototype.reduceRight; - -/** - * Removes whitespaces from the right side of the `subject`. - * - * @function trimRight - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to trim. - * @param {string} [whitespace=whitespace] The whitespace characters to trim. List all characters that you want to be stripped. - * @return {string} Returns the trimmed string. - * @example - * v.trimRight('the fire rises '); - * // => 'the fire rises' - * - * v.trimRight('do you feel in charge?!!!', '!'); - * // => 'do you feel in charge?' - */ -function trimRight(subject, whitespace$$1) { - var subjectString = coerceToString(subject); - if (whitespace$$1 === '' || subjectString === '') { - return subjectString; - } - var whitespaceString = toString(whitespace$$1); - if (isNil(whitespaceString)) { - return subjectString.replace(REGEXP_TRIM_RIGHT, ''); - } - var matchWhitespace = true; - return reduceRight.call(subjectString, function (trimmed, character) { - if (matchWhitespace && includes(whitespaceString, character)) { - return trimmed; - } - matchWhitespace = false; - return character + trimmed; - }, ''); -} - -/** - * Removes whitespaces from left and right sides of the `subject`. - * - * @function trim - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to trim. - * @param {string} [whitespace=whitespace] The whitespace characters to trim. List all characters that you want to be stripped. - * @return {string} Returns the trimmed string. - * @example - * v.trim(' Mother nature '); - * // => 'Mother nature' - * - * v.trim('--Earth--', '-'); - * // => 'Earth' - */ -function trim(subject, whitespace) { - var subjectString = coerceToString(subject); - if (whitespace === '' || subjectString === '') { - return subjectString; - } - var whitespaceString = toString(whitespace); - if (isNil(whitespaceString)) { - return subjectString.trim(); - } - return trimRight(trimLeft(subjectString, whitespaceString), whitespaceString); -} - -var OPTION_WIDTH = 'width'; -var OPTION_NEW_LINE = 'newLine'; -var OPTION_INDENT = 'indent'; -var OPTION_CUT = 'cut'; - -/** - * Wraps `subject` to a given number of characters using a string break character. - * - * @function wordWrap - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to wrap. - * @param {Object} [options={}] The wrap options. - * @param {number} [options.width=75] The number of characters at which to wrap. - * @param {string} [options.newLine='\n'] The string to add at the end of line. - * @param {string} [options.indent=''] The string to intend the line. - * @param {boolean} [options.cut=false] When `false` (default) does not split the word even if word length is bigger than `width`.
- * When `true` breaks the word that has length bigger than `width`. - * - * @return {string} Returns wrapped string. - * @example - * v.wordWrap('Hello world', { - * width: 5 - * }); - * // => 'Hello\nworld' - * - * v.wordWrap('Hello world', { - * width: 5, - * newLine: '
', - * indent: '__' - * }); - * // => '__Hello
__world' - * - * v.wordWrap('Wonderful world', { - * width: 5, - * cut: true - * }); - * // => 'Wonde\nrful\nworld' - * - */ -function wordWrap(subject) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - var subjectString = coerceToString(subject); - - var _determineOptions = determineOptions(options), - width = _determineOptions.width, - newLine = _determineOptions.newLine, - indent = _determineOptions.indent, - cut = _determineOptions.cut; - - if (subjectString === '' || width <= 0) { - return indent; - } - var subjectLength = subjectString.length; - var substring = subjectString.substring.bind(subjectString); - var offset = 0; - var wrappedLine = ''; - while (subjectLength - offset > width) { - if (subjectString[offset] === ' ') { - offset++; - continue; - } - var spaceToWrapAt = subjectString.lastIndexOf(' ', width + offset); - if (spaceToWrapAt >= offset) { - wrappedLine += indent + substring(offset, spaceToWrapAt) + newLine; - offset = spaceToWrapAt + 1; - } else { - if (cut) { - wrappedLine += indent + substring(offset, width + offset) + newLine; - offset += width; - } else { - spaceToWrapAt = subjectString.indexOf(' ', width + offset); - if (spaceToWrapAt >= 0) { - wrappedLine += indent + substring(offset, spaceToWrapAt) + newLine; - offset = spaceToWrapAt + 1; - } else { - wrappedLine += indent + substring(offset); - offset = subjectLength; - } - } - } - } - if (offset < subjectLength) { - wrappedLine += indent + substring(offset); - } - return wrappedLine; -} - -/** - * Determine the word wrap options. The missing values are filled with defaults. - * - * @param {Object} options The options object. - * @return {Object} The word wrap options, with default settings if necessary. - * @ignore - */ -function determineOptions(options) { - return { - width: coerceToNumber(options[OPTION_WIDTH], 75), - newLine: coerceToString(options[OPTION_NEW_LINE], '\n'), - indent: coerceToString(options[OPTION_INDENT], ''), - cut: coerceToBoolean(options[OPTION_CUT], false) - }; -} - -/** - * Checks whether `subject` ends with `end`. - * - * @function endsWith - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @param {string} end The ending string. - * @param {number} [position=subject.length] Search within `subject` as if the string were only `position` long. - * @return {boolean} Returns `true` if `subject` ends with `end` or `false` otherwise. - * @example - * v.endsWith('red alert', 'alert'); - * // => true - * - * v.endsWith('metro south', 'metro'); - * // => false - * - * v.endsWith('Murphy', 'ph', 5); - * // => true - */ -function endsWith(subject, end, position) { - if (isNil(end)) { - return false; - } - var subjectString = coerceToString(subject); - var endString = coerceToString(end); - if (endString === '') { - return true; - } - position = isNil(position) ? subjectString.length : clipNumber(toInteger(position), 0, subjectString.length); - position -= endString.length; - var lastIndex = subjectString.indexOf(endString, position); - return lastIndex !== -1 && lastIndex === position; -} - -/** - * Checks whether `subject` contains only alpha characters. - * - * @function isAlpha - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @return {boolean} Returns `true` if `subject` contains only alpha characters or `false` otherwise. - * @example - * v.isAlpha('bart'); - * // => true - * - * v.isAlpha('lisa!'); - * // => false - * - * v.isAlpha('lisa and bart'); - * // => false - */ -function isAlpha(subject) { - var subjectString = coerceToString(subject); - return REGEXP_ALPHA.test(subjectString); -} - -/** - * Checks whether `subject` contains only alpha and digit characters. - * - * @function isAlphaDigit - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @return {boolean} Returns `true` if `subject` contains only alpha and digit characters or `false` otherwise. - * @example - * v.isAlphaDigit('year2020'); - * // => true - * - * v.isAlphaDigit('1448'); - * // => true - * - * v.isAlphaDigit('40-20'); - * // => false - */ -function isAlphaDigit(subject) { - var subjectString = coerceToString(subject); - return REGEXP_ALPHA_DIGIT.test(subjectString); -} - -/** - * Checks whether `subject` is empty or contains only whitespaces. - * - * @function isBlank - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @return {boolean} Returns `true` if `subject` is empty or contains only whitespaces or `false` otherwise. - * @example - * v.isBlank(''); - * // => true - * - * v.isBlank(' '); - * // => true - * - * v.isBlank('World'); - * // => false - */ -function isBlank(subject) { - var subjectString = coerceToString(subject); - return subjectString.trim().length === 0; -} - -/** - * Checks whether `subject` contains only digit characters. - * - * @function isDigit - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @return {boolean} Returns `true` if `subject` contains only digit characters or `false` otherwise. - * @example - * v.isDigit('35'); - * // => true - * - * v.isDigit('1.5'); - * // => false - * - * v.isDigit('ten'); - * // => false - */ -function isDigit(subject) { - var subjectString = coerceToString(subject); - return REGEXP_DIGIT.test(subjectString); -} - -/** - * Checks whether `subject` is empty. - * - * @function isEmpty - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @return {boolean} Returns `true` if `subject` is empty or `false` otherwise - * @example - * v.isEmpty(''); - * // => true - * - * v.isEmpty(' '); - * // => false - * - * v.isEmpty('sun'); - * // => false - */ -function isEmpty(subject) { - var subjectString = coerceToString(subject); - return subjectString.length === 0; -} - -/** - * Checks whether `subject` has only lower case characters. - * - * @function isLowerCase - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @return {boolean} Returns `true` if `subject` is lower case or `false` otherwise. - * @example - * v.isLowerCase('motorcycle'); - * // => true - * - * v.isLowerCase('John'); - * // => false - * - * v.isLowerCase('T1000'); - * // => false - */ -function isLowerCase(subject) { - var valueString = coerceToString(subject); - return isAlpha(valueString) && valueString.toLowerCase() === valueString; -} - -/** - * Checks whether `subject` is numeric. - * - * @function isNumeric - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @return {boolean} Returns `true` if `subject` is numeric or `false` otherwise. - * @example - * v.isNumeric('350'); - * // => true - * - * v.isNumeric('-20.5'); - * // => true - * - * v.isNumeric('1.5E+2'); - * // => true - * - * v.isNumeric('five'); - * // => false - */ -function isNumeric(subject) { - var valueNumeric = typeof subject === 'object' && !isNil(subject) ? Number(subject) : subject; - return (typeof valueNumeric === 'number' || typeof valueNumeric === 'string') && !isNaN(valueNumeric - parseFloat(valueNumeric)); -} - -/** - * Checks whether `subject` contains only upper case characters. - * - * @function isUpperCase - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @return {boolean} Returns `true` if `subject` is upper case or `false` otherwise. - * @example - * v.isUpperCase('ACDC'); - * // => true - * - * v.isUpperCase('Morning'); - * // => false - */ -function isUpperCase(subject) { - var subjectString = coerceToString(subject); - return isAlpha(subjectString) && subjectString.toUpperCase() === subjectString; -} - -/** - * Checks whether `subject` matches the regular expression `pattern`. - * - * @function matches - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @param {RegExp|string} pattern The pattern to match. If `pattern` is not RegExp, it is transformed to `new RegExp(pattern, flags)`. - * @param {string} [flags=''] The regular expression flags. Applies when `pattern` is string type. - * @return {boolean} Returns `true` if `subject` matches `pattern` or `false` otherwise. - * @example - * v.matches('pluto', /plu.{2}/); - * // => true - * - * v.matches('sun', 'S', 'i'); - * // => true - * - * v.matches('apollo 11', '\\d{3}'); - * // => false - */ -function matches(subject, pattern, flags) { - var subjectString = coerceToString(subject); - var flagsString = coerceToString(flags); - var patternString = void 0; - if (!(pattern instanceof RegExp)) { - patternString = toString(pattern); - if (patternString === null) { - return false; - } - pattern = new RegExp(patternString, flagsString); - } - return pattern.test(subjectString); -} - -/** - * Checks whether `subject` starts with `start`. - * - * @function startsWith - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @param {string} start The starting string. - * @param {number} [position=0] The position to start searching. - * @return {boolean} Returns `true` if `subject` starts with `start` or `false` otherwise. - * @example - * v.startsWith('say hello to my little friend', 'say hello'); - * // => true - * - * v.startsWith('tony', 'on', 1); - * // => true - * - * v.startsWith('the world is yours', 'world'); - * // => false - */ -function startsWith(subject, start, position) { - var subjectString = coerceToString(subject); - var startString = toString(start); - if (startString === null) { - return false; - } - if (startString === '') { - return true; - } - position = isNil(position) ? 0 : clipNumber(toInteger(position), 0, subjectString.length); - return subjectString.substr(position, startString.length) === startString; -} - -/** - * Splits `subject` into an array of characters. - * - * @function chars - * @static - * @since 1.0.0 - * @memberOf Split - * @param {string} [subject=''] The string to split into characters. - * @return {Array} Returns the array of characters. - * @example - * v.chars('cloud'); - * // => ['c', 'l', 'o', 'u', 'd'] - */ -function chars(subject) { - var subjectString = coerceToString(subject); - return subjectString.split(''); -} - -/** - * Returns an array of Unicode code point values from characters of `subject`. - * - * @function codePoints - * @static - * @since 1.0.0 - * @memberOf Split - * @param {string} [subject=''] The string to extract from. - * @return {Array} Returns an array of non-negative numbers less than or equal to `0x10FFFF`. - * @example - * v.codePoints('rain'); - * // => [114, 97, 105, 110], or - * // [0x72, 0x61, 0x69, 0x6E] - * - * v.codePoints('\uD83D\uDE00 smile'); // or '😀 smile' - * // => [128512, 32, 115, 109, 105, 108, 101], or - * // [0x1F600, 0x20, 0x73, 0x6D, 0x69, 0x6C, 0x65] - */ -function codePoints(subject) { - var subjectString = coerceToString(subject); - var subjectStringLength = subjectString.length; - var codePointArray = []; - var index = 0; - var codePointNumber = void 0; - while (index < subjectStringLength) { - codePointNumber = codePointAt(subjectString, index); - codePointArray.push(codePointNumber); - index += codePointNumber > 0xFFFF ? 2 : 1; - } - return codePointArray; -} - -/** - * Splits `subject` into an array of graphemes taking care of - * surrogate pairs and - * combining marks. - * - * @function graphemes - * @static - * @since 1.0.0 - * @memberOf Split - * @param {string} [subject=''] The string to split into characters. - * @return {Array} Returns the array of graphemes. - * @example - * v.graphemes('\uD835\uDC00\uD835\uDC01'); // or '𝐀𝐁' - * // => ['\uD835\uDC00', '\uD835\uDC01'], or - * // ['𝐀', '𝐁'] - * - * v.graphemes('cafe\u0301'); // or 'café' - * // => ['c', 'a', 'f', 'e\u0301'], or - * // ['c', 'a', 'f', 'é'] - */ -function graphemes(subject) { - var subjectString = coerceToString(subject); - return nilDefault(subjectString.match(REGEXP_UNICODE_CHARACTER), []); -} - -/** - * Splits `subject` into an array of chunks by `separator`. - * - * @function split - * @static - * @since 1.0.0 - * @memberOf Split - * @param {string} [subject=''] The string to split into characters. - * @param {string|RegExp} [separator] The pattern to match the separator. - * @param {number} [limit] Limit the number of chunks to be found. - * @return {Array} Returns the array of chunks. - * @example - * v.split('rage against the dying of the light', ' '); - * // => ['rage', 'against', 'the', 'dying', 'of', 'the', 'light'] - * - * v.split('the dying of the light', /\s/, 3); - * // => ['the', 'dying', 'of'] - */ -function split(subject, separator, limit) { - var subjectString = coerceToString(subject); - return subjectString.split(separator, limit); -} - -var BYRE_ORDER_MARK = '\uFEFF'; - -/** - * Strips the byte order mark (BOM) from the beginning of `subject`. - * - * @function stripBom - * @static - * @since 1.2.0 - * @memberOf Strip - * @param {string} [subject=''] The string to strip from. - * @return {string} Returns the stripped string. - * @example - * - * v.stripBom('\uFEFFsummertime sadness'); - * // => 'summertime sadness' - * - * v.stripBom('summertime happiness'); - * // => 'summertime happiness' - * - */ -function trim$1(subject) { - var subjectString = coerceToString(subject); - if (subjectString === '') { - return ''; - } - if (subjectString[0] === BYRE_ORDER_MARK) { - return subjectString.substring(1); - } - return subjectString; -} - -/** - * Checks whether `subject` contains substring at specific `index`. - * - * @ignore - * @param {string} subject The subject to search in. - * @param {string} substring The substring to search/ - * @param {number} index The index to search substring. - * @param {boolean} lookBehind Whether to look behind (true) or ahead (false). - * @return {boolean} Returns a boolean whether the substring exists. - */ -function hasSubstringAtIndex(subject, substring, index) { - var lookBehind = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; - - var indexOffset = 0; - if (lookBehind) { - indexOffset = -substring.length + 1; - } - var extractedSubstring = subject.substr(index + indexOffset, substring.length); - return extractedSubstring.toLowerCase() === substring; -} - -/** - * Parses the tags from the string '...'. - * - * @ignore - * @param {string} tags The string that contains the tags. - * @return {string[]} Returns the array of tag names. - */ -function parseTagList(tags) { - var tagsList = []; - var match = void 0; - while ((match = REGEXP_TAG_LIST.exec(tags)) !== null) { - tagsList.push(match[1]); - } - return tagsList; -} - -var STATE_START_TAG = 0; -var STATE_NON_WHITESPACE = 1; -var STATE_DONE = 2; - -/** - * Parses the tag name from html content. - * - * @ignore - * @param {string} tagContent The tag content. - * @return {string} Returns the tag name. - */ -function parseTagName(tagContent) { - var state = STATE_START_TAG; - var tagName = ''; - var index = 0; - while (state !== STATE_DONE) { - var char = tagContent[index++].toLowerCase(); - switch (char) { - case '<': - break; - case '>': - state = STATE_DONE; - break; - default: - if (REGEXP_WHITESPACE.test(char)) { - if (state === STATE_NON_WHITESPACE) { - state = STATE_DONE; - } - } else { - if (state === STATE_START_TAG) { - state = STATE_NON_WHITESPACE; - } - if (char !== '/') { - tagName += char; - } - } - break; - } - } - return tagName; -} - -var STATE_OUTPUT = 0; -var STATE_HTML = 1; -var STATE_EXCLAMATION = 2; -var STATE_COMMENT = 3; - -/** - * Strips HTML tags from `subject`. - * - * @function stripTags - * @static - * @since 1.1.0 - * @memberOf Strip - * @param {string} [subject=''] The string to strip from. - * @param {string|Array} [allowableTags] The string `''` or array `['tag1', 'tag2']` of tags that should not be stripped. - * @param {string} [replacement=''] The string to replace the stripped tag. - * @return {string} Returns the stripped string. - * @example - * - * v.stripTags('Summer is nice'); - * // => 'Summer is nice' - * - * v.stripTags('Winter is cold', ['b', 'i']); - * // => 'Winter is cold' - * - * v.stripTags('Sun
set', '', '-'); - * // => 'Sun-set' - */ -function trim$2(subject, allowableTags, replacement) { - subject = coerceToString(subject); - if (subject === '') { - return ''; - } - if (!Array.isArray(allowableTags)) { - var allowableTagsString = coerceToString(allowableTags); - allowableTags = allowableTagsString === '' ? [] : parseTagList(allowableTagsString); - } - var replacementString = coerceToString(replacement); - var length = subject.length; - var hasAllowableTags = allowableTags.length > 0; - var hasSubstring = hasSubstringAtIndex.bind(null, subject); - var state = STATE_OUTPUT; - var depth = 0; - var output = ''; - var tagContent = ''; - var quote = null; - for (var index = 0; index < length; index++) { - var char = subject[index]; - var advance = false; - switch (char) { - case '<': - if (quote) { - break; - } - if (hasSubstring('< ', index, false)) { - advance = true; - break; - } - if (state === STATE_OUTPUT) { - advance = true; - state = STATE_HTML; - break; - } - if (state === STATE_HTML) { - depth++; - break; - } - advance = true; - break; - case '!': - if (state === STATE_HTML && hasSubstring('': - if (depth > 0) { - depth--; - break; - } - if (quote) { - break; - } - if (state === STATE_HTML) { - quote = null; - state = STATE_OUTPUT; - if (hasAllowableTags) { - tagContent += '>'; - var tagName = parseTagName(tagContent); - if (allowableTags.indexOf(tagName.toLowerCase()) !== -1) { - output += tagContent; - } else { - output += replacementString; - } - tagContent = ''; - } else { - output += replacementString; - } - break; - } - if (state === STATE_EXCLAMATION || state === STATE_COMMENT && hasSubstring('-->', index)) { - quote = null; - state = STATE_OUTPUT; - tagContent = ''; - break; - } - advance = true; - break; - default: - advance = true; - } - if (advance) { - switch (state) { - case STATE_OUTPUT: - output += char; - break; - case STATE_HTML: - if (hasAllowableTags) { - tagContent += char; - } - break; - } - } - } - return output; -} - -var globalObject$1 = null; - -function getGlobalObject() { - if (globalObject$1 !== null) { - return globalObject$1; - } - /* istanbul ignore next */ - // It's hard to mock the global variables. This code surely works fine. I hope :) - if (typeof global === 'object' && global.Object === Object) { - // NodeJS global object - globalObject$1 = global; - } else if (typeof self === 'object' && self.Object === Object) { - // self property from Window object - globalObject$1 = self; - } else { - // Other cases. Function constructor always has the context as global object - globalObject$1 = new Function('return this')(); - } - return globalObject$1; -} - -var globalObject = getGlobalObject(); -var previousV = globalObject.v; - -/** - * Restores `v` variable to previous value and returns Voca library instance. - * - * @function noConflict - * @static - * @since 1.0.0 - * @memberOf Util - * @return {Object} Returns Voca library instance. - * @example - * var voca = v.noConflict(); - * voca.isAlpha('Hello'); - * // => true - */ -function noConflict() { - if (this === globalObject.v) { - globalObject.v = previousV; - } - return this; -} - -/** - * A property that contains the library semantic version number. - * @name version - * @static - * @since 1.0.0 - * @memberOf Util - * @type string - * @example - * v.version - * // => '1.3.0' - */ -var version = '1.3.0'; - -/* eslint sort-imports: "off" */ - -/** - * Functions to change the case - * @namespace Case - */ -/** - * Chain functions - * @namespace Chain - */ - -/** - * Functions to cut a string - * @namespace Chop - */ -/** - * Functions to count characters in a string - * @namespace Count - */ -/** - * Functions to format - * @namespace Format - */ -/** - * Functions to escape RegExp special characters - * @namespace Escape - */ -/** - * Functions to find index - * @namespace Index - */ -/** - * Functions to manipulate a string - * @namespace Manipulate - */ -/** - * Functions to query a string - * @namespace Query - */ -/** - * Functions to split a string - * @namespace Split - */ -/** - * Functions to strip a string - * @namespace Strip - */ -/** - * Util functions and properties - * @namespace Util - */ -var functions = { - camelCase: camelCase, - capitalize: capitalize, - decapitalize: decapitalize, - kebabCase: kebabCase, - lowerCase: lowerCase, - snakeCase: snakeCase, - swapCase: swapCase, - titleCase: titleCase, - upperCase: upperCase, - - count: count, - countGraphemes: countGrapheme, - countSubstrings: countSubstrings, - countWhere: countWhere, - countWords: countWords, - - escapeHtml: escapeHtml, - escapeRegExp: escapeRegExp, - unescapeHtml: unescapeHtml, - - sprintf: sprintf, - vprintf: vprintf, - - indexOf: indexOf, - lastIndexOf: lastIndexOf, - search: search, - - charAt: charAt, - codePointAt: codePointAt, - first: first, - graphemeAt: graphemeAt, - last: last, - prune: prune, - slice: slice, - substr: substr, - substring: substring, - truncate: truncate, - - insert: insert, - latinise: latinise, - pad: pad, - padLeft: padLeft, - padRight: padRight, - repeat: repeat, - replace: replace, - replaceAll: replaceAll, - reverse: reverse, - reverseGrapheme: reverseGrapheme, - slugify: slugify, - splice: splice, - tr: tr, - trim: trim, - trimLeft: trimLeft, - trimRight: trimRight, - wordWrap: wordWrap, - - endsWith: endsWith, - includes: includes, - isAlpha: isAlpha, - isAlphaDigit: isAlphaDigit, - isBlank: isBlank, - isDigit: isDigit, - isEmpty: isEmpty, - isLowerCase: isLowerCase, - isNumeric: isNumeric, - isString: isString, - isUpperCase: isUpperCase, - matches: matches, - startsWith: startsWith, - - chars: chars, - codePoints: codePoints, - graphemes: graphemes, - split: split, - words: words, - - stripBom: trim$1, - stripTags: trim$2, - - noConflict: noConflict, - version: version -}; - -/** - * The chain wrapper constructor. - * - * @ignore - * @param {string} subject The string to be wrapped. - * @param {boolean} [explicitChain=false] A boolean that indicates if the chain sequence is explicit or implicit. - * @return {ChainWrapper} Returns a new instance of `ChainWrapper` - * @constructor - */ -function ChainWrapper(subject, explicitChain) { - this._wrappedValue = subject; - this._explicitChain = explicitChain; -} - -/** - * Unwraps the chain sequence wrapped value. - * - * @memberof Chain - * @since 1.0.0 - * @function __proto__value - * @return {*} Returns the unwrapped value. - * @example - * v - * .chain('Hello world') - * .replace('Hello', 'Hi') - * .lowerCase() - * .slugify() - * .value() - * // => 'hi-world' - * - * v(' Space travel ') - * .trim() - * .truncate(8) - * .value() - * // => 'Space...' - */ -ChainWrapper.prototype.value = function () { - return this._wrappedValue; -}; - -/** - * Override the default object valueOf(). - * - * @ignore - * @return {*} Returns the wrapped value. - */ -ChainWrapper.prototype.valueOf = function () { - return this.value(); -}; - -/** - * Returns the wrapped value to be used in JSON.stringify(). - * - * @ignore - * @return {*} Returns the wrapped value. - */ -ChainWrapper.prototype.toJSON = function () { - return this.value(); -}; - -/** - * Returns the string representation of the wrapped value. - * - * @ignore - * @return {string} Returns the string representation. - */ -ChainWrapper.prototype.toString = function () { - return String(this.value()); -}; - -/** - * Creates a new chain object that enables explicit chain sequences. - * Use `v.prototype.value()` to unwrap the result.
- * Does not modify the wrapped value. - * - * @memberof Chain - * @since 1.0.0 - * @function __proto__chain - * @return {Object} Returns the wrapper in explicit mode. - * @example - * v('Back to School') - * .chain() - * .lowerCase() - * .words() - * .value() - * // => ['back', 'to', 'school'] - * - * v(" Back to School ") - * .chain() - * .trim() - * .truncate(7) - * .value() - * // => 'Back...' - */ -ChainWrapper.prototype.chain = function () { - return new ChainWrapper(this._wrappedValue, true); -}; - -/** - * Modifies the wrapped value with the invocation result of `changer` function. The current wrapped value is the - * argument of `changer` invocation. - * - * @memberof Chain - * @since 1.0.0 - * @function __proto__thru - * @param {Function} changer The function to invoke. - * @return {Object} Returns the new wrapper that wraps the invocation result of `changer`. - * @example - * v - * .chain('sun is shining') - * .words() - * .thru(function(words) { - * return words[0]; - * }) - * .value() - * // => 'sun' - * - */ -ChainWrapper.prototype.thru = function (changer) { - if (typeof changer === 'function') { - return new ChainWrapper(changer(this._wrappedValue), this._explicitChain); - } - return this; -}; - -/** - * A boolean that indicates if the chain sequence is explicit or implicit. - * @ignore - * @type {boolean} - * @private - */ -ChainWrapper.prototype._explicitChain = true; - -/** - * Make a voca function chainable. - * - * @ignore - * @param {Function} functionInstance The function to make chainable - * @return {Function} Returns the chainable function - */ -function makeFunctionChainable(functionInstance) { - return function () { - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - var result = functionInstance.apply(undefined, [this._wrappedValue].concat(args)); - if (this._explicitChain || typeof result === 'string') { - return new ChainWrapper(result, this._explicitChain); - } else { - return result; - } - }; -} - -Object.keys(functions).forEach(function (name) { - ChainWrapper.prototype[name] = makeFunctionChainable(functions[name]); -}); - -/** - * Creates a chain object that wraps `subject`, enabling explicit chain sequences.
- * Use `v.prototype.value()` to unwrap the result. - * - * @memberOf Chain - * @since 1.0.0 - * @function chain - * @param {string} subject The string to wrap. - * @return {Object} Returns the new wrapper object. - * @example - * v - * .chain('Back to School') - * .lowerCase() - * .words() - * .value() - * // => ['back', 'to', 'school'] - */ -function chain(subject) { - return new ChainWrapper(subject, true); -} - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -/** - * Creates a chain object that wraps `subject`, enabling implicit chain sequences.
- * A function that returns `number`, `boolean` or `array` type terminates the chain sequence and returns the unwrapped value. - * Otherwise use `v.prototype.value()` to unwrap the result. - * - * @memberOf Chain - * @since 1.0.0 - * @function v - * @param {string} subject The string to wrap. - * @return {Object} Returns the new wrapper object. - * @example - * v('Back to School') - * .lowerCase() - * .words() - * // => ['back', 'to', 'school'] - * - * v(" Back to School ") - * .trim() - * .truncate(7) - * .value() - * // => 'Back...' - */ -function Voca(subject) { - return new ChainWrapper(subject, false); -} - -_extends(Voca, functions, { - chain: chain -}); - -return Voca; - -}))); diff --git a/dist/voca.min.js b/dist/voca.min.js deleted file mode 100644 index e87bd3a..0000000 --- a/dist/voca.min.js +++ /dev/null @@ -1,9 +0,0 @@ -/*! - * Voca string library 1.3.0 - * https://vocajs.com - * - * Copyright Dmitri Pavlutin and other contributors - * Released under the MIT license - */ -!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):e.v=r()}(this,function(){"use strict";function e(e){return void 0===e||null===e}function r(r){var u=arguments.length>1&&void 0!==arguments[1]&&arguments[1];return e(r)?u:Boolean(r)}function u(e){return"string"==typeof e}function n(r){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return e(r)?n:u(r)?r:String(r)}function t(e,u){var t=n(e),i=r(u);return""===t?"":(i&&(t=t.toLowerCase()),t.substr(0,1).toUpperCase()+t.substr(1))}function i(e){var r=n(e,"");return r.toLowerCase()}function a(e,r){return null==e?r:e}function o(r){return e(r)?null:u(r)?r:String(r)}function c(r,u,t){var i=n(r),c=void 0;if(e(u))c=kr.test(i)?Nr:Or;else if(u instanceof RegExp)c=u;else{var f=o(a(t,""));c=new RegExp(o(u),f)}return a(i.match(c),[])}function f(e,r){return 0===r?i(e):t(e,!0)}function s(e){var r=n(e);return""===r?"":c(r).map(f).join("")}function l(e){var r=n(e);return""===r?"":r.substr(0,1).toLowerCase()+r.substr(1)}function p(e){var r=n(e);return""===r?"":c(r).map(i).join("-")}function E(e){var r=n(e);return""===r?"":c(r).map(i).join("_")}function h(e){var r=n(e);return r.toUpperCase()}function g(e){var r=n(e);return r.split("").reduce(v,"")}function v(e,r){var u=r.toLowerCase(),n=r.toUpperCase();return e+(r===u?n:u)}function A(e,r){var u=n(e),i=Array.isArray(r)?r:[],a=kr.test(u)?Nr:Or;return u.replace(a,function(e){var r=e.toLowerCase();return i.indexOf(r)!==-1?r:t(r,!0)})}function d(e,r,u){return e<=r?r:e>=u?u:e}function T(e){return e===1/0?Br:e===-(1/0)?-Br:~~e}function _(r,u,t){var i=n(r),a=e(u)?i.length:d(T(u),0,Br),o=n(t,"...");return a>=i.length?i:i.substr(0,u-o.length)+o}function C(e,r){var u=n(e);return u.charAt(r)}function F(e){return e>=Gr&&e<=Ur}function I(e){return e>=jr&&e<=Hr}function b(e,r){return 1024*(e-Gr)+r-jr+65536}function x(r){var u=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;return e(r)?u:"number"==typeof r?r:Number(r)}function R(e,r){return e!==e?r:e}function y(e,r){var u=n(e),t=u.length,i=x(r);if(i=R(i,0),!(i<0||i>=t)){var a=u.charCodeAt(i),o=void 0;return F(a)&&t>i+1&&(o=u.charCodeAt(i+1),I(o))?b(a,o):a}}function P(r,u){var t=n(r),i=e(u)?1:d(T(u),0,Br);return t.length<=i?t:t.substr(0,i)}function L(e,r){var u=n(e),t=x(r),i=void 0,a=0;for(t=R(t,0);null!==(i=vr.exec(u));){if(a===t)return vr.lastIndex=0,i[0];a++}return""}function S(r,u){var t=n(r),i=e(u)?1:d(T(u),0,Br);return t.length<=i?t:t.substr(t.length-i,i)}function D(r,u,t){var i=n(r),a=e(u)?i.length:d(T(u),0,Br),o=n(t,"...");if(a>=i.length)return i;var c=kr.test(i)?Nr:Or,f=0;return i.replace(c,function(e,r){var u=r+e.length;u<=a-o.length&&(f=u)}),i.substr(0,f)+o}function w(e,r,u){return n(e).slice(r,u)}function O(e,r,u){return n(e).substr(r,u)}function N(e,r,u){return n(e).substring(r,u)}function m(e){return n(e).length}function Y(e){return n(e).replace(hr,"*").replace(gr,"*").length}function k(e,r){var u=n(e),t=n(r),i=t.length,a=0,o=0;if(""===u||""===t)return a;do o=u.indexOf(t,o),o!==-1&&(a++,o+=i);while(o!==-1);return a}function B(e,r,u){var t=n(e);if(""===t||"function"!=typeof r)return 0;var i=r.bind(u);return Xr.call(t,function(e,r,u){return i(r,u,t)?e+1:e},0)}function G(e,r,u){return c(e,r,u).length}function U(){this.index=0}function j(r,u){for(var t=n(r),i=e(u)?1:d(T(u),0,Br),a="";i;)1&i&&(a+=t),i>1&&(t+=t),i>>=1;return a}function H(e,r){var u=T(r/e.length),n=r%e.length;return j(e,u+n).substr(0,r)}function X(r,u,t){var i=n(r),a=e(u)?0:d(T(u),0,Br),o=n(t," ");return a<=i.length?i:H(o,a-i.length)+i}function M(r,u,t){var i=n(r),a=e(u)?0:d(T(u),0,Br),o=n(t," ");return a<=i.length?i:i+H(o,a-i.length)}function z(r,u){var n=u.width;if(e(n)||r.length>=n)return r;var t=u.alignmentSpecifier===Mr.LITERAL_MINUS?M:X;return t(r,n,u.getPaddingCharacter())}function $(e,r,u){return u.signSpecifier===Mr.LITERAL_PLUS&&e>=0&&(r=Mr.LITERAL_PLUS+r),r}function V(e,r){var u=parseFloat(e),t=void 0;isNaN(u)&&(u=0);var i=x(r.precision,6);switch(r.typeSpecifier){case Mr.TYPE_FLOAT:t=u.toFixed(i);break;case Mr.TYPE_FLOAT_SCIENTIFIC:t=u.toExponential(i);break;case Mr.TYPE_FLOAT_SCIENTIFIC_UPPERCASE:t=u.toExponential(i).toUpperCase();break;case Mr.TYPE_FLOAT_SHORT:case Mr.TYPE_FLOAT_SHORT_UPPERCASE:t=Z(u,i,r)}return t=$(u,t,r),n(t)}function Z(e,r,u){if(0===e)return"0";var n=0===r?1:r,t=e.toPrecision(n).replace(xr,"");return u.typeSpecifier===Mr.TYPE_FLOAT_SHORT_UPPERCASE&&(t=t.toUpperCase()),t}function W(e,r){var u=parseInt(e);switch(isNaN(u)&&(u=0),u>>>=0,r.typeSpecifier){case Mr.TYPE_INTEGER_ASCII_CHARACTER:u=String.fromCharCode(u);break;case Mr.TYPE_INTEGER_BINARY:u=u.toString(Mr.RADIX_BINARY);break;case Mr.TYPE_INTEGER_OCTAL:u=u.toString(Mr.RADIX_OCTAL);break;case Mr.TYPE_INTEGER_HEXADECIMAL:u=u.toString(Mr.RADIX_HEXADECIMAL);break;case Mr.TYPE_INTEGER_HEXADECIMAL_UPPERCASE:u=u.toString(Mr.RADIX_HEXADECIMAL).toUpperCase()}return n(u)}function J(e,r){var u=parseInt(e);return isNaN(u)&&(u=0),$(u,o(u),r)}function q(r,u){var n=r,t=u.precision;return!e(t)&&n.length>t&&(n=_(n,t,"")),n}function Q(e,r){var u=void 0;switch(r.typeSpecifier){case Mr.TYPE_STRING:u=q;break;case Mr.TYPE_INTEGER_DECIMAL:case Mr.TYPE_INTEGER:u=J;break;case Mr.TYPE_INTEGER_ASCII_CHARACTER:case Mr.TYPE_INTEGER_BINARY:case Mr.TYPE_INTEGER_OCTAL:case Mr.TYPE_INTEGER_HEXADECIMAL:case Mr.TYPE_INTEGER_HEXADECIMAL_UPPERCASE:case Mr.TYPE_INTEGER_UNSIGNED_DECIMAL:u=W;break;case Mr.TYPE_FLOAT:case Mr.TYPE_FLOAT_SCIENTIFIC:case Mr.TYPE_FLOAT_SCIENTIFIC_UPPERCASE:case Mr.TYPE_FLOAT_SHORT:case Mr.TYPE_FLOAT_SHORT_UPPERCASE:u=V}var n=u(e,r);return z(n,r)}function K(e){this.percent=e.percent,this.signSpecifier=e.signSpecifier,this.paddingSpecifier=e.paddingSpecifier,this.alignmentSpecifier=e.alignmentSpecifier,this.width=e.width,this.precision=e.precision,this.typeSpecifier=e.typeSpecifier}function ee(r,u,n){if(e(n.typeSpecifier))throw new Error("sprintf(): Unknown type specifier");if(r>u-1)throw new Error("sprintf(): Too few arguments");if(r<0)throw new Error("sprintf(): Argument number must be greater than zero")}function re(e,r,u,n,t,i,a,o,c,f,s){var l=new K({percent:n,signSpecifier:i,paddingSpecifier:a,alignmentSpecifier:o,width:x(c,null),precision:x(f,null),typeSpecifier:s});if(l.isPercentLiteral())return u.slice(1);var p=e.getIndexByPosition(t);return e.incrementOnEmptyPosition(t),ee(p,r.length,l),Q(r[p],l)}function ue(e){var r=n(e);if(""===r)return r;for(var u=arguments.length,t=Array(u>1?u-1:0),i=1;it.length||""===i?t:t.slice(0,a)+i+t.slice(a)}function he(){return null!==Wr?Wr:(Wr={},Object.keys(Zr).forEach(function(e){for(var r=Zr[e],u=0;ui.length&&(o=i.length);var c=x(u,i.length-o);return c<0&&(c=0),i.slice(0,o)+a+i.slice(o+c)}function Pe(e,r,t){var i=n(e),o=void 0,c=void 0;if(u(r)&&u(t))o=r.split(""),c=t.split("");else{var f=Le(a(r,{})),s=Jr(f,2);o=s[0],c=s[1]}if(0===o.length)return i;for(var l="",p=c.length,E=o.length,h=0;h1&&void 0!==arguments[1]?arguments[1]:{},u=n(e),t=me(r),i=t.width,a=t.newLine,o=t.indent,c=t.cut;if(""===u||i<=0)return o;for(var f=u.length,s=u.substring.bind(u),l=0,p="";f-l>i;)if(" "!==u[l]){var E=u.lastIndexOf(" ",i+l);E>=l?(p+=o+s(l,E)+a,l=E+1):c?(p+=o+s(l,i+l)+a,l+=i):(E=u.indexOf(" ",i+l),E>=0?(p+=o+s(l,E)+a,l=E+1):(p+=o+s(l),l=f))}else l++;return l65535?2:1;return t}function We(e){var r=n(e);return a(r.match(vr),[])}function Je(e,r,u){var t=n(e);return t.split(r,u)}function qe(e){var r=n(e);return""===r?"":r[0]===nu?r.substring(1):r}function Qe(e,r,u){var n=!(arguments.length>3&&void 0!==arguments[3])||arguments[3],t=0;n&&(t=-r.length+1);var i=e.substr(u+t,r.length);return i.toLowerCase()===r}function Ke(e){for(var r=[],u=void 0;null!==(u=yr.exec(e));)r.push(u[1]);return r}function er(e){for(var r=tu,u="",n=0;r!==au;){var t=e[n++].toLowerCase();switch(t){case"<":break;case">":r=au;break;default:Ar.test(t)?r===iu&&(r=au):(r===tu&&(r=iu),"/"!==t&&(u+=t))}}return u}function rr(e,r,u){if(e=n(e),""===e)return"";if(!Array.isArray(r)){var t=n(r);r=""===t?[]:Ke(t)}for(var i=n(u),a=e.length,o=r.length>0,c=Qe.bind(null,e),f=ou,s=0,l="",p="",E=null,h=0;h":if(s>0){s--;break}if(E)break;if(f===cu){if(E=null,f=ou,o){p+=">";var A=er(p);l+=r.indexOf(A.toLowerCase())!==-1?p:i,p=""}else l+=i;break}if(f===fu||f===su&&c("-->",h)){E=null,f=ou,p="";break}v=!0;break;default:v=!0}if(v)switch(f){case ou:l+=g;break;case cu:o&&(p+=g)}}return l}function ur(){return null!==lu?lu:lu="object"==typeof global&&global.Object===Object?global:"object"==typeof self&&self.Object===Object?self:new Function("return this")()}function nr(){return this===pu.v&&(pu.v=Eu),this}function tr(e,r){this._wrappedValue=e,this._explicitChain=r}function ir(e){return function(){for(var r=arguments.length,u=Array(r),n=0;n&"'`]/g,br=/(%{1,2})(?:(\d+)\$)?(\+)?([ 0]|'.{1})?(-)?(\d+)?(?:\.(\d+))?([bcdiouxXeEfgGs])?/g,xr=/\.?0+$/g,Rr=/[gimuy]*$/,yr=/<([A-Za-z0-9]+)>/g,Pr="\\u2000-\\u206F",Lr="\\x00-\\x2F\\x3A-\\x40\\x5B-\\x60\\x7b-\\xBF\\xD7\\xF7",Sr="\\u2700-\\u27BF",Dr="a-z\\xB5\\xDF-\\xF6\\xF8-\\xFF\\u0101\\u0103\\u0105\\u0107\\u0109\\u010B\\u010D\\u010F\\u0111\\u0113\\u0115\\u0117\\u0119\\u011B\\u011D\\u011F\\u0121\\u0123\\u0125\\u0127\\u0129\\u012B\\u012D\\u012F\\u0131\\u0133\\u0135\\u0137\\u0138\\u013A\\u013C\\u013E\\u0140\\u0142\\u0144\\u0146\\u0148\\u0149\\u014B\\u014D\\u014F\\u0151\\u0153\\u0155\\u0157\\u0159\\u015B\\u015D\\u015F\\u0161\\u0163\\u0165\\u0167\\u0169\\u016B\\u016D\\u016F\\u0171\\u0173\\u0175\\u0177\\u017A\\u017C\\u017E-\\u0180\\u0183\\u0185\\u0188\\u018C\\u018D\\u0192\\u0195\\u0199-\\u019B\\u019E\\u01A1\\u01A3\\u01A5\\u01A8\\u01AA\\u01AB\\u01AD\\u01B0\\u01B4\\u01B6\\u01B9\\u01BA\\u01BD-\\u01BF\\u01C6\\u01C9\\u01CC\\u01CE\\u01D0\\u01D2\\u01D4\\u01D6\\u01D8\\u01DA\\u01DC\\u01DD\\u01DF\\u01E1\\u01E3\\u01E5\\u01E7\\u01E9\\u01EB\\u01ED\\u01EF\\u01F0\\u01F3\\u01F5\\u01F9\\u01FB\\u01FD\\u01FF\\u0201\\u0203\\u0205\\u0207\\u0209\\u020B\\u020D\\u020F\\u0211\\u0213\\u0215\\u0217\\u0219\\u021B\\u021D\\u021F\\u0221\\u0223\\u0225\\u0227\\u0229\\u022B\\u022D\\u022F\\u0231\\u0233-\\u0239\\u023C\\u023F\\u0240\\u0242\\u0247\\u0249\\u024B\\u024D\\u024F",wr="\\x41-\\x5a\\xc0-\\xd6\\xd8-\\xde\\u0100\\u0102\\u0104\\u0106\\u0108\\u010a\\u010c\\u010e\\u0110\\u0112\\u0114\\u0116\\u0118\\u011a\\u011c\\u011e\\u0120\\u0122\\u0124\\u0126\\u0128\\u012a\\u012c\\u012e\\u0130\\u0132\\u0134\\u0136\\u0139\\u013b\\u013d\\u013f\\u0141\\u0143\\u0145\\u0147\\u014a\\u014c\\u014e\\u0150\\u0152\\u0154\\u0156\\u0158\\u015a\\u015c\\u015e\\u0160\\u0162\\u0164\\u0166\\u0168\\u016a\\u016c\\u016e\\u0170\\u0172\\u0174\\u0176\\u0178\\u0179\\u017b\\u017d\\u0181\\u0182\\u0184\\u0186\\u0187\\u0189-\\u018b\\u018e-\\u0191\\u0193\\u0194\\u0196-\\u0198\\u019c\\u019d\\u019f\\u01a0\\u01a2\\u01a4\\u01a6\\u01a7\\u01a9\\u01ac\\u01ae\\u01af\\u01b1-\\u01b3\\u01b5\\u01b7\\u01b8\\u01bc\\u01c4\\u01c5\\u01c7\\u01c8\\u01ca\\u01cb\\u01cd\\u01cf\\u01d1\\u01d3\\u01d5\\u01d7\\u01d9\\u01db\\u01de\\u01e0\\u01e2\\u01e4\\u01e6\\u01e8\\u01ea\\u01ec\\u01ee\\u01f1\\u01f2\\u01f4\\u01f6-\\u01f8\\u01fa\\u01fc\\u01fe\\u0200\\u0202\\u0204\\u0206\\u0208\\u020a\\u020c\\u020e\\u0210\\u0212\\u0214\\u0216\\u0218\\u021a\\u021c\\u021e\\u0220\\u0222\\u0224\\u0226\\u0228\\u022a\\u022c\\u022e\\u0230\\u0232\\u023a\\u023b\\u023d\\u023e\\u0241\\u0243-\\u0246\\u0248\\u024a\\u024c\\u024e",Or=new RegExp("(?:["+wr+"]["+pr+"]*)?(?:["+Dr+"]["+pr+"]*)+|(?:["+wr+"]["+pr+"]*)+(?!["+Dr+"])|["+cr+"]+|["+Sr+"]|[^"+Lr+Pr+fr+"]+","g"),Nr=/[A-Z\xC0-\xD6\xD8-\xDE]?[a-z\xDF-\xF6\xF8-\xFF]+|[A-Z\xC0-\xD6\xD8-\xDE]+(?![a-z\xDF-\xF6\xF8-\xFF])|\d+/g,mr=new RegExp("^(?:["+Dr+wr+"]["+pr+"]*)+$"),Yr=new RegExp("^((?:["+Dr+wr+"]["+pr+"]*)|["+cr+"])+$"),kr=/^[\x00-\xFF]*$/,Br=9007199254740991,Gr=55296,Ur=56319,jr=56320,Hr=57343,Xr=Array.prototype.reduce;U.prototype.increment=function(){this.index++},U.prototype.incrementOnEmptyPosition=function(r){e(r)&&this.increment()},U.prototype.getIndexByPosition=function(r){return e(r)?this.index:r-1};var Mr=Object.freeze({TYPE_INTEGER:"i",TYPE_INTEGER_BINARY:"b",TYPE_INTEGER_ASCII_CHARACTER:"c",TYPE_INTEGER_DECIMAL:"d",TYPE_INTEGER_OCTAL:"o",TYPE_INTEGER_UNSIGNED_DECIMAL:"u",TYPE_INTEGER_HEXADECIMAL:"x",TYPE_INTEGER_HEXADECIMAL_UPPERCASE:"X",TYPE_FLOAT_SCIENTIFIC:"e",TYPE_FLOAT_SCIENTIFIC_UPPERCASE:"E",TYPE_FLOAT:"f",TYPE_FLOAT_SHORT:"g",TYPE_FLOAT_SHORT_UPPERCASE:"G",TYPE_STRING:"s",LITERAL_PERCENT:"%",LITERAL_SINGLE_QUOTE:"'",LITERAL_PLUS:"+",LITERAL_MINUS:"-",LITERAL_PERCENT_SPECIFIER:"%%",RADIX_BINARY:2,RADIX_OCTAL:8,RADIX_DECIMAL:10,RADIX_HEXADECIMAL:16});K.prototype.isPercentLiteral=function(){return Mr.LITERAL_PERCENT_SPECIFIER===this.percent},K.prototype.getPaddingCharacter=function(){var e=a(this.paddingSpecifier," ");return 2===e.length&&e[0]===Mr.LITERAL_SINGLE_QUOTE&&(e=e[1]),e};var zr={"<":"<",">":">","&":"&",'"':""","'":"'","`":"`"},$r={"<":/(<)|(�*3c;)|(�*60;)/gi,">":/(>)|(�*3e;)|(�*62;)/gi,"&":/(&)|(�*26;)|(�*38;)/gi,'"':/(")|(�*22;)|(�*34;)/gi,"'":/(�*27;)|(�*39;)/gi,"`":/(�*60;)|(�*96;)/gi},Vr=Object.keys($r),Zr={3:"Ξξ",8:"Θθ",A:"AÀÁÂÃÄÅĀĂĄǍǞǠǺȀȂȦȺḀẠẢẤẦẨẪẬẮẰẲẴẶⒶⱯAΆΑА",B:"BƁƂɃḂḄḆⒷBΒБ",C:"CÇĆĈĊČƇȻḈⒸꜾCЦ",D:"DĎĐƉƊƋḊḌḎḐḒⒹꝹDÐΔД",E:"EÈÉÊËĒĔĖĘĚƎƐȄȆȨḔḖḘḚḜẸẺẼẾỀỂỄỆⒺEΈΕЕЭ",F:"FƑḞⒻꝻFΦФ",G:"GĜĞĠĢƓǤǦǴḠⒼꝽꝾꞠGΓГҐ",H:"HĤĦȞḢḤḦḨḪⒽⱧⱵꞍHΉΗХ",I:"IÌÍÎÏĨĪĬĮİƗǏȈȊḬḮỈỊⒾIΊΙΪІИ",J:"JĴɈⒿJЙ",K:"KĶƘǨḰḲḴⓀⱩꝀꝂꝄꞢKΚК",L:"LĹĻĽĿŁȽḶḸḺḼⓁⱠⱢꝆꝈꞀLΛЛ",M:"MƜḾṀṂⓂⱮMΜМ",N:"NÑŃŅŇƝǸȠṄṆṈṊⓃꞐꞤNΝН",O:"OÒÓÔÕÖØŌŎŐƆƟƠǑǪǬǾȌȎȪȬȮȰṌṎṐṒỌỎỐỒỔỖỘỚỜỞỠỢⓄꝊꝌOΌΟО",P:"PƤṔṖⓅⱣꝐꝒꝔPΠП",Q:"QɊⓆꝖꝘQ",R:"RŔŖŘȐȒɌṘṚṜṞⓇⱤꝚꞂꞦRΡР",S:"SŚŜŞŠȘṠṢṤṦṨẞⓈⱾꞄꞨSΣС",T:"TŢŤŦƬƮȚȾṪṬṮṰⓉꞆTΤТ",U:"UÙÚÛÜŨŪŬŮŰŲƯǓǕǗǙǛȔȖɄṲṴṶṸṺỤỦỨỪỬỮỰⓊUУЪ",V:"VƲɅṼṾⓋꝞVВ",W:"WŴẀẂẄẆẈⓌⱲWΏΩ",X:"XẊẌⓍXΧ",Y:"YÝŶŸƳȲɎẎỲỴỶỸỾⓎYΎΥΫЫ",Z:"ZŹŻŽƵȤẐẒẔⓏⱫⱿꝢZΖЗ",a:"aàáâãäåāăąǎǟǡǻȁȃȧɐḁẚạảấầẩẫậắằẳẵặⓐⱥaάαа",b:"bƀƃɓḃḅḇⓑbβб",c:"cçćĉċčƈȼḉↄⓒꜿcц",d:"dďđƌɖɗḋḍḏḑḓⓓꝺdðδд",e:"eèéêëēĕėęěǝȅȇȩɇɛḕḗḙḛḝẹẻẽếềểễệⓔeέεеэ",f:"fƒḟⓕꝼfφф",g:"gĝğġģǥǧǵɠᵹḡⓖꝿꞡgγгґ",h:"hĥħȟɥḣḥḧḩḫẖⓗⱨⱶhήηх",i:"iìíîïĩīĭįıǐȉȋɨḭḯỉịⓘiΐίιϊиі",j:"jĵǰɉⓙjй",k:"kķƙǩḱḳḵⓚⱪꝁꝃꝅꞣkκк",l:"lĺļľŀłſƚɫḷḹḻḽⓛⱡꝇꝉꞁlλл",m:"mɯɱḿṁṃⓜmμм",n:"nñńņňʼnƞǹɲṅṇṉṋⓝꞑꞥnνн",o:"oòóôõöøōŏőơǒǫǭǿȍȏȫȭȯȱɔɵṍṏṑṓọỏốồổỗộớờởỡợⓞꝋꝍoοόо",p:"pƥᵽṕṗⓟꝑꝓꝕpπп",q:"qɋⓠꝗꝙq",r:"rŕŗřȑȓɍɽṙṛṝṟⓡꝛꞃꞧrρр",s:"sßśŝşšșȿṡṣṥṧṩẛⓢꞅꞩsςσс",t:"tţťŧƭțʈṫṭṯṱẗⓣⱦꞇtτт",u:"uùúûüũūŭůűųưǔǖǘǚǜȕȗʉṳṵṷṹṻụủứừửữựⓤuуъ",v:"vʋʌṽṿⓥꝟvв",w:"wŵẁẃẅẇẉẘⓦⱳwωώ",x:"xẋẍⓧxχ",y:"yýÿŷƴȳɏẏẙỳỵỷỹỿⓨyΰυϋύы",z:"zźżžƶȥɀẑẓẕⓩⱬꝣzζз",OE:"ŒŒ",oe:"œœ",AE:"ÆǢǼ",ae:"æǣǽ",hv:"ƕ",OI:"Ƣ",oi:"ƣ",DZ:"DŽDZ",Dz:"DžDz",dz:"dždz",LJ:"LJ",Lj:"Lj",lj:"lj",NJ:"NJ",Nj:"Nj",nj:"nj",OU:"Ȣ",ou:"ȣ",TZ:"Ꜩ",tz:"ꜩ",AA:"Ꜳ",aa:"ꜳ",AO:"Ꜵ",ao:"ꜵ",AU:"Ꜷ",au:"ꜷ",AV:"ꜸꜺ",av:"ꜹꜻ",AY:"Ꜽ",ay:"ꜽ",OO:"Ꝏ",oo:"ꝏ",VY:"Ꝡ",vy:"ꝡ",TH:"Þ",th:"þ",PS:"Ψ",ps:"ψ",Yo:"Ё",Ye:"Є",Yi:"Ї",Zh:"Ж",Ch:"Ч",Sh:"ШЩ","":"Ьь",Yu:"Ю",Ya:"Я",zh:"ж",ch:"ч",sh:"шщ",yu:"ю",ya:"я",yo:"ё",ye:"є",yi:"ї"},Wr=null,Jr=function(){function e(e,r){var u=[],n=!0,t=!1,i=void 0;try{for(var a,o=e[Symbol.iterator]();!(n=(a=o.next()).done)&&(u.push(a.value),!r||u.length!==r);n=!0);}catch(e){t=!0,i=e}finally{try{!n&&o.return&&o.return()}finally{if(t)throw i}}return u}return function(r,u){if(Array.isArray(r))return r;if(Symbol.iterator in Object(r))return e(r,u);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),qr=Array.prototype.reduce,Qr=Array.prototype.reduceRight,Kr="width",eu="newLine",ru="indent",uu="cut",nu="\ufeff",tu=0,iu=1,au=2,ou=0,cu=1,fu=2,su=3,lu=null,pu=ur(),Eu=pu.v,hu="1.3.0",gu={camelCase:s,capitalize:t,decapitalize:l,kebabCase:p,lowerCase:i,snakeCase:E,swapCase:g,titleCase:A,upperCase:h,count:m,countGraphemes:Y,countSubstrings:k,countWhere:B,countWords:G,escapeHtml:ae,escapeRegExp:oe,unescapeHtml:fe,sprintf:ue,vprintf:te,indexOf:se,lastIndexOf:le,search:pe,charAt:C,codePointAt:y,first:P,graphemeAt:L,last:S,prune:D,slice:w,substr:O,substring:N,truncate:_,insert:Ee,latinise:Ae,pad:de,padLeft:X,padRight:M,repeat:j,replace:Te,replaceAll:Ie,reverse:be,reverseGrapheme:xe,slugify:Re,splice:ye,tr:Pe,trim:Oe,trimLeft:De,trimRight:we,wordWrap:Ne,endsWith:Ye,includes:Ce,isAlpha:ke,isAlphaDigit:Be,isBlank:Ge,isDigit:Ue,isEmpty:je,isLowerCase:He,isNumeric:Xe,isString:u,isUpperCase:Me,matches:ze,startsWith:$e,chars:Ve,codePoints:Ze,graphemes:We,split:Je,words:c,stripBom:qe,stripTags:rr,noConflict:nr,version:hu};tr.prototype.value=function(){return this._wrappedValue},tr.prototype.valueOf=function(){return this.value()},tr.prototype.toJSON=function(){return this.value()},tr.prototype.toString=function(){return String(this.value())},tr.prototype.chain=function(){return new tr(this._wrappedValue,!0)},tr.prototype.thru=function(e){return"function"==typeof e?new tr(e(this._wrappedValue),this._explicitChain):this},tr.prototype._explicitChain=!0,Object.keys(gu).forEach(function(e){tr.prototype[e]=ir(gu[e])});var vu=Object.assign||function(e){for(var r=1;r true\n *\n * v.isString(560);\n * // => false\n */\nexport default function isString(subject) {\n return typeof subject === 'string';\n}","import isNil from 'helper/object/is_nil';\nimport isString from 'query/is_string';\n\n/**\n * Get the string representation of the `value`.\n * Converts the `value` to string.\n * If `value` is `null` or `undefined`, return `defaultValue`.\n *\n * @ignore\n * @function toString\n * @param {*} value The value to convert.\n * @param {*} [defaultValue=''] The default value to return.\n * @return {string|null} Returns the string representation of `value`. Returns `defaultValue` if `value` is\n * `null` or `undefined`.\n */\nexport default function coerceToString(value, defaultValue = '') {\n if (isNil(value)) {\n return defaultValue;\n }\n if (isString(value)) {\n return value;\n }\n return String(value);\n}","import coerceToBoolean from 'helper/boolean/coerce_to_boolean';\nimport coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Converts the first character of `subject` to upper case. If `restToLower` is `true`, convert the rest of\n * `subject` to lower case.\n *\n * @function capitalize\n * @static\n * @since 1.0.0\n * @memberOf Case\n * @param {string} [subject=''] The string to capitalize.\n * @param {boolean} [restToLower=false] Convert the rest of `subject` to lower case.\n * @return {string} Returns the capitalized string.\n * @example\n * v.capitalize('apple');\n * // => 'Apple'\n *\n * v.capitalize('aPPle', true);\n * // => 'Apple'\n */\nexport default function capitalize(subject, restToLower) {\n let subjectString = coerceToString(subject);\n const restToLowerCaseBoolean = coerceToBoolean(restToLower);\n if (subjectString === '') {\n return '';\n }\n if (restToLowerCaseBoolean) {\n subjectString = subjectString.toLowerCase();\n }\n return subjectString.substr(0, 1).toUpperCase() + subjectString.substr(1);\n}","import coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Converts the `subject` to lower case.\n *\n * @function lowerCase\n * @static\n * @since 1.0.0\n * @memberOf Case\n * @param {string} [subject=''] The string to convert to lower case.\n * @return {string} Returns the lower case string.\n * @example\n * v.lowerCase('Green');\n * // => 'green'\n *\n * v.lowerCase('BLUE');\n * // => 'blue'\n */\nexport default function lowerCase(subject) {\n const subjectString = coerceToString(subject, '');\n return subjectString.toLowerCase();\n}\n","/**\n * Verifies if `value` is `undefined` or `null` and returns `defaultValue`. In other case returns `value`.\n *\n * @ignore\n * @function nilDefault\n * @param {*} value The value to verify.\n * @param {*} defaultValue The default value.\n * @return {*} Returns `defaultValue` if `value` is `undefined` or `null`, otherwise `defaultValue`.\n */\nexport default function nilDefault(value, defaultValue) {\n return value == null ? defaultValue : value;\n}","import isNil from 'helper/object/is_nil';\nimport isString from 'query/is_string';\n\n/**\n * Get the string representation of the `value`.\n * Converts the `value` to string.\n *\n * @ignore\n * @function toString\n * @param {*} value The value to convert.\n * @return {string|null} Returns the string representation of `value`.\n */\nexport default function toString(value) {\n if (isNil(value)) {\n return null;\n }\n if (isString(value)) {\n return value;\n }\n return String(value);\n}","import { REGEXP_EXTENDED_ASCII, REGEXP_LATIN_WORD, REGEXP_WORD } from 'helper/reg_exp/const_extended';\nimport coerceToString from 'helper/string/coerce_to_string';\nimport isNil from 'helper/object/is_nil';\nimport nilDefault from 'helper/undefined/nil_default';\nimport toString from 'helper/string/to_string';\n\n/**\n * Splits `subject` into an array of words.\n *\n * @function words\n * @static\n * @since 1.0.0\n * @memberOf Split\n * @param {string} [subject=''] The string to split into words.\n * @param {string|RegExp} [pattern] The pattern to watch words. If `pattern` is not RegExp, it is transformed to `new RegExp(pattern, flags)`.\n * @param {string} [flags=''] The regular expression flags. Applies when `pattern` is string type.\n * @return {Array} Returns the array of words.\n * @example\n * v.words('gravity can cross dimensions');\n * // => ['gravity', 'can', 'cross', 'dimensions']\n *\n * v.words('GravityCanCrossDimensions');\n * // => ['Gravity', 'Can', 'Cross', 'Dimensions']\n *\n * v.words('Gravity - can cross dimensions!');\n * // => ['Gravity', 'can', 'cross', 'dimensions']\n *\n * v.words('Earth gravity', /[^\\s]+/g);\n * // => ['Earth', 'gravity']\n */\nexport default function words(subject, pattern, flags) {\n const subjectString = coerceToString(subject);\n let patternRegExp;\n if (isNil(pattern)) {\n patternRegExp = REGEXP_EXTENDED_ASCII.test(subjectString) ? REGEXP_LATIN_WORD : REGEXP_WORD;\n } else if (pattern instanceof RegExp) {\n patternRegExp = pattern;\n } else {\n const flagsString = toString(nilDefault(flags, ''));\n patternRegExp = new RegExp(toString(pattern), flagsString);\n }\n return nilDefault(subjectString.match(patternRegExp), []);\n}","import capitalize from 'case/capitalize';\nimport coerceToString from 'helper/string/coerce_to_string';\nimport lowerCase from 'case/lower_case';\nimport words from 'split/words';\n\n/**\n * Transforms the `word` into camel case chunk.\n *\n * @param {string} word The word string\n * @param {number} index The index of the word in phrase.\n * @return {string} The transformed word.\n * @ignore\n */\nfunction wordToCamel(word, index) {\n return index === 0 ? lowerCase(word) : capitalize(word, true);\n}\n\n/**\n * Converts the `subject` to camel case.\n *\n * @function camelCase\n * @static\n * @since 1.0.0\n * @memberOf Case\n * @param {string} [subject=''] The string to convert to camel case.\n * @return {string} The camel case string.\n * @example\n * v.camelCase('bird flight');\n * // => 'birdFlight'\n *\n * v.camelCase('BirdFlight');\n * // => 'birdFlight'\n *\n * v.camelCase('-BIRD-FLIGHT-');\n * // => 'birdFlight'\n */\nexport default function camelCase(subject) {\n const subjectString = coerceToString(subject);\n if (subjectString === '') {\n return '';\n }\n return words(subjectString).map(wordToCamel).join('');\n}","import coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Converts the first character of `subject` to lower case.\n *\n * @function decapitalize\n * @static\n * @since 1.0.0\n * @memberOf Case\n * @param {string} [subject=''] The string to decapitalize.\n * @return {string} Returns the decapitalized string.\n * @example\n * v.decapitalize('Sun');\n * // => 'sun'\n *\n * v.decapitalize('moon');\n * // => 'moon'\n */\nexport default function decapitalize(subject) {\n const subjectString = coerceToString(subject);\n if (subjectString === '') {\n return '';\n }\n return subjectString.substr(0, 1).toLowerCase() + subjectString.substr(1);\n}","import coerceToString from 'helper/string/coerce_to_string';\nimport lowerCase from 'case/lower_case';\nimport words from 'split/words';\n\n/**\n * Converts the `subject` to kebab case,\n * also called spinal case or lisp case.\n *\n * @function kebabCase\n * @static\n * @since 1.0.0\n * @memberOf Case\n * @param {string} [subject=''] The string to convert to kebab case.\n * @return {string} Returns the kebab case string.\n * @example\n * v.kebabCase('goodbye blue sky');\n * // => 'goodbye-blue-sky'\n *\n * v.kebabCase('GoodbyeBlueSky');\n * // => 'goodbye-blue-sky'\n *\n * v.kebabCase('-Goodbye-Blue-Sky-');\n * // => 'goodbye-blue-sky'\n */\nexport default function kebabCase(subject) {\n const subjectString = coerceToString(subject);\n if (subjectString === '') {\n return '';\n }\n return words(subjectString).map(lowerCase).join('-');\n}","import coerceToString from 'helper/string/coerce_to_string';\nimport lowerCase from 'case/lower_case';\nimport words from 'split/words';\n\n/**\n * Converts the `subject` to snake case.\n *\n * @function snakeCase\n * @static\n * @since 1.0.0\n * @memberOf Case\n * @param {string} [subject=''] The string to convert to snake case.\n * @return {string} Returns the snake case string.\n * @example\n * v.snakeCase('learning to fly');\n * // => 'learning_to_fly'\n *\n * v.snakeCase('LearningToFly');\n * // => 'learning_to_fly'\n *\n * v.snakeCase('-Learning-To-Fly-');\n * // => 'learning_to_fly'\n */\nexport default function snakeCase(subject) {\n const subjectString = coerceToString(subject);\n if (subjectString === '') {\n return '';\n }\n return words(subjectString).map(lowerCase).join('_');\n}","import coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Converts the `subject` to upper case.\n *\n * @function upperCase\n * @static\n * @since 1.0.0\n * @memberOf Case\n * @param {string} [subject=''] The string to convert to upper case.\n * @return {string} Returns the upper case string.\n * @example\n * v.upperCase('school');\n * // => 'SCHOOL'\n */\nexport default function upperCase(subject) {\n const subjectString = coerceToString(subject);\n return subjectString.toUpperCase();\n}","import coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Converts the uppercase alpha caracters of `subject` to lowercase and lowercase \n * characters to uppercase.\n *\n * @function swapCase\n * @static\n * @since 1.3.0\n * @memberOf Case\n * @param {string} [subject=''] The string to swap the case.\n * @return {string} Returns the converted string.\n * @example\n * v.swapCase('League of Shadows');\n * // => 'lEAGE OF sHADOWS'\n *\n * v.swapCase('2 Bees');\n * // => '2 bEES'\n */\nexport default function swapCase(subject) {\n const subjectString = coerceToString(subject);\n return subjectString.split('').reduce(swapAndConcat, '');\n}\n\nfunction swapAndConcat(swapped, character) {\n const lowerCase = character.toLowerCase();\n const upperCase = character.toUpperCase();\n return swapped + (character === lowerCase ? upperCase : lowerCase);\n}","import { REGEXP_EXTENDED_ASCII, REGEXP_LATIN_WORD, REGEXP_WORD } from 'helper/reg_exp/const_extended';\nimport capitalize from 'case/capitalize';\nimport coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Converts the subject to title case.\n *\n * @function titleCase\n * @static\n * @since 1.2.0\n * @memberOf Case\n * @param {string} [subject=''] The string to convert to title case.\n * @param {Array} [ignoreWords] The words that should not be capitalized.\n * @return {string} Returns the title case string.\n * @example\n * v.titleCase('learning to fly');\n * // => 'Learning To Fly'\n *\n * v.titleCase('another brick in the wall', ['in', 'the']);\n * // => 'Another Brick in the Wall'\n */\nexport default function titleCase(subject, ignoreWords) {\n const subjectString = coerceToString(subject);\n const ignoreWordsArray = Array.isArray(ignoreWords) ? ignoreWords : [];\n const wordsRegExp = REGEXP_EXTENDED_ASCII.test(subjectString) ? REGEXP_LATIN_WORD : REGEXP_WORD;\n return subjectString.replace(wordsRegExp, function(word) {\n const lowerCaseWord = word.toLowerCase();\n return ignoreWordsArray.indexOf(lowerCaseWord) !== -1 ? lowerCaseWord : capitalize(lowerCaseWord, true);\n });\n}","/**\n * Clip the number to interval `downLimit` to `upLimit`.\n *\n * @ignore\n * @function clipNumber\n * @param {number} value The number to clip\n * @param {number} downLimit The down limit\n * @param {number} upLimit The upper limit\n * @return {number} The clipped number\n */\nexport default function clipNumber(value, downLimit, upLimit) {\n if (value <= downLimit) {\n return downLimit;\n }\n if (value >= upLimit) {\n return upLimit;\n }\n return value;\n}","import { MAX_SAFE_INTEGER } from 'helper/number/const';\n\n/**\n * Transforms `value` to an integer.\n *\n * @ignore\n * @function toInteger\n * @param {number} value The number to transform.\n * @returns {number} Returns the transformed integer.\n */\nexport default function toInteger(value) {\n if (value === Infinity) {\n return MAX_SAFE_INTEGER;\n }\n if (value === -Infinity) {\n return - MAX_SAFE_INTEGER;\n }\n return ~~value;\n}","import clipNumber from 'helper/number/clip_number';\nimport coerceToString from 'helper/string/coerce_to_string';\nimport isNil from 'helper/object/is_nil';\nimport { MAX_SAFE_INTEGER } from 'helper/number/const';\nimport toInteger from 'helper/number/to_integer';\n\n/**\n * Truncates `subject` to a new `length`.\n *\n * @function truncate\n * @static\n * @since 1.0.0\n * @memberOf Chop\n * @param {string} [subject=''] The string to truncate.\n * @param {int} length The length to truncate the string.\n * @param {string} [end='...'] The string to be added at the end.\n * @return {string} Returns the truncated string.\n * @example\n * v.truncate('Once upon a time', 7);\n * // => 'Once...'\n *\n * v.truncate('Good day, Little Red Riding Hood', 14, ' (...)');\n * // => 'Good day (...)'\n *\n * v.truncate('Once upon', 10);\n * // => 'Once upon'\n */\nexport default function truncate(subject, length, end) {\n const subjectString = coerceToString(subject);\n const lengthInt = isNil(length) ? subjectString.length : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER);\n const endString = coerceToString(end, '...');\n if (lengthInt >= subjectString.length) {\n return subjectString;\n }\n return subjectString.substr(0, length - endString.length) + endString;\n}","import coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Access a character from `subject` at specified `position`.\n *\n * @function charAt\n * @static\n * @since 1.0.0\n * @memberOf Chop\n * @param {string} [subject=''] The string to extract from.\n * @param {numbers} position The position to get the character.\n * @return {string} Returns the character at specified position.\n * @example\n * v.charAt('helicopter', 0);\n * // => 'h'\n *\n * v.charAt('helicopter', 1);\n * // => 'e'\n */\nexport default function charAt(subject, position) {\n const subjectString = coerceToString(subject);\n return subjectString.charAt(position);\n}","const HIGH_SURROGATE_START = 0xD800;\nconst HIGH_SURROGATE_END = 0xDBFF;\nconst LOW_SURROGATE_START = 0xDC00;\nconst LOW_SURROGATE_END = 0xDFFF;\n\n/**\n * Checks if `codePoint` is a high-surrogate number from range 0xD800 to 0xDBFF.\n *\n * @ignore\n * @param {number} codePoint The code point number to be verified\n * @return {boolean} Returns a boolean whether `codePoint` is a high-surrogate number.\n */\nexport function isHighSurrogate(codePoint) {\n return codePoint >= HIGH_SURROGATE_START && codePoint <= HIGH_SURROGATE_END;\n}\n\n/**\n * Checks if `codePoint` is a low-surrogate number from range 0xDC00 to 0xDFFF.\n *\n * @ignore\n * @param {number} codePoint The code point number to be verified\n * @return {boolean} Returns a boolean whether `codePoint` is a low-surrogate number.\n */\nexport function isLowSurrogate(codePoint) {\n return codePoint >= LOW_SURROGATE_START && codePoint <= LOW_SURROGATE_END;\n}\n\n/**\n * Get the astral code point number based on surrogate pair numbers.\n *\n * @ignore\n * @param {number} highSurrogate The high-surrogate code point number.\n * @param {number} lowSurrogate The low-surrogate code point number.\n * @return {number} Returns the astral symbol number.\n */\nexport function getAstralNumberFromSurrogatePair(highSurrogate, lowSurrogate) {\n return (highSurrogate - HIGH_SURROGATE_START) * 0x400 + lowSurrogate - LOW_SURROGATE_START + 0x10000;\n}","import isNil from 'helper/object/is_nil';\n\n/**\n * Get the number representation of the `value`.\n * Converts the `value` to number.\n * If `value` is `null` or `undefined`, return `defaultValue`.\n *\n * @ignore\n * @function toString\n * @param {*} value The value to convert.\n * @param {*} [defaultValue=''] The default value to return.\n * @return {number|null} Returns the number representation of `value`. Returns `defaultValue` if `value` is\n * `null` or `undefined`.\n */\nexport default function coerceToNumber(value, defaultValue = 0) {\n if (isNil(value)) {\n return defaultValue;\n }\n if (typeof value === 'number') {\n return value;\n }\n return Number(value);\n}","/**\n * If `value` is `NaN`, return `defaultValue`. In other case returns `value`.\n *\n * @ignore\n * @function nanDefault\n * @param {*} value The value to verify.\n * @param {*} defaultValue The default value.\n * @return {*} Returns `defaultValue` if `value` is `NaN`, otherwise `defaultValue`.\n */\nexport default function nanDefault(value, defaultValue) {\n return value !== value ? defaultValue : value;\n}","import { getAstralNumberFromSurrogatePair, isHighSurrogate, isLowSurrogate } from 'helper/string/surrogate_pair';\nimport coerceToNumber from 'helper/number/coerce_to_number';\nimport coerceToString from 'helper/string/coerce_to_string';\nimport nanDefault from 'helper/number/nan_default';\n\n/**\n * Get the Unicode code point value of the character at `position`.
\n * If a valid UTF-16 \n * surrogate pair starts at `position`, the\n * astral code point\n * value at `position` is returned.\n *\n * @function codePointAt\n * @static\n * @since 1.0.0\n * @memberOf Chop\n * @param {string} [subject=''] The string to extract from.\n * @param {number} position The position to get the code point number.\n * @return {number} Returns a non-negative number less than or equal to `0x10FFFF`.\n * @example\n * v.codePointAt('rain', 1);\n * // => 97, or 0x0061\n *\n * v.codePointAt('\\uD83D\\uDE00 is smile', 0); // or '😀 is smile'\n * // => 128512, or 0x1F600\n */\nexport default function codePointAt(subject, position) {\n const subjectString = coerceToString(subject);\n const subjectStringLength = subjectString.length;\n let positionNumber = coerceToNumber(position);\n positionNumber = nanDefault(positionNumber, 0);\n if (positionNumber < 0 || positionNumber >= subjectStringLength) {\n return undefined;\n }\n const firstCodePoint = subjectString.charCodeAt(positionNumber);\n let secondCodePoint;\n if (isHighSurrogate(firstCodePoint) && subjectStringLength > positionNumber + 1) {\n secondCodePoint = subjectString.charCodeAt(positionNumber + 1);\n if (isLowSurrogate(secondCodePoint)) {\n return getAstralNumberFromSurrogatePair(firstCodePoint, secondCodePoint);\n }\n }\n return firstCodePoint;\n}","import clipNumber from 'helper/number/clip_number';\nimport coerceToString from 'helper/string/coerce_to_string';\nimport isNil from 'helper/object/is_nil';\nimport { MAX_SAFE_INTEGER } from 'helper/number/const';\nimport toInteger from 'helper/number/to_integer';\n\n/**\n * Extracts the first `length` characters from `subject`.\n *\n * @function first\n * @static\n * @since 1.0.0\n * @memberOf Chop\n * @param {string} [subject=''] The string to extract from.\n * @param {int} [length=1] The number of characters to extract.\n * @return {string} Returns the first characters string.\n * @example\n * v.first('helicopter');\n * // => 'h'\n *\n * v.first('vehicle', 2);\n * // => 've'\n *\n * v.first('car', 5);\n * // => 'car'\n */\nexport default function first(subject, length) {\n const subjectString = coerceToString(subject);\n const lengthInt = isNil(length) ? 1 : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER);\n if (subjectString.length <= lengthInt) {\n return subjectString;\n }\n return subjectString.substr(0, lengthInt);\n}","import coerceToNumber from 'helper/number/coerce_to_number';\nimport coerceToString from 'helper/string/coerce_to_string';\nimport nanDefault from 'helper/number/nan_default';\nimport { REGEXP_UNICODE_CHARACTER } from 'helper/reg_exp/const';\n\n/**\n * Get a grapheme from `subject` at specified `position` taking care of\n * surrogate pairs and\n * combining marks.\n *\n * @function graphemeAt\n * @static\n * @since 1.0.0\n * @memberOf Chop\n * @param {string} [subject=''] The string to extract from.\n * @param {number} position The position to get the grapheme.\n * @return {string} Returns the grapheme at specified position.\n * @example\n * v.graphemeAt('\\uD835\\uDC00\\uD835\\uDC01', 0); // or '𝐀𝐁'\n * // => 'A'\n *\n * v.graphemeAt('cafe\\u0301', 3); // or 'café'\n * // => 'é'\n */\nexport default function graphemeAt(subject, position) {\n const subjectString = coerceToString(subject);\n let positionNumber = coerceToNumber(position);\n let graphemeMatch;\n let graphemeMatchIndex = 0;\n positionNumber = nanDefault(positionNumber, 0);\n while ((graphemeMatch = REGEXP_UNICODE_CHARACTER.exec(subjectString)) !== null) {\n if (graphemeMatchIndex === positionNumber) {\n REGEXP_UNICODE_CHARACTER.lastIndex = 0;\n return graphemeMatch[0];\n }\n graphemeMatchIndex++;\n }\n return '';\n}","import clipNumber from 'helper/number/clip_number';\nimport coerceToString from 'helper/string/coerce_to_string';\nimport isNil from 'helper/object/is_nil';\nimport { MAX_SAFE_INTEGER } from 'helper/number/const';\nimport toInteger from 'helper/number/to_integer';\n\n/**\n * Extracts the last `length` characters from `subject`.\n *\n * @function last\n * @static\n * @since 1.0.0\n * @memberOf Chop\n * @param {string} [subject=''] The string to extract from.\n * @param {int} [length=1] The number of characters to extract.\n * @return {string} Returns the last characters string.\n * @example\n * v.last('helicopter');\n * // => 'r'\n *\n * v.last('vehicle', 2);\n * // => 'le'\n *\n * v.last('car', 5);\n * // => 'car'\n */\nexport default function last(subject, length) {\n const subjectString = coerceToString(subject);\n const lengthInt = isNil(length) ? 1 : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER);\n if (subjectString.length <= lengthInt) {\n return subjectString;\n }\n return subjectString.substr(subjectString.length - lengthInt, lengthInt);\n}","import { REGEXP_EXTENDED_ASCII, REGEXP_LATIN_WORD, REGEXP_WORD } from 'helper/reg_exp/const_extended';\nimport clipNumber from 'helper/number/clip_number';\nimport coerceToString from 'helper/string/coerce_to_string';\nimport isNil from 'helper/object/is_nil';\nimport { MAX_SAFE_INTEGER } from 'helper/number/const';\nimport toInteger from 'helper/number/to_integer';\n\n/**\n * Truncates `subject` to a new `length` and does not break the words. Guarantees that the truncated string is no longer\n * than `length`.\n *\n * @static\n * @function prune\n * @since 1.0.0\n * @memberOf Chop\n * @param {string} [subject=''] The string to prune.\n * @param {int} length The length to prune the string.\n * @param {string} [end='...'] The string to be added at the end.\n * @return {string} Returns the pruned string.\n * @example\n * v.prune('Once upon a time', 7);\n * // => 'Once...'\n *\n * v.prune('Good day, Little Red Riding Hood', 16, ' (more)');\n * // => 'Good day (more)'\n *\n * v.prune('Once upon', 10);\n * // => 'Once upon'\n */\nexport default function prune(subject, length, end) {\n const subjectString = coerceToString(subject);\n const lengthInt = isNil(length) ? subjectString.length : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER);\n const endString = coerceToString(end, '...');\n if (lengthInt >= subjectString.length) {\n return subjectString;\n }\n const pattern = REGEXP_EXTENDED_ASCII.test(subjectString) ? REGEXP_LATIN_WORD : REGEXP_WORD;\n let truncatedLength = 0;\n subjectString.replace(pattern, function(word, offset) {\n const wordInsertLength = offset + word.length;\n if (wordInsertLength <= lengthInt - endString.length) {\n truncatedLength = wordInsertLength;\n }\n });\n return subjectString.substr(0, truncatedLength) + endString;\n}","import coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Extracts from `subject` a string from `start` position up to `end` position. The character at `end` position is not\n * included.\n *\n * @function slice\n * @static\n * @since 1.0.0\n * @memberOf Chop\n * @param {string} [subject=''] The string to extract from.\n * @param {number} start The position to start extraction. If negative use `subject.length + start`.\n * @param {number} [end=subject.length] The position to end extraction. If negative use `subject.length + end`.\n * @return {string} Returns the extracted string.\n * @note Uses native `String.prototype.slice()`\n * @example\n * v.slice('miami', 1);\n * // => 'iami'\n *\n * v.slice('florida', -4);\n * // => 'rida'\n *\n * v.slice('florida', 1, 4);\n * // => \"lor\"\n */\nexport default function slice(subject, start, end) {\n return coerceToString(subject).slice(start, end);\n}","import coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Extracts from `subject` a string from `start` position a number of `length` characters.\n *\n * @function substr\n * @static\n * @since 1.0.0\n * @memberOf Chop\n * @param {string} [subject=''] The string to extract from.\n * @param {number} start The position to start extraction.\n * @param {number} [length=subject.endOfString] The number of characters to extract. If omitted, extract to the end of `subject`.\n * @return {string} Returns the extracted string.\n * @note Uses native `String.prototype.substr()`\n * @example\n * v.substr('infinite loop', 9);\n * // => 'loop'\n *\n * v.substr('dreams', 2, 2);\n * // => 'ea'\n */\nexport default function substr(subject, start, length) {\n return coerceToString(subject).substr(start, length);\n}","import coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Extracts from `subject` a string from `start` position up to `end` position. The character at `end` position is not\n * included.\n *\n * @function substring\n * @static\n * @since 1.0.0\n * @memberOf Chop\n * @param {string} [subject=''] The string to extract from.\n * @param {number} start The position to start extraction.\n * @param {number} [end=subject.length] The position to end extraction.\n * @return {string} Returns the extracted string.\n * @note Uses native `String.prototype.substring()`\n * @example\n * v.substring('beach', 1);\n * // => 'each'\n *\n * v.substring('ocean', 1, 3);\n * // => 'ea'\n */\nexport default function substring(subject, start, end) {\n return coerceToString(subject).substring(start, end);\n}","import coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Counts the characters in `subject`.
\n *\n * @function count\n * @static\n * @since 1.0.0\n * @memberOf Count\n * @param {string} [subject=''] The string to count characters.\n * @return {number} Returns the number of characters in `subject`.\n * @example\n * v.count('rain');\n * // => 4\n */\nexport default function count(subject) {\n return coerceToString(subject).length;\n}","import { REGEXP_COMBINING_MARKS, REGEXP_SURROGATE_PAIRS } from 'helper/reg_exp/const';\nimport coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Counts the graphemes in `subject` taking care of\n * surrogate pairs and\n * combining marks.\n *\n * @function countGraphemes\n * @static\n * @since 1.0.0\n * @memberOf Count\n * @param {string} [subject=''] The string to count graphemes.\n * @return {number} Returns the number of graphemes in `subject`.\n * @example\n * v.countGraphemes('cafe\\u0301'); // or 'café'\n * // => 4\n *\n * v.countGraphemes('\\uD835\\uDC00\\uD835\\uDC01'); // or '𝐀𝐁'\n * // => 2\n *\n * v.countGraphemes('rain');\n * // => 4\n */\nexport default function countGrapheme(subject) {\n return coerceToString(subject)\n .replace(REGEXP_COMBINING_MARKS, '*')\n .replace(REGEXP_SURROGATE_PAIRS, '*')\n .length;\n}","import coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Counts the number of `substring` appearances in `subject`.\n *\n * @function countSubstrings\n * @static\n * @since 1.0.0\n * @memberOf Count\n * @param {string} [subject=''] The string where to count.\n * @param {string} substring The substring to be counted.\n * @return {number} Returns the number of `substring` appearances.\n * @example\n * v.countSubstrings('bad boys, bad boys whatcha gonna do?', 'boys');\n * // => 2\n *\n * v.countSubstrings('every dog has its day', 'cat');\n * // => 0\n */\nexport default function countSubstrings(subject, substring) {\n const subjectString = coerceToString(subject);\n const substringString = coerceToString(substring);\n const substringLength = substringString.length;\n let count = 0;\n let matchIndex = 0;\n if (subjectString === '' || substringString === '') {\n return count;\n }\n do {\n matchIndex = subjectString.indexOf(substringString, matchIndex);\n if (matchIndex !== -1) {\n count++;\n matchIndex += substringLength;\n }\n } while (matchIndex !== -1);\n return count;\n}","import coerceToString from 'helper/string/coerce_to_string';\n\nconst reduce = Array.prototype.reduce;\n\n/**\n * Counts the characters in `subject` for which `predicate` returns truthy.\n *\n * @function countWhere\n * @static\n * @since 1.0.0\n * @memberOf Count\n * @param {string} [subject=''] The string to count characters.\n * @param {Function} predicate The predicate function invoked on each character with parameters `(character, index, string)`.\n * @param {Object} [context] The context to invoke the `predicate`.\n * @return {number} Returns the number of characters for which `predicate` returns truthy.\n * @example\n * v.countWhere('hola!', v.isAlpha);\n * // => 4\n *\n * v.countWhere('2022', function(character, index, str) {\n * return character === '2';\n * });\n * // => 3\n */\nexport default function countWhere(subject, predicate, context) {\n const subjectString = coerceToString(subject);\n if (subjectString === '' || typeof predicate !== 'function') {\n return 0;\n }\n const predicateWithContext = predicate.bind(context);\n return reduce.call(subjectString, function(countTruthy, character, index) {\n return predicateWithContext(character, index, subjectString) ? countTruthy + 1 : countTruthy;\n }, 0);\n}","import words from 'split/words';\n\n/**\n * Counts the number of words in `subject`.\n *\n * @function countWords\n * @static\n * @since 1.0.0\n * @memberOf Count\n * @param {string} [subject=''] The string to split into words.\n * @param {string|RegExp} [pattern] The pattern to watch words. If `pattern` is not RegExp, it is transformed to `new RegExp(pattern, flags)`.\n * @param {string} [flags=''] The regular expression flags. Applies when `pattern` is string type.\n * @return {number} Returns the number of words.\n * @example\n * v.countWords('gravity can cross dimensions');\n * // => 4\n *\n * v.countWords('GravityCanCrossDimensions');\n * // => 4\n *\n * v.countWords('Gravity - can cross dimensions!');\n * // => 4\n *\n * v.words('Earth gravity', /[^\\s]+/g);\n * // => 2\n */\nexport default function countWords(subject, pattern, flags) {\n return words(subject, pattern, flags).length;\n}","import isNil from 'helper/object/is_nil';\n\n/**\n * The current index.\n *\n * @ignore\n * @name ReplacementIndex#index\n * @type {number}\n * @return {ReplacementIndex} ReplacementIndex instance.\n */\nfunction ReplacementIndex() {\n this.index = 0;\n}\n\n/**\n * Increment the current index.\n *\n * @ignore\n * @return {undefined}\n */\nReplacementIndex.prototype.increment = function() {\n this.index++;\n};\n\n/**\n * Increment the current index by position.\n *\n * @ignore\n * @param {number} [position] The replacement position.\n * @return {undefined}\n */\nReplacementIndex.prototype.incrementOnEmptyPosition = function(position) {\n if (isNil(position)) {\n this.increment();\n }\n};\n\n/**\n * Get the replacement index by position.\n *\n * @ignore\n * @param {number} [position] The replacement position.\n * @return {number} The replacement index.\n */\nReplacementIndex.prototype.getIndexByPosition = function(position) {\n return isNil(position) ? this.index : position - 1;\n};\n\nexport default ReplacementIndex;","import clipNumber from 'helper/number/clip_number';\nimport coerceToString from 'helper/string/coerce_to_string';\nimport isNil from 'helper/object/is_nil';\nimport { MAX_SAFE_INTEGER } from 'helper/number/const';\nimport toInteger from 'helper/number/to_integer';\n\n/**\n * Repeats the `subject` number of `times`.\n *\n * @function repeat\n * @static\n * @since 1.0.0\n * @memberOf Manipulate\n * @param {string} [subject=''] The string to repeat.\n * @param {number} [times=1] The number of times to repeat.\n * @return {string} Returns the repeated string.\n * @example\n * v.repeat('w', 3);\n * // => 'www'\n *\n * v.repeat('world', 0);\n * // => ''\n */\nexport default function repeat(subject, times) {\n let subjectString = coerceToString(subject);\n let timesInt = isNil(times) ? 1 : clipNumber(toInteger(times), 0, MAX_SAFE_INTEGER);\n let repeatString = '';\n while (timesInt) {\n if (timesInt & 1) {\n repeatString += subjectString;\n }\n if (timesInt > 1) {\n subjectString += subjectString;\n }\n timesInt >>= 1;\n }\n return repeatString;\n}","import repeat from 'manipulate/repeat';\nimport toInteger from 'helper/number/to_integer';\n\n/**\n * Creates the padding string.\n *\n * @ignore\n * @param {string} padCharacters The characters to create padding string.\n * @param {number} length The padding string length.\n * @return {string} The padding string.\n */\nexport default function buildPadding(padCharacters, length) {\n const padStringRepeat = toInteger(length / padCharacters.length);\n const padStringRest = length % padCharacters.length;\n return repeat(padCharacters, padStringRepeat + padStringRest).substr(0, length);\n}","import buildPadding from 'helper/string/build_padding';\nimport clipNumber from 'helper/number/clip_number';\nimport coerceToString from 'helper/string/coerce_to_string';\nimport isNil from 'helper/object/is_nil';\nimport { MAX_SAFE_INTEGER } from 'helper/number/const';\nimport toInteger from 'helper/number/to_integer';\n\n/**\n * Pads `subject` from left to a new `length`.\n *\n * @function padLeft\n * @static\n * @since 1.0.0\n * @memberOf Manipulate\n * @param {string} [subject=''] The string to pad.\n * @param {int} [length=0] The length to left pad the string. No changes are made if `length` is less than `subject.length`.\n * @param {string} [pad=' '] The string to be used for padding.\n * @return {string} Returns the left padded string.\n * @example\n * v.padLeft('dog', 5);\n * // => ' dog'\n *\n * v.padLeft('bird', 6, '-');\n * // => '--bird'\n *\n * v.padLeft('cat', 6, '-=');\n * // => '-=-cat'\n */\nexport default function padLeft(subject, length, pad) {\n const subjectString = coerceToString(subject);\n const lengthInt = isNil(length) ? 0 : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER);\n const padString = coerceToString(pad, ' ');\n if (lengthInt <= subjectString.length) {\n return subjectString;\n }\n return buildPadding(padString, lengthInt - subjectString.length) + subjectString;\n}","import buildPadding from 'helper/string/build_padding';\nimport clipNumber from 'helper/number/clip_number';\nimport coerceToString from 'helper/string/coerce_to_string';\nimport isNil from 'helper/object/is_nil';\nimport { MAX_SAFE_INTEGER } from 'helper/number/const';\nimport toInteger from 'helper/number/to_integer';\n\n/**\n * Pads `subject` from right to a new `length`.\n *\n * @function padRight\n * @static\n * @since 1.0.0\n * @memberOf Manipulate\n * @param {string} [subject=''] The string to pad.\n * @param {int} [length=0] The length to right pad the string. No changes are made if `length` is less than `subject.length`.\n * @param {string} [pad=' '] The string to be used for padding.\n * @return {string} Returns the right padded string.\n * @example\n * v.padRight('dog', 5);\n * // => 'dog '\n *\n * v.padRight('bird', 6, '-');\n * // => 'bird--'\n *\n * v.padRight('cat', 6, '-=');\n * // => 'cat-=-'\n */\nexport default function padRight(subject, length, pad) {\n const subjectString = coerceToString(subject);\n const lengthInt = isNil(length) ? 0 : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER);\n const padString = coerceToString(pad, ' ');\n if (lengthInt <= subjectString.length) {\n return subjectString;\n }\n return subjectString + buildPadding(padString, lengthInt - subjectString.length);\n}","import Const from 'helper/format/const';\nimport isNil from 'helper/object/is_nil';\nimport padLeft from 'manipulate/pad_left';\nimport padRight from 'manipulate/pad_right';\n\n/**\n * Aligns and pads `subject` string.\n *\n * @ignore\n * @param {string} subject The subject string.\n * @param {ConversionSpecification} conversion The conversion specification object.\n * @return {string} Returns the aligned and padded string.\n */\nexport default function alignAndPad(subject, conversion) {\n const width = conversion.width;\n if (isNil(width) || subject.length >= width) {\n return subject;\n }\n const padType = conversion.alignmentSpecifier === Const.LITERAL_MINUS ? padRight : padLeft;\n return padType(subject, width, conversion.getPaddingCharacter());\n}","import Const from 'helper/format/const';\n\n/**\n * Add sign to the formatted number.\n *\n * @ignore\n * @name addSignToFormattedNumber\n * @param {number} replacementNumber The number to be replaced.\n * @param {string} formattedReplacement The formatted version of number.\n * @param {ConversionSpecification} conversion The conversion specification object.\n * @return {string} Returns the formatted number string with a sign.\n */\nexport default function addSignToFormattedNumber(replacementNumber, formattedReplacement, conversion) {\n if (conversion.signSpecifier === Const.LITERAL_PLUS && replacementNumber >= 0) {\n formattedReplacement = Const.LITERAL_PLUS + formattedReplacement;\n }\n return formattedReplacement;\n}","import addSignToFormattedNumber from 'helper/format/type_format/add_sign_to_formatted_number';\nimport coerceToNumber from 'helper/number/coerce_to_number';\nimport Const from 'helper/format/const';\nimport { REGEXP_TRAILING_ZEROS } from 'helper/reg_exp/const';\nimport toString from 'helper/string/coerce_to_string';\n\n/**\n * Formats a float type according to specifiers.\n *\n * @ignore\n * @param {string} replacement The string to be formatted.\n * @param {ConversionSpecification} conversion The conversion specification object.\n * @return {string} Returns the formatted string.\n */\n\nexport default function float(replacement, conversion) {\n let replacementNumber = parseFloat(replacement);\n let formattedReplacement;\n if (isNaN(replacementNumber)) {\n replacementNumber = 0;\n }\n const precision = coerceToNumber(conversion.precision, 6);\n switch (conversion.typeSpecifier) {\n case Const.TYPE_FLOAT:\n formattedReplacement = replacementNumber.toFixed(precision);\n break;\n case Const.TYPE_FLOAT_SCIENTIFIC:\n formattedReplacement = replacementNumber.toExponential(precision);\n break;\n case Const.TYPE_FLOAT_SCIENTIFIC_UPPERCASE:\n formattedReplacement = replacementNumber.toExponential(precision).toUpperCase();\n break;\n case Const.TYPE_FLOAT_SHORT:\n case Const.TYPE_FLOAT_SHORT_UPPERCASE:\n formattedReplacement = formatFloatAsShort(replacementNumber, precision, conversion);\n break;\n }\n formattedReplacement = addSignToFormattedNumber(replacementNumber, formattedReplacement, conversion);\n return toString(formattedReplacement);\n}\n\n/**\n * Formats the short float.\n *\n * @ignore\n * @param {number} replacementNumber The number to format.\n * @param {number} precision The precision to format the float.\n * @param {ConversionSpecification} conversion The conversion specification object.\n * @return {string} Returns the formatted short float.\n */\nfunction formatFloatAsShort(replacementNumber, precision, conversion) {\n if (replacementNumber === 0) {\n return '0';\n }\n const nonZeroPrecision = precision === 0 ? 1 : precision;\n let formattedReplacement = replacementNumber\n .toPrecision(nonZeroPrecision)\n .replace(REGEXP_TRAILING_ZEROS, '');\n if (conversion.typeSpecifier === Const.TYPE_FLOAT_SHORT_UPPERCASE) {\n formattedReplacement = formattedReplacement.toUpperCase();\n }\n return formattedReplacement;\n}","import Const from 'helper/format/const';\nimport toString from 'helper/string/coerce_to_string';\n\n/**\n * Formats an integer type according to specifiers.\n *\n * @ignore\n * @param {string} replacement The string to be formatted.\n * @param {ConversionSpecification} conversion The conversion specification object.\n * @return {string} Returns the formatted string.\n */\n\nexport default function integerBase(replacement, conversion) {\n let integer = parseInt(replacement);\n if (isNaN(integer)) {\n integer = 0;\n }\n integer = integer >>> 0;\n switch (conversion.typeSpecifier) {\n case Const.TYPE_INTEGER_ASCII_CHARACTER:\n integer = String.fromCharCode(integer);\n break;\n case Const.TYPE_INTEGER_BINARY:\n integer = integer.toString(Const.RADIX_BINARY);\n break;\n case Const.TYPE_INTEGER_OCTAL:\n integer = integer.toString(Const.RADIX_OCTAL);\n break;\n case Const.TYPE_INTEGER_HEXADECIMAL:\n integer = integer.toString(Const.RADIX_HEXADECIMAL);\n break;\n case Const.TYPE_INTEGER_HEXADECIMAL_UPPERCASE:\n integer = integer.toString(Const.RADIX_HEXADECIMAL).toUpperCase();\n break;\n }\n return toString(integer);\n}","import addSignToFormattedNumber from 'helper/format/type_format/add_sign_to_formatted_number';\nimport toString from 'helper/string/to_string';\n\n/**\n * Formats a decimal integer type according to specifiers.\n *\n * @ignore\n * @param {string} replacement The string to be formatted.\n * @param {ConversionSpecification} conversion The conversion specification object.\n * @return {string} Returns the formatted string.\n */\n\nexport default function integerDecimal(replacement, conversion) {\n let integer = parseInt(replacement);\n if (isNaN(integer)) {\n integer = 0;\n }\n return addSignToFormattedNumber(integer, toString(integer), conversion);\n}","import isNil from 'helper/object/is_nil';\nimport truncate from 'chop/truncate';\n\n/**\n * Formats a string type according to specifiers.\n *\n * @ignore\n * @param {string} replacement The string to be formatted.\n * @param {ConversionSpecification} conversion The conversion specification object.\n * @return {string} Returns the formatted string.\n */\nexport default function stringFormat(replacement, conversion) {\n let formattedReplacement = replacement;\n const precision = conversion.precision;\n if (!isNil(precision) && formattedReplacement.length > precision) {\n formattedReplacement = truncate(formattedReplacement, precision, '');\n }\n return formattedReplacement;\n}","import alignAndPad from 'helper/format/align_and_pad';\nimport Const from 'helper/format/const';\nimport formatFloat from 'helper/format/type_format/float';\nimport formatIntegerBase from 'helper/format/type_format/integer_base';\nimport formatIntegerDecimal from 'helper/format/type_format/integer_decimal';\nimport formatString from 'helper/format/type_format/string';\n\n/**\n * Returns the computed string based on format specifiers.\n *\n * @ignore\n * @name computeReplacement\n * @param {string} replacement The replacement value.\n * @param {ConversionSpecification} conversion The conversion specification object.\n * @return {string} Returns the computed string.\n */\nexport default function compute(replacement, conversion) {\n let formatFunction;\n switch (conversion.typeSpecifier) {\n case Const.TYPE_STRING:\n formatFunction = formatString;\n break;\n case Const.TYPE_INTEGER_DECIMAL:\n case Const.TYPE_INTEGER:\n formatFunction = formatIntegerDecimal;\n break;\n case Const.TYPE_INTEGER_ASCII_CHARACTER:\n case Const.TYPE_INTEGER_BINARY:\n case Const.TYPE_INTEGER_OCTAL:\n case Const.TYPE_INTEGER_HEXADECIMAL:\n case Const.TYPE_INTEGER_HEXADECIMAL_UPPERCASE:\n case Const.TYPE_INTEGER_UNSIGNED_DECIMAL:\n formatFunction = formatIntegerBase;\n break;\n case Const.TYPE_FLOAT:\n case Const.TYPE_FLOAT_SCIENTIFIC:\n case Const.TYPE_FLOAT_SCIENTIFIC_UPPERCASE:\n case Const.TYPE_FLOAT_SHORT:\n case Const.TYPE_FLOAT_SHORT_UPPERCASE:\n formatFunction = formatFloat;\n break;\n }\n const formattedString = formatFunction(replacement, conversion);\n return alignAndPad(formattedString, conversion);\n}","import Const from 'helper/format/const';\nimport nilDefault from 'helper/undefined/nil_default';\n\n/**\n * Construct the new conversion specification object.\n *\n * @ignore\n * @param {Object} properties An object with properties to initialize.\n * @return {ConversionSpecification} ConversionSpecification instance.\n */\nfunction ConversionSpecification(properties) {\n\n /**\n * The percent characters from conversion specification.\n *\n * @ignore\n * @name ConversionSpecification#percent\n * @type {string}\n */\n this.percent = properties.percent;\n\n /**\n * The sign specifier to force a sign to be used on a number.\n *\n * @ignore\n * @name ConversionSpecification#signSpecifier\n * @type {string}\n */\n this.signSpecifier = properties.signSpecifier;\n\n /**\n * The padding specifier that says what padding character will be used.\n *\n * @ignore\n * @name ConversionSpecification#paddingSpecifier\n * @type {string}\n */\n this.paddingSpecifier = properties.paddingSpecifier;\n\n /**\n * The alignment specifier that says if the result should be left-justified or right-justified.\n *\n * @ignore\n * @name ConversionSpecification#alignmentSpecifier\n * @type {string}\n */\n this.alignmentSpecifier = properties.alignmentSpecifier;\n\n /**\n * The width specifier how many characters this conversion should result in.\n *\n * @ignore\n * @name ConversionSpecification#width\n * @type {number}\n */\n this.width = properties.width;\n\n /**\n * The precision specifier says how many decimal digits should be displayed for floating-point numbers.\n *\n * @ignore\n * @name ConversionSpecification#precision\n * @type {number}\n */\n this.precision = properties.precision;\n\n /**\n * The type specifier says what type the argument data should be treated as.\n *\n * @ignore\n * @name ConversionSpecification#typeSpecifier\n * @type {string}\n */\n this.typeSpecifier = properties.typeSpecifier;\n}\n\n\n/**\n * Check if the conversion specification is a percent literal \"%%\".\n *\n * @ignore\n * @return {boolean} Returns true if the conversion is a percent literal, false otherwise.\n */\nConversionSpecification.prototype.isPercentLiteral = function() {\n return Const.LITERAL_PERCENT_SPECIFIER === this.percent;\n};\n\n/**\n * Get the padding character from padding specifier.\n *\n * @ignore\n * @returns {string} Returns the padding character.\n */\nConversionSpecification.prototype.getPaddingCharacter = function() {\n let paddingCharacter = nilDefault(this.paddingSpecifier, ' ');\n if (paddingCharacter.length === 2 && paddingCharacter[0] === Const.LITERAL_SINGLE_QUOTE) {\n paddingCharacter = paddingCharacter[1];\n }\n return paddingCharacter;\n};\n\nexport default ConversionSpecification;","import isNil from 'helper/object/is_nil';\n\n/**\n * Validates the specifier type and replacement position.\n *\n * @ignore\n * @throws {Error} Throws an exception on insufficient arguments or unknown specifier.\n * @param {number} index The index of the matched specifier.\n * @param {number} replacementsLength The number of replacements.\n * @param {ConversionSpecification} conversion The conversion specification object.\n * @return {undefined}\n */\nexport default function validate(index, replacementsLength, conversion) {\n if (isNil(conversion.typeSpecifier)) {\n throw new Error('sprintf(): Unknown type specifier');\n }\n if (index > replacementsLength - 1) {\n throw new Error('sprintf(): Too few arguments');\n }\n if (index < 0) {\n throw new Error('sprintf(): Argument number must be greater than zero');\n }\n}","import coerceToNumber from 'helper/number/coerce_to_number';\nimport computeReplacement from 'helper/format/replacement/compute';\nimport ConversionSpecification from 'helper/format/conversion_specification';\nimport validateReplacement from 'helper/format/replacement/validate';\n\n/**\n * Return the replacement for regular expression match of the conversion specification.\n *\n * @ignore\n * @name matchReplacement\n * @param {ReplacementIndex} replacementIndex The replacement index object.\n * @param {string[]} replacements The array of replacements.\n * @param {string} conversionSpecification The conversion specification.\n * @param {string} percent The percent characters from conversion specification.\n * @param {string} position The position to insert the replacement.\n * @param {string} signSpecifier The sign specifier to force a sign to be used on a number.\n * @param {string} paddingSpecifier The padding specifier that says what padding character will be used.\n * @param {string} alignmentSpecifier The alignment specifier that says if the result should be left-justified or right-justified.\n * @param {string} widthSpecifier The width specifier how many characters this conversion should result in.\n * @param {string} precisionSpecifier The precision specifier says how many decimal digits should be displayed for floating-point numbers.\n * @param {string} typeSpecifier The type specifier says what type the argument data should be treated as.\n * @return {string} Returns the computed replacement.\n */\nexport default function match(replacementIndex, replacements, conversionSpecification, percent, position, signSpecifier,\n paddingSpecifier, alignmentSpecifier, widthSpecifier, precisionSpecifier, typeSpecifier) {\n const conversion = new ConversionSpecification({\n percent,\n signSpecifier,\n paddingSpecifier,\n alignmentSpecifier,\n width: coerceToNumber(widthSpecifier, null),\n precision: coerceToNumber(precisionSpecifier, null),\n typeSpecifier\n });\n if (conversion.isPercentLiteral()) {\n return conversionSpecification.slice(1);\n }\n const actualReplacementIndex = replacementIndex.getIndexByPosition(position);\n replacementIndex.incrementOnEmptyPosition(position);\n validateReplacement(actualReplacementIndex, replacements.length, conversion);\n return computeReplacement(replacements[actualReplacementIndex], conversion);\n}","import coerceToString from 'helper/string/coerce_to_string';\nimport { REGEXP_CONVERSION_SPECIFICATION } from 'helper/reg_exp/const';\nimport ReplacementIndex from 'helper/format/replacement/index.js';\nimport replacementMatch from 'helper/format/replacement/match';\n\n/**\n * Produces a string according to `format`.\n *\n *
\n * `format` string is composed of zero or more directives: ordinary characters (not %), which are copied unchanged\n * to the output string and conversion specifications, each of which results in fetching zero or more subsequent\n * arguments.

\n *\n * Each conversion specification is introduced by the character %, and ends with a conversion\n * specifier. In between there may be (in this order) zero or more flags, an optional minimum field width\n * and an optional precision.
\n * The syntax is: ConversionSpecification = \"%\" { Flags }\n * [ MinimumFieldWidth ] [ Precision ] ConversionSpecifier, where curly braces { } denote repetition\n * and square brackets [ ] optionality.

\n *\n * By default, the arguments are used in the given order.
\n * For argument numbering and swapping, `%m$` (where `m` is a number indicating the argument order)\n * is used instead of `%` to specify explicitly which argument is taken. For instance `%1$s` fetches the 1st argument,\n * `%2$s` the 2nd and so on, no matter what position the conversion specification has in `format`.\n *

\n *\n * The flags
\n * The character % is followed by zero or more of the following flags:
\n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n *
+\n * A sign (+ or -) should always be placed before a number produced by a\n * signed conversion. By default a sign is used only for negative numbers.\n *
0The value should be zero padded.
(a space) The value should be space padded.
'Indicates alternate padding character, specified by prefixing it with a single quote '.
-The converted value is to be left adjusted on the field boundary (the default is right justification).
\n *\n * The minimum field width
\n * An optional decimal digit string (with nonzero first digit) specifying a minimum field width. If the converted\n * value has fewer characters than the field width, it will be padded with spaces on the left (or right, if the\n * left-adjustment flag has been given).

\n *\n * The precision
\n * An optional precision, in the form of a period `.` followed by an optional decimal digit string.
\n * This gives the number of digits to appear after the radix character for `e`, `E`, `f` and `F` conversions, the\n * maximum number of significant digits for `g` and `G` conversions or the maximum number of characters to be printed\n * from a string for `s` conversion.

\n *\n * The conversion specifier
\n * A specifier that mentions what type the argument should be treated as:\n *\n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n * \n *\n *
`s`The string argument is treated as and presented as a string.
`d` `i`The integer argument is converted to signed decimal notation.
`b`The unsigned integer argument is converted to unsigned binary.
`c`The unsigned integer argument is converted to an ASCII character with that number.
`o`The unsigned integer argument is converted to unsigned octal.
`u`The unsigned integer argument is converted to unsigned decimal.
`x` `X`The unsigned integer argument is converted to unsigned hexadecimal. The letters `abcdef` are used for `x`\n * conversions; the letters `ABCDEF` are used for `X` conversions.
`f`\n * The float argument is rounded and converted to decimal notation in the style `[-]ddd.ddd`, where the number of\n * digits after the decimal-point character is equal to the precision specification. If the precision is missing,\n * it is taken as 6; if the precision is explicitly zero, no decimal-point character appears.\n * If a decimal point appears, at least one digit appears before it.\n *
`e` `E`\n * The float argument is rounded and converted in the style `[-]d.ddde±dd`, where there is one digit\n * before the decimal-point character and the number of digits after it is equal to the precision. If\n * the precision is missing, it is taken as `6`; if the precision is zero, no decimal-point character\n * appears. An `E` conversion uses the letter `E` (rather than `e`) to introduce the exponent.\n *
`g` `G`\n * The float argument is converted in style `f` or `e` (or `F` or `E` for `G` conversions). The precision specifies\n * the number of significant digits. If the precision is missing, `6` digits are given; if the\n * precision is zero, it is treated as `1`. Style `e` is used if the exponent from its conversion is less\n * than `-6` or greater than or equal to the precision. Trailing zeros are removed from the fractional\n * part of the result; a decimal point appears only if it is followed by at least one digit.\n *
`%`A literal `%` is written. No argument is converted. The complete conversion specification is `%%`.
\n *
\n *\n * @function sprintf\n * @static\n * @since 1.0.0\n * @memberOf Format\n * @param {string} [format=''] The format string.\n * @param {...*} replacements The replacements to produce the string.\n * @return {string} Returns the produced string.\n * @example\n * v.sprintf('%s, %s!', 'Hello', 'World');\n * // => 'Hello World!'\n *\n * v.sprintf('%s costs $%d', 'coffee', 2);\n * // => 'coffee costs $2'\n *\n * v.sprintf('%1$s %2$s %1$s %2$s, watcha gonna %3$s', 'bad', 'boys', 'do')\n * // => 'bad boys bad boys, watcha gonna do'\n *\n * v.sprintf('% 6s', 'bird');\n * // => ' bird'\n *\n * v.sprintf('% -6s', 'crab');\n * // => 'crab '\n *\n * v.sprintf(\"%'*5s\", 'cat');\n * // => '**cat'\n *\n * v.sprintf(\"%'*-6s\", 'duck');\n * // => 'duck**'\n *\n * v.sprintf('%d %i %+d', 15, -2, 25);\n * // => '15 -2 +25'\n *\n * v.sprintf(\"%06d\", 15);\n * // => '000015'\n *\n * v.sprintf('0b%b 0o%o 0x%X', 12, 9, 155);\n * // => '0b1100 0o11 0x9B'\n *\n * v.sprintf('%.2f', 10.469);\n * // => '10.47'\n *\n * v.sprintf('%.2e %g', 100.5, 0.455);\n * // => '1.01e+2 0.455'\n * \n */\nexport default function sprintf(format, ...replacements) {\n const formatString = coerceToString(format);\n if (formatString === '') {\n return formatString;\n }\n const boundReplacementMatch = replacementMatch.bind(undefined, new ReplacementIndex(), replacements);\n return formatString.replace(REGEXP_CONVERSION_SPECIFICATION, boundReplacementMatch);\n}","import nilDefault from 'helper/undefined/nil_default';\nimport sprintf from 'format/sprintf';\n\n/**\n * Produces a string according to `format`. Works exactly like sprintf(),\n * with the only difference that accepts the formatting arguments in an array `values`.
\n * See here `format` string specifications.\n *\n * @function vprintf\n * @static\n * @since 1.0.0\n * @memberOf Format\n * @param {string} format=''] The format string.\n * @param {Array} replacements The array of replacements to produce the string.\n * @return {string} Returns the produced string.\n * @example\n * v.vprintf('%s', ['Welcome'])\n * // => 'Welcome'\n *\n * v.vprintf('%s has %d apples', ['Alexandra', 3]);\n * // => 'Alexandra has 3 apples'\n */\nexport default function vprintf(format, replacements) {\n return sprintf(format, ...nilDefault(replacements, []));\n}","import coerceToString from 'helper/string/coerce_to_string';\nimport { REGEXP_HTML_SPECIAL_CHARACTERS } from 'helper/reg_exp/const';\n\nconst escapeCharactersMap = {\n '<': '<',\n '>': '>',\n '&': '&',\n '\"': '"',\n \"'\": ''',\n '`': '`'\n};\n\n/**\n * Return the escaped version of `character`.\n *\n * @ignore\n * @param {string} character The character to be escape.\n * @return {string} The escaped version of character.\n */\nfunction replaceSpecialCharacter(character) {\n return escapeCharactersMap[character];\n}\n\n/**\n * Escapes HTML special characters < > & ' \" ` in subject.\n *\n * @function escapeHtml\n * @static\n * @since 1.0.0 \n * @memberOf Escape\n * @param {string} [subject=''] The string to escape.\n * @return {string} Returns the escaped string.\n * @example\n * v.escapeHtml('

wonderful world

');\n * // => '<p>wonderful world</p>'\n */\nexport default function escapeHtml(subject) {\n return coerceToString(subject).replace(REGEXP_HTML_SPECIAL_CHARACTERS, replaceSpecialCharacter);\n}","import coerceToString from 'helper/string/coerce_to_string';\nimport { REGEXP_SPECIAL_CHARACTERS } from 'helper/reg_exp/const';\n\n/**\n * Escapes the regular expression special characters `- [ ] / { } ( ) * + ? . \\ ^ $ |` in `subject`.\n *\n * @function escapeRegExp\n * @static\n * @since 1.0.0\n * @memberOf Escape\n * @param {string} [subject=''] The string to escape.\n * @return {string} Returns the escaped string.\n * @example\n * v.escapeRegExp('(hours)[minutes]{seconds}');\n * // => '\\(hours\\)\\[minutes\\]\\{seconds\\}'\n */\nexport default function escapeRegExp(subject) {\n return coerceToString(subject).replace(REGEXP_SPECIAL_CHARACTERS, '\\\\$&');\n}","import coerceToString from 'helper/string/coerce_to_string';\n\nconst unescapeCharactersMap = {\n '<': /(<)|(�*3c;)|(�*60;)/gi,\n '>': /(>)|(�*3e;)|(�*62;)/gi,\n '&': /(&)|(�*26;)|(�*38;)/gi,\n '\"': /(")|(�*22;)|(�*34;)/gi,\n \"'\": /(�*27;)|(�*39;)/gi,\n '`': /(�*60;)|(�*96;)/gi\n};\nconst characters = Object.keys(unescapeCharactersMap);\n\n/**\n * Replaces the HTML entities with corresponding characters.\n *\n * @ignore\n * @param {string} string The accumulator string.\n * @param {string} key The character.\n * @return {string} The string with replaced HTML entity\n */\nfunction reduceUnescapedString(string, key) {\n return string.replace(unescapeCharactersMap[key], key);\n}\n\n/**\n * Unescapes HTML special characters from &lt; &gt; &amp; &quot; &#x27; &#x60;\n * to corresponding < > & ' \" ` in subject.\n *\n * @function unescapeHtml\n * @static\n * @since 1.0.0\n * @memberOf Escape\n * @param {string} [subject=''] The string to unescape.\n * @return {string} Returns the unescaped string.\n * @example\n * v.unescapeHtml('<p>wonderful world</p>');\n * // => '

wonderful world

'\n */\nexport default function unescapeHtml(subject) {\n const subjectString = coerceToString(subject);\n return characters.reduce(reduceUnescapedString, subjectString);\n}","import coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Returns the first occurrence index of `search` in `subject`.\n *\n * @function indexOf\n * @static\n * @since 1.0.0\n * @memberOf Index\n * @param {string} [subject=''] The string where to search.\n * @param {string} search The string to search.\n * @param {number} [fromIndex=0] The index to start searching.\n * @return {number} Returns the first occurrence index or `-1` if not found.\n * @example\n * v.indexOf('morning', 'n');\n * // => 3\n *\n * v.indexOf('evening', 'o');\n * // => -1\n */\nexport default function indexOf(subject, search, fromIndex) {\n const subjectString = coerceToString(subject);\n return subjectString.indexOf(search, fromIndex);\n}","import coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Returns the last occurrence index of `search` in `subject`.\n *\n * @function lastIndexOf\n * @static\n * @since 1.0.0\n * @memberOf Index\n * @param {string} [subject=''] The string where to search.\n * @param {string} search The string to search.\n * @param {number} [fromIndex=subject.length - 1] The index to start searching backward in the string.\n * @return {number} Returns the last occurrence index or `-1` if not found.\n * @example\n * v.lastIndexOf('morning', 'n');\n * // => 5\n *\n * v.lastIndexOf('evening', 'o');\n * // => -1\n */\nexport default function lastIndexOf(subject, search, fromIndex) {\n const subjectString = coerceToString(subject);\n return subjectString.lastIndexOf(search, fromIndex);\n}","import clipNumber from 'helper/number/clip_number';\nimport coerceToString from 'helper/string/coerce_to_string';\nimport isNil from 'helper/object/is_nil';\nimport toInteger from 'helper/number/to_integer';\n\n/**\n * Returns the first index of a `pattern` match in `subject`.\n *\n * @function search\n * @static\n * @since 1.0.0\n * @memberOf Index\n * @param {string} [subject=''] The string where to search.\n * @param {string|RegExp} pattern The pattern to match. If `pattern` is not RegExp, it is transformed to `new RegExp(pattern)`.\n * @param {number} [fromIndex=0] The index to start searching.\n * @return {number} Returns the first match index or `-1` if not found.\n * @example\n * v.search('morning', /rn/);\n * // => 2\n *\n * v.search('evening', '/\\d/');\n * // => -1\n */\nexport default function search(subject, pattern, fromIndex) {\n const subjectString = coerceToString(subject);\n const fromIndexNumber = isNil(fromIndex) ? 0 : clipNumber(toInteger(fromIndex), 0, subjectString.length);\n let matchIndex = subjectString.substr(fromIndexNumber).search(pattern);\n if (matchIndex !== -1 && !isNaN(fromIndexNumber)) {\n matchIndex += fromIndexNumber;\n }\n return matchIndex;\n}","import coerceToNumber from 'helper/number/coerce_to_number';\nimport coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Inserts into `subject` a string `toInsert` at specified `position`.\n *\n * @function insert\n * @static\n * @since 1.0.0\n * @memberOf Manipulate\n * @param {string} [subject=''] The string where to insert.\n * @param {string} [toInsert=''] The string to be inserted.\n * @param {number} [position=0] The position to insert.\n * @return {string} Returns the string after insertion.\n * @example\n * v.insert('ct', 'a', 1);\n * // => 'cat'\n *\n * v.insert('sunny', ' day', 5);\n * // => 'sunny day'\n */\nexport default function insert(subject, toInsert, position) {\n const subjectString = coerceToString(subject);\n const toInsertString = coerceToString(toInsert);\n const positionNumber = coerceToNumber(position);\n if (positionNumber < 0 || positionNumber > subjectString.length || toInsertString === '') {\n return subjectString;\n }\n return subjectString.slice(0, positionNumber) + toInsertString + subjectString.slice(positionNumber);\n}","/**\n * Generated diacritics map. See bellow the base code.\n * @ignore\n * @see http://stackoverflow.com/a/18391901/1894471\n * @type Object\n */\n\nconst diacritics = {\n \"3\": \"\\u039e\\u03be\",\n \"8\": \"\\u0398\\u03b8\",\n \"A\": \"\\x41\\xc0\\xc1\\xc2\\xc3\\xc4\\xc5\\u0100\\u0102\\u0104\\u01cd\\u01de\\u01e0\\u01fa\\u0200\\u0202\\u0226\\u023a\\u1e00\\u1ea0\\u1ea2\\u1ea4\\u1ea6\\u1ea8\\u1eaa\\u1eac\\u1eae\\u1eb0\\u1eb2\\u1eb4\\u1eb6\\u24b6\\u2c6f\\uff21\\u0386\\u0391\\u0410\",\n \"B\": \"\\x42\\u0181\\u0182\\u0243\\u1e02\\u1e04\\u1e06\\u24b7\\uff22\\u0392\\u0411\",\n \"C\": \"\\x43\\xc7\\u0106\\u0108\\u010a\\u010c\\u0187\\u023b\\u1e08\\u24b8\\ua73e\\uff23\\u0426\",\n \"D\": \"\\x44\\u010e\\u0110\\u0189\\u018a\\u018b\\u1e0a\\u1e0c\\u1e0e\\u1e10\\u1e12\\u24b9\\ua779\\uff24\\xd0\\u0394\\u0414\",\n \"E\": \"\\x45\\xc8\\xc9\\xca\\xcb\\u0112\\u0114\\u0116\\u0118\\u011a\\u018e\\u0190\\u0204\\u0206\\u0228\\u1e14\\u1e16\\u1e18\\u1e1a\\u1e1c\\u1eb8\\u1eba\\u1ebc\\u1ebe\\u1ec0\\u1ec2\\u1ec4\\u1ec6\\u24ba\\uff25\\u0388\\u0395\\u0415\\u042d\",\n \"F\": \"\\x46\\u0191\\u1e1e\\u24bb\\ua77b\\uff26\\u03a6\\u0424\",\n \"G\": \"\\x47\\u011c\\u011e\\u0120\\u0122\\u0193\\u01e4\\u01e6\\u01f4\\u1e20\\u24bc\\ua77d\\ua77e\\ua7a0\\uff27\\u0393\\u0413\\u0490\",\n \"H\": \"\\x48\\u0124\\u0126\\u021e\\u1e22\\u1e24\\u1e26\\u1e28\\u1e2a\\u24bd\\u2c67\\u2c75\\ua78d\\uff28\\u0389\\u0397\\u0425\",\n \"I\": \"\\x49\\xcc\\xcd\\xce\\xcf\\u0128\\u012a\\u012c\\u012e\\u0130\\u0197\\u01cf\\u0208\\u020a\\u1e2c\\u1e2e\\u1ec8\\u1eca\\u24be\\uff29\\u038a\\u0399\\u03aa\\u0406\\u0418\",\n \"J\": \"\\x4a\\u0134\\u0248\\u24bf\\uff2a\\u0419\",\n \"K\": \"\\x4b\\u0136\\u0198\\u01e8\\u1e30\\u1e32\\u1e34\\u24c0\\u2c69\\ua740\\ua742\\ua744\\ua7a2\\uff2b\\u039a\\u041a\",\n \"L\": \"\\x4c\\u0139\\u013b\\u013d\\u013f\\u0141\\u023d\\u1e36\\u1e38\\u1e3a\\u1e3c\\u24c1\\u2c60\\u2c62\\ua746\\ua748\\ua780\\uff2c\\u039b\\u041b\",\n \"M\": \"\\x4d\\u019c\\u1e3e\\u1e40\\u1e42\\u24c2\\u2c6e\\uff2d\\u039c\\u041c\",\n \"N\": \"\\x4e\\xd1\\u0143\\u0145\\u0147\\u019d\\u01f8\\u0220\\u1e44\\u1e46\\u1e48\\u1e4a\\u24c3\\ua790\\ua7a4\\uff2e\\u039d\\u041d\",\n \"O\": \"\\x4f\\xd2\\xd3\\xd4\\xd5\\xd6\\xd8\\u014c\\u014e\\u0150\\u0186\\u019f\\u01a0\\u01d1\\u01ea\\u01ec\\u01fe\\u020c\\u020e\\u022a\\u022c\\u022e\\u0230\\u1e4c\\u1e4e\\u1e50\\u1e52\\u1ecc\\u1ece\\u1ed0\\u1ed2\\u1ed4\\u1ed6\\u1ed8\\u1eda\\u1edc\\u1ede\\u1ee0\\u1ee2\\u24c4\\ua74a\\ua74c\\uff2f\\u038c\\u039f\\u041e\",\n \"P\": \"\\x50\\u01a4\\u1e54\\u1e56\\u24c5\\u2c63\\ua750\\ua752\\ua754\\uff30\\u03a0\\u041f\",\n \"Q\": \"\\x51\\u024a\\u24c6\\ua756\\ua758\\uff31\",\n \"R\": \"\\x52\\u0154\\u0156\\u0158\\u0210\\u0212\\u024c\\u1e58\\u1e5a\\u1e5c\\u1e5e\\u24c7\\u2c64\\ua75a\\ua782\\ua7a6\\uff32\\u03a1\\u0420\",\n \"S\": \"\\x53\\u015a\\u015c\\u015e\\u0160\\u0218\\u1e60\\u1e62\\u1e64\\u1e66\\u1e68\\u1e9e\\u24c8\\u2c7e\\ua784\\ua7a8\\uff33\\u03a3\\u0421\",\n \"T\": \"\\x54\\u0162\\u0164\\u0166\\u01ac\\u01ae\\u021a\\u023e\\u1e6a\\u1e6c\\u1e6e\\u1e70\\u24c9\\ua786\\uff34\\u03a4\\u0422\",\n \"U\": \"\\x55\\xd9\\xda\\xdb\\xdc\\u0168\\u016a\\u016c\\u016e\\u0170\\u0172\\u01af\\u01d3\\u01d5\\u01d7\\u01d9\\u01db\\u0214\\u0216\\u0244\\u1e72\\u1e74\\u1e76\\u1e78\\u1e7a\\u1ee4\\u1ee6\\u1ee8\\u1eea\\u1eec\\u1eee\\u1ef0\\u24ca\\uff35\\u0423\\u042a\",\n \"V\": \"\\x56\\u01b2\\u0245\\u1e7c\\u1e7e\\u24cb\\ua75e\\uff36\\u0412\",\n \"W\": \"\\x57\\u0174\\u1e80\\u1e82\\u1e84\\u1e86\\u1e88\\u24cc\\u2c72\\uff37\\u038f\\u03a9\",\n \"X\": \"\\x58\\u1e8a\\u1e8c\\u24cd\\uff38\\u03a7\",\n \"Y\": \"\\x59\\xdd\\u0176\\u0178\\u01b3\\u0232\\u024e\\u1e8e\\u1ef2\\u1ef4\\u1ef6\\u1ef8\\u1efe\\u24ce\\uff39\\u038e\\u03a5\\u03ab\\u042b\",\n \"Z\": \"\\x5a\\u0179\\u017b\\u017d\\u01b5\\u0224\\u1e90\\u1e92\\u1e94\\u24cf\\u2c6b\\u2c7f\\ua762\\uff3a\\u0396\\u0417\",\n \"a\": \"\\x61\\xe0\\xe1\\xe2\\xe3\\xe4\\xe5\\u0101\\u0103\\u0105\\u01ce\\u01df\\u01e1\\u01fb\\u0201\\u0203\\u0227\\u0250\\u1e01\\u1e9a\\u1ea1\\u1ea3\\u1ea5\\u1ea7\\u1ea9\\u1eab\\u1ead\\u1eaf\\u1eb1\\u1eb3\\u1eb5\\u1eb7\\u24d0\\u2c65\\uff41\\u03ac\\u03b1\\u0430\",\n \"b\": \"\\x62\\u0180\\u0183\\u0253\\u1e03\\u1e05\\u1e07\\u24d1\\uff42\\u03b2\\u0431\",\n \"c\": \"\\x63\\xe7\\u0107\\u0109\\u010b\\u010d\\u0188\\u023c\\u1e09\\u2184\\u24d2\\ua73f\\uff43\\u0446\",\n \"d\": \"\\x64\\u010f\\u0111\\u018c\\u0256\\u0257\\u1e0b\\u1e0d\\u1e0f\\u1e11\\u1e13\\u24d3\\ua77a\\uff44\\xf0\\u03b4\\u0434\",\n \"e\": \"\\x65\\xe8\\xe9\\xea\\xeb\\u0113\\u0115\\u0117\\u0119\\u011b\\u01dd\\u0205\\u0207\\u0229\\u0247\\u025b\\u1e15\\u1e17\\u1e19\\u1e1b\\u1e1d\\u1eb9\\u1ebb\\u1ebd\\u1ebf\\u1ec1\\u1ec3\\u1ec5\\u1ec7\\u24d4\\uff45\\u03ad\\u03b5\\u0435\\u044d\",\n \"f\": \"\\x66\\u0192\\u1e1f\\u24d5\\ua77c\\uff46\\u03c6\\u0444\",\n \"g\": \"\\x67\\u011d\\u011f\\u0121\\u0123\\u01e5\\u01e7\\u01f5\\u0260\\u1d79\\u1e21\\u24d6\\ua77f\\ua7a1\\uff47\\u03b3\\u0433\\u0491\",\n \"h\": \"\\x68\\u0125\\u0127\\u021f\\u0265\\u1e23\\u1e25\\u1e27\\u1e29\\u1e2b\\u1e96\\u24d7\\u2c68\\u2c76\\uff48\\u03ae\\u03b7\\u0445\",\n \"i\": \"\\x69\\xec\\xed\\xee\\xef\\u0129\\u012b\\u012d\\u012f\\u0131\\u01d0\\u0209\\u020b\\u0268\\u1e2d\\u1e2f\\u1ec9\\u1ecb\\u24d8\\uff49\\u0390\\u03af\\u03b9\\u03ca\\u0438\\u0456\",\n \"j\": \"\\x6a\\u0135\\u01f0\\u0249\\u24d9\\uff4a\\u0439\",\n \"k\": \"\\x6b\\u0137\\u0199\\u01e9\\u1e31\\u1e33\\u1e35\\u24da\\u2c6a\\ua741\\ua743\\ua745\\ua7a3\\uff4b\\u03ba\\u043a\",\n \"l\": \"\\x6c\\u013a\\u013c\\u013e\\u0140\\u0142\\u017f\\u019a\\u026b\\u1e37\\u1e39\\u1e3b\\u1e3d\\u24db\\u2c61\\ua747\\ua749\\ua781\\uff4c\\u03bb\\u043b\",\n \"m\": \"\\x6d\\u026f\\u0271\\u1e3f\\u1e41\\u1e43\\u24dc\\uff4d\\u03bc\\u043c\",\n \"n\": \"\\x6e\\xf1\\u0144\\u0146\\u0148\\u0149\\u019e\\u01f9\\u0272\\u1e45\\u1e47\\u1e49\\u1e4b\\u24dd\\ua791\\ua7a5\\uff4e\\u03bd\\u043d\",\n \"o\": \"\\x6f\\xf2\\xf3\\xf4\\xf5\\xf6\\xf8\\u014d\\u014f\\u0151\\u01a1\\u01d2\\u01eb\\u01ed\\u01ff\\u020d\\u020f\\u022b\\u022d\\u022f\\u0231\\u0254\\u0275\\u1e4d\\u1e4f\\u1e51\\u1e53\\u1ecd\\u1ecf\\u1ed1\\u1ed3\\u1ed5\\u1ed7\\u1ed9\\u1edb\\u1edd\\u1edf\\u1ee1\\u1ee3\\u24de\\ua74b\\ua74d\\uff4f\\u03bf\\u03cc\\u043e\",\n \"p\": \"\\x70\\u01a5\\u1d7d\\u1e55\\u1e57\\u24df\\ua751\\ua753\\ua755\\uff50\\u03c0\\u043f\",\n \"q\": \"\\x71\\u024b\\u24e0\\ua757\\ua759\\uff51\",\n \"r\": \"\\x72\\u0155\\u0157\\u0159\\u0211\\u0213\\u024d\\u027d\\u1e59\\u1e5b\\u1e5d\\u1e5f\\u24e1\\ua75b\\ua783\\ua7a7\\uff52\\u03c1\\u0440\",\n \"s\": \"\\x73\\xdf\\u015b\\u015d\\u015f\\u0161\\u0219\\u023f\\u1e61\\u1e63\\u1e65\\u1e67\\u1e69\\u1e9b\\u24e2\\ua785\\ua7a9\\uff53\\u03c2\\u03c3\\u0441\",\n \"t\": \"\\x74\\u0163\\u0165\\u0167\\u01ad\\u021b\\u0288\\u1e6b\\u1e6d\\u1e6f\\u1e71\\u1e97\\u24e3\\u2c66\\ua787\\uff54\\u03c4\\u0442\",\n \"u\": \"\\x75\\xf9\\xfa\\xfb\\xfc\\u0169\\u016b\\u016d\\u016f\\u0171\\u0173\\u01b0\\u01d4\\u01d6\\u01d8\\u01da\\u01dc\\u0215\\u0217\\u0289\\u1e73\\u1e75\\u1e77\\u1e79\\u1e7b\\u1ee5\\u1ee7\\u1ee9\\u1eeb\\u1eed\\u1eef\\u1ef1\\u24e4\\uff55\\u0443\\u044a\",\n \"v\": \"\\x76\\u028b\\u028c\\u1e7d\\u1e7f\\u24e5\\ua75f\\uff56\\u0432\",\n \"w\": \"\\x77\\u0175\\u1e81\\u1e83\\u1e85\\u1e87\\u1e89\\u1e98\\u24e6\\u2c73\\uff57\\u03c9\\u03ce\",\n \"x\": \"\\x78\\u1e8b\\u1e8d\\u24e7\\uff58\\u03c7\",\n \"y\": \"\\x79\\xfd\\xff\\u0177\\u01b4\\u0233\\u024f\\u1e8f\\u1e99\\u1ef3\\u1ef5\\u1ef7\\u1ef9\\u1eff\\u24e8\\uff59\\u03b0\\u03c5\\u03cb\\u03cd\\u044b\",\n \"z\": \"\\x7a\\u017a\\u017c\\u017e\\u01b6\\u0225\\u0240\\u1e91\\u1e93\\u1e95\\u24e9\\u2c6c\\ua763\\uff5a\\u03b6\\u0437\",\n \"OE\": \"\\x8c\\u0152\",\n \"oe\": \"\\x9c\\u0153\",\n \"AE\": \"\\xc6\\u01e2\\u01fc\",\n \"ae\": \"\\xe6\\u01e3\\u01fd\",\n \"hv\": \"\\u0195\",\n \"OI\": \"\\u01a2\",\n \"oi\": \"\\u01a3\",\n \"DZ\": \"\\u01c4\\u01f1\",\n \"Dz\": \"\\u01c5\\u01f2\",\n \"dz\": \"\\u01c6\\u01f3\",\n \"LJ\": \"\\u01c7\",\n \"Lj\": \"\\u01c8\",\n \"lj\": \"\\u01c9\",\n \"NJ\": \"\\u01ca\",\n \"Nj\": \"\\u01cb\",\n \"nj\": \"\\u01cc\",\n \"OU\": \"\\u0222\",\n \"ou\": \"\\u0223\",\n \"TZ\": \"\\ua728\",\n \"tz\": \"\\ua729\",\n \"AA\": \"\\ua732\",\n \"aa\": \"\\ua733\",\n \"AO\": \"\\ua734\",\n \"ao\": \"\\ua735\",\n \"AU\": \"\\ua736\",\n \"au\": \"\\ua737\",\n \"AV\": \"\\ua738\\ua73a\",\n \"av\": \"\\ua739\\ua73b\",\n \"AY\": \"\\ua73c\",\n \"ay\": \"\\ua73d\",\n \"OO\": \"\\ua74e\",\n \"oo\": \"\\ua74f\",\n \"VY\": \"\\ua760\",\n \"vy\": \"\\ua761\",\n \"TH\": \"\\xde\",\n \"th\": \"\\xfe\",\n \"PS\": \"\\u03a8\",\n \"ps\": \"\\u03c8\",\n \"Yo\": \"\\u0401\",\n \"Ye\": \"\\u0404\",\n \"Yi\": \"\\u0407\",\n \"Zh\": \"\\u0416\",\n \"Ch\": \"\\u0427\",\n \"Sh\": \"\\u0428\\u0429\",\n \"\": \"\\u042c\\u044c\",\n \"Yu\": \"\\u042e\",\n \"Ya\": \"\\u042f\",\n \"zh\": \"\\u0436\",\n \"ch\": \"\\u0447\",\n \"sh\": \"\\u0448\\u0449\",\n \"yu\": \"\\u044e\",\n \"ya\": \"\\u044f\",\n \"yo\": \"\\u0451\",\n \"ye\": \"\\u0454\",\n \"yi\": \"\\u0457\"\n};\n\nlet diacriticsMap = null;\n\n/**\n * Creates a map of the diacritics.\n *\n * @ignore\n * @returns {Object} Returns the diacritics map.\n */\nfunction getDiacriticsMap() {\n if (diacriticsMap !== null) {\n return diacriticsMap;\n }\n diacriticsMap = {};\n Object.keys(diacritics).forEach(function(key) {\n const characters = diacritics[key];\n for (let index = 0; index < characters.length; index++) {\n const character = characters[index];\n diacriticsMap[character] = key;\n }\n });\n return diacriticsMap;\n}\n\n/**\n * Get the latin character from character with diacritics.\n *\n * @ignore\n * @param {string} character The character with diacritics.\n * @returns {string} Returns the character without diacritics.\n */\nexport function getLatinCharacter(character) {\n const characterWithoutDiacritic = getDiacriticsMap()[character];\n return characterWithoutDiacritic ? characterWithoutDiacritic : character;\n}","import { REGEXP_COMBINING_MARKS, REGEXP_NON_LATIN } from 'helper/reg_exp/const';\nimport coerceToString from 'helper/string/coerce_to_string';\nimport { getLatinCharacter } from 'helper/string/diacritics_map';\n\n/**\n * Returns the `cleanCharacter` from combining marks regular expression match.\n *\n * @ignore\n * @param {string} character The character with combining marks\n * @param {string} cleanCharacter The character without combining marks.\n * @return {string} The character without combining marks.\n */\nfunction removeCombiningMarks(character, cleanCharacter) {\n return cleanCharacter;\n}\n\n/**\n * Latinises the `subject` by removing diacritic characters.\n *\n * @function latinise\n * @static\n * @since 1.0.0\n * @memberOf Manipulate\n * @param {string} [subject=''] The string to latinise.\n * @return {string} Returns the latinised string.\n * @example\n * v.latinise('cafe\\u0301'); // or 'café'\n * // => 'cafe'\n *\n * v.latinise('août décembre');\n * // => 'aout decembre'\n *\n * v.latinise('как прекрасен этот мир');\n * // => 'kak prekrasen etot mir'\n */\nexport default function latinise(subject) {\n const subjectString = coerceToString(subject);\n if (subjectString === '') {\n return '';\n }\n return subjectString\n .replace(REGEXP_NON_LATIN, getLatinCharacter)\n .replace(REGEXP_COMBINING_MARKS, removeCombiningMarks);\n}","import buildPadding from 'helper/string/build_padding';\nimport clipNumber from 'helper/number/clip_number';\nimport coerceToString from 'helper/string/coerce_to_string';\nimport isNil from 'helper/object/is_nil';\nimport { MAX_SAFE_INTEGER } from 'helper/number/const';\nimport toInteger from 'helper/number/to_integer';\n\n/**\n * Pads `subject` to a new `length`.\n *\n * @function pad\n * @static\n * @since 1.0.0\n * @memberOf Manipulate\n * @param {string} [subject=''] The string to pad.\n * @param {int} [length=0] The length to pad the string. No changes are made if `length` is less than `subject.length`.\n * @param {string} [pad=' '] The string to be used for padding.\n * @return {string} Returns the padded string.\n * @example\n * v.pad('dog', 5);\n * // => ' dog '\n *\n * v.pad('bird', 6, '-');\n * // => '-bird-'\n *\n * v.pad('cat', 6, '-=');\n * // => '-cat-='\n */\nexport default function pad(subject, length, pad) {\n const subjectString = coerceToString(subject);\n const lengthInt = isNil(length) ? 0 : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER);\n const padString = coerceToString(pad, ' ');\n if (lengthInt <= subjectString.length) {\n return subjectString;\n }\n const paddingLength = lengthInt - subjectString.length;\n const paddingSideLength = toInteger(paddingLength / 2);\n const paddingSideRemainingLength = paddingLength % 2;\n return buildPadding(padString, paddingSideLength) + subjectString +\n buildPadding(padString, paddingSideLength + paddingSideRemainingLength);\n}","import coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Replaces the matches of `pattern` with `replacement`.
\n *\n * @function replace\n * @static\n * @since 1.0.0\n * @memberOf Manipulate\n * @param {string} [subject=''] The string to verify.\n * @param {string|RegExp} pattern The pattern which match is replaced. If `pattern` is a string,\n * a simple string match is evaluated and only the first occurrence replaced.\n * @param {string|Function} replacement The string or function which invocation result replaces `pattern` match.\n * @return {string} Returns the replacement result.\n * @example\n * v.replace('swan', 'wa', 'u');\n * // => 'sun'\n *\n * v.replace('domestic duck', /domestic\\s/, '');\n * // => 'duck'\n *\n * v.replace('nice duck', /(nice)(duck)/, function(match, nice, duck) {\n * return 'the ' + duck + ' is ' + nice;\n * });\n * // => 'the duck is nice'\n */\nexport default function replace(subject, pattern, replacement) {\n const subjectString = coerceToString(subject);\n return subjectString.replace(pattern, replacement);\n}","import { REGEXP_FLAGS } from 'helper/reg_exp/const';\n\n/**\n * Get the flags string from a regular expression object.\n *\n * @ignore\n * @param {RegExp} regExp The regular expression object.\n * @return {string} Returns the string with flags chars.\n */\nexport default function getRegExpFlags(regExp) {\n return regExp.toString().match(REGEXP_FLAGS)[0];\n}","import clipNumber from 'helper/number/clip_number';\nimport coerceToString from 'helper/string/coerce_to_string';\nimport isNil from 'helper/object/is_nil';\nimport toInteger from 'helper/number/to_integer';\nimport toString from 'helper/string/to_string';\n\n/**\n * Checks whether `subject` includes `search` starting from `position`.\n *\n * @function includes\n * @static\n * @since 1.0.0\n * @memberOf Query\n * @param {string} [subject=''] The string where to search.\n * @param {string} search The string to search.\n * @param {number} [position=0] The position to start searching.\n * @return {boolean} Returns `true` if `subject` includes `search` or `false` otherwise.\n * @example\n * v.includes('starship', 'star');\n * // => true\n *\n * v.includes('galaxy', 'g', 1);\n * // => false\n */\nexport default function includes(subject, search, position) {\n const subjectString = coerceToString(subject);\n const searchString = toString(search);\n if (searchString === null) {\n return false;\n }\n if (searchString === '') {\n return true;\n }\n position = isNil(position) ? 0 : clipNumber(toInteger(position), 0, subjectString.length);\n return subjectString.indexOf(searchString, position) !== -1;\n}","import getRegExpFlags from 'helper/reg_exp/get_reg_exp_flags';\nimport includes from 'query/includes';\n\n/**\n * Append flag to a regular expression.\n *\n * @ignore\n * @param {RegExp} pattern The pattern to coerce.\n * @param {string} appendFlag The flag to append to regular expression.\n * @return {RegExp} The regular expression with added flag.\n */\nexport default function appendFlagToRegExp(pattern, appendFlag) {\n const regularExpressionFlags = getRegExpFlags(pattern);\n if (!includes(regularExpressionFlags, appendFlag)) {\n return new RegExp(pattern.source, regularExpressionFlags + appendFlag);\n }\n return pattern;\n}","import appendFlagToRegularExpression from 'helper/reg_exp/append_flag_to_reg_exp';\nimport coerceToString from 'helper/string/coerce_to_string';\nimport escapeRegExp from 'escape/escape_reg_exp';\n\n/**\n * Replaces all matches of `pattern` with `replacement`.
\n *\n * @function replaceAll\n * @static\n * @since 1.0.0\n * @memberOf Manipulate\n * @param {string} [subject=''] The string to verify.\n * @param {string|RegExp} pattern The pattern which match is replaced. If `pattern` is a string, a simple string match is evaluated.\n * All matches are replaced.\n * @param {string|Function} replacement The string or function which invocation result replaces `pattern` match.\n * @return {string} Returns the replacement result.\n * @example\n * v.replaceAll('good morning', 'o', '*');\n * // => 'g**d m*rning'\n * v.replaceAll('evening', /n/, 's');\n * // => 'evesisg'\n *\n */\nexport default function replaceAll(subject, pattern, replacement) {\n const subjectString = coerceToString(subject);\n let regExp = pattern;\n if (!(pattern instanceof RegExp)) {\n regExp = new RegExp(escapeRegExp(pattern), 'g');\n } else if (!pattern.global) {\n regExp = appendFlagToRegularExpression(pattern, 'g');\n }\n return subjectString.replace(regExp, replacement);\n}","import coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Reverses the `subject`.\n *\n * @function reverse\n * @static\n * @since 1.0.0\n * @memberOf Manipulate\n * @param {string} [subject=''] The string to reverse.\n * @return {string} Returns the reversed string.\n * @example\n * v.reverse('winter');\n * // => 'retniw'\n */\nexport default function reverse(subject) {\n const subjectString = coerceToString(subject);\n return subjectString.split('').reverse().join('');\n}","import { REGEXP_COMBINING_MARKS, REGEXP_SURROGATE_PAIRS } from 'helper/reg_exp/const';\nimport coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Reverses the `subject` taking care of\n * surrogate pairs and\n * combining marks.\n *\n * @function reverseGrapheme\n * @static\n * @since 1.0.0\n * @memberOf Manipulate\n * @param {string} [subject=''] The string to reverse.\n * @return {string} Returns the reversed string.\n * @example\n * v.reverseGrapheme('summer');\n * // => 'remmus'\n *\n * v.reverseGrapheme('𝌆 bar mañana mañana');\n * // => 'anañam anañam rab 𝌆'\n */\nexport default function reverseGrapheme(subject) {\n let subjectString = coerceToString(subject);\n /**\n * @see https://github.com/mathiasbynens/esrever\n */\n subjectString = subjectString\n .replace(REGEXP_COMBINING_MARKS, function($0, $1, $2) {\n return reverseGrapheme($2) + $1;\n })\n .replace(REGEXP_SURROGATE_PAIRS, '$2$1');\n let reversedString = '';\n let index = subjectString.length;\n while (index--) {\n reversedString += subjectString.charAt(index);\n }\n return reversedString;\n}","import coerceToString from 'helper/string/coerce_to_string';\nimport kebabCase from 'case/kebab_case';\nimport latinise from 'manipulate/latinise';\nimport { REGEXP_NON_LATIN } from 'helper/reg_exp/const';\n\n/**\n * Slugifies the `subject`. Cleans the `subject` by replacing diacritics with corresponding latin characters.\n *\n * @function slugify\n * @static\n * @since 1.0.0\n * @memberOf Manipulate\n * @param {string} [subject=''] The string to slugify.\n * @return {string} Returns the slugified string.\n * @example\n * v.slugify('Italian cappuccino drink');\n * // => 'italian-cappuccino-drink'\n *\n * v.slugify('caffé latté');\n * // => 'caffe-latte'\n *\n * v.slugify('хорошая погода');\n * // => 'horoshaya-pogoda'\n */\nexport default function slugify(subject) {\n const subjectString = coerceToString(subject);\n if (subjectString === '') {\n return '';\n }\n const cleanSubjectString = latinise(subjectString).replace(REGEXP_NON_LATIN, '-');\n return kebabCase(cleanSubjectString);\n}","import coerceToNumber from 'helper/number/coerce_to_number';\nimport coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Changes `subject` by deleting `deleteCount` of characters starting at position `start`. Places a new string\n * `toAdd` instead of deleted characters.\n *\n * @function splice\n * @static\n * @since 1.0.0\n * @memberOf Manipulate\n * @param {string} [subject=''] The string where to insert.\n * @param {string} start The position to start changing the string. For a negative position will start from the end of\n * the string.\n * @param {number} [deleteCount=subject.length-start] The number of characters to delete from string.\n * @param {string} [toAdd=''] The string to be added instead of deleted characters.\n * @return {string} Returns the modified string.\n * @example\n * v.splice('new year', 0, 4);\n * // => 'year'\n *\n * v.splice('new year', 0, 3, 'happy');\n * // => 'happy year'\n *\n * v.splice('new year', -4, 4, 'day');\n * // => 'new day'\n */\nexport default function splice(subject, start, deleteCount, toAdd) {\n const subjectString = coerceToString(subject);\n const toAddString = coerceToString(toAdd);\n let startPosition = coerceToNumber(start);\n if (startPosition < 0) {\n startPosition = subjectString.length + startPosition;\n if (startPosition < 0) {\n startPosition = 0;\n }\n } else if (startPosition > subjectString.length) {\n startPosition = subjectString.length;\n }\n let deleteCountNumber = coerceToNumber(deleteCount, subjectString.length - startPosition);\n if (deleteCountNumber < 0) {\n deleteCountNumber = 0;\n }\n return subjectString.slice(0, startPosition) + toAddString + subjectString.slice(startPosition + deleteCountNumber);\n}","import coerceToString from 'helper/string/coerce_to_string';\nimport isString from 'query/is_string';\nimport nilDefault from 'helper/undefined/nil_default';\n\n/**\n * Translates characters or replaces substrings in `subject`.\n *\n * @function tr\n * @static\n * @since 1.3.0\n * @memberOf Manipulate\n * @param {string} [subject=''] The string to translate.\n * @param {string|Object} from The string of characters to translate from. Or an object, then the object keys are replaced with corresponding values (longest keys are tried first).\n * @param {string} to The string of characters to translate to. Ignored when `from` is an object.\n * @return {string} Returns the translated string.\n * @example\n * v.tr('hello', 'el', 'ip');\n * // => 'hippo'\n * \n * v.tr('légèreté', 'éè', 'ee');\n * // => 'legerete'\n * \n * v.tr('Yes. The fire rises.', {\n * 'Yes': 'Awesome',\n * 'fire': 'flame'\n * })\n * // => 'Awesome. The flame rises.'\n * \n * v.tr(':where is the birthplace of :what', {\n * ':where': 'Africa',\n * ':what': 'Humanity'\n * });\n * // => 'Africa is the birthplace of Humanity'\n * \n */\nexport default function tr(subject, from, to) {\n const subjectString = coerceToString(subject);\n let keys;\n let values;\n if (isString(from) && isString(to)) {\n keys = from.split('');\n values = to.split('');\n } else {\n [keys, values] = extractKeysAndValues(nilDefault(from, {}));\n }\n if (keys.length === 0) {\n return subjectString;\n }\n let result = '';\n const valuesLength = values.length;\n const keysLength = keys.length;\n for (let index = 0; index < subjectString.length; index++) {\n let isMatch = false;\n let matchValue;\n for (let keyIndex = 0; keyIndex < keysLength && keyIndex < valuesLength; keyIndex++) {\n const key = keys[keyIndex];\n if (subjectString.substr(index, key.length) === key) {\n isMatch = true;\n matchValue = values[keyIndex];\n index = index + key.length - 1;\n break;\n }\n }\n result += isMatch ? matchValue : subjectString[index];\n }\n return result;\n}\n\nfunction extractKeysAndValues(object) {\n const keys = Object.keys(object);\n const values = keys.sort(sortStringByLength).map(function (key) {\n return object[key];\n });\n return [keys, values];\n}\n\nfunction sortStringByLength(str1, str2) {\n if (str1.length === str2.length) {\n return 0;\n }\n return str1.length < str2.length ? 1 : -1;\n}","import coerceToString from 'helper/string/coerce_to_string';\nimport includes from 'query/includes';\nimport isNil from 'helper/object/is_nil';\nimport { REGEXP_TRIM_LEFT } from 'helper/reg_exp/const';\nimport toString from 'helper/string/to_string';\n\nconst reduce = Array.prototype.reduce;\n\n/**\n * Removes whitespaces from the left side of the `subject`.\n *\n * @function trimLeft\n * @static\n * @since 1.0.0\n * @memberOf Manipulate\n * @param {string} [subject=''] The string to trim.\n * @param {string} [whitespace=whitespace] The whitespace characters to trim. List all characters that you want to be stripped.\n * @return {string} Returns the trimmed string.\n * @example\n * v.trimLeft(' Starship Troopers');\n * // => 'Starship Troopers'\n *\n * v.trimLeft('***Mobile Infantry', '*');\n * // => 'Mobile Infantry'\n */\nexport default function trimLeft(subject, whitespace) {\n const subjectString = coerceToString(subject);\n if (whitespace === '' || subjectString === '') {\n return subjectString;\n }\n const whitespaceString = toString(whitespace);\n if (isNil(whitespaceString)) {\n return subjectString.replace(REGEXP_TRIM_LEFT, '');\n }\n let matchWhitespace = true;\n return reduce.call(subjectString, function(trimmed, character) {\n if (matchWhitespace && includes(whitespaceString, character)) {\n return trimmed;\n }\n matchWhitespace = false;\n return trimmed + character;\n }, '');\n}","import coerceToString from 'helper/string/coerce_to_string';\nimport includes from 'query/includes';\nimport isNil from 'helper/object/is_nil';\nimport { REGEXP_TRIM_RIGHT } from 'helper/reg_exp/const';\nimport toString from 'helper/string/to_string';\n\nconst reduceRight = Array.prototype.reduceRight;\n\n/**\n * Removes whitespaces from the right side of the `subject`.\n *\n * @function trimRight\n * @static\n * @since 1.0.0\n * @memberOf Manipulate\n * @param {string} [subject=''] The string to trim.\n * @param {string} [whitespace=whitespace] The whitespace characters to trim. List all characters that you want to be stripped.\n * @return {string} Returns the trimmed string.\n * @example\n * v.trimRight('the fire rises ');\n * // => 'the fire rises'\n *\n * v.trimRight('do you feel in charge?!!!', '!');\n * // => 'do you feel in charge?'\n */\nexport default function trimRight(subject, whitespace) {\n const subjectString = coerceToString(subject);\n if (whitespace === '' || subjectString === '') {\n return subjectString;\n }\n const whitespaceString = toString(whitespace);\n if (isNil(whitespaceString)) {\n return subjectString.replace(REGEXP_TRIM_RIGHT, '');\n }\n let matchWhitespace = true;\n return reduceRight.call(subjectString, function(trimmed, character) {\n if (matchWhitespace && includes(whitespaceString, character)) {\n return trimmed;\n }\n matchWhitespace = false;\n return character + trimmed;\n }, '');\n}","import coerceToString from 'helper/string/coerce_to_string';\nimport isNil from 'helper/object/is_nil';\nimport toString from 'helper/string/to_string';\nimport trimLeft from 'manipulate/trim_left';\nimport trimRight from 'manipulate/trim_right';\n\n/**\n * Removes whitespaces from left and right sides of the `subject`.\n *\n * @function trim\n * @static\n * @since 1.0.0\n * @memberOf Manipulate\n * @param {string} [subject=''] The string to trim.\n * @param {string} [whitespace=whitespace] The whitespace characters to trim. List all characters that you want to be stripped.\n * @return {string} Returns the trimmed string.\n * @example\n * v.trim(' Mother nature ');\n * // => 'Mother nature'\n *\n * v.trim('--Earth--', '-');\n * // => 'Earth'\n */\nexport default function trim(subject, whitespace) {\n const subjectString = coerceToString(subject);\n if (whitespace === '' || subjectString === '') {\n return subjectString;\n }\n const whitespaceString = toString(whitespace);\n if (isNil(whitespaceString)) {\n return subjectString.trim();\n }\n return trimRight(trimLeft(subjectString, whitespaceString), whitespaceString);\n}","import coerceToBoolean from 'helper/boolean/coerce_to_boolean';\nimport coerceToNumber from 'helper/number/coerce_to_number';\nimport coerceToString from 'helper/string/coerce_to_string';\n\nconst OPTION_WIDTH = 'width';\nconst OPTION_NEW_LINE = 'newLine';\nconst OPTION_INDENT = 'indent';\nconst OPTION_CUT = 'cut';\n\n/**\n * Wraps `subject` to a given number of characters using a string break character.\n *\n * @function wordWrap\n * @static\n * @since 1.0.0\n * @memberOf Manipulate\n * @param {string} [subject=''] The string to wrap.\n * @param {Object} [options={}] The wrap options.\n * @param {number} [options.width=75] The number of characters at which to wrap.\n * @param {string} [options.newLine='\\n'] The string to add at the end of line.\n * @param {string} [options.indent=''] The string to intend the line.\n * @param {boolean} [options.cut=false] When `false` (default) does not split the word even if word length is bigger than `width`.
\n * When `true` breaks the word that has length bigger than `width`.\n *\n * @return {string} Returns wrapped string.\n * @example\n * v.wordWrap('Hello world', {\n * width: 5\n * });\n * // => 'Hello\\nworld'\n *\n * v.wordWrap('Hello world', {\n * width: 5,\n * newLine: '
',\n * indent: '__'\n * });\n * // => '__Hello
__world'\n *\n * v.wordWrap('Wonderful world', {\n * width: 5,\n * cut: true\n * });\n * // => 'Wonde\\nrful\\nworld'\n *\n */\nexport default function wordWrap(subject, options = {}) {\n const subjectString = coerceToString(subject);\n const { width, newLine, indent, cut } = determineOptions(options);\n if (subjectString === '' || width <= 0) {\n return indent;\n }\n const subjectLength = subjectString.length;\n const substring = subjectString.substring.bind(subjectString);\n let offset = 0;\n let wrappedLine = '';\n while ((subjectLength - offset) > width) {\n if (subjectString[offset] === ' ') {\n offset++;\n continue;\n }\n let spaceToWrapAt = subjectString.lastIndexOf(' ', width + offset);\n if (spaceToWrapAt >= offset) {\n wrappedLine += indent + substring(offset, spaceToWrapAt) + newLine;\n offset = spaceToWrapAt + 1;\n } else {\n if (cut) {\n wrappedLine += indent + substring(offset, width + offset) + newLine;\n offset += width;\n } else {\n spaceToWrapAt = subjectString.indexOf(' ', width + offset);\n if (spaceToWrapAt >= 0) {\n wrappedLine += indent + substring(offset, spaceToWrapAt) + newLine;\n offset = spaceToWrapAt + 1;\n } else {\n wrappedLine += indent + substring(offset);\n offset = subjectLength;\n }\n }\n }\n }\n if (offset < subjectLength) {\n wrappedLine += indent + substring(offset);\n }\n return wrappedLine;\n}\n\n/**\n * Determine the word wrap options. The missing values are filled with defaults.\n *\n * @param {Object} options The options object.\n * @return {Object} The word wrap options, with default settings if necessary.\n * @ignore\n */\nfunction determineOptions(options) {\n return {\n width: coerceToNumber(options[OPTION_WIDTH], 75),\n newLine: coerceToString(options[OPTION_NEW_LINE], '\\n'),\n indent: coerceToString(options[OPTION_INDENT], ''),\n cut: coerceToBoolean(options[OPTION_CUT], false)\n };\n}","import clipNumber from 'helper/number/clip_number';\nimport coerceToString from 'helper/string/coerce_to_string';\nimport isNil from 'helper/object/is_nil';\nimport toInteger from 'helper/number/to_integer';\n\n/**\n * Checks whether `subject` ends with `end`.\n *\n * @function endsWith\n * @static\n * @since 1.0.0\n * @memberOf Query\n * @param {string} [subject=''] The string to verify.\n * @param {string} end The ending string.\n * @param {number} [position=subject.length] Search within `subject` as if the string were only `position` long.\n * @return {boolean} Returns `true` if `subject` ends with `end` or `false` otherwise.\n * @example\n * v.endsWith('red alert', 'alert');\n * // => true\n *\n * v.endsWith('metro south', 'metro');\n * // => false\n *\n * v.endsWith('Murphy', 'ph', 5);\n * // => true\n */\nexport default function endsWith(subject, end, position) {\n if (isNil(end)) {\n return false;\n }\n const subjectString = coerceToString(subject);\n const endString = coerceToString(end);\n if (endString === '') {\n return true;\n }\n position = isNil(position) ? subjectString.length : clipNumber(toInteger(position), 0, subjectString.length);\n position -= endString.length;\n const lastIndex = subjectString.indexOf(endString, position);\n return lastIndex !== -1 && lastIndex === position;\n}","import coerceToString from 'helper/string/coerce_to_string';\nimport { REGEXP_ALPHA } from 'helper/reg_exp/const_extended';\n\n/**\n * Checks whether `subject` contains only alpha characters.\n *\n * @function isAlpha\n * @static\n * @since 1.0.0\n * @memberOf Query\n * @param {string} [subject=''] The string to verify.\n * @return {boolean} Returns `true` if `subject` contains only alpha characters or `false` otherwise.\n * @example\n * v.isAlpha('bart');\n * // => true\n *\n * v.isAlpha('lisa!');\n * // => false\n *\n * v.isAlpha('lisa and bart');\n * // => false\n */\nexport default function isAlpha(subject) {\n const subjectString = coerceToString(subject);\n return REGEXP_ALPHA.test(subjectString);\n}","import coerceToString from 'helper/string/coerce_to_string';\nimport { REGEXP_ALPHA_DIGIT } from 'helper/reg_exp/const_extended';\n\n/**\n * Checks whether `subject` contains only alpha and digit characters.\n *\n * @function isAlphaDigit\n * @static\n * @since 1.0.0\n * @memberOf Query\n * @param {string} [subject=''] The string to verify.\n * @return {boolean} Returns `true` if `subject` contains only alpha and digit characters or `false` otherwise.\n * @example\n * v.isAlphaDigit('year2020');\n * // => true\n *\n * v.isAlphaDigit('1448');\n * // => true\n *\n * v.isAlphaDigit('40-20');\n * // => false\n */\nexport default function isAlphaDigit(subject) {\n const subjectString = coerceToString(subject);\n return REGEXP_ALPHA_DIGIT.test(subjectString);\n}","import coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Checks whether `subject` is empty or contains only whitespaces.\n *\n * @function isBlank\n * @static\n * @since 1.0.0\n * @memberOf Query\n * @param {string} [subject=''] The string to verify.\n * @return {boolean} Returns `true` if `subject` is empty or contains only whitespaces or `false` otherwise.\n * @example\n * v.isBlank('');\n * // => true\n *\n * v.isBlank(' ');\n * // => true\n *\n * v.isBlank('World');\n * // => false\n */\nexport default function isBlank(subject) {\n const subjectString = coerceToString(subject);\n return subjectString.trim().length === 0;\n}","import coerceToString from 'helper/string/coerce_to_string';\nimport { REGEXP_DIGIT } from 'helper/reg_exp/const';\n\n/**\n * Checks whether `subject` contains only digit characters.\n *\n * @function isDigit\n * @static\n * @since 1.0.0\n * @memberOf Query\n * @param {string} [subject=''] The string to verify.\n * @return {boolean} Returns `true` if `subject` contains only digit characters or `false` otherwise.\n * @example\n * v.isDigit('35');\n * // => true\n *\n * v.isDigit('1.5');\n * // => false\n *\n * v.isDigit('ten');\n * // => false\n */\nexport default function isDigit(subject) {\n const subjectString = coerceToString(subject);\n return REGEXP_DIGIT.test(subjectString);\n}","import coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Checks whether `subject` is empty.\n *\n * @function isEmpty\n * @static\n * @since 1.0.0\n * @memberOf Query\n * @param {string} [subject=''] The string to verify.\n * @return {boolean} Returns `true` if `subject` is empty or `false` otherwise\n * @example\n * v.isEmpty('');\n * // => true\n *\n * v.isEmpty(' ');\n * // => false\n *\n * v.isEmpty('sun');\n * // => false\n */\nexport default function isEmpty(subject) {\n const subjectString = coerceToString(subject);\n return subjectString.length === 0;\n}","import coerceToString from 'helper/string/coerce_to_string';\nimport isAlpha from 'query/is_alpha';\n\n/**\n * Checks whether `subject` has only lower case characters.\n *\n * @function isLowerCase\n * @static\n * @since 1.0.0\n * @memberOf Query\n * @param {string} [subject=''] The string to verify.\n * @return {boolean} Returns `true` if `subject` is lower case or `false` otherwise.\n * @example\n * v.isLowerCase('motorcycle');\n * // => true\n *\n * v.isLowerCase('John');\n * // => false\n *\n * v.isLowerCase('T1000');\n * // => false\n */\nexport default function isLowerCase(subject) {\n const valueString = coerceToString(subject);\n return isAlpha(valueString) && valueString.toLowerCase() === valueString;\n}","import isNil from 'helper/object/is_nil';\n\n/**\n * Checks whether `subject` is numeric.\n *\n * @function isNumeric\n * @static\n * @since 1.0.0\n * @memberOf Query\n * @param {string} [subject=''] The string to verify.\n * @return {boolean} Returns `true` if `subject` is numeric or `false` otherwise.\n * @example\n * v.isNumeric('350');\n * // => true\n *\n * v.isNumeric('-20.5');\n * // => true\n *\n * v.isNumeric('1.5E+2');\n * // => true\n *\n * v.isNumeric('five');\n * // => false\n */\nexport default function isNumeric(subject) {\n const valueNumeric = typeof subject === 'object' && !isNil(subject) ? Number(subject) : subject;\n return (typeof valueNumeric === 'number' || typeof valueNumeric === 'string')\n && !isNaN(valueNumeric - parseFloat(valueNumeric));\n}","import coerceToString from 'helper/string/coerce_to_string';\nimport isAlpha from 'query/is_alpha';\n\n/**\n * Checks whether `subject` contains only upper case characters.\n *\n * @function isUpperCase\n * @static\n * @since 1.0.0\n * @memberOf Query\n * @param {string} [subject=''] The string to verify.\n * @return {boolean} Returns `true` if `subject` is upper case or `false` otherwise.\n * @example\n * v.isUpperCase('ACDC');\n * // => true\n *\n * v.isUpperCase('Morning');\n * // => false\n */\nexport default function isUpperCase(subject) {\n const subjectString = coerceToString(subject);\n return isAlpha(subjectString) && subjectString.toUpperCase() === subjectString;\n}","import coerceToString from 'helper/string/coerce_to_string';\nimport toString from 'helper/string/to_string';\n\n/**\n * Checks whether `subject` matches the regular expression `pattern`.\n *\n * @function matches\n * @static\n * @since 1.0.0\n * @memberOf Query\n * @param {string} [subject=''] The string to verify.\n * @param {RegExp|string} pattern The pattern to match. If `pattern` is not RegExp, it is transformed to `new RegExp(pattern, flags)`.\n * @param {string} [flags=''] The regular expression flags. Applies when `pattern` is string type.\n * @return {boolean} Returns `true` if `subject` matches `pattern` or `false` otherwise.\n * @example\n * v.matches('pluto', /plu.{2}/);\n * // => true\n *\n * v.matches('sun', 'S', 'i');\n * // => true\n *\n * v.matches('apollo 11', '\\\\d{3}');\n * // => false\n */\nexport default function matches(subject, pattern, flags) {\n const subjectString = coerceToString(subject);\n const flagsString = coerceToString(flags);\n let patternString;\n if (!(pattern instanceof RegExp)) {\n patternString = toString(pattern);\n if (patternString === null) {\n return false;\n }\n pattern = new RegExp(patternString, flagsString);\n }\n return pattern.test(subjectString);\n}","import clipNumber from 'helper/number/clip_number';\nimport coerceToString from 'helper/string/coerce_to_string';\nimport isNil from 'helper/object/is_nil';\nimport toInteger from 'helper/number/to_integer';\nimport toString from 'helper/string/to_string';\n\n/**\n * Checks whether `subject` starts with `start`.\n *\n * @function startsWith\n * @static\n * @since 1.0.0\n * @memberOf Query\n * @param {string} [subject=''] The string to verify.\n * @param {string} start The starting string.\n * @param {number} [position=0] The position to start searching.\n * @return {boolean} Returns `true` if `subject` starts with `start` or `false` otherwise.\n * @example\n * v.startsWith('say hello to my little friend', 'say hello');\n * // => true\n *\n * v.startsWith('tony', 'on', 1);\n * // => true\n *\n * v.startsWith('the world is yours', 'world');\n * // => false\n */\nexport default function startsWith(subject, start, position) {\n const subjectString = coerceToString(subject);\n const startString = toString(start);\n if (startString === null) {\n return false;\n }\n if (startString === '') {\n return true;\n }\n position = isNil(position) ? 0 : clipNumber(toInteger(position), 0, subjectString.length);\n return subjectString.substr(position, startString.length) === startString;\n}","import coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Splits `subject` into an array of characters.\n *\n * @function chars\n * @static\n * @since 1.0.0\n * @memberOf Split\n * @param {string} [subject=''] The string to split into characters.\n * @return {Array} Returns the array of characters.\n * @example\n * v.chars('cloud');\n * // => ['c', 'l', 'o', 'u', 'd']\n */\nexport default function chars(subject) {\n const subjectString = coerceToString(subject);\n return subjectString.split('');\n}","import codePointAt from 'chop/code_point_at';\nimport coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Returns an array of Unicode code point values from characters of `subject`.\n *\n * @function codePoints\n * @static\n * @since 1.0.0\n * @memberOf Split\n * @param {string} [subject=''] The string to extract from.\n * @return {Array} Returns an array of non-negative numbers less than or equal to `0x10FFFF`.\n * @example\n * v.codePoints('rain');\n * // => [114, 97, 105, 110], or\n * // [0x72, 0x61, 0x69, 0x6E]\n *\n * v.codePoints('\\uD83D\\uDE00 smile'); // or '😀 smile'\n * // => [128512, 32, 115, 109, 105, 108, 101], or\n * // [0x1F600, 0x20, 0x73, 0x6D, 0x69, 0x6C, 0x65]\n */\nexport default function codePoints(subject) {\n const subjectString = coerceToString(subject);\n const subjectStringLength = subjectString.length;\n const codePointArray = [];\n let index = 0;\n let codePointNumber;\n while (index < subjectStringLength) {\n codePointNumber = codePointAt(subjectString, index);\n codePointArray.push(codePointNumber);\n index += codePointNumber > 0xFFFF ? 2 : 1;\n }\n return codePointArray;\n}","import coerceToString from 'helper/string/coerce_to_string';\nimport nilDefault from 'helper/undefined/nil_default';\nimport { REGEXP_UNICODE_CHARACTER } from 'helper/reg_exp/const';\n\n/**\n * Splits `subject` into an array of graphemes taking care of\n * surrogate pairs and\n * combining marks.\n *\n * @function graphemes\n * @static\n * @since 1.0.0\n * @memberOf Split\n * @param {string} [subject=''] The string to split into characters.\n * @return {Array} Returns the array of graphemes.\n * @example\n * v.graphemes('\\uD835\\uDC00\\uD835\\uDC01'); // or '𝐀𝐁'\n * // => ['\\uD835\\uDC00', '\\uD835\\uDC01'], or\n * // ['𝐀', '𝐁']\n *\n * v.graphemes('cafe\\u0301'); // or 'café'\n * // => ['c', 'a', 'f', 'e\\u0301'], or\n * // ['c', 'a', 'f', 'é']\n */\nexport default function graphemes(subject) {\n const subjectString = coerceToString(subject);\n return nilDefault(subjectString.match(REGEXP_UNICODE_CHARACTER), []);\n}","import coerceToString from 'helper/string/coerce_to_string';\n\n/**\n * Splits `subject` into an array of chunks by `separator`.\n *\n * @function split\n * @static\n * @since 1.0.0\n * @memberOf Split\n * @param {string} [subject=''] The string to split into characters.\n * @param {string|RegExp} [separator] The pattern to match the separator.\n * @param {number} [limit] Limit the number of chunks to be found.\n * @return {Array} Returns the array of chunks.\n * @example\n * v.split('rage against the dying of the light', ' ');\n * // => ['rage', 'against', 'the', 'dying', 'of', 'the', 'light']\n *\n * v.split('the dying of the light', /\\s/, 3);\n * // => ['the', 'dying', 'of']\n */\nexport default function split(subject, separator, limit) {\n const subjectString = coerceToString(subject);\n return subjectString.split(separator, limit);\n}","import coerceToString from 'helper/string/coerce_to_string';\n\nconst BYRE_ORDER_MARK = '\\uFEFF';\n\n/**\n * Strips the byte order mark (BOM) from the beginning of `subject`.\n *\n * @function stripBom\n * @static\n * @since 1.2.0\n * @memberOf Strip\n * @param {string} [subject=''] The string to strip from.\n * @return {string} Returns the stripped string.\n * @example\n *\n * v.stripBom('\\uFEFFsummertime sadness');\n * // => 'summertime sadness'\n *\n * v.stripBom('summertime happiness');\n * // => 'summertime happiness'\n *\n */\nexport default function trim(subject) {\n const subjectString = coerceToString(subject);\n if (subjectString === '') {\n return '';\n }\n if (subjectString[0] === BYRE_ORDER_MARK) {\n return subjectString.substring(1);\n }\n return subjectString;\n}","/**\n * Checks whether `subject` contains substring at specific `index`.\n *\n * @ignore\n * @param {string} subject The subject to search in.\n * @param {string} substring The substring to search/\n * @param {number} index The index to search substring.\n * @param {boolean} lookBehind Whether to look behind (true) or ahead (false).\n * @return {boolean} Returns a boolean whether the substring exists.\n */\nexport default function hasSubstringAtIndex(subject, substring, index, lookBehind = true) {\n let indexOffset = 0;\n if (lookBehind) {\n indexOffset = - substring.length + 1;\n }\n const extractedSubstring = subject.substr(index + indexOffset, substring.length);\n return extractedSubstring.toLowerCase() === substring;\n}","import { REGEXP_TAG_LIST } from 'helper/reg_exp/const';\n\n/**\n * Parses the tags from the string '...'.\n *\n * @ignore\n * @param {string} tags The string that contains the tags.\n * @return {string[]} Returns the array of tag names.\n */\nexport default function parseTagList(tags) {\n const tagsList = [];\n let match;\n while ((match = REGEXP_TAG_LIST.exec(tags)) !== null) {\n tagsList.push(match[1]);\n }\n return tagsList;\n}","import { REGEXP_WHITESPACE } from 'helper/reg_exp/const';\n\nconst STATE_START_TAG = 0;\nconst STATE_NON_WHITESPACE = 1;\nconst STATE_DONE = 2;\n\n/**\n * Parses the tag name from html content.\n *\n * @ignore\n * @param {string} tagContent The tag content.\n * @return {string} Returns the tag name.\n */\nexport default function parseTagName(tagContent) {\n let state = STATE_START_TAG;\n let tagName = '';\n let index = 0;\n while (state !== STATE_DONE) {\n const char = tagContent[index++].toLowerCase();\n switch (char) {\n case '<':\n break;\n case '>':\n state = STATE_DONE;\n break;\n default:\n if (REGEXP_WHITESPACE.test(char)) {\n if (state === STATE_NON_WHITESPACE) {\n state = STATE_DONE;\n }\n } else {\n if (state === STATE_START_TAG) {\n state = STATE_NON_WHITESPACE;\n }\n if (char !== '/') {\n tagName += char;\n }\n }\n break;\n }\n }\n return tagName;\n}","import coerceToString from 'helper/string/coerce_to_string';\nimport hasSubstringAtIndex from 'helper/string/has_substring_at_index';\nimport parseTagList from 'helper/strip/parse_tag_list';\nimport parseTagName from 'helper/strip/parse_tag_name';\n\nconst STATE_OUTPUT = 0;\nconst STATE_HTML = 1;\nconst STATE_EXCLAMATION = 2;\nconst STATE_COMMENT = 3;\n\n/**\n * Strips HTML tags from `subject`.\n *\n * @function stripTags\n * @static\n * @since 1.1.0\n * @memberOf Strip\n * @param {string} [subject=''] The string to strip from.\n * @param {string|Array} [allowableTags] The string `''` or array `['tag1', 'tag2']` of tags that should not be stripped.\n * @param {string} [replacement=''] The string to replace the stripped tag.\n * @return {string} Returns the stripped string.\n * @example\n *\n * v.stripTags('Summer is nice');\n * // => 'Summer is nice'\n *\n * v.stripTags('Winter is cold', ['b', 'i']);\n * // => 'Winter is cold'\n *\n * v.stripTags('Sun
set', '', '-');\n * // => 'Sun-set'\n */\nexport default function trim(subject, allowableTags, replacement) {\n subject = coerceToString(subject);\n if (subject === '') {\n return '';\n }\n if (!Array.isArray(allowableTags)) {\n const allowableTagsString = coerceToString(allowableTags);\n allowableTags = allowableTagsString === '' ? [] : parseTagList(allowableTagsString);\n }\n const replacementString = coerceToString(replacement);\n const length = subject.length;\n const hasAllowableTags = allowableTags.length > 0;\n const hasSubstring = hasSubstringAtIndex.bind(null, subject);\n let state = STATE_OUTPUT;\n let depth = 0;\n let output = '';\n let tagContent = '';\n let quote = null;\n for (let index = 0; index < length; index++) {\n const char = subject[index];\n let advance = false;\n switch (char) {\n case '<':\n if (quote) {\n break;\n }\n if (hasSubstring('< ', index, false)) {\n advance = true;\n break;\n }\n if (state === STATE_OUTPUT) {\n advance = true;\n state = STATE_HTML;\n break;\n }\n if (state === STATE_HTML) {\n depth++;\n break;\n }\n advance = true;\n break;\n case '!':\n if (state === STATE_HTML && hasSubstring('':\n if (depth > 0) {\n depth--;\n break;\n }\n if (quote) {\n break;\n }\n if (state === STATE_HTML) {\n quote = null;\n state = STATE_OUTPUT;\n if (hasAllowableTags) {\n tagContent += '>';\n const tagName = parseTagName(tagContent);\n if (allowableTags.indexOf(tagName.toLowerCase()) !== -1) {\n output += tagContent;\n } else {\n output += replacementString;\n }\n tagContent = '';\n } else {\n output += replacementString;\n }\n break;\n }\n if (state === STATE_EXCLAMATION || state === STATE_COMMENT && hasSubstring('-->', index)) {\n quote = null;\n state = STATE_OUTPUT;\n tagContent = '';\n break;\n }\n advance = true;\n break;\n default:\n advance = true;\n }\n if (advance) {\n switch (state) {\n case STATE_OUTPUT:\n output += char;\n break;\n case STATE_HTML:\n if (hasAllowableTags) {\n tagContent += char;\n }\n break;\n }\n }\n }\n return output;\n}","let globalObject = null;\n\nfunction getGlobalObject() {\n if (globalObject !== null) {\n return globalObject;\n }\n /* istanbul ignore next */\n // It's hard to mock the global variables. This code surely works fine. I hope :)\n if (typeof global === 'object' && global.Object === Object) {\n // NodeJS global object\n globalObject = global;\n } else if (typeof self === 'object' && self.Object === Object) {\n // self property from Window object\n globalObject = self;\n } else {\n // Other cases. Function constructor always has the context as global object\n globalObject = new Function('return this')();\n }\n return globalObject;\n}\n\nexport default getGlobalObject;","import getGlobalObject from 'helper/object/get_global';\n\nconst globalObject = getGlobalObject();\nconst previousV = globalObject.v;\n\n/**\n * Restores `v` variable to previous value and returns Voca library instance.\n *\n * @function noConflict\n * @static\n * @since 1.0.0\n * @memberOf Util\n * @return {Object} Returns Voca library instance.\n * @example\n * var voca = v.noConflict();\n * voca.isAlpha('Hello');\n * // => true\n */\nexport default function noConflict() {\n if (this === globalObject.v) {\n globalObject.v = previousV;\n }\n return this;\n}\n","import functions from 'functions';\n\n\n/**\n * The chain wrapper constructor.\n *\n * @ignore\n * @param {string} subject The string to be wrapped.\n * @param {boolean} [explicitChain=false] A boolean that indicates if the chain sequence is explicit or implicit.\n * @return {ChainWrapper} Returns a new instance of `ChainWrapper`\n * @constructor\n */\nfunction ChainWrapper(subject, explicitChain) {\n this._wrappedValue = subject;\n this._explicitChain = explicitChain;\n}\n\n/**\n * Unwraps the chain sequence wrapped value.\n *\n * @memberof Chain\n * @since 1.0.0\n * @function __proto__value\n * @return {*} Returns the unwrapped value.\n * @example\n * v\n * .chain('Hello world')\n * .replace('Hello', 'Hi')\n * .lowerCase()\n * .slugify()\n * .value()\n * // => 'hi-world'\n *\n * v(' Space travel ')\n * .trim()\n * .truncate(8)\n * .value()\n * // => 'Space...'\n */\nChainWrapper.prototype.value = function() {\n return this._wrappedValue;\n};\n\n/**\n * Override the default object valueOf().\n *\n * @ignore\n * @return {*} Returns the wrapped value.\n */\nChainWrapper.prototype.valueOf = function() {\n return this.value();\n};\n\n/**\n * Returns the wrapped value to be used in JSON.stringify().\n *\n * @ignore\n * @return {*} Returns the wrapped value.\n */\nChainWrapper.prototype.toJSON = function() {\n return this.value();\n};\n\n/**\n * Returns the string representation of the wrapped value.\n *\n * @ignore\n * @return {string} Returns the string representation.\n */\nChainWrapper.prototype.toString = function() {\n return String(this.value());\n};\n\n/**\n * Creates a new chain object that enables explicit chain sequences.\n * Use `v.prototype.value()` to unwrap the result.
\n * Does not modify the wrapped value.\n *\n * @memberof Chain\n * @since 1.0.0\n * @function __proto__chain\n * @return {Object} Returns the wrapper in explicit mode.\n * @example\n * v('Back to School')\n * .chain()\n * .lowerCase()\n * .words()\n * .value()\n * // => ['back', 'to', 'school']\n *\n * v(\" Back to School \")\n * .chain()\n * .trim()\n * .truncate(7)\n * .value()\n * // => 'Back...'\n */\nChainWrapper.prototype.chain = function() {\n return new ChainWrapper(this._wrappedValue, true);\n};\n\n/**\n * Modifies the wrapped value with the invocation result of `changer` function. The current wrapped value is the\n * argument of `changer` invocation.\n *\n * @memberof Chain\n * @since 1.0.0\n * @function __proto__thru\n * @param {Function} changer The function to invoke.\n * @return {Object} Returns the new wrapper that wraps the invocation result of `changer`.\n * @example\n * v\n * .chain('sun is shining')\n * .words()\n * .thru(function(words) {\n * return words[0];\n * })\n * .value()\n * // => 'sun'\n *\n */\nChainWrapper.prototype.thru = function(changer) {\n if (typeof changer === 'function') {\n return new ChainWrapper(changer(this._wrappedValue), this._explicitChain);\n }\n return this;\n};\n\n/**\n * A boolean that indicates if the chain sequence is explicit or implicit.\n * @ignore\n * @type {boolean}\n * @private\n */\nChainWrapper.prototype._explicitChain = true;\n\n/**\n * Make a voca function chainable.\n *\n * @ignore\n * @param {Function} functionInstance The function to make chainable\n * @return {Function} Returns the chainable function\n */\nfunction makeFunctionChainable(functionInstance) {\n return function(...args) {\n const result = functionInstance(this._wrappedValue, ...args);\n if (this._explicitChain || typeof result === 'string') {\n return new ChainWrapper(result, this._explicitChain);\n } else {\n return result;\n }\n };\n}\n\nObject.keys(functions).forEach(function(name) {\n ChainWrapper.prototype[name] = makeFunctionChainable(functions[name]);\n});\n\n\nexport default ChainWrapper;","import ChainWrapper from 'chain/wrapper';\n\n/**\n * Creates a chain object that wraps `subject`, enabling explicit chain sequences.
\n * Use `v.prototype.value()` to unwrap the result.\n *\n * @memberOf Chain\n * @since 1.0.0\n * @function chain\n * @param {string} subject The string to wrap.\n * @return {Object} Returns the new wrapper object.\n * @example\n * v\n * .chain('Back to School')\n * .lowerCase()\n * .words()\n * .value()\n * // => ['back', 'to', 'school']\n */\nexport default function chain(subject) {\n return new ChainWrapper(subject, true);\n}","import chain from './chain/chain'; // include chain here to resolve af circular reference\nimport ChainWrapper from './chain/wrapper';\nimport functions from './functions';\n\n/**\n * Creates a chain object that wraps `subject`, enabling implicit chain sequences.
\n * A function that returns `number`, `boolean` or `array` type terminates the chain sequence and returns the unwrapped value.\n * Otherwise use `v.prototype.value()` to unwrap the result.\n *\n * @memberOf Chain\n * @since 1.0.0\n * @function v\n * @param {string} subject The string to wrap.\n * @return {Object} Returns the new wrapper object.\n * @example\n * v('Back to School')\n * .lowerCase()\n * .words()\n * // => ['back', 'to', 'school']\n *\n * v(\" Back to School \")\n * .trim()\n * .truncate(7)\n * .value()\n * // => 'Back...'\n */\nfunction Voca(subject) {\n return new ChainWrapper(subject, false);\n}\n\nObject.assign(Voca, functions, {\n chain: chain\n});\n\nexport default Voca;","/**\n * A regular expression string matching digits\n *\n * @type {string}\n * @ignore\n */\nexport const digit = '\\\\d';\n\n/**\n * A regular expression string matching whitespace\n *\n * @type {string}\n * @ignore\n */\nexport const whitespace = '\\\\s\\\\uFEFF\\\\xA0';\n\n/**\n * A regular expression string matching high surrogate\n *\n * @type {string}\n * @ignore\n */\nexport const highSurrogate = '\\\\uD800-\\\\uDBFF';\n\n/**\n * A regular expression string matching low surrogate\n *\n * @type {string}\n * @ignore\n */\nexport const lowSurrogate = '\\\\uDC00-\\\\uDFFF';\n\n/**\n * A regular expression string matching diacritical mark\n *\n * @type {string}\n * @ignore\n */\nexport const diacriticalMark = '\\\\u0300-\\\\u036F\\\\u1AB0-\\\\u1AFF\\\\u1DC0-\\\\u1DFF\\\\u20D0-\\\\u20FF\\\\uFE20-\\\\uFE2F';\n\n/**\n * A regular expression to match the base character for a combining mark\n *\n * @type {string}\n * @ignore\n */\nexport const base = '\\\\0-\\\\u02FF\\\\u0370-\\\\u1AAF\\\\u1B00-\\\\u1DBF\\\\u1E00-\\\\u20CF\\\\u2100-\\\\uD7FF\\\\uE000-\\\\uFE1F\\\\uFE30-\\\\uFFFF';\n\n/**\n * Regular expression to match combining marks\n *\n * @see http://unicode.org/faq/char_combmark.html\n * @type {RegExp}\n * @ignore\n */\nexport const REGEXP_COMBINING_MARKS = new RegExp('([' + base + ']|[' + highSurrogate + '][' + lowSurrogate + ']|[' + highSurrogate + '](?![' + lowSurrogate + '])|(?:[^' + highSurrogate + ']|^)[' + lowSurrogate + '])([' + diacriticalMark + ']+)', 'g');\n\n/**\n * Regular expression to match surrogate pairs\n *\n * @see http://www.unicode.org/faq/utf_bom.html#utf16-2\n * @type {RegExp}\n * @ignore\n */\nexport const REGEXP_SURROGATE_PAIRS = new RegExp('([' + highSurrogate + '])([' + lowSurrogate + '])', 'g');\n\n/**\n * Regular expression to match an unicode character\n *\n * @type {RegExp}\n * @ignore\n */\nexport const REGEXP_UNICODE_CHARACTER = new RegExp(\n'((?:[' + base + ']|[' + highSurrogate + '][' + lowSurrogate + ']|[' + highSurrogate + '](?![' + lowSurrogate + '])|(?:[^' + highSurrogate + ']|^)[' + lowSurrogate + '])(?:[' + diacriticalMark + ']+))|\\\n([' + highSurrogate + '][' + lowSurrogate + '])|\\\n([\\\\n\\\\r\\\\u2028\\\\u2029])|\\\n(.)', 'g');\n\n/**\n * Regular expression to match whitespaces\n *\n * @type {RegExp}\n * @ignore\n */\nexport const REGEXP_WHITESPACE = new RegExp('[' + whitespace + ']');\n\n/**\n * Regular expression to match whitespaces from the left side\n *\n * @type {RegExp}\n * @ignore\n */\nexport const REGEXP_TRIM_LEFT = new RegExp('^[' + whitespace + ']+');\n\n/**\n * Regular expression to match whitespaces from the right side\n *\n * @type {RegExp}\n * @ignore\n */\nexport const REGEXP_TRIM_RIGHT = new RegExp('[' + whitespace + ']+$');\n\n/**\n * Regular expression to match digit characters\n *\n * @type {RegExp}\n * @ignore\n */\nexport const REGEXP_DIGIT = new RegExp('^' + digit + '+$');\n\n/**\n * Regular expression to match regular expression special characters\n *\n * @type {RegExp}\n * @ignore\n */\nexport const REGEXP_SPECIAL_CHARACTERS = /[-[\\]{}()*+!<=:?.\\/\\\\^$|#,]/g;\n\n/**\n * Regular expression to match not latin characters\n *\n * @type {RegExp}\n * @ignore\n */\nexport const REGEXP_NON_LATIN = /[^A-Za-z0-9]/g;\n\n/**\n * Regular expression to match HTML special characters.\n *\n * @type {RegExp}\n * @ignore\n */\nexport const REGEXP_HTML_SPECIAL_CHARACTERS = /[<>&\"'`]/g;\n\n/**\n * Regular expression to match sprintf format string\n *\n * @type {RegExp}\n * @ignore\n */\nexport const REGEXP_CONVERSION_SPECIFICATION = /(%{1,2})(?:(\\d+)\\$)?(\\+)?([ 0]|'.{1})?(-)?(\\d+)?(?:\\.(\\d+))?([bcdiouxXeEfgGs])?/g;\n\n/**\n * Regular expression to match trailing zeros in a number\n *\n * @type {RegExp}\n * @ignore\n */\nexport const REGEXP_TRAILING_ZEROS = /\\.?0+$/g;\n\n/**\n * Regular expression to match flags from a regular expression.\n *\n * @type {RegExp}\n * @ignore\n */\nexport const REGEXP_FLAGS = /[gimuy]*$/;\n\n/**\n * Regular expression to match a list of tags.\n *\n * @see https://html.spec.whatwg.org/multipage/syntax.html#syntax-tag-name\n * @type {RegExp}\n * @ignore\n */\n\nexport const REGEXP_TAG_LIST = /<([A-Za-z0-9]+)>/g;","import { diacriticalMark, digit, whitespace } from 'helper/reg_exp/const';\n\n/**\n * A regular expression to match the General Punctuation Unicode block\n *\n * @type {string}\n * @ignore\n */\nconst generalPunctuationBlock = '\\\\u2000-\\\\u206F';\n\n/**\n * A regular expression to match non characters from from Basic Latin and Latin-1 Supplement Unicode blocks\n *\n * @type {string}\n * @ignore\n */\nconst nonCharacter = '\\\\x00-\\\\x2F\\\\x3A-\\\\x40\\\\x5B-\\\\x60\\\\x7b-\\\\xBF\\\\xD7\\\\xF7';\n\n/**\n * A regular expression to match the dingbat Unicode block\n *\n * @type {string}\n * @ignore\n */\nconst dingbatBlock = '\\\\u2700-\\\\u27BF';\n\n/**\n * A regular expression string that matches lower case letters: LATIN\n *\n * @type {string}\n * @ignore\n */\nconst lowerCaseLetter = 'a-z\\\\xB5\\\\xDF-\\\\xF6\\\\xF8-\\\\xFF\\\\u0101\\\\u0103\\\\u0105\\\\u0107\\\\u0109\\\\u010B\\\\u010D\\\\u010F\\\\u0111\\\\u0113\\\\u0115\\\\u0117\\\\u0119\\\\u011B\\\\u011D\\\\u011F\\\\u0121\\\\u0123\\\\u0125\\\\u0127\\\\u0129\\\\u012B\\\\u012D\\\\u012F\\\\u0131\\\\u0133\\\\u0135\\\\u0137\\\\u0138\\\\u013A\\\\u013C\\\\u013E\\\\u0140\\\\u0142\\\\u0144\\\\u0146\\\\u0148\\\\u0149\\\\u014B\\\\u014D\\\\u014F\\\\u0151\\\\u0153\\\\u0155\\\\u0157\\\\u0159\\\\u015B\\\\u015D\\\\u015F\\\\u0161\\\\u0163\\\\u0165\\\\u0167\\\\u0169\\\\u016B\\\\u016D\\\\u016F\\\\u0171\\\\u0173\\\\u0175\\\\u0177\\\\u017A\\\\u017C\\\\u017E-\\\\u0180\\\\u0183\\\\u0185\\\\u0188\\\\u018C\\\\u018D\\\\u0192\\\\u0195\\\\u0199-\\\\u019B\\\\u019E\\\\u01A1\\\\u01A3\\\\u01A5\\\\u01A8\\\\u01AA\\\\u01AB\\\\u01AD\\\\u01B0\\\\u01B4\\\\u01B6\\\\u01B9\\\\u01BA\\\\u01BD-\\\\u01BF\\\\u01C6\\\\u01C9\\\\u01CC\\\\u01CE\\\\u01D0\\\\u01D2\\\\u01D4\\\\u01D6\\\\u01D8\\\\u01DA\\\\u01DC\\\\u01DD\\\\u01DF\\\\u01E1\\\\u01E3\\\\u01E5\\\\u01E7\\\\u01E9\\\\u01EB\\\\u01ED\\\\u01EF\\\\u01F0\\\\u01F3\\\\u01F5\\\\u01F9\\\\u01FB\\\\u01FD\\\\u01FF\\\\u0201\\\\u0203\\\\u0205\\\\u0207\\\\u0209\\\\u020B\\\\u020D\\\\u020F\\\\u0211\\\\u0213\\\\u0215\\\\u0217\\\\u0219\\\\u021B\\\\u021D\\\\u021F\\\\u0221\\\\u0223\\\\u0225\\\\u0227\\\\u0229\\\\u022B\\\\u022D\\\\u022F\\\\u0231\\\\u0233-\\\\u0239\\\\u023C\\\\u023F\\\\u0240\\\\u0242\\\\u0247\\\\u0249\\\\u024B\\\\u024D\\\\u024F';\n\n/**\n * A regular expression string that matches upper case letters: LATIN\n *\n * @type {string}\n * @ignore\n */\nconst upperCaseLetter = '\\\\x41-\\\\x5a\\\\xc0-\\\\xd6\\\\xd8-\\\\xde\\\\u0100\\\\u0102\\\\u0104\\\\u0106\\\\u0108\\\\u010a\\\\u010c\\\\u010e\\\\u0110\\\\u0112\\\\u0114\\\\u0116\\\\u0118\\\\u011a\\\\u011c\\\\u011e\\\\u0120\\\\u0122\\\\u0124\\\\u0126\\\\u0128\\\\u012a\\\\u012c\\\\u012e\\\\u0130\\\\u0132\\\\u0134\\\\u0136\\\\u0139\\\\u013b\\\\u013d\\\\u013f\\\\u0141\\\\u0143\\\\u0145\\\\u0147\\\\u014a\\\\u014c\\\\u014e\\\\u0150\\\\u0152\\\\u0154\\\\u0156\\\\u0158\\\\u015a\\\\u015c\\\\u015e\\\\u0160\\\\u0162\\\\u0164\\\\u0166\\\\u0168\\\\u016a\\\\u016c\\\\u016e\\\\u0170\\\\u0172\\\\u0174\\\\u0176\\\\u0178\\\\u0179\\\\u017b\\\\u017d\\\\u0181\\\\u0182\\\\u0184\\\\u0186\\\\u0187\\\\u0189-\\\\u018b\\\\u018e-\\\\u0191\\\\u0193\\\\u0194\\\\u0196-\\\\u0198\\\\u019c\\\\u019d\\\\u019f\\\\u01a0\\\\u01a2\\\\u01a4\\\\u01a6\\\\u01a7\\\\u01a9\\\\u01ac\\\\u01ae\\\\u01af\\\\u01b1-\\\\u01b3\\\\u01b5\\\\u01b7\\\\u01b8\\\\u01bc\\\\u01c4\\\\u01c5\\\\u01c7\\\\u01c8\\\\u01ca\\\\u01cb\\\\u01cd\\\\u01cf\\\\u01d1\\\\u01d3\\\\u01d5\\\\u01d7\\\\u01d9\\\\u01db\\\\u01de\\\\u01e0\\\\u01e2\\\\u01e4\\\\u01e6\\\\u01e8\\\\u01ea\\\\u01ec\\\\u01ee\\\\u01f1\\\\u01f2\\\\u01f4\\\\u01f6-\\\\u01f8\\\\u01fa\\\\u01fc\\\\u01fe\\\\u0200\\\\u0202\\\\u0204\\\\u0206\\\\u0208\\\\u020a\\\\u020c\\\\u020e\\\\u0210\\\\u0212\\\\u0214\\\\u0216\\\\u0218\\\\u021a\\\\u021c\\\\u021e\\\\u0220\\\\u0222\\\\u0224\\\\u0226\\\\u0228\\\\u022a\\\\u022c\\\\u022e\\\\u0230\\\\u0232\\\\u023a\\\\u023b\\\\u023d\\\\u023e\\\\u0241\\\\u0243-\\\\u0246\\\\u0248\\\\u024a\\\\u024c\\\\u024e';\n\n/**\n * Regular expression to match Unicode words\n *\n * @type {RegExp}\n * @ignore\n */\nexport const REGEXP_WORD = new RegExp(\n '(?:[' + upperCaseLetter + '][' + diacriticalMark + ']*)?(?:[' + lowerCaseLetter + '][' + diacriticalMark + ']*)+|\\\n(?:[' + upperCaseLetter + '][' + diacriticalMark + ']*)+(?![' + lowerCaseLetter + '])|\\\n[' + digit + ']+|\\\n[' + dingbatBlock + ']|\\\n[^' + nonCharacter + generalPunctuationBlock + whitespace + ']+', 'g');\n\n/**\n * Regular expression to match words from Basic Latin and Latin-1 Supplement blocks\n *\n * @type {RegExp}\n * @ignore\n */\nexport const REGEXP_LATIN_WORD = /[A-Z\\xC0-\\xD6\\xD8-\\xDE]?[a-z\\xDF-\\xF6\\xF8-\\xFF]+|[A-Z\\xC0-\\xD6\\xD8-\\xDE]+(?![a-z\\xDF-\\xF6\\xF8-\\xFF])|\\d+/g;\n\n/**\n * Regular expression to match alpha characters\n *\n * @see http://stackoverflow.com/a/22075070/1894471\n * @type {RegExp}\n * @ignore\n */\nexport const REGEXP_ALPHA = new RegExp('^(?:[' + lowerCaseLetter + upperCaseLetter + '][' + diacriticalMark + ']*)+$');\n\n/**\n * Regular expression to match alpha and digit characters\n *\n * @see http://stackoverflow.com/a/22075070/1894471\n * @type {RegExp}\n * @ignore\n */\nexport const REGEXP_ALPHA_DIGIT = new RegExp('^((?:[' + lowerCaseLetter + upperCaseLetter + '][' + diacriticalMark + ']*)|[' + digit + '])+$');\n\n/**\n * Regular expression to match Extended ASCII characters, i.e. the first 255\n *\n * @type {RegExp}\n * @ignore\n */\nexport const REGEXP_EXTENDED_ASCII = /^[\\x00-\\xFF]*$/;","/**\n * Max save integer value\n *\n * @ignore\n * @type {number}\n */\nexport const MAX_SAFE_INTEGER = 0x1fffffffffffff;","export default Object.freeze({\n // Type specifiers\n TYPE_INTEGER : 'i',\n TYPE_INTEGER_BINARY : 'b',\n TYPE_INTEGER_ASCII_CHARACTER : 'c',\n TYPE_INTEGER_DECIMAL : 'd',\n TYPE_INTEGER_OCTAL : 'o',\n TYPE_INTEGER_UNSIGNED_DECIMAL : 'u',\n TYPE_INTEGER_HEXADECIMAL : 'x',\n TYPE_INTEGER_HEXADECIMAL_UPPERCASE : 'X',\n TYPE_FLOAT_SCIENTIFIC : 'e',\n TYPE_FLOAT_SCIENTIFIC_UPPERCASE : 'E',\n TYPE_FLOAT : 'f',\n TYPE_FLOAT_SHORT : 'g',\n TYPE_FLOAT_SHORT_UPPERCASE : 'G',\n TYPE_STRING : 's',\n\n // Simple literals\n LITERAL_PERCENT : '%',\n LITERAL_SINGLE_QUOTE : \"'\",\n LITERAL_PLUS : '+',\n LITERAL_MINUS : '-',\n LITERAL_PERCENT_SPECIFIER : '%%',\n\n // Radix constants to format numbers\n RADIX_BINARY : 2,\n RADIX_OCTAL : 8,\n RADIX_DECIMAL : 10,\n RADIX_HEXADECIMAL : 16\n});","/**\n * A property that contains the library semantic version number.\n * @name version\n * @static\n * @since 1.0.0\n * @memberOf Util\n * @type string\n * @example\n * v.version\n * // => '1.3.0'\n */\nconst version = '1.3.0';\n\nexport default version;"],"names":["isNil","value","undefined","coerceToBoolean","defaultValue","Boolean","isString","subject","coerceToString","String","capitalize","restToLower","subjectString","restToLowerCaseBoolean","toLowerCase","substr","toUpperCase","lowerCase","nilDefault","toString","words","pattern","flags","patternRegExp","REGEXP_EXTENDED_ASCII","test","REGEXP_LATIN_WORD","REGEXP_WORD","RegExp","flagsString","match","wordToCamel","word","index","camelCase","map","join","decapitalize","kebabCase","snakeCase","upperCase","swapCase","split","reduce","swapAndConcat","swapped","character","titleCase","ignoreWords","ignoreWordsArray","Array","isArray","wordsRegExp","replace","lowerCaseWord","indexOf","clipNumber","downLimit","upLimit","toInteger","Infinity","MAX_SAFE_INTEGER","truncate","length","end","lengthInt","endString","charAt","position","isHighSurrogate","codePoint","HIGH_SURROGATE_START","HIGH_SURROGATE_END","isLowSurrogate","LOW_SURROGATE_START","LOW_SURROGATE_END","getAstralNumberFromSurrogatePair","highSurrogate","lowSurrogate","coerceToNumber","Number","nanDefault","codePointAt","subjectStringLength","positionNumber","firstCodePoint","charCodeAt","secondCodePoint","first","graphemeAt","graphemeMatch","graphemeMatchIndex","REGEXP_UNICODE_CHARACTER","exec","lastIndex","last","prune","truncatedLength","offset","wordInsertLength","slice","start","substring","count","countGrapheme","REGEXP_COMBINING_MARKS","REGEXP_SURROGATE_PAIRS","countSubstrings","substringString","substringLength","matchIndex","countWhere","predicate","context","predicateWithContext","bind","call","countTruthy","countWords","ReplacementIndex","repeat","times","timesInt","repeatString","buildPadding","padCharacters","padStringRepeat","padStringRest","padLeft","pad","padString","padRight","alignAndPad","conversion","width","padType","alignmentSpecifier","Const","LITERAL_MINUS","getPaddingCharacter","addSignToFormattedNumber","replacementNumber","formattedReplacement","signSpecifier","LITERAL_PLUS","float","replacement","parseFloat","isNaN","precision","typeSpecifier","TYPE_FLOAT","toFixed","TYPE_FLOAT_SCIENTIFIC","toExponential","TYPE_FLOAT_SCIENTIFIC_UPPERCASE","TYPE_FLOAT_SHORT","TYPE_FLOAT_SHORT_UPPERCASE","formatFloatAsShort","nonZeroPrecision","toPrecision","REGEXP_TRAILING_ZEROS","integerBase","integer","parseInt","TYPE_INTEGER_ASCII_CHARACTER","fromCharCode","TYPE_INTEGER_BINARY","RADIX_BINARY","TYPE_INTEGER_OCTAL","RADIX_OCTAL","TYPE_INTEGER_HEXADECIMAL","RADIX_HEXADECIMAL","TYPE_INTEGER_HEXADECIMAL_UPPERCASE","integerDecimal","stringFormat","compute","formatFunction","TYPE_STRING","formatString","TYPE_INTEGER_DECIMAL","TYPE_INTEGER","formatIntegerDecimal","TYPE_INTEGER_UNSIGNED_DECIMAL","formatIntegerBase","formatFloat","formattedString","ConversionSpecification","properties","percent","paddingSpecifier","validate","replacementsLength","Error","replacementIndex","replacements","conversionSpecification","widthSpecifier","precisionSpecifier","isPercentLiteral","actualReplacementIndex","getIndexByPosition","incrementOnEmptyPosition","computeReplacement","sprintf","format","boundReplacementMatch","replacementMatch","REGEXP_CONVERSION_SPECIFICATION","vprintf","replaceSpecialCharacter","escapeCharactersMap","escapeHtml","REGEXP_HTML_SPECIAL_CHARACTERS","escapeRegExp","REGEXP_SPECIAL_CHARACTERS","reduceUnescapedString","string","key","unescapeCharactersMap","unescapeHtml","characters","search","fromIndex","lastIndexOf","fromIndexNumber","insert","toInsert","toInsertString","getDiacriticsMap","diacriticsMap","keys","diacritics","forEach","getLatinCharacter","characterWithoutDiacritic","removeCombiningMarks","cleanCharacter","latinise","REGEXP_NON_LATIN","paddingLength","paddingSideLength","paddingSideRemainingLength","getRegExpFlags","regExp","REGEXP_FLAGS","includes","searchString","appendFlagToRegExp","appendFlag","regularExpressionFlags","source","replaceAll","global","appendFlagToRegularExpression","reverse","reverseGrapheme","$0","$1","$2","reversedString","slugify","cleanSubjectString","splice","deleteCount","toAdd","toAddString","startPosition","deleteCountNumber","tr","from","to","values","extractKeysAndValues","result","valuesLength","keysLength","isMatch","matchValue","keyIndex","object","Object","sort","sortStringByLength","str1","str2","trimLeft","whitespace","whitespaceString","REGEXP_TRIM_LEFT","matchWhitespace","trimmed","trimRight","REGEXP_TRIM_RIGHT","reduceRight","trim","wordWrap","options","determineOptions","newLine","indent","cut","subjectLength","wrappedLine","spaceToWrapAt","OPTION_WIDTH","OPTION_NEW_LINE","OPTION_INDENT","OPTION_CUT","endsWith","isAlpha","REGEXP_ALPHA","isAlphaDigit","REGEXP_ALPHA_DIGIT","isBlank","isDigit","REGEXP_DIGIT","isEmpty","isLowerCase","valueString","isNumeric","valueNumeric","isUpperCase","matches","patternString","startsWith","startString","chars","codePoints","codePointArray","codePointNumber","push","graphemes","separator","limit","BYRE_ORDER_MARK","hasSubstringAtIndex","lookBehind","indexOffset","extractedSubstring","parseTagList","tags","tagsList","REGEXP_TAG_LIST","parseTagName","tagContent","state","STATE_START_TAG","tagName","STATE_DONE","char","REGEXP_WHITESPACE","STATE_NON_WHITESPACE","allowableTags","allowableTagsString","replacementString","hasAllowableTags","hasSubstring","STATE_OUTPUT","depth","output","quote","advance","STATE_HTML","STATE_EXCLAMATION","STATE_COMMENT","getGlobalObject","globalObject","self","Function","noConflict","this","v","previousV","ChainWrapper","explicitChain","_wrappedValue","_explicitChain","makeFunctionChainable","functionInstance","args","chain","Voca","digit","diacriticalMark","base","generalPunctuationBlock","nonCharacter","dingbatBlock","lowerCaseLetter","upperCaseLetter","prototype","increment","freeze","LITERAL_PERCENT_SPECIFIER","paddingCharacter","LITERAL_SINGLE_QUOTE","version","valueOf","toJSON","thru","changer","functions","name","_extends"],"mappings":";;;;;;;4KAQA,SAAwBA,GAAMC,SACXC,UAAVD,GAAiC,OAAVA,ECEhC,QAAwBE,GAAgBF,MAAOG,iEACzCJ,GAAMC,GACDG,EAEFC,QAAQJ,GCCjB,QAAwBK,GAASC,SACL,gBAAZA,GCFhB,QAAwBC,GAAeP,MAAOG,0DAAe,SACvDJ,GAAMC,GACDG,EAELE,EAASL,GACJA,EAEFQ,OAAOR,GCDhB,QAAwBS,GAAWH,EAASI,MACtCC,GAAgBJ,EAAeD,GAC7BM,EAAyBV,EAAgBQ,SACzB,KAAlBC,EACK,IAELC,MACcD,EAAcE,eAEzBF,EAAcG,OAAO,EAAG,GAAGC,cAAgBJ,EAAcG,OAAO,ICZzE,QAAwBE,GAAUV,MAC1BK,GAAgBJ,EAAeD,EAAS,UACvCK,GAAcE,cCXvB,QAAwBI,GAAWjB,EAAOG,SACxB,OAATH,EAAgBG,EAAeH,ECExC,QAAwBkB,GAASlB,SAC3BD,GAAMC,GACD,KAELK,EAASL,GACJA,EAEFQ,OAAOR,GCWhB,QAAwBmB,GAAMb,EAASc,EAASC,MACxCV,GAAgBJ,EAAeD,GACjCgB,YACAvB,EAAMqB,KACQG,GAAsBC,KAAKb,GAAiBc,GAAoBC,OAC3E,IAAIN,YAAmBO,UACZP,MACX,IACCQ,GAAcV,EAASD,EAAWI,EAAO,OAC/B,GAAIM,QAAOT,EAASE,GAAUQ,SAEzCX,GAAWN,EAAckB,MAAMP,OC5BxC,QAASQ,GAAYC,EAAMC,SACR,KAAVA,EAAchB,EAAUe,GAAQtB,EAAWsB,GAAM,GAsB1D,QAAwBE,GAAU3B,MAC1BK,GAAgBJ,EAAeD,SACf,KAAlBK,EACK,GAEFQ,EAAMR,GAAeuB,IAAIJ,GAAaK,KAAK,ICvBpD,QAAwBC,GAAa9B,MAC7BK,GAAgBJ,EAAeD,SACf,KAAlBK,EACK,GAEFA,EAAcG,OAAO,EAAG,GAAGD,cAAgBF,EAAcG,OAAO,GCCzE,QAAwBuB,GAAU/B,MAC1BK,GAAgBJ,EAAeD,SACf,KAAlBK,EACK,GAEFQ,EAAMR,GAAeuB,IAAIlB,GAAWmB,KAAK,KCNlD,QAAwBG,GAAUhC,MAC1BK,GAAgBJ,EAAeD,SACf,KAAlBK,EACK,GAEFQ,EAAMR,GAAeuB,IAAIlB,GAAWmB,KAAK,KCblD,QAAwBI,GAAUjC,MAC1BK,GAAgBJ,EAAeD,SAC9BK,GAAcI,cCEvB,QAAwByB,GAASlC,MACzBK,GAAgBJ,EAAeD,SAC9BK,GAAc8B,MAAM,IAAIC,OAAOC,EAAe,IAGvD,QAASA,GAAcC,EAASC,MACxB7B,GAAY6B,EAAUhC,cACtB0B,EAAYM,EAAU9B,oBACrB6B,IAAWC,IAAc7B,EAAYuB,EAAYvB,GCN1D,QAAwB8B,GAAUxC,EAASyC,MACnCpC,GAAgBJ,EAAeD,GAC/B0C,EAAmBC,MAAMC,QAAQH,GAAeA,KAChDI,EAAc5B,GAAsBC,KAAKb,GAAiBc,GAAoBC,SAC7Ef,GAAcyC,QAAQD,EAAa,SAASpB,MAC3CsB,GAAgBtB,EAAKlB,oBACpBmC,GAAiBM,QAAQD,MAAmB,EAAKA,EAAgB5C,EAAW4C,GAAe,KCjBtG,QAAwBE,GAAWvD,EAAOwD,EAAWC,SAC/CzD,IAASwD,EACJA,EAELxD,GAASyD,EACJA,EAEFzD,ECPT,QAAwB0D,GAAU1D,SAC5BA,KAAU2D,EAAAA,EACLC,GAEL5D,MAAW2D,EAAAA,IACJC,KAEF5D,ECUX,QAAwB6D,GAASvD,EAASwD,EAAQC,MAC1CpD,GAAgBJ,EAAeD,GAC/B0D,EAAYjE,EAAM+D,GAAUnD,EAAcmD,OAASP,EAAWG,EAAUI,GAAS,EAAGF,IACpFK,EAAY1D,EAAewD,EAAK,aAClCC,IAAarD,EAAcmD,OACtBnD,EAEFA,EAAcG,OAAO,EAAGgD,EAASG,EAAUH,QAAUG,ECf9D,QAAwBC,GAAO5D,EAAS6D,MAChCxD,GAAgBJ,EAAeD,SAC9BK,GAAcuD,OAAOC,GCT9B,QAAgBC,GAAgBC,SACvBA,IAAaC,IAAwBD,GAAaE,GAU3D,QAAgBC,GAAeH,SACtBA,IAAaI,IAAuBJ,GAAaK,GAW1D,QAAgBC,GAAiCC,EAAeC,SACd,OAAxCD,EAAgBN,IAAgCO,EAAeJ,GAAsB,MCtB/F,QAAwBK,GAAe9E,MAAOG,0DAAe,QACvDJ,GAAMC,GACDG,EAEY,gBAAVH,GACFA,EAEF+E,OAAO/E,GCZhB,QAAwBgF,GAAWhF,EAAOG,SACjCH,KAAUA,EAAQG,EAAeH,ECgB1C,QAAwBiF,GAAY3E,EAAS6D,MACrCxD,GAAgBJ,EAAeD,GAC/B4E,EAAsBvE,EAAcmD,OACtCqB,EAAiBL,EAAeX,QACnBa,EAAWG,EAAgB,KACxCA,EAAiB,GAAKA,GAAkBD,OAGtCE,GAAiBzE,EAAc0E,WAAWF,GAC5CG,eACAlB,GAAgBgB,IAAmBF,EAAsBC,EAAiB,MAC1DxE,EAAc0E,WAAWF,EAAiB,GACxDX,EAAec,IACVX,EAAiCS,EAAgBE,GAGrDF,GChBT,QAAwBG,GAAMjF,EAASwD,MAC/BnD,GAAgBJ,EAAeD,GAC/B0D,EAAYjE,EAAM+D,GAAU,EAAIP,EAAWG,EAAUI,GAAS,EAAGF,UACnEjD,GAAcmD,QAAUE,EACnBrD,EAEFA,EAAcG,OAAO,EAAGkD,GCRjC,QAAwBwB,GAAWlF,EAAS6D,MACpCxD,GAAgBJ,EAAeD,GACjC6E,EAAiBL,EAAeX,GAC/BsB,SACDC,EAAqB,QACRV,EAAWG,EAAgB,GAC8B,QAAlEM,EAAgBE,GAAyBC,KAAKjF,KAA0B,IAC1E+E,IAAuBP,YACAU,UAAY,EAC9BJ,EAAc,aAIlB,GCXT,QAAwBK,GAAKxF,EAASwD,MAC9BnD,GAAgBJ,EAAeD,GAC/B0D,EAAYjE,EAAM+D,GAAU,EAAIP,EAAWG,EAAUI,GAAS,EAAGF,UACnEjD,GAAcmD,QAAUE,EACnBrD,EAEFA,EAAcG,OAAOH,EAAcmD,OAASE,EAAWA,GCHhE,QAAwB+B,GAAMzF,EAASwD,EAAQC,MACvCpD,GAAgBJ,EAAeD,GAC/B0D,EAAYjE,EAAM+D,GAAUnD,EAAcmD,OAASP,EAAWG,EAAUI,GAAS,EAAGF,IACpFK,EAAY1D,EAAewD,EAAK,UAClCC,GAAarD,EAAcmD,aACtBnD,MAEHS,GAAUG,GAAsBC,KAAKb,GAAiBc,GAAoBC,GAC5EsE,EAAkB,WACR5C,QAAQhC,EAAS,SAASW,EAAMkE,MACtCC,GAAmBD,EAASlE,EAAK+B,MACnCoC,IAAoBlC,EAAYC,EAAUH,WAC1BoC,KAGfvF,EAAcG,OAAO,EAAGkF,GAAmB/B,ECnBpD,QAAwBkC,GAAM7F,EAAS8F,EAAOrC,SACrCxD,GAAeD,GAAS6F,MAAMC,EAAOrC,GCL9C,QAAwBjD,GAAOR,EAAS8F,EAAOtC,SACtCvD,GAAeD,GAASQ,OAAOsF,EAAOtC,GCA/C,QAAwBuC,GAAU/F,EAAS8F,EAAOrC,SACzCxD,GAAeD,GAAS+F,UAAUD,EAAOrC,GCRlD,QAAwBuC,GAAMhG,SACrBC,GAAeD,GAASwD,OCQjC,QAAwByC,GAAcjG,SAC7BC,GAAeD,GACnB8C,QAAQoD,GAAwB,KAChCpD,QAAQqD,GAAwB,KAChC3C,OCTL,QAAwB4C,GAAgBpG,EAAS+F,MACzC1F,GAAgBJ,EAAeD,GAC/BqG,EAAkBpG,EAAe8F,GACjCO,EAAkBD,EAAgB7C,OACpCwC,EAAQ,EACRO,EAAa,KACK,KAAlBlG,GAA4C,KAApBgG,QACnBL,QAGM3F,EAAc2C,QAAQqD,EAAiBE,GAChDA,KAAe,WAEHD,SAETC,KAAe,SACjBP,GCXT,QAAwBQ,GAAWxG,EAASyG,EAAWC,MAC/CrG,GAAgBJ,EAAeD,MACf,KAAlBK,GAA6C,kBAAdoG,SAC1B,MAEHE,GAAuBF,EAAUG,KAAKF,SACrCtE,IAAOyE,KAAKxG,EAAe,SAASyG,EAAavE,EAAWb,SAC1DiF,GAAqBpE,EAAWb,EAAOrB,GAAiByG,EAAc,EAAIA,GAChF,GCNL,QAAwBC,GAAW/G,EAASc,EAASC,SAC5CF,GAAMb,EAASc,EAASC,GAAOyC,OCjBxC,QAASwD,UACFtF,MAAQ,ECYf,QAAwBuF,GAAOjH,EAASkH,UAClC7G,GAAgBJ,EAAeD,GAC/BmH,EAAW1H,EAAMyH,GAAS,EAAIjE,EAAWG,EAAU8D,GAAQ,EAAG5D,IAC9D8D,EAAe,GACZD,GACU,EAAXA,OACc9G,GAEd8G,EAAW,OACI9G,OAEN,QAER+G,GCzBT,QAAwBC,GAAaC,EAAe9D,MAC5C+D,GAAkBnE,EAAUI,EAAS8D,EAAc9D,QACnDgE,EAAgBhE,EAAS8D,EAAc9D,aACtCyD,GAAOK,EAAeC,EAAkBC,GAAehH,OAAO,EAAGgD,GCc1E,QAAwBiE,GAAQzH,EAASwD,EAAQkE,MACzCrH,GAAgBJ,EAAeD,GAC/B0D,EAAYjE,EAAM+D,GAAU,EAAIP,EAAWG,EAAUI,GAAS,EAAGF,IACjEqE,EAAY1H,EAAeyH,EAAK,WAClChE,IAAarD,EAAcmD,OACtBnD,EAEFgH,EAAaM,EAAWjE,EAAYrD,EAAcmD,QAAUnD,ECPrE,QAAwBuH,GAAS5H,EAASwD,EAAQkE,MAC1CrH,GAAgBJ,EAAeD,GAC/B0D,EAAYjE,EAAM+D,GAAU,EAAIP,EAAWG,EAAUI,GAAS,EAAGF,IACjEqE,EAAY1H,EAAeyH,EAAK,WAClChE,IAAarD,EAAcmD,OACtBnD,EAEFA,EAAgBgH,EAAaM,EAAWjE,EAAYrD,EAAcmD,QCtB3E,QAAwBqE,GAAY7H,EAAS8H,MACrCC,GAAQD,EAAWC,SACrBtI,EAAMsI,IAAU/H,EAAQwD,QAAUuE,QAC7B/H,MAEHgI,GAAUF,EAAWG,qBAAuBC,GAAMC,cAAgBP,EAAWH,QAC5EO,GAAQhI,EAAS+H,EAAOD,EAAWM,uBCP5C,QAAwBC,GAAyBC,EAAmBC,EAAsBT,SACpFA,GAAWU,gBAAkBN,GAAMO,cAAgBH,GAAqB,MACnDJ,GAAMO,aAAeF,GAEvCA,ECDT,QAAwBG,GAAMC,EAAab,MACrCQ,GAAoBM,WAAWD,GAC/BJ,QACAM,OAAMP,OACY,MAEhBQ,GAAYtE,EAAesD,EAAWgB,UAAW,UAC/ChB,EAAWiB,mBACZb,IAAMc,aACcV,EAAkBW,QAAQH,aAE9CZ,IAAMgB,wBACcZ,EAAkBa,cAAcL,aAEpDZ,IAAMkB,kCACcd,EAAkBa,cAAcL,GAAWrI,wBAE/DyH,IAAMmB,qBACNnB,IAAMoB,6BACcC,EAAmBjB,EAAmBQ,EAAWhB,YAGrDO,EAAyBC,EAAmBC,EAAsBT,GAClFlH,EAAS2H,GAYlB,QAASgB,GAAmBjB,EAAmBQ,EAAWhB,MAC9B,IAAtBQ,QACK,OAEHkB,GAAiC,IAAdV,EAAkB,EAAIA,EAC3CP,EAAuBD,EACxBmB,YAAYD,GACZ1G,QAAQ4G,GAAuB,UAC9B5B,GAAWiB,gBAAkBb,GAAMoB,+BACdf,EAAqB9H,eAEvC8H,ECjDT,QAAwBoB,GAAYhB,EAAab,MAC3C8B,GAAUC,SAASlB,UACnBE,MAAMe,OACE,QAEU,EACd9B,EAAWiB,mBACZb,IAAM4B,+BACC5J,OAAO6J,aAAaH,aAE3B1B,IAAM8B,sBACCJ,EAAQhJ,SAASsH,GAAM+B,wBAE9B/B,IAAMgC,qBACCN,EAAQhJ,SAASsH,GAAMiC,uBAE9BjC,IAAMkC,2BACCR,EAAQhJ,SAASsH,GAAMmC,6BAE9BnC,IAAMoC,qCACCV,EAAQhJ,SAASsH,GAAMmC,mBAAmB5J,oBAGjDG,GAASgJ,GCvBlB,QAAwBW,GAAe5B,EAAab,MAC9C8B,GAAUC,SAASlB,SACnBE,OAAMe,OACE,GAELvB,EAAyBuB,EAAShJ,EAASgJ,GAAU9B,GCN9D,QAAwB0C,GAAa7B,EAAab,MAC5CS,GAAuBI,EACrBG,EAAYhB,EAAWgB,iBACxBrJ,EAAMqJ,IAAcP,EAAqB/E,OAASsF,MAC9BvF,EAASgF,EAAsBO,EAAW,KAE5DP,ECDT,QAAwBkC,GAAQ9B,EAAab,MACvC4C,iBACI5C,EAAWiB,mBACZb,IAAMyC,cACQC,YAEd1C,IAAM2C,yBACN3C,IAAM4C,eACQC,YAEd7C,IAAM4B,iCACN5B,IAAM8B,wBACN9B,IAAMgC,uBACNhC,IAAMkC,6BACNlC,IAAMoC,uCACNpC,IAAM8C,gCACQC,YAEd/C,IAAMc,eACNd,IAAMgB,0BACNhB,IAAMkB,oCACNlB,IAAMmB,qBACNnB,IAAMoB,6BACQ4B,KAGfC,GAAkBT,EAAe/B,EAAab,SAC7CD,GAAYsD,EAAiBrD,GCjCtC,QAASsD,GAAwBC,QAS1BC,QAAUD,EAAWC,aASrB9C,cAAgB6C,EAAW7C,mBAS3B+C,iBAAmBF,EAAWE,sBAS9BtD,mBAAqBoD,EAAWpD,wBAShCF,MAAQsD,EAAWtD,WASnBe,UAAYuC,EAAWvC,eASvBC,cAAgBsC,EAAWtC,cC7DlC,QAAwByC,IAAS9J,EAAO+J,EAAoB3D,MACtDrI,EAAMqI,EAAWiB,oBACb,IAAI2C,OAAM,wCAEdhK,EAAQ+J,EAAqB,OACzB,IAAIC,OAAM,mCAEdhK,EAAQ,OACJ,IAAIgK,OAAM,wDCGpB,QAAwBnK,IAAMoK,EAAkBC,EAAcC,EAAyBP,EAASzH,EAAU2E,EAClF+C,EAAkBtD,EAAoB6D,EAAgBC,EAAoBhD,MAC1FjB,GAAa,GAAIsD,4EAKd5G,EAAesH,EAAgB,gBAC3BtH,EAAeuH,EAAoB,2BAG5CjE,EAAWkE,yBACNH,GAAwBhG,MAAM,MAEjCoG,GAAyBN,EAAiBO,mBAAmBrI,YAClDsI,yBAAyBtI,MACtBoI,EAAwBL,EAAapI,OAAQsE,GAC1DsE,EAAmBR,EAAaK,GAAyBnE,GC2IlE,QAAwBuE,IAAQC,MACxB1B,GAAe3K,EAAeqM,MACf,KAAjB1B,QACKA,8BAHgCgB,sDAKnCW,GAAwBC,GAAiB5F,KAAKjH,OAAW,GAAIqH,GAAoB4E,SAChFhB,GAAa9H,QAAQ2J,GAAiCF,4HCnK/D,QAAwBG,IAAQJ,EAAQV,SAC/BS,kBAAQC,aAAW3L,EAAWiL,SCJvC,QAASe,IAAwBpK,SACxBqK,IAAoBrK,GAgB7B,QAAwBsK,IAAW7M,SAC1BC,GAAeD,GAAS8C,QAAQgK,GAAgCH,ICrBzE,QAAwBI,IAAa/M,SAC5BC,GAAeD,GAAS8C,QAAQkK,GAA2B,QCGpE,QAASC,IAAsBC,EAAQC,SAC9BD,GAAOpK,QAAQsK,GAAsBD,GAAMA,GAiBpD,QAAwBE,IAAarN,MAC7BK,GAAgBJ,EAAeD,SAC9BsN,IAAWlL,OAAO6K,GAAuB5M,GCpBlD,QAAwB2C,IAAQhD,EAASuN,EAAQC,MACzCnN,GAAgBJ,EAAeD,SAC9BK,GAAc2C,QAAQuK,EAAQC,GCFvC,QAAwBC,IAAYzN,EAASuN,EAAQC,MAC7CnN,GAAgBJ,EAAeD,SAC9BK,GAAcoN,YAAYF,EAAQC,GCC3C,QAAwBD,IAAOvN,EAASc,EAAS0M,MACzCnN,GAAgBJ,EAAeD,GAC/B0N,EAAkBjO,EAAM+N,GAAa,EAAIvK,EAAWG,EAAUoK,GAAY,EAAGnN,EAAcmD,QAC7F+C,EAAclG,EAAcG,OAAOkN,GAAiBH,OAAOzM,SAC3DyF,MAAe,GAAOsC,MAAM6E,QAChBA,GAETnH,ECTT,QAAwBoH,IAAO3N,EAAS4N,EAAU/J,MAC1CxD,GAAgBJ,EAAeD,GAC/B6N,EAAiB5N,EAAe2N,GAChC/I,EAAiBL,EAAeX,SAClCgB,GAAiB,GAAKA,EAAiBxE,EAAcmD,QAA6B,KAAnBqK,EAC1DxN,EAEFA,EAAcwF,MAAM,EAAGhB,GAAkBgJ,EAAiBxN,EAAcwF,MAAMhB,GCmGvF,QAASiJ,YACe,QAAlBC,GACKA,iBAGFC,KAAKC,IAAYC,QAAQ,SAASf,OAElC,GADCG,GAAaW,GAAWd,GACrBzL,EAAQ,EAAGA,EAAQ4L,EAAW9J,OAAQ9B,IAAS,IAChDa,GAAY+K,EAAW5L,MACfa,GAAa4K,KAGxBY,IAUT,QAAgBI,IAAkB5L,MAC1B6L,GAA4BN,KAAmBvL,SAC9C6L,GAA4BA,EAA4B7L,EC3IjE,QAAS8L,IAAqB9L,EAAW+L,SAChCA,GAsBT,QAAwBC,IAASvO,MACzBK,GAAgBJ,EAAeD,SACf,KAAlBK,EACK,GAEFA,EACJyC,QAAQ0L,GAAkBL,IAC1BrL,QAAQoD,GAAwBmI,ICdrC,QAAwB3G,IAAI1H,EAASwD,EAAQkE,MACrCrH,GAAgBJ,EAAeD,GAC/B0D,EAAYjE,EAAM+D,GAAU,EAAIP,EAAWG,EAAUI,GAAS,EAAGF,IACjEqE,EAAY1H,EAAeyH,EAAK,QAClChE,GAAarD,EAAcmD,aACtBnD,MAEHoO,GAAgB/K,EAAYrD,EAAcmD,OAC1CkL,EAAoBtL,EAAUqL,EAAgB,GAC9CE,EAA6BF,EAAgB,QAC5CpH,GAAaM,EAAW+G,GAAqBrO,EAChDgH,EAAaM,EAAW+G,EAAoBC,GCblD,QAAwB7L,IAAQ9C,EAASc,EAAS6H,MAC1CtI,GAAgBJ,EAAeD,SAC9BK,GAAcyC,QAAQhC,EAAS6H,GCnBxC,QAAwBiG,IAAeC,SAC9BA,GAAOjO,WAAWW,MAAMuN,IAAc,GCc/C,QAAwBC,IAAS/O,EAASuN,EAAQ1J,MAC1CxD,GAAgBJ,EAAeD,GAC/BgP,EAAepO,EAAS2M,SACT,QAAjByB,IAGiB,KAAjBA,MAGOvP,EAAMoE,GAAY,EAAIZ,EAAWG,EAAUS,GAAW,EAAGxD,EAAcmD,QAC3EnD,EAAc2C,QAAQgM,EAAcnL,MAAc,ICvB3D,QAAwBoL,IAAmBnO,EAASoO,MAC5CC,GAAyBP,GAAe9N,SACzCiO,IAASI,EAAwBD,GAG/BpO,EAFE,GAAIO,QAAOP,EAAQsO,OAAQD,EAAyBD,GCS/D,QAAwBG,IAAWrP,EAASc,EAAS6H,MAC7CtI,GAAgBJ,EAAeD,GACjC6O,EAAS/N,QACPA,aAAmBO,QAEbP,EAAQwO,WACTC,GAA8BzO,EAAS,QAFvC,GAAIO,QAAO0L,GAAajM,GAAU,KAItCT,EAAcyC,QAAQ+L,EAAQlG,GChBvC,QAAwB6G,IAAQxP,MACxBK,GAAgBJ,EAAeD,SAC9BK,GAAc8B,MAAM,IAAIqN,UAAU3N,KAAK,ICIhD,QAAwB4N,IAAgBzP,MAClCK,GAAgBJ,EAAeD,KAInBK,EACbyC,QAAQoD,GAAwB,SAASwJ,EAAIC,EAAIC,SACzCH,IAAgBG,GAAMD,IAE9B7M,QAAQqD,GAAwB,eAC/B0J,GAAiB,GACjBnO,EAAQrB,EAAcmD,OACnB9B,QACarB,EAAcuD,OAAOlC,SAElCmO,GCZT,QAAwBC,IAAQ9P,MACxBK,GAAgBJ,EAAeD,MACf,KAAlBK,QACK,MAEH0P,GAAqBxB,GAASlO,GAAeyC,QAAQ0L,GAAkB,WACtEzM,GAAUgO,GCHnB,QAAwBC,IAAOhQ,EAAS8F,EAAOmK,EAAaC,MACpD7P,GAAgBJ,EAAeD,GAC/BmQ,EAAclQ,EAAeiQ,GAC/BE,EAAgB5L,EAAesB,EAC/BsK,GAAgB,KACF/P,EAAcmD,OAAS4M,EACnCA,EAAgB,MACF,IAETA,EAAgB/P,EAAcmD,WACvBnD,EAAcmD,WAE5B6M,GAAoB7L,EAAeyL,EAAa5P,EAAcmD,OAAS4M,SACvEC,GAAoB,MACF,GAEfhQ,EAAcwF,MAAM,EAAGuK,GAAiBD,EAAc9P,EAAcwF,MAAMuK,EAAgBC,GCRnG,QAAwBC,IAAGtQ,EAASuQ,EAAMC,MAClCnQ,GAAgBJ,EAAeD,GACjCgO,SACAyC,YACA1Q,EAASwQ,IAASxQ,EAASyQ,KACtBD,EAAKpO,MAAM,MACTqO,EAAGrO,MAAM,QACb,OACYuO,GAAqB/P,EAAW4P,kCAE/B,IAAhBvC,EAAKxK,aACAnD,OAKJ,GAHDsQ,GAAS,GACPC,EAAeH,EAAOjN,OACtBqN,EAAa7C,EAAKxK,OACf9B,EAAQ,EAAGA,EAAQrB,EAAcmD,OAAQ9B,IAAS,KAGpD,GAFDoP,IAAU,EACVC,SACKC,EAAW,EAAGA,EAAWH,GAAcG,EAAWJ,EAAcI,IAAY,IAC7E7D,GAAMa,EAAKgD,MACb3Q,EAAcG,OAAOkB,EAAOyL,EAAI3J,UAAY2J,EAAK,IACzC,IACGsD,EAAOO,KACZtP,EAAQyL,EAAI3J,OAAS,YAIvBsN,EAAUC,EAAa1Q,EAAcqB,SAE1CiP,GAGT,QAASD,IAAqBO,MACtBjD,GAAOkD,OAAOlD,KAAKiD,GACnBR,EAASzC,EAAKmD,KAAKC,IAAoBxP,IAAI,SAAUuL,SAClD8D,GAAO9D,YAERa,EAAMyC,GAGhB,QAASW,IAAmBC,EAAMC,SAC5BD,GAAK7N,SAAW8N,EAAK9N,OAChB,EAEF6N,EAAK7N,OAAS8N,EAAK9N,OAAS,GAAI,ECvDzC,QAAwB+N,IAASvR,EAASwR,MAClCnR,GAAgBJ,EAAeD,MAClB,KAAfwR,GAAuC,KAAlBnR,QAChBA,MAEHoR,GAAmB7Q,EAAS4Q,MAC9B/R,EAAMgS,SACDpR,GAAcyC,QAAQ4O,GAAkB,OAE7CC,IAAkB,QACfvP,IAAOyE,KAAKxG,EAAe,SAASuR,EAASrP,SAC9CoP,IAAmB5C,GAAS0C,EAAkBlP,GACzCqP,MAES,EACXA,EAAUrP,IAChB,IChBL,QAAwBsP,IAAU7R,EAASwR,MACnCnR,GAAgBJ,EAAeD,MAClB,KAAfwR,GAAuC,KAAlBnR,QAChBA,MAEHoR,GAAmB7Q,EAAS4Q,MAC9B/R,EAAMgS,SACDpR,GAAcyC,QAAQgP,GAAmB,OAE9CH,IAAkB,QACfI,IAAYlL,KAAKxG,EAAe,SAASuR,EAASrP,SACnDoP,IAAmB5C,GAAS0C,EAAkBlP,GACzCqP,MAES,EACXrP,EAAYqP,IAClB,IClBL,QAAwBI,IAAKhS,EAASwR,MAC9BnR,GAAgBJ,EAAeD,MAClB,KAAfwR,GAAuC,KAAlBnR,QAChBA,MAEHoR,GAAmB7Q,EAAS4Q,SAC9B/R,GAAMgS,GACDpR,EAAc2R,OAEhBH,GAAUN,GAASlR,EAAeoR,GAAmBA,GCa9D,QAAwBQ,IAASjS,MAASkS,6DAClC7R,EAAgBJ,EAAeD,KACGmS,GAAiBD,GAAjDnK,IAAAA,MAAOqK,IAAAA,QAASC,IAAAA,OAAQC,IAAAA,OACV,KAAlBjS,GAAwB0H,GAAS,QAC5BsK,UAEHE,GAAgBlS,EAAcmD,OAC9BuC,EAAY1F,EAAc0F,UAAUa,KAAKvG,GAC3CsF,EAAS,EACT6M,EAAc,GACVD,EAAgB5M,EAAUoC,MACF,MAA1B1H,EAAcsF,OAId8M,GAAgBpS,EAAcoN,YAAY,IAAK1F,EAAQpC,EACvD8M,IAAiB9M,MACJ0M,EAAStM,EAAUJ,EAAQ8M,GAAiBL,IAClDK,EAAgB,GAErBH,MACaD,EAAStM,EAAUJ,EAAQoC,EAAQpC,GAAUyM,KAClDrK,MAEM1H,EAAc2C,QAAQ,IAAK+E,EAAQpC,GAC/C8M,GAAiB,MACJJ,EAAStM,EAAUJ,EAAQ8M,GAAiBL,IAClDK,EAAgB,OAEVJ,EAAStM,EAAUJ,KACzB4M,mBAKb5M,GAAS4M,OACIF,EAAStM,EAAUJ,IAE7B6M,EAUT,QAASL,IAAiBD,gBAEf1N,EAAe0N,EAAQQ,IAAe,YACpCzS,EAAeiS,EAAQS,IAAkB,aAC1C1S,EAAeiS,EAAQU,IAAgB,QAC1ChT,EAAgBsS,EAAQW,KAAa,ICxE9C,QAAwBC,IAAS9S,EAASyD,EAAKI,MACzCpE,EAAMgE,UACD,KAEHpD,GAAgBJ,EAAeD,GAC/B2D,EAAY1D,EAAewD,MACf,KAAdE,SACK,IAEElE,EAAMoE,GAAYxD,EAAcmD,OAASP,EAAWG,EAAUS,GAAW,EAAGxD,EAAcmD,WACzFG,EAAUH,UAChB+B,GAAYlF,EAAc2C,QAAQW,EAAWE,SAC5C0B,MAAc,GAAMA,IAAc1B,EChB3C,QAAwBkP,IAAQ/S,MACxBK,GAAgBJ,EAAeD,SAC9BgT,IAAa9R,KAAKb,GCF3B,QAAwB4S,IAAajT,MAC7BK,GAAgBJ,EAAeD,SAC9BkT,IAAmBhS,KAAKb,GCHjC,QAAwB8S,IAAQnT,MACxBK,GAAgBJ,EAAeD,SACE,KAAhCK,EAAc2R,OAAOxO,OCD9B,QAAwB4P,IAAQpT,MACxBK,GAAgBJ,EAAeD,SAC9BqT,IAAanS,KAAKb,GCH3B,QAAwBiT,IAAQtT,MACxBK,GAAgBJ,EAAeD,SACL,KAAzBK,EAAcmD,OCDvB,QAAwB+P,IAAYvT,MAC5BwT,GAAcvT,EAAeD,SAC5B+S,IAAQS,IAAgBA,EAAYjT,gBAAkBiT,ECA/D,QAAwBC,IAAUzT,MAC1B0T,GAAkC,gBAAZ1T,IAAyBP,EAAMO,GAA6BA,EAAlByE,OAAOzE,UAC7C,gBAAjB0T,IAAqD,gBAAjBA,MAC7C7K,MAAM6K,EAAe9K,WAAW8K,ICRxC,QAAwBC,IAAY3T,MAC5BK,GAAgBJ,EAAeD,SAC9B+S,IAAQ1S,IAAkBA,EAAcI,gBAAkBJ,ECGnE,QAAwBuT,IAAQ5T,EAASc,EAASC,MAC1CV,GAAgBJ,EAAeD,GAC/BsB,EAAcrB,EAAec,GAC/B8S,cACE/S,YAAmBO,SAAS,MAChBT,EAASE,GACH,OAAlB+S,SACK,IAEC,GAAIxS,QAAOwS,EAAevS,SAE/BR,GAAQI,KAAKb,GCRtB,QAAwByT,IAAW9T,EAAS8F,EAAOjC,MAC3CxD,GAAgBJ,EAAeD,GAC/B+T,EAAcnT,EAASkF,SACT,QAAhBiO,IAGgB,KAAhBA,MAGOtU,EAAMoE,GAAY,EAAIZ,EAAWG,EAAUS,GAAW,EAAGxD,EAAcmD,QAC3EnD,EAAcG,OAAOqD,EAAUkQ,EAAYvQ,UAAYuQ,ICtBhE,QAAwBC,IAAMhU,MACtBK,GAAgBJ,EAAeD,SAC9BK,GAAc8B,MAAM,ICI7B,QAAwB8R,IAAWjU,UAC3BK,GAAgBJ,EAAeD,GAC/B4E,EAAsBvE,EAAcmD,OACpC0Q,KACFxS,EAAQ,EACRyS,SACGzS,EAAQkD,KACKD,EAAYtE,EAAeqB,KAC9B0S,KAAKD,MACXA,EAAkB,MAAS,EAAI,QAEnCD,GCRT,QAAwBG,IAAUrU,MAC1BK,GAAgBJ,EAAeD,SAC9BW,GAAWN,EAAckB,MAAM8D,QCNxC,QAAwBlD,IAAMnC,EAASsU,EAAWC,MAC1ClU,GAAgBJ,EAAeD,SAC9BK,GAAc8B,MAAMmS,EAAWC,GCAxC,QAAwBvC,IAAKhS,MACrBK,GAAgBJ,EAAeD,SACf,KAAlBK,EACK,GAELA,EAAc,KAAOmU,GAChBnU,EAAc0F,UAAU,GAE1B1F,ECpBT,QAAwBoU,IAAoBzU,EAAS+F,EAAWrE,MAAOgT,8DACjEC,EAAc,CACdD,QACc3O,EAAUvC,OAAS,MAE/BoR,GAAqB5U,EAAQQ,OAAOkB,EAAQiT,EAAa5O,EAAUvC,cAClEoR,GAAmBrU,gBAAkBwF,ECP9C,QAAwB8O,IAAaC,UAC7BC,MACFxT,SAC4C,QAAxCA,EAAQyT,GAAgB1P,KAAKwP,OAC1BV,KAAK7S,EAAM,UAEfwT,GCFT,QAAwBE,IAAaC,UAC/BC,GAAQC,GACRC,EAAU,GACV3T,EAAQ,EACLyT,IAAUG,IAAY,IACrBC,GAAOL,EAAWxT,KAASnB,qBACzBgV,OACD,cAEA,MACKD,iBAGJE,GAAkBtU,KAAKqU,GACrBJ,IAAUM,OACJH,KAGNH,IAAUC,OACJK,IAEG,MAATF,OACSA,WAMdF,GCTT,QAAwBrD,IAAKhS,EAAS0V,EAAe/M,QACzC1I,EAAeD,GACT,KAAZA,QACK,OAEJ2C,MAAMC,QAAQ8S,GAAgB,IAC3BC,GAAsB1V,EAAeyV,KACH,KAAxBC,KAAkCd,GAAac,OAW5D,GATCC,GAAoB3V,EAAe0I,GACnCnF,EAASxD,EAAQwD,OACjBqS,EAAmBH,EAAclS,OAAS,EAC1CsS,EAAerB,GAAoB7N,KAAK,KAAM5G,GAChDmV,EAAQY,GACRC,EAAQ,EACRC,EAAS,GACTf,EAAa,GACbgB,EAAQ,KACHxU,EAAQ,EAAGA,EAAQ8B,EAAQ9B,IAAS,IACrC6T,GAAOvV,EAAQ0B,GACjByU,GAAU,SACNZ,OACD,OACCW,WAGAJ,EAAa,KAAMpU,GAAO,GAAQ,IAC1B,WAGRyT,IAAUY,GAAc,IAChB,IACFK,YAGNjB,IAAUiB,GAAY,cAIhB,YAEP,OACCjB,IAAUiB,IAAcN,EAAa,KAAMpU,GAAQ,GAC7C2U,YAGA,YAEP,OACClB,IAAUkB,IAAqBP,EAAa,MAAOpU,GAAQ,GACrD4U,YAGA,YAEP,QACA,IACCnB,IAAUiB,KACRF,IAAUX,IACJ,KACEW,MACFX,OAGF,YAEP,QACA,OACCJ,IAAUkB,IAAqBP,EAAa,UAAWpU,GAAQ,GACzD0U,YAGA,YAEP,OACCJ,EAAQ,EAAG,cAIXE,WAGAf,IAAUiB,GAAY,MAChB,OACAL,GACJF,EAAkB,IACN,OACRR,GAAUJ,GAAaC,MACzBQ,EAAc1S,QAAQqS,EAAQ9U,kBAAmB,EACzC2U,EAEAU,IAEC,WAEHA,WAIVT,IAAUkB,IAAqBlB,IAAUmB,IAAiBR,EAAa,MAAOpU,GAAQ,GAChF,OACAqU,KACK,YAGL,mBAGA,KAEVI,SACMhB,OACDY,OACOR,YAEPa,IACCP,OACYN,UAMjBU,GCzJT,QAASM,YACc,QAAjBC,GACKA,MAIa,gBAAXlH,SAAuBA,OAAO4B,SAAWA,OAEnC5B,OACU,gBAATmH,OAAqBA,KAAKvF,SAAWA,OAEtCuF,KAGA,GAAIC,UAAS,iBCEhC,QAAwBC,YAClBC,QAASJ,GAAaK,OACXA,EAAIC,IAEZF,KCVT,QAASG,IAAa/W,EAASgX,QACxBC,cAAgBjX,OAChBkX,eAAiBF,EAiIxB,QAASG,IAAsBC,SACtB,uCAAYC,4CACX1G,GAASyG,gBAAiBR,KAAKK,sBAAkBI,UACnDT,MAAKM,gBAAoC,gBAAXvG,GACzB,GAAIoG,IAAapG,EAAQiG,KAAKM,gBAE9BvG,GClIb,QAAwB2G,IAAMtX,SACrB,IAAI+W,IAAa/W,GAAS,GCMnC,QAASuX,IAAKvX,SACL,IAAI+W,IAAa/W,GAAS,GCrBnC,GAAawX,IAAQ,MAQRhG,GAAa,kBAQblN,GAAgB,kBAQhBC,GAAe,kBAQfkT,GAAkB,8EAQlBC,GAAO,wGASPxR,GAAyB,GAAI7E,QAAO,KAAOqW,GAAO,MAAQpT,GAAgB,KAAOC,GAAe,MAAQD,GAAgB,QAAUC,GAAe,WAAaD,GAAgB,QAAUC,GAAe,OAASkT,GAAkB,MAAO,KASzOtR,GAAyB,GAAI9E,QAAO,KAAOiD,GAAgB,OAASC,GAAe,KAAM,KAQzFc,GAA2B,GAAIhE,QAC5C,QAAUqW,GAAO,MAAQpT,GAAgB,KAAOC,GAAe,MAAQD,GAAgB,QAAUC,GAAe,WAAaD,GAAgB,QAAUC,GAAe,SAAWkT,GAAkB,UAC7LnT,GAAgB,KAAOC,GAAe,kCAEtC,KAQOiR,GAAoB,GAAInU,QAAO,IAAMmQ,GAAa,KAQlDE,GAAmB,GAAIrQ,QAAO,KAAOmQ,GAAa,MAQlDM,GAAoB,GAAIzQ,QAAO,IAAMmQ,GAAa,OAQlD6B,GAAe,GAAIhS,QAAO,IAAMmW,GAAQ,MAQxCxK,GAA4B,+BAQ5BwB,GAAmB,gBAQnB1B,GAAiC,YAQjCL,GAAkC,mFAQlC/C,GAAwB,UAQxBoF,GAAe,YAUfkG,GAAkB,oBC9JzB2C,GAA0B,kBAQ1BC,GAAe,yDAQfC,GAAe,kBAQfC,GAAkB,olCAQlBC,GAAkB,wpCAQX3W,GAAc,GAAIC,QAC7B,OAAS0W,GAAkB,KAAON,GAAkB,WAAaK,GAAkB,KAAOL,GAAkB,YACtGM,GAAkB,KAAON,GAAkB,WAAaK,GAAkB,OAC7EN,GAAQ,OACRK,GAAe,OACdD,GAAeD,GAA0BnG,GAAa,KAAM,KAQrDrQ,GAAoB,4GASpB6R,GAAe,GAAI3R,QAAO,QAAUyW,GAAkBC,GAAkB,KAAON,GAAkB,SASjGvE,GAAqB,GAAI7R,QAAO,SAAWyW,GAAkBC,GAAkB,KAAON,GAAkB,QAAUD,GAAQ,QAQ1HvW,GAAwB,iBCjFxBqC,GAAmB,iBpFN1BU,GAAuB,MACvBC,GAAqB,MACrBE,GAAsB,MACtBC,GAAoB,McDpBhC,GAASO,MAAMqV,UAAU5V,MEkB/B4E,GAAiBgR,UAAUC,UAAY,gBAChCvW,SAUPsF,EAAiBgR,UAAU7L,yBAA2B,SAAStI,GACzDpE,EAAMoE,SACHoU,aAWTjR,EAAiBgR,UAAU9L,mBAAqB,SAASrI,SAChDpE,GAAMoE,GAAY+S,KAAKlV,MAAQmC,EAAW,EqE7CnD,QAAeqN,OAAOgH,qBAEiB,wBACA,iCACA,yBACA,uBACA,kCACA,6BACA,uCACA,0BACA,oCACA,eACA,qBACA,+BACA,gBACA,oBAGT,yBACA,iBACA,kBACA,8BACA,kBAGR,cACA,gBACA,qBACA,IzDuDtB9M,GAAwB4M,UAAUhM,iBAAmB,iBAC5C9D,IAAMiQ,4BAA8BvB,KAAKtL,SASlDF,EAAwB4M,UAAU5P,oBAAsB,cAClDgQ,GAAmBzX,EAAWiW,KAAKrL,iBAAkB,WACzB,KAA5B6M,EAAiB5U,QAAgB4U,EAAiB,KAAOlQ,GAAMmQ,yBAC9CD,EAAiB,IAE/BA,EK/FT,IAAMxL,SACC,WACA,WACA,YACA,aACA,aACA,UEPDQ,QACC,oCACA,oCACA,qCACA,sCACA,6BACA,0BAEDE,GAAa4D,OAAOlD,KAAKZ,IKHzBa,MACC,OACA,OACA,0CACA,gBACA,kBACA,sBACA,uCACA,aACA,uBACA,sBACA,8BACA,WACA,qBACA,yBACA,eACA,uBACA,mDACA,iBACA,WACA,wBACA,wBACA,sBACA,yCACA,cACA,iBACA,WACA,wBACA,qBACA,2CACA,gBACA,mBACA,sBACA,wCACA,aACA,uBACA,uBACA,+BACA,YACA,qBACA,0BACA,eACA,wBACA,mDACA,iBACA,WACA,wBACA,0BACA,uBACA,yCACA,cACA,kBACA,WACA,0BACA,sBACC,QACA,QACA,SACA,SACA,OACA,OACA,OACA,QACA,QACA,QACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,QACA,QACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,OACA,QACF,QACE,OACA,OACA,OACA,OACA,QACA,OACA,OACA,OACA,OACA,KAGJF,GAAgB,4aajHd3L,GAASO,MAAMqV,UAAU5V,OCAzB2P,GAAcpP,MAAMqV,UAAUjG,YEF9BW,GAAe,QACfC,GAAkB,UAClBC,GAAgB,SAChBC,GAAa,MgBLb2B,GAAkB,SGAlBY,GAAkB,EAClBK,GAAuB,EACvBH,GAAa,ECCbS,GAAe,EACfK,GAAa,EACbC,GAAoB,EACpBC,GAAgB,ECRlBE,GAAe,KCEbA,GAAeD,KACfO,GAAYN,GAAaK,EQQzByB,GAAU,+0BP4BhBvB,IAAaiB,UAAUtY,MAAQ,iBACtBkX,MAAKK,eASdF,GAAaiB,UAAUO,QAAU,iBACxB3B,MAAKlX,SASdqX,GAAaiB,UAAUQ,OAAS,iBACvB5B,MAAKlX,SASdqX,GAAaiB,UAAUpX,SAAW,iBACzBV,QAAO0W,KAAKlX,UA2BrBqX,GAAaiB,UAAUV,MAAQ,iBACtB,IAAIP,IAAaH,KAAKK,eAAe,IAuB9CF,GAAaiB,UAAUS,KAAO,SAASC,SACd,kBAAZA,GACF,GAAI3B,IAAa2B,EAAQ9B,KAAKK,eAAgBL,KAAKM,gBAErDN,MASTG,GAAaiB,UAAUd,gBAAiB,EAoBxChG,OAAOlD,KAAK2K,IAAWzK,QAAQ,SAAS0K,MACzBZ,UAAUY,GAAQzB,GAAsBwB,GAAUC,qLE7HjEC,IAActB,GAAMoB,UACXrB"} \ No newline at end of file diff --git a/src/helper/format/align_and_pad.js b/src/helper/format/align_and_pad.js index 3670d2b..5b420bd 100644 --- a/src/helper/format/align_and_pad.js +++ b/src/helper/format/align_and_pad.js @@ -1,5 +1,5 @@ -import Const from 'helper/format/const'; import isNil from 'helper/object/is_nil'; +import { LITERAL_MINUS } from 'helper/format/const'; import padLeft from 'manipulate/pad_left'; import padRight from 'manipulate/pad_right'; @@ -16,6 +16,6 @@ export default function alignAndPad(subject, conversion) { if (isNil(width) || subject.length >= width) { return subject; } - const padType = conversion.alignmentSpecifier === Const.LITERAL_MINUS ? padRight : padLeft; + const padType = conversion.alignmentSpecifier === LITERAL_MINUS ? padRight : padLeft; return padType(subject, width, conversion.getPaddingCharacter()); } \ No newline at end of file diff --git a/src/helper/format/const.js b/src/helper/format/const.js index 493d304..c48f771 100644 --- a/src/helper/format/const.js +++ b/src/helper/format/const.js @@ -1,30 +1,28 @@ -export default Object.freeze({ - // Type specifiers - TYPE_INTEGER : 'i', - TYPE_INTEGER_BINARY : 'b', - TYPE_INTEGER_ASCII_CHARACTER : 'c', - TYPE_INTEGER_DECIMAL : 'd', - TYPE_INTEGER_OCTAL : 'o', - TYPE_INTEGER_UNSIGNED_DECIMAL : 'u', - TYPE_INTEGER_HEXADECIMAL : 'x', - TYPE_INTEGER_HEXADECIMAL_UPPERCASE : 'X', - TYPE_FLOAT_SCIENTIFIC : 'e', - TYPE_FLOAT_SCIENTIFIC_UPPERCASE : 'E', - TYPE_FLOAT : 'f', - TYPE_FLOAT_SHORT : 'g', - TYPE_FLOAT_SHORT_UPPERCASE : 'G', - TYPE_STRING : 's', +// Type specifiers +export const TYPE_INTEGER = 'i'; +export const TYPE_INTEGER_BINARY = 'b'; +export const TYPE_INTEGER_ASCII_CHARACTER = 'c'; +export const TYPE_INTEGER_DECIMAL = 'd'; +export const TYPE_INTEGER_OCTAL = 'o'; +export const TYPE_INTEGER_UNSIGNED_DECIMAL = 'u'; +export const TYPE_INTEGER_HEXADECIMAL = 'x'; +export const TYPE_INTEGER_HEXADECIMAL_UPPERCASE = 'X'; +export const TYPE_FLOAT_SCIENTIFIC = 'e'; +export const TYPE_FLOAT_SCIENTIFIC_UPPERCASE = 'E'; +export const TYPE_FLOAT = 'f'; +export const TYPE_FLOAT_SHORT = 'g'; +export const TYPE_FLOAT_SHORT_UPPERCASE = 'G'; +export const TYPE_STRING = 's'; // Simple literals - LITERAL_PERCENT : '%', - LITERAL_SINGLE_QUOTE : "'", - LITERAL_PLUS : '+', - LITERAL_MINUS : '-', - LITERAL_PERCENT_SPECIFIER : '%%', +export const LITERAL_PERCENT = '%'; +export const LITERAL_SINGLE_QUOTE = "'"; +export const LITERAL_PLUS = '+'; +export const LITERAL_MINUS = '-'; +export const LITERAL_PERCENT_SPECIFIER = '%%'; // Radix constants to format numbers - RADIX_BINARY : 2, - RADIX_OCTAL : 8, - RADIX_DECIMAL : 10, - RADIX_HEXADECIMAL : 16 -}); \ No newline at end of file +export const RADIX_BINARY = 2; +export const RADIX_OCTAL = 8; +export const RADIX_DECIMAL = 10; +export const RADIX_HEXADECIMAL = 16; \ No newline at end of file diff --git a/src/helper/format/conversion_specification.js b/src/helper/format/conversion_specification.js index a299d0c..41b6cf1 100644 --- a/src/helper/format/conversion_specification.js +++ b/src/helper/format/conversion_specification.js @@ -1,4 +1,4 @@ -import Const from 'helper/format/const'; +import { LITERAL_PERCENT_SPECIFIER, LITERAL_SINGLE_QUOTE } from 'helper/format/const'; import nilDefault from 'helper/undefined/nil_default'; /** @@ -82,7 +82,7 @@ function ConversionSpecification(properties) { * @return {boolean} Returns true if the conversion is a percent literal, false otherwise. */ ConversionSpecification.prototype.isPercentLiteral = function() { - return Const.LITERAL_PERCENT_SPECIFIER === this.percent; + return LITERAL_PERCENT_SPECIFIER === this.percent; }; /** @@ -93,7 +93,7 @@ ConversionSpecification.prototype.isPercentLiteral = function() { */ ConversionSpecification.prototype.getPaddingCharacter = function() { let paddingCharacter = nilDefault(this.paddingSpecifier, ' '); - if (paddingCharacter.length === 2 && paddingCharacter[0] === Const.LITERAL_SINGLE_QUOTE) { + if (paddingCharacter.length === 2 && paddingCharacter[0] === LITERAL_SINGLE_QUOTE) { paddingCharacter = paddingCharacter[1]; } return paddingCharacter; diff --git a/src/helper/format/replacement/compute.js b/src/helper/format/replacement/compute.js index dfc3008..ea259c2 100644 --- a/src/helper/format/replacement/compute.js +++ b/src/helper/format/replacement/compute.js @@ -1,5 +1,20 @@ +import { + TYPE_FLOAT, + TYPE_FLOAT_SCIENTIFIC, + TYPE_FLOAT_SCIENTIFIC_UPPERCASE, + TYPE_FLOAT_SHORT, + TYPE_FLOAT_SHORT_UPPERCASE, + TYPE_INTEGER, + TYPE_INTEGER_ASCII_CHARACTER, + TYPE_INTEGER_BINARY, + TYPE_INTEGER_DECIMAL, + TYPE_INTEGER_HEXADECIMAL, + TYPE_INTEGER_HEXADECIMAL_UPPERCASE, + TYPE_INTEGER_OCTAL, + TYPE_INTEGER_UNSIGNED_DECIMAL, + TYPE_STRING +} from 'helper/format/const'; import alignAndPad from 'helper/format/align_and_pad'; -import Const from 'helper/format/const'; import formatFloat from 'helper/format/type_format/float'; import formatIntegerBase from 'helper/format/type_format/integer_base'; import formatIntegerDecimal from 'helper/format/type_format/integer_decimal'; @@ -17,26 +32,26 @@ import formatString from 'helper/format/type_format/string'; export default function compute(replacement, conversion) { let formatFunction; switch (conversion.typeSpecifier) { - case Const.TYPE_STRING: + case TYPE_STRING: formatFunction = formatString; break; - case Const.TYPE_INTEGER_DECIMAL: - case Const.TYPE_INTEGER: + case TYPE_INTEGER_DECIMAL: + case TYPE_INTEGER: formatFunction = formatIntegerDecimal; break; - case Const.TYPE_INTEGER_ASCII_CHARACTER: - case Const.TYPE_INTEGER_BINARY: - case Const.TYPE_INTEGER_OCTAL: - case Const.TYPE_INTEGER_HEXADECIMAL: - case Const.TYPE_INTEGER_HEXADECIMAL_UPPERCASE: - case Const.TYPE_INTEGER_UNSIGNED_DECIMAL: + case TYPE_INTEGER_ASCII_CHARACTER: + case TYPE_INTEGER_BINARY: + case TYPE_INTEGER_OCTAL: + case TYPE_INTEGER_HEXADECIMAL: + case TYPE_INTEGER_HEXADECIMAL_UPPERCASE: + case TYPE_INTEGER_UNSIGNED_DECIMAL: formatFunction = formatIntegerBase; break; - case Const.TYPE_FLOAT: - case Const.TYPE_FLOAT_SCIENTIFIC: - case Const.TYPE_FLOAT_SCIENTIFIC_UPPERCASE: - case Const.TYPE_FLOAT_SHORT: - case Const.TYPE_FLOAT_SHORT_UPPERCASE: + case TYPE_FLOAT: + case TYPE_FLOAT_SCIENTIFIC: + case TYPE_FLOAT_SCIENTIFIC_UPPERCASE: + case TYPE_FLOAT_SHORT: + case TYPE_FLOAT_SHORT_UPPERCASE: formatFunction = formatFloat; break; } diff --git a/src/helper/format/type_format/add_sign_to_formatted_number.js b/src/helper/format/type_format/add_sign_to_formatted_number.js index 1f9ba00..af25398 100644 --- a/src/helper/format/type_format/add_sign_to_formatted_number.js +++ b/src/helper/format/type_format/add_sign_to_formatted_number.js @@ -1,4 +1,4 @@ -import Const from 'helper/format/const'; +import { LITERAL_PLUS } from 'helper/format/const'; /** * Add sign to the formatted number. @@ -11,8 +11,8 @@ import Const from 'helper/format/const'; * @return {string} Returns the formatted number string with a sign. */ export default function addSignToFormattedNumber(replacementNumber, formattedReplacement, conversion) { - if (conversion.signSpecifier === Const.LITERAL_PLUS && replacementNumber >= 0) { - formattedReplacement = Const.LITERAL_PLUS + formattedReplacement; + if (conversion.signSpecifier === LITERAL_PLUS && replacementNumber >= 0) { + formattedReplacement = LITERAL_PLUS + formattedReplacement; } return formattedReplacement; } \ No newline at end of file diff --git a/src/helper/format/type_format/float.js b/src/helper/format/type_format/float.js index d776c03..db1a31c 100644 --- a/src/helper/format/type_format/float.js +++ b/src/helper/format/type_format/float.js @@ -1,6 +1,12 @@ +import { + TYPE_FLOAT, + TYPE_FLOAT_SCIENTIFIC, + TYPE_FLOAT_SCIENTIFIC_UPPERCASE, + TYPE_FLOAT_SHORT, + TYPE_FLOAT_SHORT_UPPERCASE +} from 'helper/format/const'; import addSignToFormattedNumber from 'helper/format/type_format/add_sign_to_formatted_number'; import coerceToNumber from 'helper/number/coerce_to_number'; -import Const from 'helper/format/const'; import { REGEXP_TRAILING_ZEROS } from 'helper/reg_exp/const'; import toString from 'helper/string/coerce_to_string'; @@ -21,17 +27,17 @@ export default function float(replacement, conversion) { } const precision = coerceToNumber(conversion.precision, 6); switch (conversion.typeSpecifier) { - case Const.TYPE_FLOAT: + case TYPE_FLOAT: formattedReplacement = replacementNumber.toFixed(precision); break; - case Const.TYPE_FLOAT_SCIENTIFIC: + case TYPE_FLOAT_SCIENTIFIC: formattedReplacement = replacementNumber.toExponential(precision); break; - case Const.TYPE_FLOAT_SCIENTIFIC_UPPERCASE: + case TYPE_FLOAT_SCIENTIFIC_UPPERCASE: formattedReplacement = replacementNumber.toExponential(precision).toUpperCase(); break; - case Const.TYPE_FLOAT_SHORT: - case Const.TYPE_FLOAT_SHORT_UPPERCASE: + case TYPE_FLOAT_SHORT: + case TYPE_FLOAT_SHORT_UPPERCASE: formattedReplacement = formatFloatAsShort(replacementNumber, precision, conversion); break; } @@ -56,7 +62,7 @@ function formatFloatAsShort(replacementNumber, precision, conversion) { let formattedReplacement = replacementNumber .toPrecision(nonZeroPrecision) .replace(REGEXP_TRAILING_ZEROS, ''); - if (conversion.typeSpecifier === Const.TYPE_FLOAT_SHORT_UPPERCASE) { + if (conversion.typeSpecifier === TYPE_FLOAT_SHORT_UPPERCASE) { formattedReplacement = formattedReplacement.toUpperCase(); } return formattedReplacement; diff --git a/src/helper/format/type_format/integer_base.js b/src/helper/format/type_format/integer_base.js index 7785f92..6e8d044 100644 --- a/src/helper/format/type_format/integer_base.js +++ b/src/helper/format/type_format/integer_base.js @@ -1,4 +1,13 @@ -import Const from 'helper/format/const'; +import { + RADIX_BINARY, + RADIX_HEXADECIMAL, + RADIX_OCTAL, + TYPE_INTEGER_ASCII_CHARACTER, + TYPE_INTEGER_BINARY, + TYPE_INTEGER_HEXADECIMAL, + TYPE_INTEGER_HEXADECIMAL_UPPERCASE, + TYPE_INTEGER_OCTAL +} from 'helper/format/const'; import toString from 'helper/string/coerce_to_string'; /** @@ -17,20 +26,20 @@ export default function integerBase(replacement, conversion) { } integer = integer >>> 0; switch (conversion.typeSpecifier) { - case Const.TYPE_INTEGER_ASCII_CHARACTER: + case TYPE_INTEGER_ASCII_CHARACTER: integer = String.fromCharCode(integer); break; - case Const.TYPE_INTEGER_BINARY: - integer = integer.toString(Const.RADIX_BINARY); + case TYPE_INTEGER_BINARY: + integer = integer.toString(RADIX_BINARY); break; - case Const.TYPE_INTEGER_OCTAL: - integer = integer.toString(Const.RADIX_OCTAL); + case TYPE_INTEGER_OCTAL: + integer = integer.toString(RADIX_OCTAL); break; - case Const.TYPE_INTEGER_HEXADECIMAL: - integer = integer.toString(Const.RADIX_HEXADECIMAL); + case TYPE_INTEGER_HEXADECIMAL: + integer = integer.toString(RADIX_HEXADECIMAL); break; - case Const.TYPE_INTEGER_HEXADECIMAL_UPPERCASE: - integer = integer.toString(Const.RADIX_HEXADECIMAL).toUpperCase(); + case TYPE_INTEGER_HEXADECIMAL_UPPERCASE: + integer = integer.toString(RADIX_HEXADECIMAL).toUpperCase(); break; } return toString(integer); diff --git a/test_runner/test_bundle.js b/test_runner/test_bundle.js deleted file mode 100644 index d2fd644..0000000 --- a/test_runner/test_bundle.js +++ /dev/null @@ -1,7889 +0,0 @@ -(function (chai) { -'use strict'; - -/** - * The string containing all printable ASCII characters. - * @ignore - * @type {string} - */ -var PRINTABLE_ASCII = ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'; - -/** - * The string containing all printable ASCII characters in reverse order. - * @ignore - * @type {string} - */ -var REVERSED_PRINTABLE_ASCII = '~}|{zyxwvutsrqponmlkjihgfedcba`_^]\\[ZYXWVUTSRQPONMLKJIHGFEDCBA@?>=<;:9876543210/.-,+*)(\'&%$#"! '; - -/** - * Regular expression to match the library version. - * @see http://semver.org/ - * @type {RegExp} - */ -var REGEXP_SEMVER = /\bv?(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)(?:-[\da-z\-]+(?:\.[\da-z\-]+)*)?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?\b/ig; - -/** - * Checks if `value` is `null` or `undefined` - * - * @ignore - * @function isNil - * @param {*} value The object to check - * @return {boolean} Returns `true` is `value` is `undefined` or `null`, `false` otherwise - */ -function isNil(value) { - return value === undefined || value === null; -} - -/** - * Converts the `value` to a boolean. If `value` is `undefined` or `null`, returns `defaultValue`. - * - * @ignore - * @function toBoolean - * @param {*} value The value to convert. - * @param {boolean} [defaultValue=false] The default value. - * @return {boolean} Returns the coercion to boolean. - */ -function coerceToBoolean(value) { - var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - if (isNil(value)) { - return defaultValue; - } - return Boolean(value); -} - -/** - * Checks whether `subject` is a string primitive type. - * - * @function isString - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} subject The value to verify. - * @return {boolean} Returns `true` if `subject` is string primitive type or `false` otherwise. - * @example - * v.isString('vacation'); - * // => true - * - * v.isString(560); - * // => false - */ -function isString(subject) { - return typeof subject === 'string'; -} - -/** - * Get the string representation of the `value`. - * Converts the `value` to string. - * If `value` is `null` or `undefined`, return `defaultValue`. - * - * @ignore - * @function toString - * @param {*} value The value to convert. - * @param {*} [defaultValue=''] The default value to return. - * @return {string|null} Returns the string representation of `value`. Returns `defaultValue` if `value` is - * `null` or `undefined`. - */ -function coerceToString(value) { - var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; - - if (isNil(value)) { - return defaultValue; - } - if (isString(value)) { - return value; - } - return String(value); -} - -/** - * Converts the first character of `subject` to upper case. If `restToLower` is `true`, convert the rest of - * `subject` to lower case. - * - * @function capitalize - * @static - * @since 1.0.0 - * @memberOf Case - * @param {string} [subject=''] The string to capitalize. - * @param {boolean} [restToLower=false] Convert the rest of `subject` to lower case. - * @return {string} Returns the capitalized string. - * @example - * v.capitalize('apple'); - * // => 'Apple' - * - * v.capitalize('aPPle', true); - * // => 'Apple' - */ -function capitalize(subject, restToLower) { - var subjectString = coerceToString(subject); - var restToLowerCaseBoolean = coerceToBoolean(restToLower); - if (subjectString === '') { - return ''; - } - if (restToLowerCaseBoolean) { - subjectString = subjectString.toLowerCase(); - } - return subjectString.substr(0, 1).toUpperCase() + subjectString.substr(1); -} - -/** - * Converts the `subject` to lower case. - * - * @function lowerCase - * @static - * @since 1.0.0 - * @memberOf Case - * @param {string} [subject=''] The string to convert to lower case. - * @return {string} Returns the lower case string. - * @example - * v.lowerCase('Green'); - * // => 'green' - * - * v.lowerCase('BLUE'); - * // => 'blue' - */ -function lowerCase(subject) { - var subjectString = coerceToString(subject, ''); - return subjectString.toLowerCase(); -} - -/** - * A regular expression string matching digits - * - * @type {string} - * @ignore - */ -var digit = '\\d'; - -/** - * A regular expression string matching whitespace - * - * @type {string} - * @ignore - */ -var whitespace = '\\s\\uFEFF\\xA0'; - -/** - * A regular expression string matching high surrogate - * - * @type {string} - * @ignore - */ -var highSurrogate = '\\uD800-\\uDBFF'; - -/** - * A regular expression string matching low surrogate - * - * @type {string} - * @ignore - */ -var lowSurrogate = '\\uDC00-\\uDFFF'; - -/** - * A regular expression string matching diacritical mark - * - * @type {string} - * @ignore - */ -var diacriticalMark = '\\u0300-\\u036F\\u1AB0-\\u1AFF\\u1DC0-\\u1DFF\\u20D0-\\u20FF\\uFE20-\\uFE2F'; - -/** - * A regular expression to match the base character for a combining mark - * - * @type {string} - * @ignore - */ -var base = '\\0-\\u02FF\\u0370-\\u1AAF\\u1B00-\\u1DBF\\u1E00-\\u20CF\\u2100-\\uD7FF\\uE000-\\uFE1F\\uFE30-\\uFFFF'; - -/** - * Regular expression to match combining marks - * - * @see http://unicode.org/faq/char_combmark.html - * @type {RegExp} - * @ignore - */ -var REGEXP_COMBINING_MARKS = new RegExp('([' + base + ']|[' + highSurrogate + '][' + lowSurrogate + ']|[' + highSurrogate + '](?![' + lowSurrogate + '])|(?:[^' + highSurrogate + ']|^)[' + lowSurrogate + '])([' + diacriticalMark + ']+)', 'g'); - -/** - * Regular expression to match surrogate pairs - * - * @see http://www.unicode.org/faq/utf_bom.html#utf16-2 - * @type {RegExp} - * @ignore - */ -var REGEXP_SURROGATE_PAIRS = new RegExp('([' + highSurrogate + '])([' + lowSurrogate + '])', 'g'); - -/** - * Regular expression to match an unicode character - * - * @type {RegExp} - * @ignore - */ -var REGEXP_UNICODE_CHARACTER = new RegExp('((?:[' + base + ']|[' + highSurrogate + '][' + lowSurrogate + ']|[' + highSurrogate + '](?![' + lowSurrogate + '])|(?:[^' + highSurrogate + ']|^)[' + lowSurrogate + '])(?:[' + diacriticalMark + ']+))|\ -([' + highSurrogate + '][' + lowSurrogate + '])|\ -([\\n\\r\\u2028\\u2029])|\ -(.)', 'g'); - -/** - * Regular expression to match whitespaces - * - * @type {RegExp} - * @ignore - */ -var REGEXP_WHITESPACE = new RegExp('[' + whitespace + ']'); - -/** - * Regular expression to match whitespaces from the left side - * - * @type {RegExp} - * @ignore - */ -var REGEXP_TRIM_LEFT = new RegExp('^[' + whitespace + ']+'); - -/** - * Regular expression to match whitespaces from the right side - * - * @type {RegExp} - * @ignore - */ -var REGEXP_TRIM_RIGHT = new RegExp('[' + whitespace + ']+$'); - -/** - * Regular expression to match digit characters - * - * @type {RegExp} - * @ignore - */ -var REGEXP_DIGIT = new RegExp('^' + digit + '+$'); - -/** - * Regular expression to match regular expression special characters - * - * @type {RegExp} - * @ignore - */ -var REGEXP_SPECIAL_CHARACTERS = /[-[\]{}()*+!<=:?.\/\\^$|#,]/g; - -/** - * Regular expression to match not latin characters - * - * @type {RegExp} - * @ignore - */ -var REGEXP_NON_LATIN = /[^A-Za-z0-9]/g; - -/** - * Regular expression to match HTML special characters. - * - * @type {RegExp} - * @ignore - */ -var REGEXP_HTML_SPECIAL_CHARACTERS = /[<>&"'`]/g; - -/** - * Regular expression to match sprintf format string - * - * @type {RegExp} - * @ignore - */ -var REGEXP_CONVERSION_SPECIFICATION = /(%{1,2})(?:(\d+)\$)?(\+)?([ 0]|'.{1})?(-)?(\d+)?(?:\.(\d+))?([bcdiouxXeEfgGs])?/g; - -/** - * Regular expression to match trailing zeros in a number - * - * @type {RegExp} - * @ignore - */ -var REGEXP_TRAILING_ZEROS = /\.?0+$/g; - -/** - * Regular expression to match flags from a regular expression. - * - * @type {RegExp} - * @ignore - */ -var REGEXP_FLAGS = /[gimuy]*$/; - -/** - * Regular expression to match a list of tags. - * - * @see https://html.spec.whatwg.org/multipage/syntax.html#syntax-tag-name - * @type {RegExp} - * @ignore - */ - -var REGEXP_TAG_LIST = /<([A-Za-z0-9]+)>/g; - -/** - * A regular expression to match the General Punctuation Unicode block - * - * @type {string} - * @ignore - */ -var generalPunctuationBlock = '\\u2000-\\u206F'; - -/** - * A regular expression to match non characters from from Basic Latin and Latin-1 Supplement Unicode blocks - * - * @type {string} - * @ignore - */ -var nonCharacter = '\\x00-\\x2F\\x3A-\\x40\\x5B-\\x60\\x7b-\\xBF\\xD7\\xF7'; - -/** - * A regular expression to match the dingbat Unicode block - * - * @type {string} - * @ignore - */ -var dingbatBlock = '\\u2700-\\u27BF'; - -/** - * A regular expression string that matches lower case letters: LATIN - * - * @type {string} - * @ignore - */ -var lowerCaseLetter = 'a-z\\xB5\\xDF-\\xF6\\xF8-\\xFF\\u0101\\u0103\\u0105\\u0107\\u0109\\u010B\\u010D\\u010F\\u0111\\u0113\\u0115\\u0117\\u0119\\u011B\\u011D\\u011F\\u0121\\u0123\\u0125\\u0127\\u0129\\u012B\\u012D\\u012F\\u0131\\u0133\\u0135\\u0137\\u0138\\u013A\\u013C\\u013E\\u0140\\u0142\\u0144\\u0146\\u0148\\u0149\\u014B\\u014D\\u014F\\u0151\\u0153\\u0155\\u0157\\u0159\\u015B\\u015D\\u015F\\u0161\\u0163\\u0165\\u0167\\u0169\\u016B\\u016D\\u016F\\u0171\\u0173\\u0175\\u0177\\u017A\\u017C\\u017E-\\u0180\\u0183\\u0185\\u0188\\u018C\\u018D\\u0192\\u0195\\u0199-\\u019B\\u019E\\u01A1\\u01A3\\u01A5\\u01A8\\u01AA\\u01AB\\u01AD\\u01B0\\u01B4\\u01B6\\u01B9\\u01BA\\u01BD-\\u01BF\\u01C6\\u01C9\\u01CC\\u01CE\\u01D0\\u01D2\\u01D4\\u01D6\\u01D8\\u01DA\\u01DC\\u01DD\\u01DF\\u01E1\\u01E3\\u01E5\\u01E7\\u01E9\\u01EB\\u01ED\\u01EF\\u01F0\\u01F3\\u01F5\\u01F9\\u01FB\\u01FD\\u01FF\\u0201\\u0203\\u0205\\u0207\\u0209\\u020B\\u020D\\u020F\\u0211\\u0213\\u0215\\u0217\\u0219\\u021B\\u021D\\u021F\\u0221\\u0223\\u0225\\u0227\\u0229\\u022B\\u022D\\u022F\\u0231\\u0233-\\u0239\\u023C\\u023F\\u0240\\u0242\\u0247\\u0249\\u024B\\u024D\\u024F'; - -/** - * A regular expression string that matches upper case letters: LATIN - * - * @type {string} - * @ignore - */ -var upperCaseLetter = '\\x41-\\x5a\\xc0-\\xd6\\xd8-\\xde\\u0100\\u0102\\u0104\\u0106\\u0108\\u010a\\u010c\\u010e\\u0110\\u0112\\u0114\\u0116\\u0118\\u011a\\u011c\\u011e\\u0120\\u0122\\u0124\\u0126\\u0128\\u012a\\u012c\\u012e\\u0130\\u0132\\u0134\\u0136\\u0139\\u013b\\u013d\\u013f\\u0141\\u0143\\u0145\\u0147\\u014a\\u014c\\u014e\\u0150\\u0152\\u0154\\u0156\\u0158\\u015a\\u015c\\u015e\\u0160\\u0162\\u0164\\u0166\\u0168\\u016a\\u016c\\u016e\\u0170\\u0172\\u0174\\u0176\\u0178\\u0179\\u017b\\u017d\\u0181\\u0182\\u0184\\u0186\\u0187\\u0189-\\u018b\\u018e-\\u0191\\u0193\\u0194\\u0196-\\u0198\\u019c\\u019d\\u019f\\u01a0\\u01a2\\u01a4\\u01a6\\u01a7\\u01a9\\u01ac\\u01ae\\u01af\\u01b1-\\u01b3\\u01b5\\u01b7\\u01b8\\u01bc\\u01c4\\u01c5\\u01c7\\u01c8\\u01ca\\u01cb\\u01cd\\u01cf\\u01d1\\u01d3\\u01d5\\u01d7\\u01d9\\u01db\\u01de\\u01e0\\u01e2\\u01e4\\u01e6\\u01e8\\u01ea\\u01ec\\u01ee\\u01f1\\u01f2\\u01f4\\u01f6-\\u01f8\\u01fa\\u01fc\\u01fe\\u0200\\u0202\\u0204\\u0206\\u0208\\u020a\\u020c\\u020e\\u0210\\u0212\\u0214\\u0216\\u0218\\u021a\\u021c\\u021e\\u0220\\u0222\\u0224\\u0226\\u0228\\u022a\\u022c\\u022e\\u0230\\u0232\\u023a\\u023b\\u023d\\u023e\\u0241\\u0243-\\u0246\\u0248\\u024a\\u024c\\u024e'; - -/** - * Regular expression to match Unicode words - * - * @type {RegExp} - * @ignore - */ -var REGEXP_WORD = new RegExp('(?:[' + upperCaseLetter + '][' + diacriticalMark + ']*)?(?:[' + lowerCaseLetter + '][' + diacriticalMark + ']*)+|\ -(?:[' + upperCaseLetter + '][' + diacriticalMark + ']*)+(?![' + lowerCaseLetter + '])|\ -[' + digit + ']+|\ -[' + dingbatBlock + ']|\ -[^' + nonCharacter + generalPunctuationBlock + whitespace + ']+', 'g'); - -/** - * Regular expression to match words from Basic Latin and Latin-1 Supplement blocks - * - * @type {RegExp} - * @ignore - */ -var REGEXP_LATIN_WORD = /[A-Z\xC0-\xD6\xD8-\xDE]?[a-z\xDF-\xF6\xF8-\xFF]+|[A-Z\xC0-\xD6\xD8-\xDE]+(?![a-z\xDF-\xF6\xF8-\xFF])|\d+/g; - -/** - * Regular expression to match alpha characters - * - * @see http://stackoverflow.com/a/22075070/1894471 - * @type {RegExp} - * @ignore - */ -var REGEXP_ALPHA = new RegExp('^(?:[' + lowerCaseLetter + upperCaseLetter + '][' + diacriticalMark + ']*)+$'); - -/** - * Regular expression to match alpha and digit characters - * - * @see http://stackoverflow.com/a/22075070/1894471 - * @type {RegExp} - * @ignore - */ -var REGEXP_ALPHA_DIGIT = new RegExp('^((?:[' + lowerCaseLetter + upperCaseLetter + '][' + diacriticalMark + ']*)|[' + digit + '])+$'); - -/** - * Regular expression to match Extended ASCII characters, i.e. the first 255 - * - * @type {RegExp} - * @ignore - */ -var REGEXP_EXTENDED_ASCII = /^[\x00-\xFF]*$/; - -/** - * Verifies if `value` is `undefined` or `null` and returns `defaultValue`. In other case returns `value`. - * - * @ignore - * @function nilDefault - * @param {*} value The value to verify. - * @param {*} defaultValue The default value. - * @return {*} Returns `defaultValue` if `value` is `undefined` or `null`, otherwise `defaultValue`. - */ -function nilDefault(value, defaultValue) { - return value == null ? defaultValue : value; -} - -/** - * Get the string representation of the `value`. - * Converts the `value` to string. - * - * @ignore - * @function toString - * @param {*} value The value to convert. - * @return {string|null} Returns the string representation of `value`. - */ -function toString(value) { - if (isNil(value)) { - return null; - } - if (isString(value)) { - return value; - } - return String(value); -} - -/** - * Splits `subject` into an array of words. - * - * @function words - * @static - * @since 1.0.0 - * @memberOf Split - * @param {string} [subject=''] The string to split into words. - * @param {string|RegExp} [pattern] The pattern to watch words. If `pattern` is not RegExp, it is transformed to `new RegExp(pattern, flags)`. - * @param {string} [flags=''] The regular expression flags. Applies when `pattern` is string type. - * @return {Array} Returns the array of words. - * @example - * v.words('gravity can cross dimensions'); - * // => ['gravity', 'can', 'cross', 'dimensions'] - * - * v.words('GravityCanCrossDimensions'); - * // => ['Gravity', 'Can', 'Cross', 'Dimensions'] - * - * v.words('Gravity - can cross dimensions!'); - * // => ['Gravity', 'can', 'cross', 'dimensions'] - * - * v.words('Earth gravity', /[^\s]+/g); - * // => ['Earth', 'gravity'] - */ -function words(subject, pattern, flags) { - var subjectString = coerceToString(subject); - var patternRegExp = void 0; - if (isNil(pattern)) { - patternRegExp = REGEXP_EXTENDED_ASCII.test(subjectString) ? REGEXP_LATIN_WORD : REGEXP_WORD; - } else if (pattern instanceof RegExp) { - patternRegExp = pattern; - } else { - var flagsString = toString(nilDefault(flags, '')); - patternRegExp = new RegExp(toString(pattern), flagsString); - } - return nilDefault(subjectString.match(patternRegExp), []); -} - -/** - * Transforms the `word` into camel case chunk. - * - * @param {string} word The word string - * @param {number} index The index of the word in phrase. - * @return {string} The transformed word. - * @ignore - */ -function wordToCamel(word, index) { - return index === 0 ? lowerCase(word) : capitalize(word, true); -} - -/** - * Converts the `subject` to camel case. - * - * @function camelCase - * @static - * @since 1.0.0 - * @memberOf Case - * @param {string} [subject=''] The string to convert to camel case. - * @return {string} The camel case string. - * @example - * v.camelCase('bird flight'); - * // => 'birdFlight' - * - * v.camelCase('BirdFlight'); - * // => 'birdFlight' - * - * v.camelCase('-BIRD-FLIGHT-'); - * // => 'birdFlight' - */ -function camelCase(subject) { - var subjectString = coerceToString(subject); - if (subjectString === '') { - return ''; - } - return words(subjectString).map(wordToCamel).join(''); -} - -/** - * Converts the first character of `subject` to lower case. - * - * @function decapitalize - * @static - * @since 1.0.0 - * @memberOf Case - * @param {string} [subject=''] The string to decapitalize. - * @return {string} Returns the decapitalized string. - * @example - * v.decapitalize('Sun'); - * // => 'sun' - * - * v.decapitalize('moon'); - * // => 'moon' - */ -function decapitalize(subject) { - var subjectString = coerceToString(subject); - if (subjectString === '') { - return ''; - } - return subjectString.substr(0, 1).toLowerCase() + subjectString.substr(1); -} - -/** - * Converts the `subject` to kebab case, - * also called spinal case or lisp case. - * - * @function kebabCase - * @static - * @since 1.0.0 - * @memberOf Case - * @param {string} [subject=''] The string to convert to kebab case. - * @return {string} Returns the kebab case string. - * @example - * v.kebabCase('goodbye blue sky'); - * // => 'goodbye-blue-sky' - * - * v.kebabCase('GoodbyeBlueSky'); - * // => 'goodbye-blue-sky' - * - * v.kebabCase('-Goodbye-Blue-Sky-'); - * // => 'goodbye-blue-sky' - */ -function kebabCase(subject) { - var subjectString = coerceToString(subject); - if (subjectString === '') { - return ''; - } - return words(subjectString).map(lowerCase).join('-'); -} - -/** - * Converts the `subject` to snake case. - * - * @function snakeCase - * @static - * @since 1.0.0 - * @memberOf Case - * @param {string} [subject=''] The string to convert to snake case. - * @return {string} Returns the snake case string. - * @example - * v.snakeCase('learning to fly'); - * // => 'learning_to_fly' - * - * v.snakeCase('LearningToFly'); - * // => 'learning_to_fly' - * - * v.snakeCase('-Learning-To-Fly-'); - * // => 'learning_to_fly' - */ -function snakeCase(subject) { - var subjectString = coerceToString(subject); - if (subjectString === '') { - return ''; - } - return words(subjectString).map(lowerCase).join('_'); -} - -/** - * Converts the `subject` to upper case. - * - * @function upperCase - * @static - * @since 1.0.0 - * @memberOf Case - * @param {string} [subject=''] The string to convert to upper case. - * @return {string} Returns the upper case string. - * @example - * v.upperCase('school'); - * // => 'SCHOOL' - */ -function upperCase(subject) { - var subjectString = coerceToString(subject); - return subjectString.toUpperCase(); -} - -/** - * Converts the uppercase alpha caracters of `subject` to lowercase and lowercase - * characters to uppercase. - * - * @function swapCase - * @static - * @since 1.3.0 - * @memberOf Case - * @param {string} [subject=''] The string to swap the case. - * @return {string} Returns the converted string. - * @example - * v.swapCase('League of Shadows'); - * // => 'lEAGE OF sHADOWS' - * - * v.swapCase('2 Bees'); - * // => '2 bEES' - */ -function swapCase(subject) { - var subjectString = coerceToString(subject); - return subjectString.split('').reduce(swapAndConcat, ''); -} - -function swapAndConcat(swapped, character) { - var lowerCase = character.toLowerCase(); - var upperCase = character.toUpperCase(); - return swapped + (character === lowerCase ? upperCase : lowerCase); -} - -/** - * Converts the subject to title case. - * - * @function titleCase - * @static - * @since 1.2.0 - * @memberOf Case - * @param {string} [subject=''] The string to convert to title case. - * @param {Array} [ignoreWords] The words that should not be capitalized. - * @return {string} Returns the title case string. - * @example - * v.titleCase('learning to fly'); - * // => 'Learning To Fly' - * - * v.titleCase('another brick in the wall', ['in', 'the']); - * // => 'Another Brick in the Wall' - */ -function titleCase(subject, ignoreWords) { - var subjectString = coerceToString(subject); - var ignoreWordsArray = Array.isArray(ignoreWords) ? ignoreWords : []; - var wordsRegExp = REGEXP_EXTENDED_ASCII.test(subjectString) ? REGEXP_LATIN_WORD : REGEXP_WORD; - return subjectString.replace(wordsRegExp, function (word) { - var lowerCaseWord = word.toLowerCase(); - return ignoreWordsArray.indexOf(lowerCaseWord) !== -1 ? lowerCaseWord : capitalize(lowerCaseWord, true); - }); -} - -/** - * Clip the number to interval `downLimit` to `upLimit`. - * - * @ignore - * @function clipNumber - * @param {number} value The number to clip - * @param {number} downLimit The down limit - * @param {number} upLimit The upper limit - * @return {number} The clipped number - */ -function clipNumber(value, downLimit, upLimit) { - if (value <= downLimit) { - return downLimit; - } - if (value >= upLimit) { - return upLimit; - } - return value; -} - -/** - * Max save integer value - * - * @ignore - * @type {number} - */ -var MAX_SAFE_INTEGER = 0x1fffffffffffff; - -/** - * Transforms `value` to an integer. - * - * @ignore - * @function toInteger - * @param {number} value The number to transform. - * @returns {number} Returns the transformed integer. - */ -function toInteger(value) { - if (value === Infinity) { - return MAX_SAFE_INTEGER; - } - if (value === -Infinity) { - return -MAX_SAFE_INTEGER; - } - return ~~value; -} - -/** - * Truncates `subject` to a new `length`. - * - * @function truncate - * @static - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to truncate. - * @param {int} length The length to truncate the string. - * @param {string} [end='...'] The string to be added at the end. - * @return {string} Returns the truncated string. - * @example - * v.truncate('Once upon a time', 7); - * // => 'Once...' - * - * v.truncate('Good day, Little Red Riding Hood', 14, ' (...)'); - * // => 'Good day (...)' - * - * v.truncate('Once upon', 10); - * // => 'Once upon' - */ -function truncate(subject, length, end) { - var subjectString = coerceToString(subject); - var lengthInt = isNil(length) ? subjectString.length : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER); - var endString = coerceToString(end, '...'); - if (lengthInt >= subjectString.length) { - return subjectString; - } - return subjectString.substr(0, length - endString.length) + endString; -} - -/** - * Access a character from `subject` at specified `position`. - * - * @function charAt - * @static - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to extract from. - * @param {numbers} position The position to get the character. - * @return {string} Returns the character at specified position. - * @example - * v.charAt('helicopter', 0); - * // => 'h' - * - * v.charAt('helicopter', 1); - * // => 'e' - */ -function charAt(subject, position) { - var subjectString = coerceToString(subject); - return subjectString.charAt(position); -} - -var HIGH_SURROGATE_START = 0xD800; -var HIGH_SURROGATE_END = 0xDBFF; -var LOW_SURROGATE_START = 0xDC00; -var LOW_SURROGATE_END = 0xDFFF; - -/** - * Checks if `codePoint` is a high-surrogate number from range 0xD800 to 0xDBFF. - * - * @ignore - * @param {number} codePoint The code point number to be verified - * @return {boolean} Returns a boolean whether `codePoint` is a high-surrogate number. - */ -function isHighSurrogate(codePoint) { - return codePoint >= HIGH_SURROGATE_START && codePoint <= HIGH_SURROGATE_END; -} - -/** - * Checks if `codePoint` is a low-surrogate number from range 0xDC00 to 0xDFFF. - * - * @ignore - * @param {number} codePoint The code point number to be verified - * @return {boolean} Returns a boolean whether `codePoint` is a low-surrogate number. - */ -function isLowSurrogate(codePoint) { - return codePoint >= LOW_SURROGATE_START && codePoint <= LOW_SURROGATE_END; -} - -/** - * Get the astral code point number based on surrogate pair numbers. - * - * @ignore - * @param {number} highSurrogate The high-surrogate code point number. - * @param {number} lowSurrogate The low-surrogate code point number. - * @return {number} Returns the astral symbol number. - */ -function getAstralNumberFromSurrogatePair(highSurrogate, lowSurrogate) { - return (highSurrogate - HIGH_SURROGATE_START) * 0x400 + lowSurrogate - LOW_SURROGATE_START + 0x10000; -} - -/** - * Get the number representation of the `value`. - * Converts the `value` to number. - * If `value` is `null` or `undefined`, return `defaultValue`. - * - * @ignore - * @function toString - * @param {*} value The value to convert. - * @param {*} [defaultValue=''] The default value to return. - * @return {number|null} Returns the number representation of `value`. Returns `defaultValue` if `value` is - * `null` or `undefined`. - */ -function coerceToNumber(value) { - var defaultValue = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; - - if (isNil(value)) { - return defaultValue; - } - if (typeof value === 'number') { - return value; - } - return Number(value); -} - -/** - * If `value` is `NaN`, return `defaultValue`. In other case returns `value`. - * - * @ignore - * @function nanDefault - * @param {*} value The value to verify. - * @param {*} defaultValue The default value. - * @return {*} Returns `defaultValue` if `value` is `NaN`, otherwise `defaultValue`. - */ -function nanDefault(value, defaultValue) { - return value !== value ? defaultValue : value; -} - -/** - * Get the Unicode code point value of the character at `position`.
- * If a valid UTF-16 - * surrogate pair starts at `position`, the - * astral code point - * value at `position` is returned. - * - * @function codePointAt - * @static - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to extract from. - * @param {number} position The position to get the code point number. - * @return {number} Returns a non-negative number less than or equal to `0x10FFFF`. - * @example - * v.codePointAt('rain', 1); - * // => 97, or 0x0061 - * - * v.codePointAt('\uD83D\uDE00 is smile', 0); // or '😀 is smile' - * // => 128512, or 0x1F600 - */ -function codePointAt(subject, position) { - var subjectString = coerceToString(subject); - var subjectStringLength = subjectString.length; - var positionNumber = coerceToNumber(position); - positionNumber = nanDefault(positionNumber, 0); - if (positionNumber < 0 || positionNumber >= subjectStringLength) { - return undefined; - } - var firstCodePoint = subjectString.charCodeAt(positionNumber); - var secondCodePoint = void 0; - if (isHighSurrogate(firstCodePoint) && subjectStringLength > positionNumber + 1) { - secondCodePoint = subjectString.charCodeAt(positionNumber + 1); - if (isLowSurrogate(secondCodePoint)) { - return getAstralNumberFromSurrogatePair(firstCodePoint, secondCodePoint); - } - } - return firstCodePoint; -} - -/** - * Extracts the first `length` characters from `subject`. - * - * @function first - * @static - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to extract from. - * @param {int} [length=1] The number of characters to extract. - * @return {string} Returns the first characters string. - * @example - * v.first('helicopter'); - * // => 'h' - * - * v.first('vehicle', 2); - * // => 've' - * - * v.first('car', 5); - * // => 'car' - */ -function first(subject, length) { - var subjectString = coerceToString(subject); - var lengthInt = isNil(length) ? 1 : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER); - if (subjectString.length <= lengthInt) { - return subjectString; - } - return subjectString.substr(0, lengthInt); -} - -/** - * Get a grapheme from `subject` at specified `position` taking care of - * surrogate pairs and - * combining marks. - * - * @function graphemeAt - * @static - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to extract from. - * @param {number} position The position to get the grapheme. - * @return {string} Returns the grapheme at specified position. - * @example - * v.graphemeAt('\uD835\uDC00\uD835\uDC01', 0); // or '𝐀𝐁' - * // => 'A' - * - * v.graphemeAt('cafe\u0301', 3); // or 'café' - * // => 'é' - */ -function graphemeAt(subject, position) { - var subjectString = coerceToString(subject); - var positionNumber = coerceToNumber(position); - var graphemeMatch = void 0; - var graphemeMatchIndex = 0; - positionNumber = nanDefault(positionNumber, 0); - while ((graphemeMatch = REGEXP_UNICODE_CHARACTER.exec(subjectString)) !== null) { - if (graphemeMatchIndex === positionNumber) { - REGEXP_UNICODE_CHARACTER.lastIndex = 0; - return graphemeMatch[0]; - } - graphemeMatchIndex++; - } - return ''; -} - -/** - * Extracts the last `length` characters from `subject`. - * - * @function last - * @static - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to extract from. - * @param {int} [length=1] The number of characters to extract. - * @return {string} Returns the last characters string. - * @example - * v.last('helicopter'); - * // => 'r' - * - * v.last('vehicle', 2); - * // => 'le' - * - * v.last('car', 5); - * // => 'car' - */ -function last(subject, length) { - var subjectString = coerceToString(subject); - var lengthInt = isNil(length) ? 1 : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER); - if (subjectString.length <= lengthInt) { - return subjectString; - } - return subjectString.substr(subjectString.length - lengthInt, lengthInt); -} - -/** - * Truncates `subject` to a new `length` and does not break the words. Guarantees that the truncated string is no longer - * than `length`. - * - * @static - * @function prune - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to prune. - * @param {int} length The length to prune the string. - * @param {string} [end='...'] The string to be added at the end. - * @return {string} Returns the pruned string. - * @example - * v.prune('Once upon a time', 7); - * // => 'Once...' - * - * v.prune('Good day, Little Red Riding Hood', 16, ' (more)'); - * // => 'Good day (more)' - * - * v.prune('Once upon', 10); - * // => 'Once upon' - */ -function prune(subject, length, end) { - var subjectString = coerceToString(subject); - var lengthInt = isNil(length) ? subjectString.length : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER); - var endString = coerceToString(end, '...'); - if (lengthInt >= subjectString.length) { - return subjectString; - } - var pattern = REGEXP_EXTENDED_ASCII.test(subjectString) ? REGEXP_LATIN_WORD : REGEXP_WORD; - var truncatedLength = 0; - subjectString.replace(pattern, function (word, offset) { - var wordInsertLength = offset + word.length; - if (wordInsertLength <= lengthInt - endString.length) { - truncatedLength = wordInsertLength; - } - }); - return subjectString.substr(0, truncatedLength) + endString; -} - -/** - * Extracts from `subject` a string from `start` position up to `end` position. The character at `end` position is not - * included. - * - * @function slice - * @static - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to extract from. - * @param {number} start The position to start extraction. If negative use `subject.length + start`. - * @param {number} [end=subject.length] The position to end extraction. If negative use `subject.length + end`. - * @return {string} Returns the extracted string. - * @note Uses native `String.prototype.slice()` - * @example - * v.slice('miami', 1); - * // => 'iami' - * - * v.slice('florida', -4); - * // => 'rida' - * - * v.slice('florida', 1, 4); - * // => "lor" - */ -function slice(subject, start, end) { - return coerceToString(subject).slice(start, end); -} - -/** - * Extracts from `subject` a string from `start` position a number of `length` characters. - * - * @function substr - * @static - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to extract from. - * @param {number} start The position to start extraction. - * @param {number} [length=subject.endOfString] The number of characters to extract. If omitted, extract to the end of `subject`. - * @return {string} Returns the extracted string. - * @note Uses native `String.prototype.substr()` - * @example - * v.substr('infinite loop', 9); - * // => 'loop' - * - * v.substr('dreams', 2, 2); - * // => 'ea' - */ -function substr(subject, start, length) { - return coerceToString(subject).substr(start, length); -} - -/** - * Extracts from `subject` a string from `start` position up to `end` position. The character at `end` position is not - * included. - * - * @function substring - * @static - * @since 1.0.0 - * @memberOf Chop - * @param {string} [subject=''] The string to extract from. - * @param {number} start The position to start extraction. - * @param {number} [end=subject.length] The position to end extraction. - * @return {string} Returns the extracted string. - * @note Uses native `String.prototype.substring()` - * @example - * v.substring('beach', 1); - * // => 'each' - * - * v.substring('ocean', 1, 3); - * // => 'ea' - */ -function substring(subject, start, end) { - return coerceToString(subject).substring(start, end); -} - -/** - * Counts the characters in `subject`.
- * - * @function count - * @static - * @since 1.0.0 - * @memberOf Count - * @param {string} [subject=''] The string to count characters. - * @return {number} Returns the number of characters in `subject`. - * @example - * v.count('rain'); - * // => 4 - */ -function count(subject) { - return coerceToString(subject).length; -} - -/** - * Counts the graphemes in `subject` taking care of - * surrogate pairs and - * combining marks. - * - * @function countGraphemes - * @static - * @since 1.0.0 - * @memberOf Count - * @param {string} [subject=''] The string to count graphemes. - * @return {number} Returns the number of graphemes in `subject`. - * @example - * v.countGraphemes('cafe\u0301'); // or 'café' - * // => 4 - * - * v.countGraphemes('\uD835\uDC00\uD835\uDC01'); // or '𝐀𝐁' - * // => 2 - * - * v.countGraphemes('rain'); - * // => 4 - */ -function countGrapheme(subject) { - return coerceToString(subject).replace(REGEXP_COMBINING_MARKS, '*').replace(REGEXP_SURROGATE_PAIRS, '*').length; -} - -/** - * Counts the number of `substring` appearances in `subject`. - * - * @function countSubstrings - * @static - * @since 1.0.0 - * @memberOf Count - * @param {string} [subject=''] The string where to count. - * @param {string} substring The substring to be counted. - * @return {number} Returns the number of `substring` appearances. - * @example - * v.countSubstrings('bad boys, bad boys whatcha gonna do?', 'boys'); - * // => 2 - * - * v.countSubstrings('every dog has its day', 'cat'); - * // => 0 - */ -function countSubstrings(subject, substring) { - var subjectString = coerceToString(subject); - var substringString = coerceToString(substring); - var substringLength = substringString.length; - var count = 0; - var matchIndex = 0; - if (subjectString === '' || substringString === '') { - return count; - } - do { - matchIndex = subjectString.indexOf(substringString, matchIndex); - if (matchIndex !== -1) { - count++; - matchIndex += substringLength; - } - } while (matchIndex !== -1); - return count; -} - -var reduce = Array.prototype.reduce; - -/** - * Counts the characters in `subject` for which `predicate` returns truthy. - * - * @function countWhere - * @static - * @since 1.0.0 - * @memberOf Count - * @param {string} [subject=''] The string to count characters. - * @param {Function} predicate The predicate function invoked on each character with parameters `(character, index, string)`. - * @param {Object} [context] The context to invoke the `predicate`. - * @return {number} Returns the number of characters for which `predicate` returns truthy. - * @example - * v.countWhere('hola!', v.isAlpha); - * // => 4 - * - * v.countWhere('2022', function(character, index, str) { - * return character === '2'; - * }); - * // => 3 - */ -function countWhere(subject, predicate, context) { - var subjectString = coerceToString(subject); - if (subjectString === '' || typeof predicate !== 'function') { - return 0; - } - var predicateWithContext = predicate.bind(context); - return reduce.call(subjectString, function (countTruthy, character, index) { - return predicateWithContext(character, index, subjectString) ? countTruthy + 1 : countTruthy; - }, 0); -} - -/** - * Counts the number of words in `subject`. - * - * @function countWords - * @static - * @since 1.0.0 - * @memberOf Count - * @param {string} [subject=''] The string to split into words. - * @param {string|RegExp} [pattern] The pattern to watch words. If `pattern` is not RegExp, it is transformed to `new RegExp(pattern, flags)`. - * @param {string} [flags=''] The regular expression flags. Applies when `pattern` is string type. - * @return {number} Returns the number of words. - * @example - * v.countWords('gravity can cross dimensions'); - * // => 4 - * - * v.countWords('GravityCanCrossDimensions'); - * // => 4 - * - * v.countWords('Gravity - can cross dimensions!'); - * // => 4 - * - * v.words('Earth gravity', /[^\s]+/g); - * // => 2 - */ -function countWords(subject, pattern, flags) { - return words(subject, pattern, flags).length; -} - -/** - * The current index. - * - * @ignore - * @name ReplacementIndex#index - * @type {number} - * @return {ReplacementIndex} ReplacementIndex instance. - */ -function ReplacementIndex() { - this.index = 0; -} - -/** - * Increment the current index. - * - * @ignore - * @return {undefined} - */ -ReplacementIndex.prototype.increment = function () { - this.index++; -}; - -/** - * Increment the current index by position. - * - * @ignore - * @param {number} [position] The replacement position. - * @return {undefined} - */ -ReplacementIndex.prototype.incrementOnEmptyPosition = function (position) { - if (isNil(position)) { - this.increment(); - } -}; - -/** - * Get the replacement index by position. - * - * @ignore - * @param {number} [position] The replacement position. - * @return {number} The replacement index. - */ -ReplacementIndex.prototype.getIndexByPosition = function (position) { - return isNil(position) ? this.index : position - 1; -}; - -var Const = Object.freeze({ - // Type specifiers - TYPE_INTEGER: 'i', - TYPE_INTEGER_BINARY: 'b', - TYPE_INTEGER_ASCII_CHARACTER: 'c', - TYPE_INTEGER_DECIMAL: 'd', - TYPE_INTEGER_OCTAL: 'o', - TYPE_INTEGER_UNSIGNED_DECIMAL: 'u', - TYPE_INTEGER_HEXADECIMAL: 'x', - TYPE_INTEGER_HEXADECIMAL_UPPERCASE: 'X', - TYPE_FLOAT_SCIENTIFIC: 'e', - TYPE_FLOAT_SCIENTIFIC_UPPERCASE: 'E', - TYPE_FLOAT: 'f', - TYPE_FLOAT_SHORT: 'g', - TYPE_FLOAT_SHORT_UPPERCASE: 'G', - TYPE_STRING: 's', - - // Simple literals - LITERAL_PERCENT: '%', - LITERAL_SINGLE_QUOTE: "'", - LITERAL_PLUS: '+', - LITERAL_MINUS: '-', - LITERAL_PERCENT_SPECIFIER: '%%', - - // Radix constants to format numbers - RADIX_BINARY: 2, - RADIX_OCTAL: 8, - RADIX_DECIMAL: 10, - RADIX_HEXADECIMAL: 16 -}); - -/** - * Repeats the `subject` number of `times`. - * - * @function repeat - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to repeat. - * @param {number} [times=1] The number of times to repeat. - * @return {string} Returns the repeated string. - * @example - * v.repeat('w', 3); - * // => 'www' - * - * v.repeat('world', 0); - * // => '' - */ -function repeat(subject, times) { - var subjectString = coerceToString(subject); - var timesInt = isNil(times) ? 1 : clipNumber(toInteger(times), 0, MAX_SAFE_INTEGER); - var repeatString = ''; - while (timesInt) { - if (timesInt & 1) { - repeatString += subjectString; - } - if (timesInt > 1) { - subjectString += subjectString; - } - timesInt >>= 1; - } - return repeatString; -} - -/** - * Creates the padding string. - * - * @ignore - * @param {string} padCharacters The characters to create padding string. - * @param {number} length The padding string length. - * @return {string} The padding string. - */ -function buildPadding(padCharacters, length) { - var padStringRepeat = toInteger(length / padCharacters.length); - var padStringRest = length % padCharacters.length; - return repeat(padCharacters, padStringRepeat + padStringRest).substr(0, length); -} - -/** - * Pads `subject` from left to a new `length`. - * - * @function padLeft - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to pad. - * @param {int} [length=0] The length to left pad the string. No changes are made if `length` is less than `subject.length`. - * @param {string} [pad=' '] The string to be used for padding. - * @return {string} Returns the left padded string. - * @example - * v.padLeft('dog', 5); - * // => ' dog' - * - * v.padLeft('bird', 6, '-'); - * // => '--bird' - * - * v.padLeft('cat', 6, '-='); - * // => '-=-cat' - */ -function padLeft(subject, length, pad) { - var subjectString = coerceToString(subject); - var lengthInt = isNil(length) ? 0 : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER); - var padString = coerceToString(pad, ' '); - if (lengthInt <= subjectString.length) { - return subjectString; - } - return buildPadding(padString, lengthInt - subjectString.length) + subjectString; -} - -/** - * Pads `subject` from right to a new `length`. - * - * @function padRight - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to pad. - * @param {int} [length=0] The length to right pad the string. No changes are made if `length` is less than `subject.length`. - * @param {string} [pad=' '] The string to be used for padding. - * @return {string} Returns the right padded string. - * @example - * v.padRight('dog', 5); - * // => 'dog ' - * - * v.padRight('bird', 6, '-'); - * // => 'bird--' - * - * v.padRight('cat', 6, '-='); - * // => 'cat-=-' - */ -function padRight(subject, length, pad) { - var subjectString = coerceToString(subject); - var lengthInt = isNil(length) ? 0 : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER); - var padString = coerceToString(pad, ' '); - if (lengthInt <= subjectString.length) { - return subjectString; - } - return subjectString + buildPadding(padString, lengthInt - subjectString.length); -} - -/** - * Aligns and pads `subject` string. - * - * @ignore - * @param {string} subject The subject string. - * @param {ConversionSpecification} conversion The conversion specification object. - * @return {string} Returns the aligned and padded string. - */ -function alignAndPad(subject, conversion) { - var width = conversion.width; - if (isNil(width) || subject.length >= width) { - return subject; - } - var padType = conversion.alignmentSpecifier === Const.LITERAL_MINUS ? padRight : padLeft; - return padType(subject, width, conversion.getPaddingCharacter()); -} - -/** - * Add sign to the formatted number. - * - * @ignore - * @name addSignToFormattedNumber - * @param {number} replacementNumber The number to be replaced. - * @param {string} formattedReplacement The formatted version of number. - * @param {ConversionSpecification} conversion The conversion specification object. - * @return {string} Returns the formatted number string with a sign. - */ -function addSignToFormattedNumber(replacementNumber, formattedReplacement, conversion) { - if (conversion.signSpecifier === Const.LITERAL_PLUS && replacementNumber >= 0) { - formattedReplacement = Const.LITERAL_PLUS + formattedReplacement; - } - return formattedReplacement; -} - -/** - * Formats a float type according to specifiers. - * - * @ignore - * @param {string} replacement The string to be formatted. - * @param {ConversionSpecification} conversion The conversion specification object. - * @return {string} Returns the formatted string. - */ - -function float(replacement, conversion) { - var replacementNumber = parseFloat(replacement); - var formattedReplacement = void 0; - if (isNaN(replacementNumber)) { - replacementNumber = 0; - } - var precision = coerceToNumber(conversion.precision, 6); - switch (conversion.typeSpecifier) { - case Const.TYPE_FLOAT: - formattedReplacement = replacementNumber.toFixed(precision); - break; - case Const.TYPE_FLOAT_SCIENTIFIC: - formattedReplacement = replacementNumber.toExponential(precision); - break; - case Const.TYPE_FLOAT_SCIENTIFIC_UPPERCASE: - formattedReplacement = replacementNumber.toExponential(precision).toUpperCase(); - break; - case Const.TYPE_FLOAT_SHORT: - case Const.TYPE_FLOAT_SHORT_UPPERCASE: - formattedReplacement = formatFloatAsShort(replacementNumber, precision, conversion); - break; - } - formattedReplacement = addSignToFormattedNumber(replacementNumber, formattedReplacement, conversion); - return coerceToString(formattedReplacement); -} - -/** - * Formats the short float. - * - * @ignore - * @param {number} replacementNumber The number to format. - * @param {number} precision The precision to format the float. - * @param {ConversionSpecification} conversion The conversion specification object. - * @return {string} Returns the formatted short float. - */ -function formatFloatAsShort(replacementNumber, precision, conversion) { - if (replacementNumber === 0) { - return '0'; - } - var nonZeroPrecision = precision === 0 ? 1 : precision; - var formattedReplacement = replacementNumber.toPrecision(nonZeroPrecision).replace(REGEXP_TRAILING_ZEROS, ''); - if (conversion.typeSpecifier === Const.TYPE_FLOAT_SHORT_UPPERCASE) { - formattedReplacement = formattedReplacement.toUpperCase(); - } - return formattedReplacement; -} - -/** - * Formats an integer type according to specifiers. - * - * @ignore - * @param {string} replacement The string to be formatted. - * @param {ConversionSpecification} conversion The conversion specification object. - * @return {string} Returns the formatted string. - */ - -function integerBase(replacement, conversion) { - var integer = parseInt(replacement); - if (isNaN(integer)) { - integer = 0; - } - integer = integer >>> 0; - switch (conversion.typeSpecifier) { - case Const.TYPE_INTEGER_ASCII_CHARACTER: - integer = String.fromCharCode(integer); - break; - case Const.TYPE_INTEGER_BINARY: - integer = integer.toString(Const.RADIX_BINARY); - break; - case Const.TYPE_INTEGER_OCTAL: - integer = integer.toString(Const.RADIX_OCTAL); - break; - case Const.TYPE_INTEGER_HEXADECIMAL: - integer = integer.toString(Const.RADIX_HEXADECIMAL); - break; - case Const.TYPE_INTEGER_HEXADECIMAL_UPPERCASE: - integer = integer.toString(Const.RADIX_HEXADECIMAL).toUpperCase(); - break; - } - return coerceToString(integer); -} - -/** - * Formats a decimal integer type according to specifiers. - * - * @ignore - * @param {string} replacement The string to be formatted. - * @param {ConversionSpecification} conversion The conversion specification object. - * @return {string} Returns the formatted string. - */ - -function integerDecimal(replacement, conversion) { - var integer = parseInt(replacement); - if (isNaN(integer)) { - integer = 0; - } - return addSignToFormattedNumber(integer, toString(integer), conversion); -} - -/** - * Formats a string type according to specifiers. - * - * @ignore - * @param {string} replacement The string to be formatted. - * @param {ConversionSpecification} conversion The conversion specification object. - * @return {string} Returns the formatted string. - */ -function stringFormat(replacement, conversion) { - var formattedReplacement = replacement; - var precision = conversion.precision; - if (!isNil(precision) && formattedReplacement.length > precision) { - formattedReplacement = truncate(formattedReplacement, precision, ''); - } - return formattedReplacement; -} - -/** - * Returns the computed string based on format specifiers. - * - * @ignore - * @name computeReplacement - * @param {string} replacement The replacement value. - * @param {ConversionSpecification} conversion The conversion specification object. - * @return {string} Returns the computed string. - */ -function compute(replacement, conversion) { - var formatFunction = void 0; - switch (conversion.typeSpecifier) { - case Const.TYPE_STRING: - formatFunction = stringFormat; - break; - case Const.TYPE_INTEGER_DECIMAL: - case Const.TYPE_INTEGER: - formatFunction = integerDecimal; - break; - case Const.TYPE_INTEGER_ASCII_CHARACTER: - case Const.TYPE_INTEGER_BINARY: - case Const.TYPE_INTEGER_OCTAL: - case Const.TYPE_INTEGER_HEXADECIMAL: - case Const.TYPE_INTEGER_HEXADECIMAL_UPPERCASE: - case Const.TYPE_INTEGER_UNSIGNED_DECIMAL: - formatFunction = integerBase; - break; - case Const.TYPE_FLOAT: - case Const.TYPE_FLOAT_SCIENTIFIC: - case Const.TYPE_FLOAT_SCIENTIFIC_UPPERCASE: - case Const.TYPE_FLOAT_SHORT: - case Const.TYPE_FLOAT_SHORT_UPPERCASE: - formatFunction = float; - break; - } - var formattedString = formatFunction(replacement, conversion); - return alignAndPad(formattedString, conversion); -} - -/** - * Construct the new conversion specification object. - * - * @ignore - * @param {Object} properties An object with properties to initialize. - * @return {ConversionSpecification} ConversionSpecification instance. - */ -function ConversionSpecification(properties) { - - /** - * The percent characters from conversion specification. - * - * @ignore - * @name ConversionSpecification#percent - * @type {string} - */ - this.percent = properties.percent; - - /** - * The sign specifier to force a sign to be used on a number. - * - * @ignore - * @name ConversionSpecification#signSpecifier - * @type {string} - */ - this.signSpecifier = properties.signSpecifier; - - /** - * The padding specifier that says what padding character will be used. - * - * @ignore - * @name ConversionSpecification#paddingSpecifier - * @type {string} - */ - this.paddingSpecifier = properties.paddingSpecifier; - - /** - * The alignment specifier that says if the result should be left-justified or right-justified. - * - * @ignore - * @name ConversionSpecification#alignmentSpecifier - * @type {string} - */ - this.alignmentSpecifier = properties.alignmentSpecifier; - - /** - * The width specifier how many characters this conversion should result in. - * - * @ignore - * @name ConversionSpecification#width - * @type {number} - */ - this.width = properties.width; - - /** - * The precision specifier says how many decimal digits should be displayed for floating-point numbers. - * - * @ignore - * @name ConversionSpecification#precision - * @type {number} - */ - this.precision = properties.precision; - - /** - * The type specifier says what type the argument data should be treated as. - * - * @ignore - * @name ConversionSpecification#typeSpecifier - * @type {string} - */ - this.typeSpecifier = properties.typeSpecifier; -} - -/** - * Check if the conversion specification is a percent literal "%%". - * - * @ignore - * @return {boolean} Returns true if the conversion is a percent literal, false otherwise. - */ -ConversionSpecification.prototype.isPercentLiteral = function () { - return Const.LITERAL_PERCENT_SPECIFIER === this.percent; -}; - -/** - * Get the padding character from padding specifier. - * - * @ignore - * @returns {string} Returns the padding character. - */ -ConversionSpecification.prototype.getPaddingCharacter = function () { - var paddingCharacter = nilDefault(this.paddingSpecifier, ' '); - if (paddingCharacter.length === 2 && paddingCharacter[0] === Const.LITERAL_SINGLE_QUOTE) { - paddingCharacter = paddingCharacter[1]; - } - return paddingCharacter; -}; - -/** - * Validates the specifier type and replacement position. - * - * @ignore - * @throws {Error} Throws an exception on insufficient arguments or unknown specifier. - * @param {number} index The index of the matched specifier. - * @param {number} replacementsLength The number of replacements. - * @param {ConversionSpecification} conversion The conversion specification object. - * @return {undefined} - */ -function validate(index, replacementsLength, conversion) { - if (isNil(conversion.typeSpecifier)) { - throw new Error('sprintf(): Unknown type specifier'); - } - if (index > replacementsLength - 1) { - throw new Error('sprintf(): Too few arguments'); - } - if (index < 0) { - throw new Error('sprintf(): Argument number must be greater than zero'); - } -} - -/** - * Return the replacement for regular expression match of the conversion specification. - * - * @ignore - * @name matchReplacement - * @param {ReplacementIndex} replacementIndex The replacement index object. - * @param {string[]} replacements The array of replacements. - * @param {string} conversionSpecification The conversion specification. - * @param {string} percent The percent characters from conversion specification. - * @param {string} position The position to insert the replacement. - * @param {string} signSpecifier The sign specifier to force a sign to be used on a number. - * @param {string} paddingSpecifier The padding specifier that says what padding character will be used. - * @param {string} alignmentSpecifier The alignment specifier that says if the result should be left-justified or right-justified. - * @param {string} widthSpecifier The width specifier how many characters this conversion should result in. - * @param {string} precisionSpecifier The precision specifier says how many decimal digits should be displayed for floating-point numbers. - * @param {string} typeSpecifier The type specifier says what type the argument data should be treated as. - * @return {string} Returns the computed replacement. - */ -function match(replacementIndex, replacements, conversionSpecification, percent, position, signSpecifier, paddingSpecifier, alignmentSpecifier, widthSpecifier, precisionSpecifier, typeSpecifier) { - var conversion = new ConversionSpecification({ - percent: percent, - signSpecifier: signSpecifier, - paddingSpecifier: paddingSpecifier, - alignmentSpecifier: alignmentSpecifier, - width: coerceToNumber(widthSpecifier, null), - precision: coerceToNumber(precisionSpecifier, null), - typeSpecifier: typeSpecifier - }); - if (conversion.isPercentLiteral()) { - return conversionSpecification.slice(1); - } - var actualReplacementIndex = replacementIndex.getIndexByPosition(position); - replacementIndex.incrementOnEmptyPosition(position); - validate(actualReplacementIndex, replacements.length, conversion); - return compute(replacements[actualReplacementIndex], conversion); -} - -/** - * Produces a string according to `format`. - * - *
- * `format` string is composed of zero or more directives: ordinary characters (not %), which are copied unchanged - * to the output string and conversion specifications, each of which results in fetching zero or more subsequent - * arguments.

- * - * Each conversion specification is introduced by the character %, and ends with a conversion - * specifier. In between there may be (in this order) zero or more flags, an optional minimum field width - * and an optional precision.
- * The syntax is: ConversionSpecification = "%" { Flags } - * [ MinimumFieldWidth ] [ Precision ] ConversionSpecifier, where curly braces { } denote repetition - * and square brackets [ ] optionality.

- * - * By default, the arguments are used in the given order.
- * For argument numbering and swapping, `%m$` (where `m` is a number indicating the argument order) - * is used instead of `%` to specify explicitly which argument is taken. For instance `%1$s` fetches the 1st argument, - * `%2$s` the 2nd and so on, no matter what position the conversion specification has in `format`. - *

- * - * The flags
- * The character % is followed by zero or more of the following flags:
- * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
+ - * A sign (+ or -) should always be placed before a number produced by a - * signed conversion. By default a sign is used only for negative numbers. - *
0The value should be zero padded.
(a space) The value should be space padded.
'Indicates alternate padding character, specified by prefixing it with a single quote '.
-The converted value is to be left adjusted on the field boundary (the default is right justification).
- * - * The minimum field width
- * An optional decimal digit string (with nonzero first digit) specifying a minimum field width. If the converted - * value has fewer characters than the field width, it will be padded with spaces on the left (or right, if the - * left-adjustment flag has been given).

- * - * The precision
- * An optional precision, in the form of a period `.` followed by an optional decimal digit string.
- * This gives the number of digits to appear after the radix character for `e`, `E`, `f` and `F` conversions, the - * maximum number of significant digits for `g` and `G` conversions or the maximum number of characters to be printed - * from a string for `s` conversion.

- * - * The conversion specifier
- * A specifier that mentions what type the argument should be treated as: - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
`s`The string argument is treated as and presented as a string.
`d` `i`The integer argument is converted to signed decimal notation.
`b`The unsigned integer argument is converted to unsigned binary.
`c`The unsigned integer argument is converted to an ASCII character with that number.
`o`The unsigned integer argument is converted to unsigned octal.
`u`The unsigned integer argument is converted to unsigned decimal.
`x` `X`The unsigned integer argument is converted to unsigned hexadecimal. The letters `abcdef` are used for `x` - * conversions; the letters `ABCDEF` are used for `X` conversions.
`f` - * The float argument is rounded and converted to decimal notation in the style `[-]ddd.ddd`, where the number of - * digits after the decimal-point character is equal to the precision specification. If the precision is missing, - * it is taken as 6; if the precision is explicitly zero, no decimal-point character appears. - * If a decimal point appears, at least one digit appears before it. - *
`e` `E` - * The float argument is rounded and converted in the style `[-]d.ddde±dd`, where there is one digit - * before the decimal-point character and the number of digits after it is equal to the precision. If - * the precision is missing, it is taken as `6`; if the precision is zero, no decimal-point character - * appears. An `E` conversion uses the letter `E` (rather than `e`) to introduce the exponent. - *
`g` `G` - * The float argument is converted in style `f` or `e` (or `F` or `E` for `G` conversions). The precision specifies - * the number of significant digits. If the precision is missing, `6` digits are given; if the - * precision is zero, it is treated as `1`. Style `e` is used if the exponent from its conversion is less - * than `-6` or greater than or equal to the precision. Trailing zeros are removed from the fractional - * part of the result; a decimal point appears only if it is followed by at least one digit. - *
`%`A literal `%` is written. No argument is converted. The complete conversion specification is `%%`.
- *
- * - * @function sprintf - * @static - * @since 1.0.0 - * @memberOf Format - * @param {string} [format=''] The format string. - * @param {...*} replacements The replacements to produce the string. - * @return {string} Returns the produced string. - * @example - * v.sprintf('%s, %s!', 'Hello', 'World'); - * // => 'Hello World!' - * - * v.sprintf('%s costs $%d', 'coffee', 2); - * // => 'coffee costs $2' - * - * v.sprintf('%1$s %2$s %1$s %2$s, watcha gonna %3$s', 'bad', 'boys', 'do') - * // => 'bad boys bad boys, watcha gonna do' - * - * v.sprintf('% 6s', 'bird'); - * // => ' bird' - * - * v.sprintf('% -6s', 'crab'); - * // => 'crab ' - * - * v.sprintf("%'*5s", 'cat'); - * // => '**cat' - * - * v.sprintf("%'*-6s", 'duck'); - * // => 'duck**' - * - * v.sprintf('%d %i %+d', 15, -2, 25); - * // => '15 -2 +25' - * - * v.sprintf("%06d", 15); - * // => '000015' - * - * v.sprintf('0b%b 0o%o 0x%X', 12, 9, 155); - * // => '0b1100 0o11 0x9B' - * - * v.sprintf('%.2f', 10.469); - * // => '10.47' - * - * v.sprintf('%.2e %g', 100.5, 0.455); - * // => '1.01e+2 0.455' - * - */ -function sprintf(format) { - var formatString = coerceToString(format); - if (formatString === '') { - return formatString; - } - - for (var _len = arguments.length, replacements = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - replacements[_key - 1] = arguments[_key]; - } - - var boundReplacementMatch = match.bind(undefined, new ReplacementIndex(), replacements); - return formatString.replace(REGEXP_CONVERSION_SPECIFICATION, boundReplacementMatch); -} - -function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } - -/** - * Produces a string according to `format`. Works exactly like sprintf(), - * with the only difference that accepts the formatting arguments in an array `values`.
- * See here `format` string specifications. - * - * @function vprintf - * @static - * @since 1.0.0 - * @memberOf Format - * @param {string} format=''] The format string. - * @param {Array} replacements The array of replacements to produce the string. - * @return {string} Returns the produced string. - * @example - * v.vprintf('%s', ['Welcome']) - * // => 'Welcome' - * - * v.vprintf('%s has %d apples', ['Alexandra', 3]); - * // => 'Alexandra has 3 apples' - */ -function vprintf(format, replacements) { - return sprintf.apply(undefined, [format].concat(_toConsumableArray(nilDefault(replacements, [])))); -} - -var escapeCharactersMap = { - '<': '<', - '>': '>', - '&': '&', - '"': '"', - "'": ''', - '`': '`' -}; - -/** - * Return the escaped version of `character`. - * - * @ignore - * @param {string} character The character to be escape. - * @return {string} The escaped version of character. - */ -function replaceSpecialCharacter(character) { - return escapeCharactersMap[character]; -} - -/** - * Escapes HTML special characters < > & ' " ` in subject. - * - * @function escapeHtml - * @static - * @since 1.0.0 - * @memberOf Escape - * @param {string} [subject=''] The string to escape. - * @return {string} Returns the escaped string. - * @example - * v.escapeHtml('

wonderful world

'); - * // => '<p>wonderful world</p>' - */ -function escapeHtml(subject) { - return coerceToString(subject).replace(REGEXP_HTML_SPECIAL_CHARACTERS, replaceSpecialCharacter); -} - -/** - * Escapes the regular expression special characters `- [ ] / { } ( ) * + ? . \ ^ $ |` in `subject`. - * - * @function escapeRegExp - * @static - * @since 1.0.0 - * @memberOf Escape - * @param {string} [subject=''] The string to escape. - * @return {string} Returns the escaped string. - * @example - * v.escapeRegExp('(hours)[minutes]{seconds}'); - * // => '\(hours\)\[minutes\]\{seconds\}' - */ -function escapeRegExp(subject) { - return coerceToString(subject).replace(REGEXP_SPECIAL_CHARACTERS, '\\$&'); -} - -var unescapeCharactersMap = { - '<': /(<)|(�*3c;)|(�*60;)/gi, - '>': /(>)|(�*3e;)|(�*62;)/gi, - '&': /(&)|(�*26;)|(�*38;)/gi, - '"': /(")|(�*22;)|(�*34;)/gi, - "'": /(�*27;)|(�*39;)/gi, - '`': /(�*60;)|(�*96;)/gi -}; -var characters = Object.keys(unescapeCharactersMap); - -/** - * Replaces the HTML entities with corresponding characters. - * - * @ignore - * @param {string} string The accumulator string. - * @param {string} key The character. - * @return {string} The string with replaced HTML entity - */ -function reduceUnescapedString(string, key) { - return string.replace(unescapeCharactersMap[key], key); -} - -/** - * Unescapes HTML special characters from &lt; &gt; &amp; &quot; &#x27; &#x60; - * to corresponding < > & ' " ` in subject. - * - * @function unescapeHtml - * @static - * @since 1.0.0 - * @memberOf Escape - * @param {string} [subject=''] The string to unescape. - * @return {string} Returns the unescaped string. - * @example - * v.unescapeHtml('<p>wonderful world</p>'); - * // => '

wonderful world

' - */ -function unescapeHtml(subject) { - var subjectString = coerceToString(subject); - return characters.reduce(reduceUnescapedString, subjectString); -} - -/** - * Returns the first occurrence index of `search` in `subject`. - * - * @function indexOf - * @static - * @since 1.0.0 - * @memberOf Index - * @param {string} [subject=''] The string where to search. - * @param {string} search The string to search. - * @param {number} [fromIndex=0] The index to start searching. - * @return {number} Returns the first occurrence index or `-1` if not found. - * @example - * v.indexOf('morning', 'n'); - * // => 3 - * - * v.indexOf('evening', 'o'); - * // => -1 - */ -function indexOf(subject, search, fromIndex) { - var subjectString = coerceToString(subject); - return subjectString.indexOf(search, fromIndex); -} - -/** - * Returns the last occurrence index of `search` in `subject`. - * - * @function lastIndexOf - * @static - * @since 1.0.0 - * @memberOf Index - * @param {string} [subject=''] The string where to search. - * @param {string} search The string to search. - * @param {number} [fromIndex=subject.length - 1] The index to start searching backward in the string. - * @return {number} Returns the last occurrence index or `-1` if not found. - * @example - * v.lastIndexOf('morning', 'n'); - * // => 5 - * - * v.lastIndexOf('evening', 'o'); - * // => -1 - */ -function lastIndexOf(subject, search, fromIndex) { - var subjectString = coerceToString(subject); - return subjectString.lastIndexOf(search, fromIndex); -} - -/** - * Returns the first index of a `pattern` match in `subject`. - * - * @function search - * @static - * @since 1.0.0 - * @memberOf Index - * @param {string} [subject=''] The string where to search. - * @param {string|RegExp} pattern The pattern to match. If `pattern` is not RegExp, it is transformed to `new RegExp(pattern)`. - * @param {number} [fromIndex=0] The index to start searching. - * @return {number} Returns the first match index or `-1` if not found. - * @example - * v.search('morning', /rn/); - * // => 2 - * - * v.search('evening', '/\d/'); - * // => -1 - */ -function search(subject, pattern, fromIndex) { - var subjectString = coerceToString(subject); - var fromIndexNumber = isNil(fromIndex) ? 0 : clipNumber(toInteger(fromIndex), 0, subjectString.length); - var matchIndex = subjectString.substr(fromIndexNumber).search(pattern); - if (matchIndex !== -1 && !isNaN(fromIndexNumber)) { - matchIndex += fromIndexNumber; - } - return matchIndex; -} - -/** - * Inserts into `subject` a string `toInsert` at specified `position`. - * - * @function insert - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string where to insert. - * @param {string} [toInsert=''] The string to be inserted. - * @param {number} [position=0] The position to insert. - * @return {string} Returns the string after insertion. - * @example - * v.insert('ct', 'a', 1); - * // => 'cat' - * - * v.insert('sunny', ' day', 5); - * // => 'sunny day' - */ -function insert(subject, toInsert, position) { - var subjectString = coerceToString(subject); - var toInsertString = coerceToString(toInsert); - var positionNumber = coerceToNumber(position); - if (positionNumber < 0 || positionNumber > subjectString.length || toInsertString === '') { - return subjectString; - } - return subjectString.slice(0, positionNumber) + toInsertString + subjectString.slice(positionNumber); -} - -/** - * Generated diacritics map. See bellow the base code. - * @ignore - * @see http://stackoverflow.com/a/18391901/1894471 - * @type Object - */ - -var diacritics = { - "3": "\u039e\u03be", - "8": "\u0398\u03b8", - "A": "\x41\xc0\xc1\xc2\xc3\xc4\xc5\u0100\u0102\u0104\u01cd\u01de\u01e0\u01fa\u0200\u0202\u0226\u023a\u1e00\u1ea0\u1ea2\u1ea4\u1ea6\u1ea8\u1eaa\u1eac\u1eae\u1eb0\u1eb2\u1eb4\u1eb6\u24b6\u2c6f\uff21\u0386\u0391\u0410", - "B": "\x42\u0181\u0182\u0243\u1e02\u1e04\u1e06\u24b7\uff22\u0392\u0411", - "C": "\x43\xc7\u0106\u0108\u010a\u010c\u0187\u023b\u1e08\u24b8\ua73e\uff23\u0426", - "D": "\x44\u010e\u0110\u0189\u018a\u018b\u1e0a\u1e0c\u1e0e\u1e10\u1e12\u24b9\ua779\uff24\xd0\u0394\u0414", - "E": "\x45\xc8\xc9\xca\xcb\u0112\u0114\u0116\u0118\u011a\u018e\u0190\u0204\u0206\u0228\u1e14\u1e16\u1e18\u1e1a\u1e1c\u1eb8\u1eba\u1ebc\u1ebe\u1ec0\u1ec2\u1ec4\u1ec6\u24ba\uff25\u0388\u0395\u0415\u042d", - "F": "\x46\u0191\u1e1e\u24bb\ua77b\uff26\u03a6\u0424", - "G": "\x47\u011c\u011e\u0120\u0122\u0193\u01e4\u01e6\u01f4\u1e20\u24bc\ua77d\ua77e\ua7a0\uff27\u0393\u0413\u0490", - "H": "\x48\u0124\u0126\u021e\u1e22\u1e24\u1e26\u1e28\u1e2a\u24bd\u2c67\u2c75\ua78d\uff28\u0389\u0397\u0425", - "I": "\x49\xcc\xcd\xce\xcf\u0128\u012a\u012c\u012e\u0130\u0197\u01cf\u0208\u020a\u1e2c\u1e2e\u1ec8\u1eca\u24be\uff29\u038a\u0399\u03aa\u0406\u0418", - "J": "\x4a\u0134\u0248\u24bf\uff2a\u0419", - "K": "\x4b\u0136\u0198\u01e8\u1e30\u1e32\u1e34\u24c0\u2c69\ua740\ua742\ua744\ua7a2\uff2b\u039a\u041a", - "L": "\x4c\u0139\u013b\u013d\u013f\u0141\u023d\u1e36\u1e38\u1e3a\u1e3c\u24c1\u2c60\u2c62\ua746\ua748\ua780\uff2c\u039b\u041b", - "M": "\x4d\u019c\u1e3e\u1e40\u1e42\u24c2\u2c6e\uff2d\u039c\u041c", - "N": "\x4e\xd1\u0143\u0145\u0147\u019d\u01f8\u0220\u1e44\u1e46\u1e48\u1e4a\u24c3\ua790\ua7a4\uff2e\u039d\u041d", - "O": "\x4f\xd2\xd3\xd4\xd5\xd6\xd8\u014c\u014e\u0150\u0186\u019f\u01a0\u01d1\u01ea\u01ec\u01fe\u020c\u020e\u022a\u022c\u022e\u0230\u1e4c\u1e4e\u1e50\u1e52\u1ecc\u1ece\u1ed0\u1ed2\u1ed4\u1ed6\u1ed8\u1eda\u1edc\u1ede\u1ee0\u1ee2\u24c4\ua74a\ua74c\uff2f\u038c\u039f\u041e", - "P": "\x50\u01a4\u1e54\u1e56\u24c5\u2c63\ua750\ua752\ua754\uff30\u03a0\u041f", - "Q": "\x51\u024a\u24c6\ua756\ua758\uff31", - "R": "\x52\u0154\u0156\u0158\u0210\u0212\u024c\u1e58\u1e5a\u1e5c\u1e5e\u24c7\u2c64\ua75a\ua782\ua7a6\uff32\u03a1\u0420", - "S": "\x53\u015a\u015c\u015e\u0160\u0218\u1e60\u1e62\u1e64\u1e66\u1e68\u1e9e\u24c8\u2c7e\ua784\ua7a8\uff33\u03a3\u0421", - "T": "\x54\u0162\u0164\u0166\u01ac\u01ae\u021a\u023e\u1e6a\u1e6c\u1e6e\u1e70\u24c9\ua786\uff34\u03a4\u0422", - "U": "\x55\xd9\xda\xdb\xdc\u0168\u016a\u016c\u016e\u0170\u0172\u01af\u01d3\u01d5\u01d7\u01d9\u01db\u0214\u0216\u0244\u1e72\u1e74\u1e76\u1e78\u1e7a\u1ee4\u1ee6\u1ee8\u1eea\u1eec\u1eee\u1ef0\u24ca\uff35\u0423\u042a", - "V": "\x56\u01b2\u0245\u1e7c\u1e7e\u24cb\ua75e\uff36\u0412", - "W": "\x57\u0174\u1e80\u1e82\u1e84\u1e86\u1e88\u24cc\u2c72\uff37\u038f\u03a9", - "X": "\x58\u1e8a\u1e8c\u24cd\uff38\u03a7", - "Y": "\x59\xdd\u0176\u0178\u01b3\u0232\u024e\u1e8e\u1ef2\u1ef4\u1ef6\u1ef8\u1efe\u24ce\uff39\u038e\u03a5\u03ab\u042b", - "Z": "\x5a\u0179\u017b\u017d\u01b5\u0224\u1e90\u1e92\u1e94\u24cf\u2c6b\u2c7f\ua762\uff3a\u0396\u0417", - "a": "\x61\xe0\xe1\xe2\xe3\xe4\xe5\u0101\u0103\u0105\u01ce\u01df\u01e1\u01fb\u0201\u0203\u0227\u0250\u1e01\u1e9a\u1ea1\u1ea3\u1ea5\u1ea7\u1ea9\u1eab\u1ead\u1eaf\u1eb1\u1eb3\u1eb5\u1eb7\u24d0\u2c65\uff41\u03ac\u03b1\u0430", - "b": "\x62\u0180\u0183\u0253\u1e03\u1e05\u1e07\u24d1\uff42\u03b2\u0431", - "c": "\x63\xe7\u0107\u0109\u010b\u010d\u0188\u023c\u1e09\u2184\u24d2\ua73f\uff43\u0446", - "d": "\x64\u010f\u0111\u018c\u0256\u0257\u1e0b\u1e0d\u1e0f\u1e11\u1e13\u24d3\ua77a\uff44\xf0\u03b4\u0434", - "e": "\x65\xe8\xe9\xea\xeb\u0113\u0115\u0117\u0119\u011b\u01dd\u0205\u0207\u0229\u0247\u025b\u1e15\u1e17\u1e19\u1e1b\u1e1d\u1eb9\u1ebb\u1ebd\u1ebf\u1ec1\u1ec3\u1ec5\u1ec7\u24d4\uff45\u03ad\u03b5\u0435\u044d", - "f": "\x66\u0192\u1e1f\u24d5\ua77c\uff46\u03c6\u0444", - "g": "\x67\u011d\u011f\u0121\u0123\u01e5\u01e7\u01f5\u0260\u1d79\u1e21\u24d6\ua77f\ua7a1\uff47\u03b3\u0433\u0491", - "h": "\x68\u0125\u0127\u021f\u0265\u1e23\u1e25\u1e27\u1e29\u1e2b\u1e96\u24d7\u2c68\u2c76\uff48\u03ae\u03b7\u0445", - "i": "\x69\xec\xed\xee\xef\u0129\u012b\u012d\u012f\u0131\u01d0\u0209\u020b\u0268\u1e2d\u1e2f\u1ec9\u1ecb\u24d8\uff49\u0390\u03af\u03b9\u03ca\u0438\u0456", - "j": "\x6a\u0135\u01f0\u0249\u24d9\uff4a\u0439", - "k": "\x6b\u0137\u0199\u01e9\u1e31\u1e33\u1e35\u24da\u2c6a\ua741\ua743\ua745\ua7a3\uff4b\u03ba\u043a", - "l": "\x6c\u013a\u013c\u013e\u0140\u0142\u017f\u019a\u026b\u1e37\u1e39\u1e3b\u1e3d\u24db\u2c61\ua747\ua749\ua781\uff4c\u03bb\u043b", - "m": "\x6d\u026f\u0271\u1e3f\u1e41\u1e43\u24dc\uff4d\u03bc\u043c", - "n": "\x6e\xf1\u0144\u0146\u0148\u0149\u019e\u01f9\u0272\u1e45\u1e47\u1e49\u1e4b\u24dd\ua791\ua7a5\uff4e\u03bd\u043d", - "o": "\x6f\xf2\xf3\xf4\xf5\xf6\xf8\u014d\u014f\u0151\u01a1\u01d2\u01eb\u01ed\u01ff\u020d\u020f\u022b\u022d\u022f\u0231\u0254\u0275\u1e4d\u1e4f\u1e51\u1e53\u1ecd\u1ecf\u1ed1\u1ed3\u1ed5\u1ed7\u1ed9\u1edb\u1edd\u1edf\u1ee1\u1ee3\u24de\ua74b\ua74d\uff4f\u03bf\u03cc\u043e", - "p": "\x70\u01a5\u1d7d\u1e55\u1e57\u24df\ua751\ua753\ua755\uff50\u03c0\u043f", - "q": "\x71\u024b\u24e0\ua757\ua759\uff51", - "r": "\x72\u0155\u0157\u0159\u0211\u0213\u024d\u027d\u1e59\u1e5b\u1e5d\u1e5f\u24e1\ua75b\ua783\ua7a7\uff52\u03c1\u0440", - "s": "\x73\xdf\u015b\u015d\u015f\u0161\u0219\u023f\u1e61\u1e63\u1e65\u1e67\u1e69\u1e9b\u24e2\ua785\ua7a9\uff53\u03c2\u03c3\u0441", - "t": "\x74\u0163\u0165\u0167\u01ad\u021b\u0288\u1e6b\u1e6d\u1e6f\u1e71\u1e97\u24e3\u2c66\ua787\uff54\u03c4\u0442", - "u": "\x75\xf9\xfa\xfb\xfc\u0169\u016b\u016d\u016f\u0171\u0173\u01b0\u01d4\u01d6\u01d8\u01da\u01dc\u0215\u0217\u0289\u1e73\u1e75\u1e77\u1e79\u1e7b\u1ee5\u1ee7\u1ee9\u1eeb\u1eed\u1eef\u1ef1\u24e4\uff55\u0443\u044a", - "v": "\x76\u028b\u028c\u1e7d\u1e7f\u24e5\ua75f\uff56\u0432", - "w": "\x77\u0175\u1e81\u1e83\u1e85\u1e87\u1e89\u1e98\u24e6\u2c73\uff57\u03c9\u03ce", - "x": "\x78\u1e8b\u1e8d\u24e7\uff58\u03c7", - "y": "\x79\xfd\xff\u0177\u01b4\u0233\u024f\u1e8f\u1e99\u1ef3\u1ef5\u1ef7\u1ef9\u1eff\u24e8\uff59\u03b0\u03c5\u03cb\u03cd\u044b", - "z": "\x7a\u017a\u017c\u017e\u01b6\u0225\u0240\u1e91\u1e93\u1e95\u24e9\u2c6c\ua763\uff5a\u03b6\u0437", - "OE": "\x8c\u0152", - "oe": "\x9c\u0153", - "AE": "\xc6\u01e2\u01fc", - "ae": "\xe6\u01e3\u01fd", - "hv": "\u0195", - "OI": "\u01a2", - "oi": "\u01a3", - "DZ": "\u01c4\u01f1", - "Dz": "\u01c5\u01f2", - "dz": "\u01c6\u01f3", - "LJ": "\u01c7", - "Lj": "\u01c8", - "lj": "\u01c9", - "NJ": "\u01ca", - "Nj": "\u01cb", - "nj": "\u01cc", - "OU": "\u0222", - "ou": "\u0223", - "TZ": "\ua728", - "tz": "\ua729", - "AA": "\ua732", - "aa": "\ua733", - "AO": "\ua734", - "ao": "\ua735", - "AU": "\ua736", - "au": "\ua737", - "AV": "\ua738\ua73a", - "av": "\ua739\ua73b", - "AY": "\ua73c", - "ay": "\ua73d", - "OO": "\ua74e", - "oo": "\ua74f", - "VY": "\ua760", - "vy": "\ua761", - "TH": "\xde", - "th": "\xfe", - "PS": "\u03a8", - "ps": "\u03c8", - "Yo": "\u0401", - "Ye": "\u0404", - "Yi": "\u0407", - "Zh": "\u0416", - "Ch": "\u0427", - "Sh": "\u0428\u0429", - "": "\u042c\u044c", - "Yu": "\u042e", - "Ya": "\u042f", - "zh": "\u0436", - "ch": "\u0447", - "sh": "\u0448\u0449", - "yu": "\u044e", - "ya": "\u044f", - "yo": "\u0451", - "ye": "\u0454", - "yi": "\u0457" -}; - -var diacriticsMap = null; - -/** - * Creates a map of the diacritics. - * - * @ignore - * @returns {Object} Returns the diacritics map. - */ -function getDiacriticsMap() { - if (diacriticsMap !== null) { - return diacriticsMap; - } - diacriticsMap = {}; - Object.keys(diacritics).forEach(function (key) { - var characters = diacritics[key]; - for (var index = 0; index < characters.length; index++) { - var character = characters[index]; - diacriticsMap[character] = key; - } - }); - return diacriticsMap; -} - -/** - * Get the latin character from character with diacritics. - * - * @ignore - * @param {string} character The character with diacritics. - * @returns {string} Returns the character without diacritics. - */ -function getLatinCharacter(character) { - var characterWithoutDiacritic = getDiacriticsMap()[character]; - return characterWithoutDiacritic ? characterWithoutDiacritic : character; -} - -/** - * Returns the `cleanCharacter` from combining marks regular expression match. - * - * @ignore - * @param {string} character The character with combining marks - * @param {string} cleanCharacter The character without combining marks. - * @return {string} The character without combining marks. - */ -function removeCombiningMarks(character, cleanCharacter) { - return cleanCharacter; -} - -/** - * Latinises the `subject` by removing diacritic characters. - * - * @function latinise - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to latinise. - * @return {string} Returns the latinised string. - * @example - * v.latinise('cafe\u0301'); // or 'café' - * // => 'cafe' - * - * v.latinise('août décembre'); - * // => 'aout decembre' - * - * v.latinise('как прекрасен этот мир'); - * // => 'kak prekrasen etot mir' - */ -function latinise(subject) { - var subjectString = coerceToString(subject); - if (subjectString === '') { - return ''; - } - return subjectString.replace(REGEXP_NON_LATIN, getLatinCharacter).replace(REGEXP_COMBINING_MARKS, removeCombiningMarks); -} - -/** - * Pads `subject` to a new `length`. - * - * @function pad - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to pad. - * @param {int} [length=0] The length to pad the string. No changes are made if `length` is less than `subject.length`. - * @param {string} [pad=' '] The string to be used for padding. - * @return {string} Returns the padded string. - * @example - * v.pad('dog', 5); - * // => ' dog ' - * - * v.pad('bird', 6, '-'); - * // => '-bird-' - * - * v.pad('cat', 6, '-='); - * // => '-cat-=' - */ -function pad(subject, length, pad) { - var subjectString = coerceToString(subject); - var lengthInt = isNil(length) ? 0 : clipNumber(toInteger(length), 0, MAX_SAFE_INTEGER); - var padString = coerceToString(pad, ' '); - if (lengthInt <= subjectString.length) { - return subjectString; - } - var paddingLength = lengthInt - subjectString.length; - var paddingSideLength = toInteger(paddingLength / 2); - var paddingSideRemainingLength = paddingLength % 2; - return buildPadding(padString, paddingSideLength) + subjectString + buildPadding(padString, paddingSideLength + paddingSideRemainingLength); -} - -/** - * Replaces the matches of `pattern` with `replacement`.
- * - * @function replace - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to verify. - * @param {string|RegExp} pattern The pattern which match is replaced. If `pattern` is a string, - * a simple string match is evaluated and only the first occurrence replaced. - * @param {string|Function} replacement The string or function which invocation result replaces `pattern` match. - * @return {string} Returns the replacement result. - * @example - * v.replace('swan', 'wa', 'u'); - * // => 'sun' - * - * v.replace('domestic duck', /domestic\s/, ''); - * // => 'duck' - * - * v.replace('nice duck', /(nice)(duck)/, function(match, nice, duck) { - * return 'the ' + duck + ' is ' + nice; - * }); - * // => 'the duck is nice' - */ -function replace(subject, pattern, replacement) { - var subjectString = coerceToString(subject); - return subjectString.replace(pattern, replacement); -} - -/** - * Get the flags string from a regular expression object. - * - * @ignore - * @param {RegExp} regExp The regular expression object. - * @return {string} Returns the string with flags chars. - */ -function getRegExpFlags(regExp) { - return regExp.toString().match(REGEXP_FLAGS)[0]; -} - -/** - * Checks whether `subject` includes `search` starting from `position`. - * - * @function includes - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string where to search. - * @param {string} search The string to search. - * @param {number} [position=0] The position to start searching. - * @return {boolean} Returns `true` if `subject` includes `search` or `false` otherwise. - * @example - * v.includes('starship', 'star'); - * // => true - * - * v.includes('galaxy', 'g', 1); - * // => false - */ -function includes(subject, search, position) { - var subjectString = coerceToString(subject); - var searchString = toString(search); - if (searchString === null) { - return false; - } - if (searchString === '') { - return true; - } - position = isNil(position) ? 0 : clipNumber(toInteger(position), 0, subjectString.length); - return subjectString.indexOf(searchString, position) !== -1; -} - -/** - * Append flag to a regular expression. - * - * @ignore - * @param {RegExp} pattern The pattern to coerce. - * @param {string} appendFlag The flag to append to regular expression. - * @return {RegExp} The regular expression with added flag. - */ -function appendFlagToRegExp(pattern, appendFlag) { - var regularExpressionFlags = getRegExpFlags(pattern); - if (!includes(regularExpressionFlags, appendFlag)) { - return new RegExp(pattern.source, regularExpressionFlags + appendFlag); - } - return pattern; -} - -/** - * Replaces all matches of `pattern` with `replacement`.
- * - * @function replaceAll - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to verify. - * @param {string|RegExp} pattern The pattern which match is replaced. If `pattern` is a string, a simple string match is evaluated. - * All matches are replaced. - * @param {string|Function} replacement The string or function which invocation result replaces `pattern` match. - * @return {string} Returns the replacement result. - * @example - * v.replaceAll('good morning', 'o', '*'); - * // => 'g**d m*rning' - * v.replaceAll('evening', /n/, 's'); - * // => 'evesisg' - * - */ -function replaceAll(subject, pattern, replacement) { - var subjectString = coerceToString(subject); - var regExp = pattern; - if (!(pattern instanceof RegExp)) { - regExp = new RegExp(escapeRegExp(pattern), 'g'); - } else if (!pattern.global) { - regExp = appendFlagToRegExp(pattern, 'g'); - } - return subjectString.replace(regExp, replacement); -} - -/** - * Reverses the `subject`. - * - * @function reverse - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to reverse. - * @return {string} Returns the reversed string. - * @example - * v.reverse('winter'); - * // => 'retniw' - */ -function reverse(subject) { - var subjectString = coerceToString(subject); - return subjectString.split('').reverse().join(''); -} - -/** - * Reverses the `subject` taking care of - * surrogate pairs and - * combining marks. - * - * @function reverseGrapheme - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to reverse. - * @return {string} Returns the reversed string. - * @example - * v.reverseGrapheme('summer'); - * // => 'remmus' - * - * v.reverseGrapheme('𝌆 bar mañana mañana'); - * // => 'anañam anañam rab 𝌆' - */ -function reverseGrapheme(subject) { - var subjectString = coerceToString(subject); - /** - * @see https://github.com/mathiasbynens/esrever - */ - subjectString = subjectString.replace(REGEXP_COMBINING_MARKS, function ($0, $1, $2) { - return reverseGrapheme($2) + $1; - }).replace(REGEXP_SURROGATE_PAIRS, '$2$1'); - var reversedString = ''; - var index = subjectString.length; - while (index--) { - reversedString += subjectString.charAt(index); - } - return reversedString; -} - -/** - * Slugifies the `subject`. Cleans the `subject` by replacing diacritics with corresponding latin characters. - * - * @function slugify - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to slugify. - * @return {string} Returns the slugified string. - * @example - * v.slugify('Italian cappuccino drink'); - * // => 'italian-cappuccino-drink' - * - * v.slugify('caffé latté'); - * // => 'caffe-latte' - * - * v.slugify('хорошая погода'); - * // => 'horoshaya-pogoda' - */ -function slugify(subject) { - var subjectString = coerceToString(subject); - if (subjectString === '') { - return ''; - } - var cleanSubjectString = latinise(subjectString).replace(REGEXP_NON_LATIN, '-'); - return kebabCase(cleanSubjectString); -} - -/** - * Changes `subject` by deleting `deleteCount` of characters starting at position `start`. Places a new string - * `toAdd` instead of deleted characters. - * - * @function splice - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string where to insert. - * @param {string} start The position to start changing the string. For a negative position will start from the end of - * the string. - * @param {number} [deleteCount=subject.length-start] The number of characters to delete from string. - * @param {string} [toAdd=''] The string to be added instead of deleted characters. - * @return {string} Returns the modified string. - * @example - * v.splice('new year', 0, 4); - * // => 'year' - * - * v.splice('new year', 0, 3, 'happy'); - * // => 'happy year' - * - * v.splice('new year', -4, 4, 'day'); - * // => 'new day' - */ -function splice(subject, start, deleteCount, toAdd) { - var subjectString = coerceToString(subject); - var toAddString = coerceToString(toAdd); - var startPosition = coerceToNumber(start); - if (startPosition < 0) { - startPosition = subjectString.length + startPosition; - if (startPosition < 0) { - startPosition = 0; - } - } else if (startPosition > subjectString.length) { - startPosition = subjectString.length; - } - var deleteCountNumber = coerceToNumber(deleteCount, subjectString.length - startPosition); - if (deleteCountNumber < 0) { - deleteCountNumber = 0; - } - return subjectString.slice(0, startPosition) + toAddString + subjectString.slice(startPosition + deleteCountNumber); -} - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -/** - * Translates characters or replaces substrings in `subject`. - * - * @function tr - * @static - * @since 1.3.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to translate. - * @param {string|Object} from The string of characters to translate from. Or an object, then the object keys are replaced with corresponding values (longest keys are tried first). - * @param {string} to The string of characters to translate to. Ignored when `from` is an object. - * @return {string} Returns the translated string. - * @example - * v.tr('hello', 'el', 'ip'); - * // => 'hippo' - * - * v.tr('légèreté', 'éè', 'ee'); - * // => 'legerete' - * - * v.tr('Yes. The fire rises.', { - * 'Yes': 'Awesome', - * 'fire': 'flame' - * }) - * // => 'Awesome. The flame rises.' - * - * v.tr(':where is the birthplace of :what', { - * ':where': 'Africa', - * ':what': 'Humanity' - * }); - * // => 'Africa is the birthplace of Humanity' - * - */ -function tr(subject, from, to) { - var subjectString = coerceToString(subject); - var keys = void 0; - var values = void 0; - if (isString(from) && isString(to)) { - keys = from.split(''); - values = to.split(''); - } else { - var _extractKeysAndValues = extractKeysAndValues(nilDefault(from, {})); - - var _extractKeysAndValues2 = _slicedToArray(_extractKeysAndValues, 2); - - keys = _extractKeysAndValues2[0]; - values = _extractKeysAndValues2[1]; - } - if (keys.length === 0) { - return subjectString; - } - var result = ''; - var valuesLength = values.length; - var keysLength = keys.length; - for (var index = 0; index < subjectString.length; index++) { - var isMatch = false; - var matchValue = void 0; - for (var keyIndex = 0; keyIndex < keysLength && keyIndex < valuesLength; keyIndex++) { - var key = keys[keyIndex]; - if (subjectString.substr(index, key.length) === key) { - isMatch = true; - matchValue = values[keyIndex]; - index = index + key.length - 1; - break; - } - } - result += isMatch ? matchValue : subjectString[index]; - } - return result; -} - -function extractKeysAndValues(object) { - var keys = Object.keys(object); - var values = keys.sort(sortStringByLength).map(function (key) { - return object[key]; - }); - return [keys, values]; -} - -function sortStringByLength(str1, str2) { - if (str1.length === str2.length) { - return 0; - } - return str1.length < str2.length ? 1 : -1; -} - -var reduce$1 = Array.prototype.reduce; - -/** - * Removes whitespaces from the left side of the `subject`. - * - * @function trimLeft - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to trim. - * @param {string} [whitespace=whitespace] The whitespace characters to trim. List all characters that you want to be stripped. - * @return {string} Returns the trimmed string. - * @example - * v.trimLeft(' Starship Troopers'); - * // => 'Starship Troopers' - * - * v.trimLeft('***Mobile Infantry', '*'); - * // => 'Mobile Infantry' - */ -function trimLeft(subject, whitespace$$1) { - var subjectString = coerceToString(subject); - if (whitespace$$1 === '' || subjectString === '') { - return subjectString; - } - var whitespaceString = toString(whitespace$$1); - if (isNil(whitespaceString)) { - return subjectString.replace(REGEXP_TRIM_LEFT, ''); - } - var matchWhitespace = true; - return reduce$1.call(subjectString, function (trimmed, character) { - if (matchWhitespace && includes(whitespaceString, character)) { - return trimmed; - } - matchWhitespace = false; - return trimmed + character; - }, ''); -} - -var reduceRight = Array.prototype.reduceRight; - -/** - * Removes whitespaces from the right side of the `subject`. - * - * @function trimRight - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to trim. - * @param {string} [whitespace=whitespace] The whitespace characters to trim. List all characters that you want to be stripped. - * @return {string} Returns the trimmed string. - * @example - * v.trimRight('the fire rises '); - * // => 'the fire rises' - * - * v.trimRight('do you feel in charge?!!!', '!'); - * // => 'do you feel in charge?' - */ -function trimRight(subject, whitespace$$1) { - var subjectString = coerceToString(subject); - if (whitespace$$1 === '' || subjectString === '') { - return subjectString; - } - var whitespaceString = toString(whitespace$$1); - if (isNil(whitespaceString)) { - return subjectString.replace(REGEXP_TRIM_RIGHT, ''); - } - var matchWhitespace = true; - return reduceRight.call(subjectString, function (trimmed, character) { - if (matchWhitespace && includes(whitespaceString, character)) { - return trimmed; - } - matchWhitespace = false; - return character + trimmed; - }, ''); -} - -/** - * Removes whitespaces from left and right sides of the `subject`. - * - * @function trim - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to trim. - * @param {string} [whitespace=whitespace] The whitespace characters to trim. List all characters that you want to be stripped. - * @return {string} Returns the trimmed string. - * @example - * v.trim(' Mother nature '); - * // => 'Mother nature' - * - * v.trim('--Earth--', '-'); - * // => 'Earth' - */ -function trim(subject, whitespace) { - var subjectString = coerceToString(subject); - if (whitespace === '' || subjectString === '') { - return subjectString; - } - var whitespaceString = toString(whitespace); - if (isNil(whitespaceString)) { - return subjectString.trim(); - } - return trimRight(trimLeft(subjectString, whitespaceString), whitespaceString); -} - -var OPTION_WIDTH = 'width'; -var OPTION_NEW_LINE = 'newLine'; -var OPTION_INDENT = 'indent'; -var OPTION_CUT = 'cut'; - -/** - * Wraps `subject` to a given number of characters using a string break character. - * - * @function wordWrap - * @static - * @since 1.0.0 - * @memberOf Manipulate - * @param {string} [subject=''] The string to wrap. - * @param {Object} [options={}] The wrap options. - * @param {number} [options.width=75] The number of characters at which to wrap. - * @param {string} [options.newLine='\n'] The string to add at the end of line. - * @param {string} [options.indent=''] The string to intend the line. - * @param {boolean} [options.cut=false] When `false` (default) does not split the word even if word length is bigger than `width`.
- * When `true` breaks the word that has length bigger than `width`. - * - * @return {string} Returns wrapped string. - * @example - * v.wordWrap('Hello world', { - * width: 5 - * }); - * // => 'Hello\nworld' - * - * v.wordWrap('Hello world', { - * width: 5, - * newLine: '
', - * indent: '__' - * }); - * // => '__Hello
__world' - * - * v.wordWrap('Wonderful world', { - * width: 5, - * cut: true - * }); - * // => 'Wonde\nrful\nworld' - * - */ -function wordWrap(subject) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - - var subjectString = coerceToString(subject); - - var _determineOptions = determineOptions(options), - width = _determineOptions.width, - newLine = _determineOptions.newLine, - indent = _determineOptions.indent, - cut = _determineOptions.cut; - - if (subjectString === '' || width <= 0) { - return indent; - } - var subjectLength = subjectString.length; - var substring = subjectString.substring.bind(subjectString); - var offset = 0; - var wrappedLine = ''; - while (subjectLength - offset > width) { - if (subjectString[offset] === ' ') { - offset++; - continue; - } - var spaceToWrapAt = subjectString.lastIndexOf(' ', width + offset); - if (spaceToWrapAt >= offset) { - wrappedLine += indent + substring(offset, spaceToWrapAt) + newLine; - offset = spaceToWrapAt + 1; - } else { - if (cut) { - wrappedLine += indent + substring(offset, width + offset) + newLine; - offset += width; - } else { - spaceToWrapAt = subjectString.indexOf(' ', width + offset); - if (spaceToWrapAt >= 0) { - wrappedLine += indent + substring(offset, spaceToWrapAt) + newLine; - offset = spaceToWrapAt + 1; - } else { - wrappedLine += indent + substring(offset); - offset = subjectLength; - } - } - } - } - if (offset < subjectLength) { - wrappedLine += indent + substring(offset); - } - return wrappedLine; -} - -/** - * Determine the word wrap options. The missing values are filled with defaults. - * - * @param {Object} options The options object. - * @return {Object} The word wrap options, with default settings if necessary. - * @ignore - */ -function determineOptions(options) { - return { - width: coerceToNumber(options[OPTION_WIDTH], 75), - newLine: coerceToString(options[OPTION_NEW_LINE], '\n'), - indent: coerceToString(options[OPTION_INDENT], ''), - cut: coerceToBoolean(options[OPTION_CUT], false) - }; -} - -/** - * Checks whether `subject` ends with `end`. - * - * @function endsWith - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @param {string} end The ending string. - * @param {number} [position=subject.length] Search within `subject` as if the string were only `position` long. - * @return {boolean} Returns `true` if `subject` ends with `end` or `false` otherwise. - * @example - * v.endsWith('red alert', 'alert'); - * // => true - * - * v.endsWith('metro south', 'metro'); - * // => false - * - * v.endsWith('Murphy', 'ph', 5); - * // => true - */ -function endsWith(subject, end, position) { - if (isNil(end)) { - return false; - } - var subjectString = coerceToString(subject); - var endString = coerceToString(end); - if (endString === '') { - return true; - } - position = isNil(position) ? subjectString.length : clipNumber(toInteger(position), 0, subjectString.length); - position -= endString.length; - var lastIndex = subjectString.indexOf(endString, position); - return lastIndex !== -1 && lastIndex === position; -} - -/** - * Checks whether `subject` contains only alpha characters. - * - * @function isAlpha - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @return {boolean} Returns `true` if `subject` contains only alpha characters or `false` otherwise. - * @example - * v.isAlpha('bart'); - * // => true - * - * v.isAlpha('lisa!'); - * // => false - * - * v.isAlpha('lisa and bart'); - * // => false - */ -function isAlpha(subject) { - var subjectString = coerceToString(subject); - return REGEXP_ALPHA.test(subjectString); -} - -/** - * Checks whether `subject` contains only alpha and digit characters. - * - * @function isAlphaDigit - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @return {boolean} Returns `true` if `subject` contains only alpha and digit characters or `false` otherwise. - * @example - * v.isAlphaDigit('year2020'); - * // => true - * - * v.isAlphaDigit('1448'); - * // => true - * - * v.isAlphaDigit('40-20'); - * // => false - */ -function isAlphaDigit(subject) { - var subjectString = coerceToString(subject); - return REGEXP_ALPHA_DIGIT.test(subjectString); -} - -/** - * Checks whether `subject` is empty or contains only whitespaces. - * - * @function isBlank - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @return {boolean} Returns `true` if `subject` is empty or contains only whitespaces or `false` otherwise. - * @example - * v.isBlank(''); - * // => true - * - * v.isBlank(' '); - * // => true - * - * v.isBlank('World'); - * // => false - */ -function isBlank(subject) { - var subjectString = coerceToString(subject); - return subjectString.trim().length === 0; -} - -/** - * Checks whether `subject` contains only digit characters. - * - * @function isDigit - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @return {boolean} Returns `true` if `subject` contains only digit characters or `false` otherwise. - * @example - * v.isDigit('35'); - * // => true - * - * v.isDigit('1.5'); - * // => false - * - * v.isDigit('ten'); - * // => false - */ -function isDigit(subject) { - var subjectString = coerceToString(subject); - return REGEXP_DIGIT.test(subjectString); -} - -/** - * Checks whether `subject` is empty. - * - * @function isEmpty - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @return {boolean} Returns `true` if `subject` is empty or `false` otherwise - * @example - * v.isEmpty(''); - * // => true - * - * v.isEmpty(' '); - * // => false - * - * v.isEmpty('sun'); - * // => false - */ -function isEmpty(subject) { - var subjectString = coerceToString(subject); - return subjectString.length === 0; -} - -/** - * Checks whether `subject` has only lower case characters. - * - * @function isLowerCase - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @return {boolean} Returns `true` if `subject` is lower case or `false` otherwise. - * @example - * v.isLowerCase('motorcycle'); - * // => true - * - * v.isLowerCase('John'); - * // => false - * - * v.isLowerCase('T1000'); - * // => false - */ -function isLowerCase(subject) { - var valueString = coerceToString(subject); - return isAlpha(valueString) && valueString.toLowerCase() === valueString; -} - -/** - * Checks whether `subject` is numeric. - * - * @function isNumeric - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @return {boolean} Returns `true` if `subject` is numeric or `false` otherwise. - * @example - * v.isNumeric('350'); - * // => true - * - * v.isNumeric('-20.5'); - * // => true - * - * v.isNumeric('1.5E+2'); - * // => true - * - * v.isNumeric('five'); - * // => false - */ -function isNumeric(subject) { - var valueNumeric = typeof subject === 'object' && !isNil(subject) ? Number(subject) : subject; - return (typeof valueNumeric === 'number' || typeof valueNumeric === 'string') && !isNaN(valueNumeric - parseFloat(valueNumeric)); -} - -/** - * Checks whether `subject` contains only upper case characters. - * - * @function isUpperCase - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @return {boolean} Returns `true` if `subject` is upper case or `false` otherwise. - * @example - * v.isUpperCase('ACDC'); - * // => true - * - * v.isUpperCase('Morning'); - * // => false - */ -function isUpperCase(subject) { - var subjectString = coerceToString(subject); - return isAlpha(subjectString) && subjectString.toUpperCase() === subjectString; -} - -/** - * Checks whether `subject` matches the regular expression `pattern`. - * - * @function matches - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @param {RegExp|string} pattern The pattern to match. If `pattern` is not RegExp, it is transformed to `new RegExp(pattern, flags)`. - * @param {string} [flags=''] The regular expression flags. Applies when `pattern` is string type. - * @return {boolean} Returns `true` if `subject` matches `pattern` or `false` otherwise. - * @example - * v.matches('pluto', /plu.{2}/); - * // => true - * - * v.matches('sun', 'S', 'i'); - * // => true - * - * v.matches('apollo 11', '\\d{3}'); - * // => false - */ -function matches(subject, pattern, flags) { - var subjectString = coerceToString(subject); - var flagsString = coerceToString(flags); - var patternString = void 0; - if (!(pattern instanceof RegExp)) { - patternString = toString(pattern); - if (patternString === null) { - return false; - } - pattern = new RegExp(patternString, flagsString); - } - return pattern.test(subjectString); -} - -/** - * Checks whether `subject` starts with `start`. - * - * @function startsWith - * @static - * @since 1.0.0 - * @memberOf Query - * @param {string} [subject=''] The string to verify. - * @param {string} start The starting string. - * @param {number} [position=0] The position to start searching. - * @return {boolean} Returns `true` if `subject` starts with `start` or `false` otherwise. - * @example - * v.startsWith('say hello to my little friend', 'say hello'); - * // => true - * - * v.startsWith('tony', 'on', 1); - * // => true - * - * v.startsWith('the world is yours', 'world'); - * // => false - */ -function startsWith(subject, start, position) { - var subjectString = coerceToString(subject); - var startString = toString(start); - if (startString === null) { - return false; - } - if (startString === '') { - return true; - } - position = isNil(position) ? 0 : clipNumber(toInteger(position), 0, subjectString.length); - return subjectString.substr(position, startString.length) === startString; -} - -/** - * Splits `subject` into an array of characters. - * - * @function chars - * @static - * @since 1.0.0 - * @memberOf Split - * @param {string} [subject=''] The string to split into characters. - * @return {Array} Returns the array of characters. - * @example - * v.chars('cloud'); - * // => ['c', 'l', 'o', 'u', 'd'] - */ -function chars(subject) { - var subjectString = coerceToString(subject); - return subjectString.split(''); -} - -/** - * Returns an array of Unicode code point values from characters of `subject`. - * - * @function codePoints - * @static - * @since 1.0.0 - * @memberOf Split - * @param {string} [subject=''] The string to extract from. - * @return {Array} Returns an array of non-negative numbers less than or equal to `0x10FFFF`. - * @example - * v.codePoints('rain'); - * // => [114, 97, 105, 110], or - * // [0x72, 0x61, 0x69, 0x6E] - * - * v.codePoints('\uD83D\uDE00 smile'); // or '😀 smile' - * // => [128512, 32, 115, 109, 105, 108, 101], or - * // [0x1F600, 0x20, 0x73, 0x6D, 0x69, 0x6C, 0x65] - */ -function codePoints(subject) { - var subjectString = coerceToString(subject); - var subjectStringLength = subjectString.length; - var codePointArray = []; - var index = 0; - var codePointNumber = void 0; - while (index < subjectStringLength) { - codePointNumber = codePointAt(subjectString, index); - codePointArray.push(codePointNumber); - index += codePointNumber > 0xFFFF ? 2 : 1; - } - return codePointArray; -} - -/** - * Splits `subject` into an array of graphemes taking care of - * surrogate pairs and - * combining marks. - * - * @function graphemes - * @static - * @since 1.0.0 - * @memberOf Split - * @param {string} [subject=''] The string to split into characters. - * @return {Array} Returns the array of graphemes. - * @example - * v.graphemes('\uD835\uDC00\uD835\uDC01'); // or '𝐀𝐁' - * // => ['\uD835\uDC00', '\uD835\uDC01'], or - * // ['𝐀', '𝐁'] - * - * v.graphemes('cafe\u0301'); // or 'café' - * // => ['c', 'a', 'f', 'e\u0301'], or - * // ['c', 'a', 'f', 'é'] - */ -function graphemes(subject) { - var subjectString = coerceToString(subject); - return nilDefault(subjectString.match(REGEXP_UNICODE_CHARACTER), []); -} - -/** - * Splits `subject` into an array of chunks by `separator`. - * - * @function split - * @static - * @since 1.0.0 - * @memberOf Split - * @param {string} [subject=''] The string to split into characters. - * @param {string|RegExp} [separator] The pattern to match the separator. - * @param {number} [limit] Limit the number of chunks to be found. - * @return {Array} Returns the array of chunks. - * @example - * v.split('rage against the dying of the light', ' '); - * // => ['rage', 'against', 'the', 'dying', 'of', 'the', 'light'] - * - * v.split('the dying of the light', /\s/, 3); - * // => ['the', 'dying', 'of'] - */ -function split(subject, separator, limit) { - var subjectString = coerceToString(subject); - return subjectString.split(separator, limit); -} - -var BYRE_ORDER_MARK = '\uFEFF'; - -/** - * Strips the byte order mark (BOM) from the beginning of `subject`. - * - * @function stripBom - * @static - * @since 1.2.0 - * @memberOf Strip - * @param {string} [subject=''] The string to strip from. - * @return {string} Returns the stripped string. - * @example - * - * v.stripBom('\uFEFFsummertime sadness'); - * // => 'summertime sadness' - * - * v.stripBom('summertime happiness'); - * // => 'summertime happiness' - * - */ -function trim$1(subject) { - var subjectString = coerceToString(subject); - if (subjectString === '') { - return ''; - } - if (subjectString[0] === BYRE_ORDER_MARK) { - return subjectString.substring(1); - } - return subjectString; -} - -/** - * Checks whether `subject` contains substring at specific `index`. - * - * @ignore - * @param {string} subject The subject to search in. - * @param {string} substring The substring to search/ - * @param {number} index The index to search substring. - * @param {boolean} lookBehind Whether to look behind (true) or ahead (false). - * @return {boolean} Returns a boolean whether the substring exists. - */ -function hasSubstringAtIndex(subject, substring, index) { - var lookBehind = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true; - - var indexOffset = 0; - if (lookBehind) { - indexOffset = -substring.length + 1; - } - var extractedSubstring = subject.substr(index + indexOffset, substring.length); - return extractedSubstring.toLowerCase() === substring; -} - -/** - * Parses the tags from the string '...'. - * - * @ignore - * @param {string} tags The string that contains the tags. - * @return {string[]} Returns the array of tag names. - */ -function parseTagList(tags) { - var tagsList = []; - var match = void 0; - while ((match = REGEXP_TAG_LIST.exec(tags)) !== null) { - tagsList.push(match[1]); - } - return tagsList; -} - -var STATE_START_TAG = 0; -var STATE_NON_WHITESPACE = 1; -var STATE_DONE = 2; - -/** - * Parses the tag name from html content. - * - * @ignore - * @param {string} tagContent The tag content. - * @return {string} Returns the tag name. - */ -function parseTagName(tagContent) { - var state = STATE_START_TAG; - var tagName = ''; - var index = 0; - while (state !== STATE_DONE) { - var char = tagContent[index++].toLowerCase(); - switch (char) { - case '<': - break; - case '>': - state = STATE_DONE; - break; - default: - if (REGEXP_WHITESPACE.test(char)) { - if (state === STATE_NON_WHITESPACE) { - state = STATE_DONE; - } - } else { - if (state === STATE_START_TAG) { - state = STATE_NON_WHITESPACE; - } - if (char !== '/') { - tagName += char; - } - } - break; - } - } - return tagName; -} - -var STATE_OUTPUT = 0; -var STATE_HTML = 1; -var STATE_EXCLAMATION = 2; -var STATE_COMMENT = 3; - -/** - * Strips HTML tags from `subject`. - * - * @function stripTags - * @static - * @since 1.1.0 - * @memberOf Strip - * @param {string} [subject=''] The string to strip from. - * @param {string|Array} [allowableTags] The string `''` or array `['tag1', 'tag2']` of tags that should not be stripped. - * @param {string} [replacement=''] The string to replace the stripped tag. - * @return {string} Returns the stripped string. - * @example - * - * v.stripTags('Summer is nice'); - * // => 'Summer is nice' - * - * v.stripTags('Winter is cold', ['b', 'i']); - * // => 'Winter is cold' - * - * v.stripTags('Sun
set', '', '-'); - * // => 'Sun-set' - */ -function trim$2(subject, allowableTags, replacement) { - subject = coerceToString(subject); - if (subject === '') { - return ''; - } - if (!Array.isArray(allowableTags)) { - var allowableTagsString = coerceToString(allowableTags); - allowableTags = allowableTagsString === '' ? [] : parseTagList(allowableTagsString); - } - var replacementString = coerceToString(replacement); - var length = subject.length; - var hasAllowableTags = allowableTags.length > 0; - var hasSubstring = hasSubstringAtIndex.bind(null, subject); - var state = STATE_OUTPUT; - var depth = 0; - var output = ''; - var tagContent = ''; - var quote = null; - for (var index = 0; index < length; index++) { - var char = subject[index]; - var advance = false; - switch (char) { - case '<': - if (quote) { - break; - } - if (hasSubstring('< ', index, false)) { - advance = true; - break; - } - if (state === STATE_OUTPUT) { - advance = true; - state = STATE_HTML; - break; - } - if (state === STATE_HTML) { - depth++; - break; - } - advance = true; - break; - case '!': - if (state === STATE_HTML && hasSubstring('': - if (depth > 0) { - depth--; - break; - } - if (quote) { - break; - } - if (state === STATE_HTML) { - quote = null; - state = STATE_OUTPUT; - if (hasAllowableTags) { - tagContent += '>'; - var tagName = parseTagName(tagContent); - if (allowableTags.indexOf(tagName.toLowerCase()) !== -1) { - output += tagContent; - } else { - output += replacementString; - } - tagContent = ''; - } else { - output += replacementString; - } - break; - } - if (state === STATE_EXCLAMATION || state === STATE_COMMENT && hasSubstring('-->', index)) { - quote = null; - state = STATE_OUTPUT; - tagContent = ''; - break; - } - advance = true; - break; - default: - advance = true; - } - if (advance) { - switch (state) { - case STATE_OUTPUT: - output += char; - break; - case STATE_HTML: - if (hasAllowableTags) { - tagContent += char; - } - break; - } - } - } - return output; -} - -var globalObject$1 = null; - -function getGlobalObject() { - if (globalObject$1 !== null) { - return globalObject$1; - } - /* istanbul ignore next */ - // It's hard to mock the global variables. This code surely works fine. I hope :) - if (typeof global === 'object' && global.Object === Object) { - // NodeJS global object - globalObject$1 = global; - } else if (typeof self === 'object' && self.Object === Object) { - // self property from Window object - globalObject$1 = self; - } else { - // Other cases. Function constructor always has the context as global object - globalObject$1 = new Function('return this')(); - } - return globalObject$1; -} - -var globalObject = getGlobalObject(); -var previousV = globalObject.v; - -/** - * Restores `v` variable to previous value and returns Voca library instance. - * - * @function noConflict - * @static - * @since 1.0.0 - * @memberOf Util - * @return {Object} Returns Voca library instance. - * @example - * var voca = v.noConflict(); - * voca.isAlpha('Hello'); - * // => true - */ -function noConflict() { - if (this === globalObject.v) { - globalObject.v = previousV; - } - return this; -} - -/** - * A property that contains the library semantic version number. - * @name version - * @static - * @since 1.0.0 - * @memberOf Util - * @type string - * @example - * v.version - * // => '1.3.0' - */ -var version = '1.3.0'; - -/* eslint sort-imports: "off" */ - -/** - * Functions to change the case - * @namespace Case - */ -/** - * Chain functions - * @namespace Chain - */ - -/** - * Functions to cut a string - * @namespace Chop - */ -/** - * Functions to count characters in a string - * @namespace Count - */ -/** - * Functions to format - * @namespace Format - */ -/** - * Functions to escape RegExp special characters - * @namespace Escape - */ -/** - * Functions to find index - * @namespace Index - */ -/** - * Functions to manipulate a string - * @namespace Manipulate - */ -/** - * Functions to query a string - * @namespace Query - */ -/** - * Functions to split a string - * @namespace Split - */ -/** - * Functions to strip a string - * @namespace Strip - */ -/** - * Util functions and properties - * @namespace Util - */ -var functions = { - camelCase: camelCase, - capitalize: capitalize, - decapitalize: decapitalize, - kebabCase: kebabCase, - lowerCase: lowerCase, - snakeCase: snakeCase, - swapCase: swapCase, - titleCase: titleCase, - upperCase: upperCase, - - count: count, - countGraphemes: countGrapheme, - countSubstrings: countSubstrings, - countWhere: countWhere, - countWords: countWords, - - escapeHtml: escapeHtml, - escapeRegExp: escapeRegExp, - unescapeHtml: unescapeHtml, - - sprintf: sprintf, - vprintf: vprintf, - - indexOf: indexOf, - lastIndexOf: lastIndexOf, - search: search, - - charAt: charAt, - codePointAt: codePointAt, - first: first, - graphemeAt: graphemeAt, - last: last, - prune: prune, - slice: slice, - substr: substr, - substring: substring, - truncate: truncate, - - insert: insert, - latinise: latinise, - pad: pad, - padLeft: padLeft, - padRight: padRight, - repeat: repeat, - replace: replace, - replaceAll: replaceAll, - reverse: reverse, - reverseGrapheme: reverseGrapheme, - slugify: slugify, - splice: splice, - tr: tr, - trim: trim, - trimLeft: trimLeft, - trimRight: trimRight, - wordWrap: wordWrap, - - endsWith: endsWith, - includes: includes, - isAlpha: isAlpha, - isAlphaDigit: isAlphaDigit, - isBlank: isBlank, - isDigit: isDigit, - isEmpty: isEmpty, - isLowerCase: isLowerCase, - isNumeric: isNumeric, - isString: isString, - isUpperCase: isUpperCase, - matches: matches, - startsWith: startsWith, - - chars: chars, - codePoints: codePoints, - graphemes: graphemes, - split: split, - words: words, - - stripBom: trim$1, - stripTags: trim$2, - - noConflict: noConflict, - version: version -}; - -/** - * The chain wrapper constructor. - * - * @ignore - * @param {string} subject The string to be wrapped. - * @param {boolean} [explicitChain=false] A boolean that indicates if the chain sequence is explicit or implicit. - * @return {ChainWrapper} Returns a new instance of `ChainWrapper` - * @constructor - */ -function ChainWrapper(subject, explicitChain) { - this._wrappedValue = subject; - this._explicitChain = explicitChain; -} - -/** - * Unwraps the chain sequence wrapped value. - * - * @memberof Chain - * @since 1.0.0 - * @function __proto__value - * @return {*} Returns the unwrapped value. - * @example - * v - * .chain('Hello world') - * .replace('Hello', 'Hi') - * .lowerCase() - * .slugify() - * .value() - * // => 'hi-world' - * - * v(' Space travel ') - * .trim() - * .truncate(8) - * .value() - * // => 'Space...' - */ -ChainWrapper.prototype.value = function () { - return this._wrappedValue; -}; - -/** - * Override the default object valueOf(). - * - * @ignore - * @return {*} Returns the wrapped value. - */ -ChainWrapper.prototype.valueOf = function () { - return this.value(); -}; - -/** - * Returns the wrapped value to be used in JSON.stringify(). - * - * @ignore - * @return {*} Returns the wrapped value. - */ -ChainWrapper.prototype.toJSON = function () { - return this.value(); -}; - -/** - * Returns the string representation of the wrapped value. - * - * @ignore - * @return {string} Returns the string representation. - */ -ChainWrapper.prototype.toString = function () { - return String(this.value()); -}; - -/** - * Creates a new chain object that enables explicit chain sequences. - * Use `v.prototype.value()` to unwrap the result.
- * Does not modify the wrapped value. - * - * @memberof Chain - * @since 1.0.0 - * @function __proto__chain - * @return {Object} Returns the wrapper in explicit mode. - * @example - * v('Back to School') - * .chain() - * .lowerCase() - * .words() - * .value() - * // => ['back', 'to', 'school'] - * - * v(" Back to School ") - * .chain() - * .trim() - * .truncate(7) - * .value() - * // => 'Back...' - */ -ChainWrapper.prototype.chain = function () { - return new ChainWrapper(this._wrappedValue, true); -}; - -/** - * Modifies the wrapped value with the invocation result of `changer` function. The current wrapped value is the - * argument of `changer` invocation. - * - * @memberof Chain - * @since 1.0.0 - * @function __proto__thru - * @param {Function} changer The function to invoke. - * @return {Object} Returns the new wrapper that wraps the invocation result of `changer`. - * @example - * v - * .chain('sun is shining') - * .words() - * .thru(function(words) { - * return words[0]; - * }) - * .value() - * // => 'sun' - * - */ -ChainWrapper.prototype.thru = function (changer) { - if (typeof changer === 'function') { - return new ChainWrapper(changer(this._wrappedValue), this._explicitChain); - } - return this; -}; - -/** - * A boolean that indicates if the chain sequence is explicit or implicit. - * @ignore - * @type {boolean} - * @private - */ -ChainWrapper.prototype._explicitChain = true; - -/** - * Make a voca function chainable. - * - * @ignore - * @param {Function} functionInstance The function to make chainable - * @return {Function} Returns the chainable function - */ -function makeFunctionChainable(functionInstance) { - return function () { - for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - var result = functionInstance.apply(undefined, [this._wrappedValue].concat(args)); - if (this._explicitChain || typeof result === 'string') { - return new ChainWrapper(result, this._explicitChain); - } else { - return result; - } - }; -} - -Object.keys(functions).forEach(function (name) { - ChainWrapper.prototype[name] = makeFunctionChainable(functions[name]); -}); - -/** - * Creates a chain object that wraps `subject`, enabling explicit chain sequences.
- * Use `v.prototype.value()` to unwrap the result. - * - * @memberOf Chain - * @since 1.0.0 - * @function chain - * @param {string} subject The string to wrap. - * @return {Object} Returns the new wrapper object. - * @example - * v - * .chain('Back to School') - * .lowerCase() - * .words() - * .value() - * // => ['back', 'to', 'school'] - */ -function chain(subject) { - return new ChainWrapper(subject, true); -} - -var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; - -/** - * Creates a chain object that wraps `subject`, enabling implicit chain sequences.
- * A function that returns `number`, `boolean` or `array` type terminates the chain sequence and returns the unwrapped value. - * Otherwise use `v.prototype.value()` to unwrap the result. - * - * @memberOf Chain - * @since 1.0.0 - * @function v - * @param {string} subject The string to wrap. - * @return {Object} Returns the new wrapper object. - * @example - * v('Back to School') - * .lowerCase() - * .words() - * // => ['back', 'to', 'school'] - * - * v(" Back to School ") - * .trim() - * .truncate(7) - * .value() - * // => 'Back...' - */ -function Voca(subject) { - return new ChainWrapper(subject, false); -} - -_extends(Voca, functions, { - chain: chain -}); - -describe('camelCase', function () { - - it('should return the camel case of a string', function () { - chai.expect(Voca.camelCase('bird')).to.be.equal('bird'); - chai.expect(Voca.camelCase('BIRD')).to.be.equal('bird'); - chai.expect(Voca.camelCase('BirdFlight')).to.be.equal('birdFlight'); - chai.expect(Voca.camelCase('bird flight')).to.be.equal('birdFlight'); - chai.expect(Voca.camelCase('San Diego Zoo Safari Park')).to.be.equal('sanDiegoZooSafariPark'); - chai.expect(Voca.camelCase('-BIRD-FLIGHT-')).to.be.equal('birdFlight'); - chai.expect(Voca.camelCase('__BIRD___FLIGHT___')).to.be.equal('birdFlight'); - chai.expect(Voca.camelCase('Restless flycatcher')).to.be.equal('restlessFlycatcher'); - chai.expect(Voca.camelCase('XMLHttpRequest')).to.be.equal('xmlHttpRequest'); - chai.expect(Voca.camelCase('weight of up to 12 kg')).to.be.equal('weightOfUpTo12Kg'); - chai.expect(Voca.camelCase('/home/dmitri/projects/voca')).to.be.equal('homeDmitriProjectsVoca'); - chai.expect(Voca.camelCase(PRINTABLE_ASCII)).to.be.equal('0123456789AbcdefghijklmnopqrstuvwxyzAbcdefghijklmnopqrstuvwxyz'); - chai.expect(Voca.camelCase('****')).to.be.equal(''); - chai.expect(Voca.camelCase('****')).to.be.equal(''); - chai.expect(Voca.camelCase('-----')).to.be.equal(''); - chai.expect(Voca.camelCase(' ')).to.be.equal(''); - chai.expect(Voca.camelCase('\n\n\n\n ***\t\t')).to.be.equal(''); - chai.expect(Voca.camelCase('')).to.be.equal(''); - }); - - it('should return the camel case of a non-latin string', function () { - chai.expect(Voca.camelCase('zborul păsării')).to.be.equal('zborulPăsării'); - chai.expect(Voca.camelCase('полет птицы')).to.be.equal('полетПтицы'); - chai.expect(Voca.camelCase('fuerza de sustentación')).to.be.equal('fuerzaDeSustentación'); - chai.expect(Voca.camelCase('skrzydło ptaka składa się')).to.be.equal('skrzydłoPtakaSkładaSię'); - }); - - it('should not modify numbers', function () { - chai.expect(Voca.camelCase(0)).to.be.equal('0'); - chai.expect(Voca.camelCase(1200)).to.be.equal('1200'); - chai.expect(Voca.camelCase('8965')).to.be.equal('8965'); - }); - - it('should return the camel case of a string representation of an object', function () { - chai.expect(Voca.camelCase(['bird flight'])).to.be.equal('birdFlight'); - chai.expect(Voca.camelCase({ - toString: function () { - return 'bird flight'; - } - })).to.be.equal('birdFlight'); - }); - - it('should return empty string for null or undefined', function () { - chai.expect(Voca.camelCase()).to.be.equal(''); - chai.expect(Voca.camelCase(undefined)).to.be.equal(''); - chai.expect(Voca.camelCase(null)).to.be.equal(''); - }); -}); - -describe('capitalize', function () { - - it('should capitalize the first character in a string', function () { - chai.expect(Voca.capitalize('APPLE')).to.be.equal('APPLE'); - chai.expect(Voca.capitalize('apple')).to.be.equal('Apple'); - chai.expect(Voca.capitalize('macBook')).to.be.equal('MacBook'); - chai.expect(Voca.capitalize('f')).to.be.equal('F'); - chai.expect(Voca.capitalize('')).to.be.equal(''); - chai.expect(Voca.capitalize('*apple')).to.be.equal('*apple'); - chai.expect(Voca.capitalize(PRINTABLE_ASCII)).to.be.equal(PRINTABLE_ASCII); - }); - - it('should capitalize the first character in a string and keep the rest unmodified', function () { - chai.expect(Voca.capitalize('apple', true)).to.be.equal('Apple'); - chai.expect(Voca.capitalize('APPLE', true)).to.be.equal('Apple'); - chai.expect(Voca.capitalize('яблоко', true)).to.be.equal('Яблоко'); - chai.expect(Voca.capitalize('f', true)).to.be.equal('F'); - chai.expect(Voca.capitalize('', true)).to.be.equal(''); - chai.expect(Voca.capitalize('100', true)).to.be.equal('100'); - chai.expect(Voca.capitalize(' ', true)).to.be.equal(' '); - }); - - it('should capitalize the first character in a string representation of an object', function () { - chai.expect(Voca.capitalize(['grape'])).to.be.equal('Grape'); - chai.expect(Voca.capitalize({ - toString: function () { - return 'oRaNgE'; - } - }, false)).to.be.equal('ORaNgE'); - }); - - it('should not modify numbers', function () { - chai.expect(Voca.capitalize(100)).to.be.equal('100'); - chai.expect(Voca.capitalize(812, false)).to.be.equal('812'); - }); - - it('should return an empty string for null or undefined', function () { - chai.expect(Voca.capitalize()).to.be.equal(''); - chai.expect(Voca.capitalize(undefined)).to.be.equal(''); - chai.expect(Voca.capitalize(null)).to.be.equal(''); - chai.expect(Voca.capitalize(undefined, true)).to.be.equal(''); - chai.expect(Voca.capitalize(undefined, false)).to.be.equal(''); - }); -}); - -describe('decapitalize', function () { - - it('should decapitalize the first character in a string', function () { - chai.expect(Voca.decapitalize('Light')).to.be.equal('light'); - chai.expect(Voca.decapitalize('light')).to.be.equal('light'); - chai.expect(Voca.decapitalize('Sun')).to.be.equal('sun'); - chai.expect(Voca.decapitalize('f')).to.be.equal('f'); - chai.expect(Voca.decapitalize('')).to.be.equal(''); - chai.expect(Voca.decapitalize('*light')).to.be.equal('*light'); - chai.expect(Voca.decapitalize(PRINTABLE_ASCII)).to.be.equal(PRINTABLE_ASCII); - }); - - it('should decapitalize the first character in a string representation of an object', function () { - chai.expect(Voca.decapitalize(['Fruit'])).to.be.equal('fruit'); - chai.expect(Voca.decapitalize({ - toString: function () { - return 'CaRrOt'; - } - }, false)).to.be.equal('caRrOt'); - }); - - it('should not modify numbers', function () { - chai.expect(Voca.decapitalize(100)).to.be.equal('100'); - chai.expect(Voca.decapitalize(812, false)).to.be.equal('812'); - }); - - it('should return an empty string for null or undefined', function () { - chai.expect(Voca.decapitalize()).to.be.equal(''); - chai.expect(Voca.decapitalize(undefined)).to.be.equal(''); - chai.expect(Voca.decapitalize(null)).to.be.equal(''); - }); -}); - -describe('kebabCase', function () { - - it('should return the kebab case of a string', function () { - chai.expect(Voca.kebabCase('bird')).to.be.equal('bird'); - chai.expect(Voca.kebabCase('BIRD')).to.be.equal('bird'); - chai.expect(Voca.kebabCase('BirdFlight')).to.be.equal('bird-flight'); - chai.expect(Voca.kebabCase('bird flight')).to.be.equal('bird-flight'); - chai.expect(Voca.kebabCase('San Diego Zoo Safari Park')).to.be.equal('san-diego-zoo-safari-park'); - chai.expect(Voca.kebabCase('-BIRD-FLIGHT-')).to.be.equal('bird-flight'); - chai.expect(Voca.kebabCase('__BIRD___FLIGHT___')).to.be.equal('bird-flight'); - chai.expect(Voca.kebabCase('Restless flycatcher')).to.be.equal('restless-flycatcher'); - chai.expect(Voca.kebabCase('XMLHttpRequest')).to.be.equal('xml-http-request'); - chai.expect(Voca.kebabCase('weight of up to 12 kg')).to.be.equal('weight-of-up-to-12-kg'); - chai.expect(Voca.kebabCase('/home/dmitri/projects/voca')).to.be.equal('home-dmitri-projects-voca'); - chai.expect(Voca.kebabCase(PRINTABLE_ASCII)).to.be.equal('0123456789-abcdefghijklmnopqrstuvwxyz-abcdefghijklmnopqrstuvwxyz'); - chai.expect(Voca.kebabCase('****')).to.be.equal(''); - chai.expect(Voca.kebabCase('****')).to.be.equal(''); - chai.expect(Voca.kebabCase('-----')).to.be.equal(''); - chai.expect(Voca.kebabCase(' ')).to.be.equal(''); - chai.expect(Voca.kebabCase('\n\n\n\n ***\t\t')).to.be.equal(''); - chai.expect(Voca.kebabCase('')).to.be.equal(''); - }); - - it('should return the kebab case of a non-latin string', function () { - chai.expect(Voca.kebabCase('zborul păsării')).to.be.equal('zborul-păsării'); - chai.expect(Voca.kebabCase('полет птицы')).to.be.equal('полет-птицы'); - chai.expect(Voca.kebabCase('fuerza de sustentación')).to.be.equal('fuerza-de-sustentación'); - chai.expect(Voca.kebabCase('skrzydło ptaka składa się')).to.be.equal('skrzydło-ptaka-składa-się'); - }); - - it('should not modify numbers', function () { - chai.expect(Voca.kebabCase(0)).to.be.equal('0'); - chai.expect(Voca.kebabCase(1200)).to.be.equal('1200'); - chai.expect(Voca.kebabCase('8965')).to.be.equal('8965'); - }); - - it('should return the kebab case of a string representation of an object', function () { - chai.expect(Voca.kebabCase(['bird flight'])).to.be.equal('bird-flight'); - chai.expect(Voca.kebabCase({ - toString: function () { - return 'bird flight'; - } - })).to.be.equal('bird-flight'); - }); - - it('should return empty string for null or undefined', function () { - chai.expect(Voca.kebabCase()).to.be.equal(''); - chai.expect(Voca.kebabCase(undefined)).to.be.equal(''); - chai.expect(Voca.kebabCase(null)).to.be.equal(''); - }); -}); - -describe('lowerCase', function () { - - it('should return the lower case of a string', function () { - chai.expect(Voca.lowerCase('Saturn')).to.be.equal('saturn'); - chai.expect(Voca.lowerCase('EARTH')).to.be.equal('earth'); - chai.expect(Voca.lowerCase('456')).to.be.equal('456'); - chai.expect(Voca.lowerCase('')).to.be.equal(''); - }); - - it('should return the lower case of a string representation of an object', function () { - chai.expect(Voca.lowerCase(['Venus'])).to.be.equal('venus'); - chai.expect(Voca.lowerCase({ - toString: function () { - return 'Venus'; - } - })).to.be.equal('venus'); - }); - - it('should return empty string for null or undefined', function () { - chai.expect(Voca.lowerCase()).to.be.equal(''); - chai.expect(Voca.lowerCase(undefined)).to.be.equal(''); - chai.expect(Voca.lowerCase(null)).to.be.equal(''); - }); -}); - -describe('snakeCase', function () { - - it('should return the snake case of a string', function () { - chai.expect(Voca.snakeCase('bird')).to.be.equal('bird'); - chai.expect(Voca.snakeCase('BIRD')).to.be.equal('bird'); - chai.expect(Voca.snakeCase('BirdFlight')).to.be.equal('bird_flight'); - chai.expect(Voca.snakeCase('bird flight')).to.be.equal('bird_flight'); - chai.expect(Voca.snakeCase('San Diego Zoo Safari Park')).to.be.equal('san_diego_zoo_safari_park'); - chai.expect(Voca.snakeCase('-BIRD-FLIGHT-')).to.be.equal('bird_flight'); - chai.expect(Voca.snakeCase('__BIRD___FLIGHT___')).to.be.equal('bird_flight'); - chai.expect(Voca.snakeCase('Restless flycatcher')).to.be.equal('restless_flycatcher'); - chai.expect(Voca.snakeCase('XMLHttpRequest')).to.be.equal('xml_http_request'); - chai.expect(Voca.snakeCase('weight of up to 12 kg')).to.be.equal('weight_of_up_to_12_kg'); - chai.expect(Voca.snakeCase('/home/dmitri/projects/voca')).to.be.equal('home_dmitri_projects_voca'); - chai.expect(Voca.snakeCase(PRINTABLE_ASCII)).to.be.equal('0123456789_abcdefghijklmnopqrstuvwxyz_abcdefghijklmnopqrstuvwxyz'); - chai.expect(Voca.snakeCase('****')).to.be.equal(''); - chai.expect(Voca.snakeCase('-----')).to.be.equal(''); - chai.expect(Voca.snakeCase(' ')).to.be.equal(''); - chai.expect(Voca.snakeCase('\n\n\n\n ***\t\t')).to.be.equal(''); - chai.expect(Voca.snakeCase('')).to.be.equal(''); - }); - - it('should return the snake case of a non-latin string', function () { - chai.expect(Voca.snakeCase('zborul păsării')).to.be.equal('zborul_păsării'); - chai.expect(Voca.snakeCase('полет птицы')).to.be.equal('полет_птицы'); - chai.expect(Voca.snakeCase('fuerza de sustentación')).to.be.equal('fuerza_de_sustentación'); - chai.expect(Voca.snakeCase('skrzydło ptaka składa się')).to.be.equal('skrzydło_ptaka_składa_się'); - }); - - it('should not modify numbers', function () { - chai.expect(Voca.snakeCase(0)).to.be.equal('0'); - chai.expect(Voca.snakeCase(1200)).to.be.equal('1200'); - chai.expect(Voca.snakeCase('8965')).to.be.equal('8965'); - }); - - it('should return the snake case of a string representation of an object', function () { - chai.expect(Voca.snakeCase(['bird flight'])).to.be.equal('bird_flight'); - chai.expect(Voca.snakeCase({ - toString: function () { - return 'bird flight'; - } - })).to.be.equal('bird_flight'); - }); - - it('should return empty string for null or undefined', function () { - chai.expect(Voca.snakeCase()).to.be.equal(''); - chai.expect(Voca.snakeCase(undefined)).to.be.equal(''); - chai.expect(Voca.snakeCase(null)).to.be.equal(''); - }); -}); - -describe('titleCase', function () { - - it('should return the title case of a string', function () { - chai.expect(Voca.titleCase('hello world')).to.be.equal('Hello World'); - chai.expect(Voca.titleCase('Hello world')).to.be.equal('Hello World'); - chai.expect(Voca.titleCase('hello World')).to.be.equal('Hello World'); - chai.expect(Voca.titleCase('Hello World')).to.be.equal('Hello World'); - chai.expect(Voca.titleCase('HELLO WORLD')).to.be.equal('Hello World'); - chai.expect(Voca.titleCase('bird')).to.be.equal('Bird'); - chai.expect(Voca.titleCase('BIRD')).to.be.equal('Bird'); - chai.expect(Voca.titleCase('bird-flight')).to.be.equal('Bird-Flight'); - chai.expect(Voca.titleCase('bird flight')).to.be.equal('Bird Flight'); - chai.expect(Voca.titleCase('san diego zoo safari park')).to.be.equal('San Diego Zoo Safari Park'); - chai.expect(Voca.titleCase('Who wants to try next?')).to.be.equal('Who Wants To Try Next?'); - chai.expect(Voca.titleCase('WHO WANTS TO TRY NEXT?')).to.be.equal('Who Wants To Try Next?'); - chai.expect(Voca.titleCase('-BIRD-FLIGHT-')).to.be.equal('-Bird-Flight-'); - chai.expect(Voca.titleCase('__BIRD___FLIGHT___')).to.be.equal('__Bird___Flight___'); - chai.expect(Voca.titleCase('Restless flycatcher')).to.be.equal('Restless Flycatcher'); - chai.expect(Voca.titleCase('XMLHttpRequest')).to.be.equal('XmlHttpRequest'); - chai.expect(Voca.titleCase('weight of up to 12 kg')).to.be.equal('Weight Of Up To 12 Kg'); - chai.expect(Voca.titleCase('/home/dmitri/projects/voca')).to.be.equal('/Home/Dmitri/Projects/Voca'); - chai.expect(Voca.titleCase('****')).to.be.equal('****'); - chai.expect(Voca.titleCase('-----')).to.be.equal('-----'); - chai.expect(Voca.titleCase(' ')).to.be.equal(' '); - chai.expect(Voca.titleCase('\n\n\n\n ***\t\t')).to.be.equal('\n\n\n\n ***\t\t'); - chai.expect(Voca.titleCase('')).to.be.equal(''); - }); - - it('should return the title case of a non-latin string', function () { - chai.expect(Voca.titleCase('zborul păsării')).to.be.equal('Zborul Păsării'); - chai.expect(Voca.titleCase('полет птицы')).to.be.equal('Полет Птицы'); - chai.expect(Voca.titleCase('fuerza de sustentación')).to.be.equal('Fuerza De Sustentación'); - chai.expect(Voca.titleCase('skrzydło ptaka składa się')).to.be.equal('Skrzydło Ptaka Składa Się'); - }); - - it('should return the title case and not capitalize specific words', function () { - chai.expect(Voca.titleCase('Who wants to try next?', ['to'])).to.be.equal('Who Wants to Try Next?'); - chai.expect(Voca.titleCase('WHO WANTS TO TRY NEXT?', ['to'])).to.be.equal('Who Wants to Try Next?'); - chai.expect(Voca.titleCase('Well, congratulations! You got yourself caught! Now what\'s the next step in your master plan?', ["s", 'the', 'in'])).to.be.equal('Well, Congratulations! You Got Yourself Caught! Now What\'s the Next Step in Your Master Plan?'); - }); - - it('should not modify numbers', function () { - chai.expect(Voca.titleCase(0)).to.be.equal('0'); - chai.expect(Voca.titleCase(1200)).to.be.equal('1200'); - chai.expect(Voca.titleCase('8965')).to.be.equal('8965'); - }); - - it('should return the title case of a string representation of an object', function () { - chai.expect(Voca.titleCase(['bird flight'])).to.be.equal('Bird Flight'); - chai.expect(Voca.titleCase({ - toString: function () { - return 'bird flight'; - } - })).to.be.equal('Bird Flight'); - }); - - it('should return empty string for null or undefined', function () { - chai.expect(Voca.titleCase()).to.be.equal(''); - chai.expect(Voca.titleCase(undefined)).to.be.equal(''); - chai.expect(Voca.titleCase(null)).to.be.equal(''); - }); -}); - -describe('swapCase', function () { - - it('should return the swapped case of a string', function () { - chai.expect(Voca.swapCase('hello world')).to.be.equal('HELLO WORLD'); - chai.expect(Voca.swapCase('Hello world')).to.be.equal('hELLO WORLD'); - chai.expect(Voca.swapCase('hello World')).to.be.equal('HELLO wORLD'); - chai.expect(Voca.swapCase('Hello World')).to.be.equal('hELLO wORLD'); - chai.expect(Voca.swapCase('HELLO WORLD')).to.be.equal('hello world'); - chai.expect(Voca.swapCase('bird')).to.be.equal('BIRD'); - chai.expect(Voca.swapCase('BIRD')).to.be.equal('bird'); - chai.expect(Voca.swapCase('bird-flight')).to.be.equal('BIRD-FLIGHT'); - chai.expect(Voca.swapCase('bird flight')).to.be.equal('BIRD FLIGHT'); - chai.expect(Voca.swapCase('san diego zoo safari park')).to.be.equal('SAN DIEGO ZOO SAFARI PARK'); - chai.expect(Voca.swapCase('Who wants to try next?')).to.be.equal('wHO WANTS TO TRY NEXT?'); - chai.expect(Voca.swapCase('WHO WANTS TO TRY NEXT?')).to.be.equal('who wants to try next?'); - chai.expect(Voca.swapCase('-BIRD-FLIGHT-')).to.be.equal('-bird-flight-'); - chai.expect(Voca.swapCase('__BIRD___FLIGHT___')).to.be.equal('__bird___flight___'); - chai.expect(Voca.swapCase('Restless flycatcher')).to.be.equal('rESTLESS FLYCATCHER'); - chai.expect(Voca.swapCase('XMLHttpRequest')).to.be.equal('xmlhTTPrEQUEST'); - chai.expect(Voca.swapCase('weight of up to 12 kg')).to.be.equal('WEIGHT OF UP TO 12 KG'); - chai.expect(Voca.swapCase('/home/dmitri/projects/voca')).to.be.equal('/HOME/DMITRI/PROJECTS/VOCA'); - chai.expect(Voca.swapCase('****')).to.be.equal('****'); - chai.expect(Voca.swapCase('-----')).to.be.equal('-----'); - chai.expect(Voca.swapCase(' ')).to.be.equal(' '); - chai.expect(Voca.swapCase('\n\n\n\n ***\t\t')).to.be.equal('\n\n\n\n ***\t\t'); - chai.expect(Voca.swapCase('')).to.be.equal(''); - }); - - it('should return the swapped case of a non-latin string', function () { - chai.expect(Voca.swapCase('zborul păsării')).to.be.equal('ZBORUL PĂSĂRII'); - chai.expect(Voca.swapCase('полет птицы')).to.be.equal('ПОЛЕТ ПТИЦЫ'); - chai.expect(Voca.swapCase('fuerza de sustentación')).to.be.equal('FUERZA DE SUSTENTACIÓN'); - chai.expect(Voca.swapCase('Skrzydło Ptaka Składa Się')).to.be.equal('sKRZYDŁO pTAKA sKŁADA sIĘ'); - }); - - it('should not modify numbers', function () { - chai.expect(Voca.swapCase(0)).to.be.equal('0'); - chai.expect(Voca.swapCase(1200)).to.be.equal('1200'); - chai.expect(Voca.swapCase('8965')).to.be.equal('8965'); - }); - - it('should return the swapped case of a string representation of an object', function () { - chai.expect(Voca.swapCase(['bird flight'])).to.be.equal('BIRD FLIGHT'); - chai.expect(Voca.swapCase({ - toString: function () { - return 'bird flight'; - } - })).to.be.equal('BIRD FLIGHT'); - }); - - it('should return empty string for null or undefined', function () { - chai.expect(Voca.swapCase()).to.be.equal(''); - chai.expect(Voca.swapCase(undefined)).to.be.equal(''); - chai.expect(Voca.swapCase(null)).to.be.equal(''); - }); -}); - -describe('upperCase', function () { - - it('should return the upper case of a string', function () { - chai.expect(Voca.upperCase('Saturn')).to.be.equal('SATURN'); - chai.expect(Voca.upperCase('Earth')).to.be.equal('EARTH'); - chai.expect(Voca.upperCase('456')).to.be.equal('456'); - chai.expect(Voca.upperCase('')).to.be.equal(''); - }); - - it('should return the upper case of a string representation of an object', function () { - chai.expect(Voca.upperCase(['Venus'])).to.be.equal('VENUS'); - chai.expect(Voca.upperCase({ - toString: function () { - return 'Venus'; - } - })).to.be.equal('VENUS'); - }); - - it('should return empty string for null or undefined', function () { - chai.expect(Voca.upperCase()).to.be.equal(''); - chai.expect(Voca.upperCase(undefined)).to.be.equal(''); - chai.expect(Voca.upperCase(null)).to.be.equal(''); - }); -}); - -describe('chain', function () { - - it('should calculate the result using explicit chaining', function () { - chai.expect(Voca.chain('Hello world').value()).to.equal('Hello world'); - chai.expect(Voca.chain(' Hello world ').trim().value()).to.equal('Hello world'); - chai.expect(Voca.chain('world').isAlpha().value()).to.equal(true); - chai.expect(Voca.chain('Hello world').lowerCase().replace('hello', 'hi').upperCase().value()).to.equal('HI WORLD'); - }); - - it('should calculate the result using implicit chaining', function () { - chai.expect(Voca('Hello world').lowerCase().words()).to.eql(['hello', 'world']); - chai.expect(Voca(' Hello world ').trimLeft().count()).to.equal(13); - chai.expect(Voca('7 days').replace(/\sdays/, '').isDigit()).to.equal(true); - chai.expect(Voca('7 days').replace(/\sdays/, '').value()).to.equal('7'); - }); - - it('should transform implicit into explicit chaining', function () { - chai.expect(Voca('Hello world').chain().lowerCase().words().value()).to.eql(['hello', 'world']); - chai.expect(Voca('15').chain().isNumeric().value()).to.equal(true); - chai.expect(Voca('15').chain().isNumeric().thru(function (isNumeric) { - return isNumeric ? 1 : 0; - }).value()).to.be.equal(1); - }); - - it('should allow to pass thru the wrapped value', function () { - chai.expect(Voca('Hello world').chain().lowerCase().words().thru(function (words) { - return words[0]; - }).value()).to.equal('hello'); - chai.expect(Voca.chain('15').isNumeric().thru().value()).to.equal(true); - }); - - it('wrapper object should coerce to a primitive', function () { - chai.expect('nice' + Voca.chain(' evening ').trimRight()).to.be.equal('nice evening'); - chai.expect(Voca('clouds').upperCase() == 'CLOUDS').to.be.true; - }); - - it('wrapper object should coerce to a string', function () { - chai.expect('nice ' + Voca.chain('hello world').words()).to.be.equal('nice hello,world'); - chai.expect(Voca('green tree').split(' ') == 'green,tree').to.be.true; - }); - - it('wrapper object should provide toJSON method', function () { - chai.expect(JSON.stringify(Voca.chain('happy coding').upperCase().split(' '))).to.be.equal('["HAPPY","CODING"]'); - }); -}); - -describe('charAt', function () { - - it('should return the character by index', function () { - chai.expect(Voca.charAt('Good day', 0)).to.be.equal('G'); - chai.expect(Voca.charAt('Good day', 1)).to.be.equal('o'); - chai.expect(Voca.charAt('Good day', 7)).to.be.equal('y'); - chai.expect(Voca.charAt(PRINTABLE_ASCII, 0)).to.be.equal(' '); - chai.expect(Voca.charAt('', 0)).to.be.equal(''); - chai.expect(Voca.charAt('Good day')).to.be.equal('G'); - chai.expect(Voca.charAt('Good day', undefined)).to.be.equal('G'); - chai.expect(Voca.charAt('Good day', null)).to.be.equal('G'); - chai.expect(Voca.charAt('Good day', NaN)).to.be.equal('G'); - }); - - it('should return an empty string for out of bounds index', function () { - chai.expect(Voca.charAt('Good day', -1)).to.be.equal(''); - chai.expect(Voca.charAt('Good day', 100)).to.be.equal(''); - }); - - it('should return the character by index of a string representation of an object', function () { - chai.expect(Voca.charAt(['Good evening'], 5)).to.be.equal('e'); - chai.expect(Voca.charAt({ - toString: function () { - return 'Morning'; - } - }, 1)).to.be.equal('o'); - }); - - it('should return an empty string for null or undefined', function () { - chai.expect(Voca.charAt()).to.be.equal(''); - chai.expect(Voca.charAt(undefined)).to.be.equal(''); - chai.expect(Voca.charAt(null)).to.be.equal(''); - chai.expect(Voca.charAt(null, null)).to.be.equal(''); - chai.expect(Voca.charAt(undefined, undefined)).to.be.equal(''); - }); -}); - -describe('codePointAt', function () { - - it('should return the code pount number by position', function () { - chai.expect(Voca.codePointAt('Good day', 0)).to.be.equal(0x0047); - chai.expect(Voca.codePointAt('Good day', 1)).to.be.equal(0x006F); - chai.expect(Voca.codePointAt('Good day', 7)).to.be.equal(0x0079); - chai.expect(Voca.codePointAt(PRINTABLE_ASCII, 0)).to.be.equal(0x0020); - chai.expect(Voca.codePointAt('man\u0303ana', 2)).to.equal(0x006E); - chai.expect(Voca.codePointAt('\u00E9\u20DD', 0)).to.equal(0x00E9); - chai.expect(Voca.codePointAt('\uD835\uDC00\uD835\uDC01', 0)).to.equal(0x1D400); - chai.expect(Voca.codePointAt('\uD835\uDC00\uD835\uDC01', 1)).to.equal(0xDC00); - chai.expect(Voca.codePointAt('\uD835\uDC00\uD835\uDC01', 2)).to.equal(0x1D401); - chai.expect(Voca.codePointAt('\uD835\uDC00\uD835\uDC01', 3)).to.equal(0xDC01); - chai.expect(Voca.codePointAt('cafe\u0301', 3)).to.equal(0x0065); - chai.expect(Voca.codePointAt('cafe\u0301', 4)).to.equal(0x0301); - chai.expect(Voca.codePointAt('foo\u0303\u035C\u035D\u035Ebar', 2)).to.equal(0x006F); - chai.expect(Voca.codePointAt('foo\uD834\uDF06\u0303\u035C\u035D\u035Ebar\uD834\uDF06\u0303\u035C\u035D', 3)).to.equal(0x1D306); - chai.expect(Voca.codePointAt('foo\uD834\uDF06\u0303\u035C\u035D\u035Ebar\uD834\uDF06\u0303\u035C\u035D', 12)).to.equal(0x1D306); - chai.expect(Voca.codePointAt('foo\uD834\uDF06\u0303\u035C\u035D\u035Ebar\uD834\uDF06\u0303\u035C\u035D', 13)).to.equal(0xDF06); - chai.expect(Voca.codePointAt('Good day')).to.be.equal(0x0047); - chai.expect(Voca.codePointAt('Good day', undefined)).to.be.equal(0x0047); - chai.expect(Voca.codePointAt('Good day', null)).to.be.equal(0x0047); - chai.expect(Voca.codePointAt('Good day', NaN)).to.be.equal(0x0047); - chai.expect(Voca.codePointAt(String.fromCharCode(0xD835) + '0', 0)).to.be.equal(0xD835); - }); - - it('should return undefined for out of bounds position', function () { - chai.expect(Voca.codePointAt('Good day', -1)).to.be.equal(undefined); - chai.expect(Voca.codePointAt('Good day', 100)).to.be.equal(undefined); - chai.expect(Voca.codePointAt('cafe\u0301', 5)).to.be.equal(undefined); - chai.expect(Voca.codePointAt('\uD835\uDC00\uD835\uDC01', 4)).to.equal(undefined); - chai.expect(Voca.codePointAt('', 0)).to.be.equal(undefined); - }); - - it('should return the code point number by position in a string representation of an object', function () { - chai.expect(Voca.codePointAt(['Good evening'], 5)).to.be.equal(0x0065); - chai.expect(Voca.codePointAt({ - toString: function () { - return 'Morning'; - } - }, 1)).to.be.equal(0x006F); - }); - - it('should return undefined for null or undefined', function () { - chai.expect(Voca.codePointAt()).to.be.equal(undefined); - chai.expect(Voca.codePointAt(undefined)).to.be.equal(undefined); - chai.expect(Voca.codePointAt(null)).to.be.equal(undefined); - chai.expect(Voca.codePointAt(null, null)).to.be.equal(undefined); - chai.expect(Voca.codePointAt(undefined, undefined)).to.be.equal(undefined); - }); -}); - -describe('graphemeAt', function () { - - it('should return the grapheme by index', function () { - chai.expect(Voca.graphemeAt('Good day', 0)).to.be.equal('G'); - chai.expect(Voca.graphemeAt('Good day', 1)).to.be.equal('o'); - chai.expect(Voca.graphemeAt('Good day', 7)).to.be.equal('y'); - chai.expect(Voca.graphemeAt(PRINTABLE_ASCII, 0)).to.be.equal(' '); - chai.expect(Voca.graphemeAt('man\u0303ana', 2)).to.equal('n\u0303'); - chai.expect(Voca.graphemeAt('\u00E9\u20DD', 0)).to.equal('\u00E9\u20DD'); - chai.expect(Voca.graphemeAt('\uD835\uDC00\uD835\uDC01', 1)).to.equal('\uD835\uDC01'); - chai.expect(Voca.graphemeAt('cafe\u0301', 3)).to.equal('e\u0301'); - chai.expect(Voca.graphemeAt('foo\u0303\u035C\u035D\u035Ebar', 2)).to.equal('o\u0303\u035C\u035D\u035E'); - chai.expect(Voca.graphemeAt('foo\uD834\uDF06\u0303\u035C\u035D\u035Ebar\uD834\uDF06\u0303\u035C\u035D', 3)).to.equal('\uD834\uDF06\u0303\u035C\u035D\u035E'); - chai.expect(Voca.graphemeAt('foo\uD834\uDF06\u0303\u035C\u035D\u035Ebar\uD834\uDF06\u0303\u035C\u035D', 7)).to.equal('\uD834\uDF06\u0303\u035C\u035D'); - chai.expect(Voca.graphemeAt('', 0)).to.be.equal(''); - chai.expect(Voca.graphemeAt('Good day')).to.be.equal('G'); - chai.expect(Voca.graphemeAt('Good day', undefined)).to.be.equal('G'); - chai.expect(Voca.graphemeAt('Good day', null)).to.be.equal('G'); - chai.expect(Voca.graphemeAt('Good day', NaN)).to.be.equal('G'); - }); - - it('should return an empty string for out of bounds index', function () { - chai.expect(Voca.graphemeAt('Good day', -1)).to.be.equal(''); - chai.expect(Voca.graphemeAt('Good day', 100)).to.be.equal(''); - chai.expect(Voca.graphemeAt('cafe\u0301', 4)).to.be.equal(''); - }); - - it('should return the grapheme by index of a string representation of an object', function () { - chai.expect(Voca.graphemeAt(['Good evening'], 5)).to.be.equal('e'); - chai.expect(Voca.graphemeAt({ - toString: function () { - return 'Morning'; - } - }, 1)).to.be.equal('o'); - }); - - it('should return an empty string for null or undefined', function () { - chai.expect(Voca.graphemeAt()).to.be.equal(''); - chai.expect(Voca.graphemeAt(undefined)).to.be.equal(''); - chai.expect(Voca.graphemeAt(null)).to.be.equal(''); - chai.expect(Voca.graphemeAt(null, null)).to.be.equal(''); - chai.expect(Voca.graphemeAt(undefined, undefined)).to.be.equal(''); - }); -}); - -describe('first', function () { - - it('should return the first part of a string', function () { - chai.expect(Voca.first('Good day', -1)).to.be.equal(''); - chai.expect(Voca.first('Good day', 0)).to.be.equal(''); - chai.expect(Voca.first('Good day', 4)).to.be.equal('Good'); - chai.expect(Voca.first('Good day', 1)).to.be.equal('G'); - chai.expect(Voca.first('Good day', 8)).to.be.equal('Good day'); - chai.expect(Voca.first('Good day', 1000)).to.be.equal('Good day'); - chai.expect(Voca.first('Good day')).to.be.equal('G'); - chai.expect(Voca.first('', 5)).to.be.equal(''); - chai.expect(Voca.first('', 0)).to.be.equal(''); - chai.expect(Voca.first('')).to.be.equal(''); - chai.expect(Voca.first(PRINTABLE_ASCII, PRINTABLE_ASCII.length)).to.be.equal(PRINTABLE_ASCII); - chai.expect(Voca.first(PRINTABLE_ASCII, 1)).to.be.equal(PRINTABLE_ASCII[0]); - }); - - it('should return the first part of a string representation of an object', function () { - chai.expect(Voca.first(['Good evening'], 5)).to.be.equal('Good '); - chai.expect(Voca.first({ - toString: function () { - return 'Morning'; - } - }, 2)).to.be.equal('Mo'); - }); - - it('should return an empty string for null or undefined', function () { - chai.expect(Voca.first()).to.be.equal(''); - chai.expect(Voca.first(undefined)).to.be.equal(''); - chai.expect(Voca.first(null)).to.be.equal(''); - chai.expect(Voca.first(null, null)).to.be.equal(''); - chai.expect(Voca.first(undefined, undefined)).to.be.equal(''); - }); -}); - -describe('last', function () { - - it('should return the last part of a string', function () { - chai.expect(Voca.last('Good day', -1)).to.be.equal(''); - chai.expect(Voca.last('Good day', 0)).to.be.equal(''); - chai.expect(Voca.last('Good day', 4)).to.be.equal(' day'); - chai.expect(Voca.last('Good day', 1)).to.be.equal('y'); - chai.expect(Voca.last('Good day', 8)).to.be.equal('Good day'); - chai.expect(Voca.last('Good day', 1000)).to.be.equal('Good day'); - chai.expect(Voca.last('Good day')).to.be.equal('y'); - chai.expect(Voca.last('', 5)).to.be.equal(''); - chai.expect(Voca.last('', 0)).to.be.equal(''); - chai.expect(Voca.last('')).to.be.equal(''); - chai.expect(Voca.last(PRINTABLE_ASCII, PRINTABLE_ASCII.length)).to.be.equal(PRINTABLE_ASCII); - chai.expect(Voca.last(PRINTABLE_ASCII, 1)).to.be.equal(PRINTABLE_ASCII[PRINTABLE_ASCII.length - 1]); - }); - - it('should return the last part of a string representation of an object', function () { - chai.expect(Voca.last(['Good evening'], 5)).to.be.equal('ening'); - chai.expect(Voca.last({ - toString: function () { - return 'Morning'; - } - }, 2)).to.be.equal('ng'); - }); - - it('should return an empty string for null or undefined', function () { - chai.expect(Voca.last()).to.be.equal(''); - chai.expect(Voca.last(undefined)).to.be.equal(''); - chai.expect(Voca.last(null)).to.be.equal(''); - chai.expect(Voca.last(null, null)).to.be.equal(''); - chai.expect(Voca.last(undefined, undefined)).to.be.equal(''); - }); -}); - -describe('prune', function () { - - it('should prune a string', function () { - chai.expect(Voca.prune('Once upon a time there lived in a certain village a little country girl', 7)).to.be.equal('Once...'); - chai.expect(Voca.prune('I\'ll go this way and go you that', 19, ' (read more)')).to.be.equal('I\'ll go (read more)'); - chai.expect(Voca.prune('Little Red Riding Hood', 6, '...')).to.be.equal('...'); - chai.expect(Voca.prune('Little Red Riding Hood', 9, '...')).to.be.equal('Little...'); - chai.expect(Voca.prune('Little Red Riding Hood', 11, '...')).to.be.equal('Little...'); - chai.expect(Voca.prune('Little Red Riding Hood', 20, '...')).to.be.equal('Little Red Riding...'); - chai.expect(Voca.prune('Little Red Riding Hood', 22, '...')).to.be.equal('Little Red Riding Hood'); - chai.expect(Voca.prune('Little Red Riding Hood', 1, '...')).to.be.equal('...'); - chai.expect(Voca.prune('Little Red Riding Hood', 5, '...')).to.be.equal('...'); - chai.expect(Voca.prune('Little Red Riding Hood', 0, '(more)')).to.be.equal('(more)'); - chai.expect(Voca.prune(PRINTABLE_ASCII, PRINTABLE_ASCII.length)).to.be.equal(PRINTABLE_ASCII); - chai.expect(Voca.prune(PRINTABLE_ASCII, 0)).to.be.equal('...'); - }); - - it('should prune a string with extra ASCII characters', function () { - chai.expect(Voca.prune('Привет, как дела', 10, '...')).to.be.equal('Привет...'); - chai.expect(Voca.prune('La variété la plus fréquente est la blanche', 12, '..')).to.be.equal('La variété..'); - }); - - it('should not prune a string if length parameter is greater or equal than string length', function () { - chai.expect(Voca.prune('Once upon', 20)).to.be.equal('Once upon'); - chai.expect(Voca.prune('Once', 4, ' (read more)')).to.be.equal('Once'); - chai.expect(Voca.prune('', 0, '....')).to.be.equal(''); - }); - - it('should prune a string representation of an object', function () { - chai.expect(Voca.prune(['Welcome'], 4)).to.be.equal('...'); - chai.expect(Voca.prune({ - toString: function () { - return 'Have a nice day'; - } - }, 6, '..')).to.be.equal('Have..'); - }); - - it('should return an empty string for null or undefined', function () { - chai.expect(Voca.prune()).to.be.equal(''); - chai.expect(Voca.prune(undefined)).to.be.equal(''); - chai.expect(Voca.prune(null)).to.be.equal(''); - }); -}); - -describe('slice', function () { - - it('should slice a string', function () { - chai.expect(Voca.slice('infinite loop', 9)).to.be.equal('loop'); - chai.expect(Voca.slice('infinite loop', 0)).to.be.equal('infinite loop'); - chai.expect(Voca.slice('infinite loop')).to.be.equal('infinite loop'); - chai.expect(Voca.slice('infinite loop', 1)).to.be.equal('nfinite loop'); - chai.expect(Voca.slice(PRINTABLE_ASCII, 0)).to.be.equal(PRINTABLE_ASCII); - }); - - it('should slice a string with an end position', function () { - chai.expect(Voca.slice('infinite loop', 9, 12)).to.be.equal('loo'); - chai.expect(Voca.slice('infinite loop', 9, -1)).to.be.equal('loo'); - chai.expect(Voca.slice('infinite loop', 0, 'infinite loop'.length)).to.be.equal('infinite loop'); - chai.expect(Voca.slice('infinite loop', 1, 2)).to.be.equal('n'); - chai.expect(Voca.slice('infinite loop', -4, -1)).to.be.equal('loo'); - }); - - it('should slice a string representation of an object', function () { - chai.expect(Voca.slice(['infinite loop'], 10)).to.be.equal('oop'); - chai.expect(Voca.slice({ - toString: function () { - return 'loop'; - } - }, 0, 3)).to.be.equal('loo'); - }); - - it('should slice a string from a number', function () { - chai.expect(Voca.slice(12345, 3)).to.be.equal('45'); - chai.expect(Voca.slice(987, 1, 2)).to.be.equal('8'); - }); -}); - -describe('substr', function () { - - it('should substract a string', function () { - chai.expect(Voca.substr('infinite loop', 9)).to.be.equal('loop'); - chai.expect(Voca.substr('infinite loop', 0)).to.be.equal('infinite loop'); - chai.expect(Voca.substr('infinite loop')).to.be.equal('infinite loop'); - chai.expect(Voca.substr('infinite loop', 1)).to.be.equal('nfinite loop'); - chai.expect(Voca.substr('infinite loop', -4)).to.be.equal('loop'); - chai.expect(Voca.substr(PRINTABLE_ASCII, 0)).to.be.equal(PRINTABLE_ASCII); - }); - - it('should substract a string with a length', function () { - chai.expect(Voca.substr('infinite loop', 9, 3)).to.be.equal('loo'); - chai.expect(Voca.substr('infinite loop', 0, 'infinite loop'.length)).to.be.equal('infinite loop'); - chai.expect(Voca.substr('infinite loop', 1, 1)).to.be.equal('n'); - chai.expect(Voca.substr('infinite loop', -4, 1)).to.be.equal('l'); - }); - - it('should substract a string representation of an object', function () { - chai.expect(Voca.substr(['infinite loop'], 10)).to.be.equal('oop'); - chai.expect(Voca.substr({ - toString: function () { - return 'loop'; - } - }, 0, 3)).to.be.equal('loo'); - }); - - it('should substract a string from a number', function () { - chai.expect(Voca.substr(12345, 3)).to.be.equal('45'); - chai.expect(Voca.substr(987, 1, 1)).to.be.equal('8'); - }); -}); - -describe('substring', function () { - - it('should substring a string', function () { - chai.expect(Voca.substring('infinite loop', 9)).to.be.equal('loop'); - chai.expect(Voca.substring('infinite loop', 0)).to.be.equal('infinite loop'); - chai.expect(Voca.substring('infinite loop')).to.be.equal('infinite loop'); - chai.expect(Voca.substring('infinite loop', 1)).to.be.equal('nfinite loop'); - chai.expect(Voca.substring(PRINTABLE_ASCII, 0)).to.be.equal(PRINTABLE_ASCII); - }); - - it('should substring a string with an end position', function () { - chai.expect(Voca.substring('infinite loop', 9, 12)).to.be.equal('loo'); - chai.expect(Voca.substring('infinite loop', 0, 'infinite loop'.length)).to.be.equal('infinite loop'); - chai.expect(Voca.substring('infinite loop', 1, 2)).to.be.equal('n'); - }); - - it('should substring a string representation of an object', function () { - chai.expect(Voca.substring(['infinite loop'], 10)).to.be.equal('oop'); - chai.expect(Voca.substring({ - toString: function () { - return 'loop'; - } - }, 0, 3)).to.be.equal('loo'); - }); - - it('should substring a string from a number', function () { - chai.expect(Voca.substring(12345, 3)).to.be.equal('45'); - chai.expect(Voca.substring(987, 1, 2)).to.be.equal('8'); - }); -}); - -describe('truncate', function () { - - it('should truncate a string', function () { - chai.expect(Voca.truncate('Once upon a time there lived in a certain village a little country girl', 4)).to.be.equal('O...'); - chai.expect(Voca.truncate('I\'ll go this way and go you that', 19, ' (read more)')).to.be.equal('I\'ll go (read more)'); - chai.expect(Voca.truncate('Little Red Riding Hood', 9, '...')).to.be.equal('Little...'); - chai.expect(Voca.truncate('Little Red Riding Hood', 0, '(more)')).to.be.equal('(more)'); - chai.expect(Voca.truncate('Little Red Riding Hood', 1, '(more)')).to.be.equal('(more)'); - chai.expect(Voca.truncate('Little Red Riding Hood', 2, '(more)')).to.be.equal('(more)'); - chai.expect(Voca.truncate('Little Red Riding Hood', 3, '(more)')).to.be.equal('(more)'); - chai.expect(Voca.truncate('Little Red Riding Hood', 6, '(more)')).to.be.equal('(more)'); - chai.expect(Voca.truncate('Little Red Riding Hood', 7, '(more)')).to.be.equal('L(more)'); - chai.expect(Voca.truncate('Little Red Riding Hood', 7, '')).to.be.equal('Little '); - chai.expect(Voca.truncate('Little Red Riding Hood', 0, '')).to.be.equal(''); - chai.expect(Voca.truncate(PRINTABLE_ASCII, PRINTABLE_ASCII.length)).to.be.equal(PRINTABLE_ASCII); - chai.expect(Voca.truncate(PRINTABLE_ASCII, 0)).to.be.equal('...'); - }); - - it('should not truncate a string if length parameter is greater or equal than string length', function () { - chai.expect(Voca.truncate('Once upon', 20)).to.be.equal('Once upon'); - chai.expect(Voca.truncate('Once', 4, ' (read more)')).to.be.equal('Once'); - chai.expect(Voca.truncate('', 0, '....')).to.be.equal(''); - }); - - it('should truncate a string representation of an object', function () { - chai.expect(Voca.truncate(['Welcome'], 6)).to.be.equal('Wel...'); - chai.expect(Voca.truncate({ - toString: function () { - return 'Have a nice day'; - } - }, 4, '..')).to.be.equal('Ha..'); - }); - - it('should return an empty string for null or undefined', function () { - chai.expect(Voca.truncate()).to.be.equal(''); - chai.expect(Voca.truncate(undefined)).to.be.equal(''); - chai.expect(Voca.truncate(null)).to.be.equal(''); - }); -}); - -describe('count', function () { - - it('should return the number of characters in a string', function () { - chai.expect(Voca.count('rain')).to.be.equal(4); - chai.expect(Voca.count('')).to.be.equal(0); - chai.expect(Voca.count('rainbow')).to.be.equal(7); - chai.expect(Voca.count(PRINTABLE_ASCII)).to.be.equal(PRINTABLE_ASCII.length); - }); - - it('should return the number of characters in a number', function () { - chai.expect(Voca.count(123)).to.be.equal(3); - chai.expect(Voca.count(0)).to.be.equal(1); - chai.expect(Voca.count(-1.5)).to.be.equal(4); - }); - - it('should return the number of characters in a string representation of an object', function () { - chai.expect(Voca.count(['droplet'])).to.be.equal(7); - chai.expect(Voca.count({ - toString: function () { - return 'rainfall'; - } - })).to.be.equal(8); - }); - - it('should return zero for undefined or null', function () { - chai.expect(Voca.count()).to.be.equal(0); - chai.expect(Voca.count(null)).to.be.equal(0); - chai.expect(Voca.count(undefined)).to.be.equal(0); - }); -}); - -describe('countGraphemes', function () { - - it('should return the number of characters in a string', function () { - chai.expect(Voca.countGraphemes('rain')).to.be.equal(4); - chai.expect(Voca.countGraphemes('')).to.be.equal(0); - chai.expect(Voca.countGraphemes('rainbow')).to.be.equal(7); - chai.expect(Voca.countGraphemes('\u00E9\u20DD')).to.be.equal(1); - chai.expect(Voca.countGraphemes('\uD835\uDC00\uD835\uDC01')).to.be.equal(2); - chai.expect(Voca.countGraphemes('man\u0303ana')).to.be.equal(6); - chai.expect(Voca.countGraphemes('cafe\u0301')).to.be.equal(4); - chai.expect(Voca.countGraphemes('foo\u0303\u035C\u035D\u035Ebar')).to.be.equal(6); - chai.expect(Voca.countGraphemes('foo\uD834\uDF06\u0303\u035C\u035D\u035Ebar')).to.be.equal(7); - chai.expect(Voca.countGraphemes(PRINTABLE_ASCII)).to.be.equal(PRINTABLE_ASCII.length); - }); - - it('should return the number of characters in a number', function () { - chai.expect(Voca.countGraphemes(123)).to.be.equal(3); - chai.expect(Voca.countGraphemes(0)).to.be.equal(1); - chai.expect(Voca.countGraphemes(-1.5)).to.be.equal(4); - }); - - it('should return the number of characters in a string representation of an object', function () { - chai.expect(Voca.countGraphemes(['droplet'])).to.be.equal(7); - chai.expect(Voca.countGraphemes({ - toString: function () { - return 'rainfall'; - } - })).to.be.equal(8); - }); - - it('should return zero for undefined or null', function () { - chai.expect(Voca.countGraphemes()).to.be.equal(0); - chai.expect(Voca.countGraphemes(null)).to.be.equal(0); - chai.expect(Voca.countGraphemes(undefined)).to.be.equal(0); - }); -}); - -describe('countSubstrings', function () { - - it('should return the number of substring appearances in a string', function () { - chai.expect(Voca.countSubstrings('Hey man where-where-where\'s your cup holder?', 'where')).to.be.equal(3); - chai.expect(Voca.countSubstrings('And some Skittles', 'Skittles')).to.be.equal(1); - chai.expect(Voca.countSubstrings('And some Skittles', 'chocolate')).to.be.equal(0); - chai.expect(Voca.countSubstrings('******', '*')).to.be.equal(6); - chai.expect(Voca.countSubstrings('*******', '**')).to.be.equal(3); - chai.expect(Voca.countSubstrings('*******', '**-')).to.be.equal(0); - chai.expect(Voca.countSubstrings('*******', '***')).to.be.equal(2); - chai.expect(Voca.countSubstrings('*******', '****')).to.be.equal(1); - chai.expect(Voca.countSubstrings('*******', '********')).to.be.equal(0); - chai.expect(Voca.countSubstrings('*-*-*', '**')).to.be.equal(0); - chai.expect(Voca.countSubstrings('', '')).to.be.equal(0); - chai.expect(Voca.countSubstrings(PRINTABLE_ASCII, '#')).to.be.equal(1); - }); - - it('should return the number of appearances of a number in a number', function () { - chai.expect(Voca.countSubstrings(111222, 1)).to.be.equal(3); - chai.expect(Voca.countSubstrings(0, 0)).to.be.equal(1); - chai.expect(Voca.countSubstrings(15, 16)).to.be.equal(0); - }); - - it('should return the number of substring appearances in a string representation of an object', function () { - chai.expect(Voca.countSubstrings(['where-where-where'], 'where')).to.be.equal(3); - chai.expect(Voca.countSubstrings({ - toString: function () { - return 'where-where-where'; - } - }, 'where')).to.be.equal(3); - }); - - it('should return zero for undefined or null', function () { - chai.expect(Voca.countSubstrings()).to.be.equal(0); - chai.expect(Voca.countSubstrings(undefined)).to.be.equal(0); - chai.expect(Voca.countSubstrings(null)).to.be.equal(0); - chai.expect(Voca.countSubstrings(undefined, undefined)).to.be.equal(0); - chai.expect(Voca.countSubstrings(null, null)).to.be.equal(0); - }); -}); - -describe('countWhere', function () { - - it('should return the number of characters in a string for a predicate', function () { - chai.expect(Voca.countWhere('', Voca.isAlpha)).to.be.equal(0); - chai.expect(Voca.countWhere('africa654', Voca.isAlpha)).to.be.equal(6); - chai.expect(Voca.countWhere('790', Voca.isAlpha)).to.be.equal(0); - chai.expect(Voca.countWhere(PRINTABLE_ASCII, Voca.isDigit)).to.be.equal(10); - chai.expect(Voca.countWhere('****--**--**', function (character) { - return character === '*'; - })).to.be.equal(8); - chai.expect(Voca.countWhere('****--**--**', function () { - return false; - })).to.be.equal(0); - }); - - it('should invoke the predicate with correct parameters and context', function () { - var verifyIndex = 0; - var context = {}; - var verifyString = '0123456789'; - chai.expect(Voca.countWhere(verifyString, function (character, index, string) { - chai.expect(index).to.be.equal(verifyIndex); - chai.expect(this).to.be.equal(context); - chai.expect(string).to.be.equal(verifyString); - chai.expect(character).to.be.equal(verifyString[verifyIndex]); - verifyIndex++; - return true; - }, context)).to.be.equal(10); - }); - - it('should return the number of characters in a number for a predicate', function () { - chai.expect(Voca.countWhere(123, Voca.isDigit)).to.be.equal(3); - chai.expect(Voca.countWhere(0, Voca.isDigit)).to.be.equal(1); - chai.expect(Voca.countWhere(-1.5, Voca.isDigit)).to.be.equal(2); - }); - - it('should return the number of characters in a string representation of an object for a predicate', function () { - chai.expect(Voca.countWhere(['droplet'], Voca.isDigit)).to.be.equal(0); - chai.expect(Voca.countWhere({ - toString: function () { - return 'homo sapiens'; - } - }, Voca.isAlphaDigit)).to.be.equal(11); - }); - - it('should return zero for a non function predicate', function () { - chai.expect(Voca.countWhere('africa')).to.be.equal(0); - chai.expect(Voca.countWhere('africa', undefined)).to.be.equal(0); - chai.expect(Voca.countWhere('africa', null)).to.be.equal(0); - chai.expect(Voca.countWhere('africa', 'africa')).to.be.equal(0); - chai.expect(Voca.countWhere('africa', 0)).to.be.equal(0); - chai.expect(Voca.countWhere()).to.be.equal(0); - }); -}); - -describe('countcountWords', function () { - - it('should the words in a string', function () { - chai.expect(Voca.countWords('123')).to.equal(1); - chai.expect(Voca.countWords('15+20=35')).to.equal(3); - chai.expect(Voca.countWords('hello')).to.equal(1); - chai.expect(Voca.countWords(' hello ')).to.equal(1); - chai.expect(Voca.countWords('hello world')).to.equal(2); - chai.expect(Voca.countWords('12+14-18*400')).to.equal(4); - chai.expect(Voca.countWords('gravity can cross dimensions')).to.equal(4); - chai.expect(Voca.countWords('-gravity-can-cross-dimensions-')).to.equal(4); - chai.expect(Voca.countWords('gravity_can_cross_dimensions')).to.equal(4); - chai.expect(Voca.countWords('*gravity***can****cross&&dimensions++')).to.equal(4); - chai.expect(Voca.countWords('GravityCanCrossDimensions')).to.equal(4); - chai.expect(Voca.countWords('GRAVITYCan')).to.equal(2); - chai.expect(Voca.countWords('GravityCan')).to.equal(2); - chai.expect(Voca.countWords('GravityCANAttract')).to.equal(3); - chai.expect(Voca.countWords('gravityCan')).to.equal(2); - chai.expect(Voca.countWords('Gravity-Can11Cross **Dimensions1Foo')).to.equal(7); - chai.expect(Voca.countWords('Cooper... Cooper... Come in, Cooper.')).to.equal(5); - chai.expect(Voca.countWords('Newton\'s third law')).to.equal(4); - chai.expect(Voca.countWords('Newton\'s thIrd lAw')).to.equal(6); - chai.expect(Voca.countWords(PRINTABLE_ASCII)).to.equal(3); - chai.expect(Voca.countWords('')).to.equal(0); - chai.expect(Voca.countWords()).to.equal(0); - chai.expect(Voca.countWords(' ')).to.equal(0); - chai.expect(Voca.countWords(' ')).to.equal(0); - chai.expect(Voca.countWords('\n')).to.equal(0); - chai.expect(Voca.countWords('***')).to.equal(0); - chai.expect(Voca.countWords('***---')).to.equal(0); - chai.expect(Voca.countWords('***---')).to.equal(0); - chai.expect(Voca.countWords('man\u0303ana')).to.equal(1); - chai.expect(Voca.countWords('maN\u0303ana')).to.equal(2); - chai.expect(Voca.countWords('foo\u0303\u035C\u035D\u035E bar')).to.equal(2); - chai.expect(Voca.countWords('fo-O-O\u0303\u035C\u035D\u035E-bar')).to.equal(4); - }); - - it('should count the words in a string with diacritics', function () { - chai.expect(Voca.countWords('clasificación biológica.')).to.equal(2); - chai.expect(Voca.countWords('BunăZiua')).to.equal(2); - chai.expect(Voca.countWords('Bună1ZiUa!')).to.equal(4); - chai.expect(Voca.countWords('Język /polski wywodzi się z` języka` praindoeuropejskiego za**pośrednictwem+języka-prasłowiańskiego.')).to.equal(11); - chai.expect(Voca.countWords('Гравитация притягивает все')).to.equal(3); - chai.expect(Voca.countWords('Гравитация-Притягивает-ВСЕ!!')).to.equal(3); - chai.expect(Voca.countWords('Στις--αρχές** (του) 21ου, αιώνα!')).to.equal(6); - }); - - it('should count the countWords in a string representation of an object', function () { - chai.expect(Voca.countWords(['GravityCanCrossDimensions'])).to.equal(4); - chai.expect(Voca.countWords({ - toString: function () { - return 'Gr4v1ty'; - } - })).to.equal(5); - }); - - it('should count the words in a string into countWords using a pattern', function () { - chai.expect(Voca.countWords('1234567890', /\d/g)).to.equal(10); - chai.expect(Voca.countWords('gravity', /\w{1,2}/g)).to.equal(4); - chai.expect(Voca.countWords('gravity can cross dimensions', '\\w+(?=\\s?)', 'g')).to.equal(4); - chai.expect(Voca.countWords('1234567890', /\s/g)).to.equal(0); - }); - - it('should count the words in a string with default pattern for null and undefined', function () { - chai.expect(Voca.countWords('gravity_can_cross_dimensions', null)).to.equal(4); - chai.expect(Voca.countWords('gravity_can_cross_dimensions', undefined)).to.equal(4); - }); -}); - -describe('escapeHtml', function () { - - it('should return the escaped string', function () { - chai.expect(Voca.escapeHtml('<>&"\'`')).to.be.equal('<>&"'`'); - chai.expect(Voca.escapeHtml('

wonderful world

')).to.be.equal('<p>wonderful world</p>'); - chai.expect(Voca.escapeHtml(PRINTABLE_ASCII)).to.be.equal(' !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~'); - }); - - it('should return the escaped string representation of an object', function () { - chai.expect(Voca.escapeHtml([''])).to.be.equal('<span>'); - chai.expect(Voca.escapeHtml({ - toString: function () { - return '')).to.be.equal(' echo hello '); - chai.expect(Voca.stripTags('hello

world

')).to.be.equal('helloworld'); - }); - - it('should strip potential xss tags', function () { - /** - * @see https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet - */ - chai.expect(Voca.stripTags('')).to.be.equal('evil();'); - chai.expect(Voca.stripTags('')).to.be.equal(''); - chai.expect(Voca.stripTags('">')).to.be.equal(''); - chai.expect(Voca.stripTags('')).to.be.equal(''); - chai.expect(Voca.stripTags('')).to.be.equal(''); - chai.expect(Voca.stripTags('')).to.be.equal(''); - chai.expect(Voca.stripTags('<')).to.be.equal(''); - chai.expect(Voca.stripTags('')).to.be.equal(''); - chai.expect(Voca.stripTags('')).to.be.equal(''); - chai.expect(Voca.stripTags('')).to.be.equal(''); - chai.expect(Voca.stripTags('')).to.be.equal(''); - chai.expect(Voca.stripTags('')).to.be.equal('` SRC="httx://xss.rocks/xss.js">'); - chai.expect(Voca.stripTags('')).to.be.equal(''); - chai.expect(Voca.stripTags('PT SRC="httx://xss.rocks/xss.js">')).to.be.equal('document.write("'); - }); - - it('should strip tags which attributes contain < or > ', function () { - var helloWorld = 'hello world'; - chai.expect(Voca.stripTags('hello world')).to.be.equal(helloWorld); - chai.expect(Voca.stripTags('hello world')).to.be.equal(helloWorld); - chai.expect(Voca.stripTags('hello world')).to.be.equal(helloWorld); - chai.expect(Voca.stripTags("hello world")).to.be.equal(helloWorld); - chai.expect(Voca.stripTags("hello world")).to.be.equal(helloWorld); - }); - - it('should strip tags on multiple lines', function () { - var multilineHtml = 'This\'s a string with quotes:\n"strings in double quote";\n\'strings in single quote\';\nthis\line is single quoted /with\slashes '; - chai.expect(Voca.stripTags(multilineHtml, '')).to.be.equal(multilineHtml); - }); - - it('should strip comments and doctype', function () { - chai.expect(Voca.stripTags('')).to.be.equal(''); - chai.expect(Voca.stripTags('Hello world!')).to.be.equal('Hello world!'); - chai.expect(Voca.stripTags('Hello world!')).to.be.equal('Hello world!'); - chai.expect(Voca.stripTags('Hello world!')).to.be.equal('Hello world!'); - chai.expect(Voca.stripTags('Hello world!')).to.be.equal('Hello world!'); - }); - - it('should not strip allowable tags', function () { - chai.expect(Voca.stripTags('Hello world!', ['b'])).to.be.equal('Hello world!'); - chai.expect(Voca.stripTags('Hello world!', ['b'])).to.be.equal('Hello world!'); - chai.expect(Voca.stripTags('Hello world!', '')).to.be.equal('Hello world!'); - var helloWorldHtml = '

hello

world
Other text'; - chai.expect(Voca.stripTags(helloWorldHtml, '')).to.be.equal('helloworldOther text'); - chai.expect(Voca.stripTags(helloWorldHtml, ['p'])).to.be.equal('

hello

worldOther text'); - chai.expect(Voca.stripTags(helloWorldHtml, '')).to.be.equal('helloworldOther text'); - chai.expect(Voca.stripTags(helloWorldHtml, ['html', 'p', 'a', 'b'])).to.be.equal(helloWorldHtml); - }); - - it('should not modify a string without tags', function () { - chai.expect(Voca.stripTags('Hello world!')).to.be.equal('Hello world!'); - chai.expect(Voca.stripTags(' ')).to.be.equal(' '); - chai.expect(Voca.stripTags('')).to.be.equal(''); - }); - - it('should add instead of stripped tags a special string', function () { - chai.expect(Voca.stripTags('
  • Recently improved articles
  • ', '', '*')).to.be.equal('***Recently improved articles***'); - chai.expect(Voca.stripTags('HelloWorld', '', ' ')).to.be.equal(' Hello World '); - chai.expect(Voca.stripTags('Line
    break', ['i'], ' ')).to.be.equal('Line break'); - }); - - it('should treat especially broken or invalid tags', function () { - chai.expect(Voca.stripTags('< html >')).to.be.equal('< html >'); - chai.expect(Voca.stripTags('<<>>')).to.be.equal(''); - var allowableTags = '

    '; - chai.expect(Voca.stripTags('<>hello<>', allowableTags)).to.be.equal('hello'); - chai.expect(Voca.stripTags('HtMl text', allowableTags)).to.be.equal('HtMl text'); - chai.expect(Voca.stripTags('I am a quoted (\") string with special chars like \$,\!,\@,\%,\&', allowableTags)).to.be.equal('I am a quoted (\") string with special chars like \$,\!,\@,\%,\&'); - chai.expect(Voca.stripTags('hello \t\tworld... strip_tags_test', allowableTags)).to.be.equal('hello \t\tworld... strip_tags_test'); - }); - - it('should strip tags from a string representation of an object', function () { - chai.expect(Voca.stripTags('Hello')).to.equal('Hello'); - chai.expect(Voca.stripTags({ - toString: function () { - return 'Hello'; - } - }, '')).to.equal('Hello'); - }); - - it('should return empty string for null or undefined', function () { - chai.expect(Voca.stripTags(null)).to.be.equal(''); - chai.expect(Voca.stripTags(null, null)).to.be.equal(''); - chai.expect(Voca.stripTags(undefined)).to.be.equal(''); - chai.expect(Voca.stripTags(undefined, '')).to.be.equal(''); - chai.expect(Voca.stripTags(undefined, undefined)).to.be.equal(''); - }); -}); - -describe('noConflict', function () { - - it('should return Voca library instance and restore v global variable', function () { - var globalObject = getGlobalObject(); - globalObject.v = Voca; - var voca = Voca.noConflict(); - chai.expect(voca).to.be.equal(Voca); - chai.expect(globalObject.v).to.be.equal(undefined); - }); - - it('should return Voca library instance and not modify v global variable', function () { - var globalObject = getGlobalObject(); - var voca = Voca.noConflict(); - chai.expect(voca).to.be.equal(Voca); - chai.expect(globalObject.v).to.be.equal(undefined); - }); -}); - -describe('version', function () { - - it('should match semantic version number pattern', function () { - chai.expect(REGEXP_SEMVER.test(Voca.version)).to.be.true; - }); -}); - -//case -//chain -//chop -//count -//escape -//helper -//format -//index -//manipulate -//query -//split -//strip -//util - -}(chai));