tfcconnection-zola/.shadow-cljs/builds/app/dev/goog-js/goog.string.string.js

1 line
138 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

["^ ","~:resource-id",["~:shadow.build.classpath/resource","goog/string/string.js"],"~:js","goog.provide(\"goog.string\");\ngoog.provide(\"goog.string.Unicode\");\ngoog.require(\"goog.dom.safe\");\ngoog.require(\"goog.html.uncheckedconversions\");\ngoog.require(\"goog.string.Const\");\ngoog.require(\"goog.string.internal\");\ngoog.string.DETECT_DOUBLE_ESCAPING = goog.define(\"goog.string.DETECT_DOUBLE_ESCAPING\", false);\ngoog.string.FORCE_NON_DOM_HTML_UNESCAPING = goog.define(\"goog.string.FORCE_NON_DOM_HTML_UNESCAPING\", false);\ngoog.string.Unicode = {NBSP:\" \", ZERO_WIDTH_SPACE:\"\"};\ngoog.string.startsWith = goog.string.internal.startsWith;\ngoog.string.endsWith = goog.string.internal.endsWith;\ngoog.string.caseInsensitiveStartsWith = goog.string.internal.caseInsensitiveStartsWith;\ngoog.string.caseInsensitiveEndsWith = goog.string.internal.caseInsensitiveEndsWith;\ngoog.string.caseInsensitiveEquals = goog.string.internal.caseInsensitiveEquals;\ngoog.string.subs = function(str, var_args) {\n const splitParts = str.split(\"%s\");\n let returnString = \"\";\n const subsArguments = Array.prototype.slice.call(arguments, 1);\n while (subsArguments.length && splitParts.length > 1) {\n returnString += splitParts.shift() + subsArguments.shift();\n }\n return returnString + splitParts.join(\"%s\");\n};\ngoog.string.collapseWhitespace = function(str) {\n return str.replace(/[\\s\\xa0]+/g, \" \").replace(/^\\s+|\\s+$/g, \"\");\n};\ngoog.string.isEmptyOrWhitespace = goog.string.internal.isEmptyOrWhitespace;\ngoog.string.isEmptyString = function(str) {\n return str.length == 0;\n};\ngoog.string.isEmpty = goog.string.isEmptyOrWhitespace;\ngoog.string.isEmptyOrWhitespaceSafe = function(str) {\n return goog.string.isEmptyOrWhitespace(goog.string.makeSafe(str));\n};\ngoog.string.isEmptySafe = goog.string.isEmptyOrWhitespaceSafe;\ngoog.string.isBreakingWhitespace = function(str) {\n return !/[^\\t\\n\\r ]/.test(str);\n};\ngoog.string.isAlpha = function(str) {\n return !/[^a-zA-Z]/.test(str);\n};\ngoog.string.isNumeric = function(str) {\n return !/[^0-9]/.test(str);\n};\ngoog.string.isAlphaNumeric = function(str) {\n return !/[^a-zA-Z0-9]/.test(str);\n};\ngoog.string.isSpace = function(ch) {\n return ch == \" \";\n};\ngoog.string.isUnicodeChar = function(ch) {\n return ch.length == 1 && ch >= \" \" && ch <= \"~\" || ch >= \"€\" && ch <= \"<22>\";\n};\ngoog.string.stripNewlines = function(str) {\n return str.replace(/(\\r\\n|\\r|\\n)+/g, \" \");\n};\ngoog.string.canonicalizeNewlines = function(str) {\n return str.replace(/(\\r\\n|\\r|\\n)/g, \"\\n\");\n};\ngoog.string.normalizeWhitespace = function(str) {\n return str.replace(/\\xa0|\\s/g, \" \");\n};\ngoog.string.normalizeSpaces = function(str) {\n return str.replace(/\\xa0|[ \\t]+/g, \" \");\n};\ngoog.string.collapseBreakingSpaces = function(str) {\n return str.replace(/[\\t\\r\\n ]+/g, \" \").replace(/^[\\t\\r\\n ]+|[\\t\\r\\n ]+$/g, \"\");\n};\ngoog.string.trim = goog.string.internal.trim;\ngoog.string.trimLeft = function(str) {\n return str.replace(/^[\\s\\xa0]+/, \"\");\n};\ngoog.string.trimRight = function(str) {\n return str.replace(/[\\s\\xa0]+$/, \"\");\n};\ngoog.string.caseInsensitiveCompare = goog.string.internal.caseInsensitiveCompare;\ngoog.string.numberAwareCompare_ = function(str1, str2, tokenizerRegExp) {\n if (str1 == str2) {\n return 0;\n }\n if (!str1) {\n return -1;\n }\n if (!str2) {\n return 1;\n }\n const tokens1 = str1.toLowerCase().match(tokenizerRegExp);\n const tokens2 = str2.toLowerCase().match(tokenizerRegExp);\n const count = Math.min(tokens1.length, tokens2.length);\n for (let i = 0; i < count; i++) {\n const a = tokens1[i];\n const b = tokens2[i];\n if (a != b) {\n const num1 = parseInt(a, 10);\n if (!isNaN(num1)) {\n const num2 = parseInt(b, 10);\n if (!isNaN(num2) && num1 - num2) {\n return num1 - num2;\n }\n }\n return a < b ? -1 : 1;\n }\n }\n if (tokens1.length != tokens2.length) {\n return tokens1.length - tokens2.length;\n }\n return str1 < str2 ? -1 : 1;\n};\ngoog.string.intAwareCompare = function(str1, str2) {\n return goog.string.numberAwareCompare_(str1, str2, /\\d+|\\D+/g);\n};\ngoog.string.floatAwareCompare = function(str1, str2) {\n return goog.string.numberAwareCompare_(str1, str2, /\\d+|\\.\\d+|\\D+/g);\n};\ngoog.string.numerateCompare = goog.string.floatAwareCompare;\ngoog.string.urlEncode = function(str) {\n return encodeURIComponent(String(str));\n};\ngoog.string.urlDecode = function(str) {\n return decodeURIComponent(str.replace(/\\+/g, \" \"));\n};\ngoog.string.newLineToBr = goog.string.internal.newLineToBr;\ngoog.string.htmlEscape = function(str, opt_isLikelyToContainHtmlChars) {\n str = goog.string.internal.htmlEscape(str, opt_isLikelyToContainHtmlChars);\n if (goog.string.DETECT_DOUBLE_ESCAPING) {\n str = str.replace(goog.string.E_RE_, \"\\x26#101;\");\n }\n return str;\n};\ngoog.string.E_RE_ = /e/g;\ngoog.string.unescapeEntities = function(str) {\n if (goog.string.contains(str, \"\\x26\")) {\n if (!goog.string.FORCE_NON_DOM_HTML_UNESCAPING && \"document\" in goog.global) {\n return goog.string.unescapeEntitiesUsingDom_(str);\n } else {\n return goog.string.unescapePureXmlEntities_(str);\n }\n }\n return str;\n};\ngoog.string.unescapeEntitiesWithDocument = function(str, document) {\n if (goog.string.contains(str, \"\\x26\")) {\n return goog.string.unescapeEntitiesUsingDom_(str, document);\n }\n return str;\n};\ngoog.string.unescapeEntitiesUsingDom_ = function(str, opt_document) {\n const seen = {\"\\x26amp;\":\"\\x26\", \"\\x26lt;\":\"\\x3c\", \"\\x26gt;\":\"\\x3e\", \"\\x26quot;\":'\"'};\n let div;\n if (opt_document) {\n div = opt_document.createElement(\"div\");\n } else {\n div = goog.global.document.createElement(\"div\");\n }\n return str.replace(goog.string.HTML_ENTITY_PATTERN_, function(s, entity) {\n let value = seen[s];\n if (value) {\n return value;\n }\n if (entity.charAt(0) == \"#\") {\n const n = Number(\"0\" + entity.slice(1));\n if (!isNaN(n)) {\n value = String.fromCharCode(n);\n }\n }\n if (!value) {\n goog.dom.safe.setInnerHtml(div, goog.html.uncheckedconversions.safeHtmlFromStringKnownToSatisfyTypeContract(goog.string.Const.from(\"Single HTML entity.\"), s + \" \"));\n value = div.firstChild.nodeValue.slice(0, -1);\n }\n return seen[s] = value;\n });\n};\ngoog.string.unescapePureXmlEntities_ = function(str) {\n return str.replace(/&([^;]+);/g, function(s, entity) {\n switch(entity) {\n case \"amp\":\n return \"\\x26\";\n case \"lt\":\n return \"\\x3c\";\n case \"gt\":\n return \"\\x3e\";\n case \"quot\":\n return '\"';\n default:\n if (entity.charAt(0) == \"#\") {\n const n = Number(\"0\" + entity.slice(1));\n if (!isNaN(n)) {\n return String.fromCharCode(n);\n }\n }\n return s;\n }\n });\n};\ngoog.string.HTML_ENTITY_PATTERN_ = /&([^;\\s<&]+);?/g;\ngoog.string.whitespaceEscape = function(str, opt_xml) {\n return goog.string.newLineToBr(str.replace(/ /g, \" \\x26#160;\"), opt_xml);\n};\ngoog.string.preserveSpaces = function(str) {\n return str.replace(/(^|[\\n ]) /g, \"$1\" + goog.string.Unicode.NBSP);\n};\ngoog.string.stripQuotes = function(str, quoteChars) {\n const length = quoteChars.length;\n for (let i = 0; i < length; i++) {\n const quoteChar = length == 1 ? quoteChars : quoteChars.charAt(i);\n if (str.charAt(0) == quoteChar && str.charAt(str.length - 1) == quoteChar) {\n return str.substring(1, str.length - 1);\n }\n }\n return str;\n};\ngoog.string.truncate = function(str, chars, opt_protectEscapedCharacters) {\n if (opt_protectEscapedCharacters) {\n str = goog.string.unescapeEntities(str);\n }\n if (str.length > chars) {\n str = str.substring(0, chars - 3) + \"...\";\n }\n if (opt_protectEscapedCharacters) {\n str = goog.string.htmlEscape(str);\n }\n return str;\n};\ngoog.string.truncateMiddle = function(str, chars, opt_protectEscapedCharacters, opt_trailingChars) {\n if (opt_protectEscapedCharacters) {\n str = goog.string.unescapeEntities(str);\n }\n if (opt_trailingChars && str.length > chars) {\n if (opt_trailingChars > chars) {\n opt_trailingChars = chars;\n }\n const endPoint = str.length - opt_trailingChars;\n const startPoint = chars - opt_trailingChars;\n str = str.substring(0, startPoint) + \"...\" + str.substring(endPoint);\n } else if (str.length > chars) {\n let half = Math.floor(chars / 2);\n const endPos = str.length - half;\n half += chars % 2;\n str = str.substring(0, half) + \"...\" + str.substring(endPos);\n }\n if (opt_protectEscapedCharacters) {\n str = goog.string.htmlEscape(str);\n }\n return str;\n};\ngoog.string.specialEscapeChars_ = {\"\\x00\":\"\\\\0\", \"\\b\":\"\\\\b\", \"\\f\":\"\\\\f\", \"\\n\":\"\\\\n\", \"\\r\":\"\\\\r\", \"\\t\":\"\\\\t\", \"\\v\":\"\\\\x0B\", '\"':'\\\\\"', \"\\\\\":\"\\\\\\\\\", \"\\x3c\":\"\\\\u003C\"};\ngoog.string.jsEscapeCache_ = {\"'\":\"\\\\'\"};\ngoog.string.quote = function(s) {\n s = String(s);\n const sb = ['\"'];\n for (let i = 0; i < s.length; i++) {\n const ch = s.charAt(i);\n const cc = ch.charCodeAt(0);\n sb[i + 1] = goog.string.specialEscapeChars_[ch] || (cc > 31 && cc < 127 ? ch : goog.string.escapeChar(ch));\n }\n sb.push('\"');\n return sb.join(\"\");\n};\ngoog.string.escapeString = function(str) {\n const sb = [];\n for (let i = 0; i < str.length; i++) {\n sb[i] = goog.string.escapeChar(str.charAt(i));\n }\n return sb.join(\"\");\n};\ngoog.string.escapeChar = function(c) {\n if (c in goog.string.jsEscapeCache_) {\n return goog.string.jsEscapeCache_[c];\n }\n if (c in goog.string.specialEscapeChars_) {\n return goog.string.jsEscapeCache_[c] = goog.string.specialEscapeChars_[c];\n }\n let rv = c;\n const cc = c.charCodeAt(0);\n if (cc > 31 && cc < 127) {\n rv = c;\n } else {\n if (cc < 256) {\n rv = \"\\\\x\";\n if (cc < 16 || cc > 256) {\n rv += \"0\";\n }\n } else {\n rv = \"\\\\u\";\n if (cc < 4096) {\n rv += \"0\";\n }\n }\n rv += cc.toString(16).toUpperCase();\n }\n return goog.string.jsEscapeCache_[c] = rv;\n};\ngoog.string.contains = goog.string.internal.contains;\ngoog.string.caseInsensitiveContains = goog.string.internal.caseInsensitiveContains;\ngoog.string.countOf = function(s, ss) {\n return s && ss ? s.split(ss).length - 1 : 0;\n};\ngoog.string.removeAt = function(s, index, stringLength) {\n let resultStr = s;\n if (index >= 0 && index < s.length && stringLength > 0) {\n resultStr = s.slice(0, index) + s.slice(index + stringLength);\n }\n return resultStr;\n};\ngoog.string.remove = function(str, substr) {\n return str.replace(substr, \"\");\n};\ngoog.string.removeAll = function(s, ss) {\n const re = new RegExp(goog.string.regExpEscape(ss), \"g\");\n return s.replace(re, \"\");\n};\ngoog.string.replaceAll = function(s, ss, replacement) {\n const re = new RegExp(goog.string.regExpEscape(ss), \"g\");\n return s.replace(re, replacement.replace(/\\$/g, \"$$$$\"));\n};\ngoog.string.regExpEscape = function(s) {\n return String(s).replace(/([-()\\[\\]{}+?*.$\\^|,:#<!\\\\])/g, \"\\\\$1\").replace(/\\x08/g, \"\\\\x08\");\n};\ngoog.string.repeat = String.prototype.repeat ? function(string, length) {\n return string.repeat(length);\n} : function(string, length) {\n return (new Array(length + 1)).join(string);\n};\ngoog.string.padNumber = function(num, length, opt_precision) {\n if (!Number.isFinite(num)) {\n return String(num);\n }\n let s = opt_precision !== undefined ? num.toFixed(opt_precision) : String(num);\n let index = s.indexOf(\".\");\n if (index === -1) {\n index = s.length;\n }\n const sign = s[0] === \"-\" ? \"-\" : \"\";\n if (sign) {\n s = s.substring(1);\n }\n return sign + goog.string.repeat(\"0\", Math.max(0, length - index)) + s;\n};\ngoog.string.makeSafe = function(obj) {\n return obj == null ? \"\" : String(obj);\n};\ngoog.string.getRandomString = function() {\n const x = 2147483648;\n return Math.floor(Math.random() * x).toString(36) + Math.abs(Math.floor(Math.random() * x) ^ goog.now()).toString(36);\n};\ngoog.string.compareVersions = goog.string.internal.compareVersions;\ngoog.string.hashCode = function(str) {\n let result = 0;\n for (let i = 0; i < str.length; ++i) {\n result = 31 * result + str.charCodeAt(i) >>> 0;\n }\n return result;\n};\ngoog.string.uniqueStringCounter_ = Math.random() * 2147483648 | 0;\ngoog.string.createUniqueString = function() {\n return \"goog_\" + goog.string.uniqueStringCounter_++;\n};\ngoog.string.toNumber = function(str) {\n const num = Number(str);\n if (num == 0 && goog.string.isEmptyOrWhitespace(str)) {\n return NaN;\n }\n return num;\n};\ngoog.string.isLowerCamelCase = function(str) {\n return /^[a-z]+([A-Z][a-z]*)*$/.test(str);\n};\ngoog.string.isUpperCamelCase = function(str) {\n return /^([A-Z][a-z]*)+$/.test(str);\n};\ngoog.string.toCamelCase = function(str) {\n return String(str).replace(/\\-([a-z])/g, function(all, match) {\n return match.toUpperCase();\n });\n};\ngoog.string.toSelectorCase = function(str) {\n return String(str).replace(/([A-Z])/g, \"-$1\").toLowerCase();\n};\ngoog.string.toTitleCase = function(str, opt_delimiters) {\n let delimiters = typeof opt_delimiters === \"string\" ? goog.string.regExpEscape(opt_delimiters) : \"\\\\s\";\n delimiters = delimiters ? \"|[\" + delimiters + \"]+\" : \"\";\n const regexp = new RegExp(\"(^\" + delimiters + \")([a-z])\", \"g\");\n return str.replace(regexp, function(all, p1, p2) {\n return p1 + p2.toUpperCase();\n });\n};\ngoog.string.capitalize = function(str) {\n return String(str.charAt(0)).toUpperCase() + String(str.slice(1)).toLowerCase();\n};\ngoog.string.parseInt = function(value) {\n if (isFinite(value)) {\n value = String(value);\n }\n if (typeof value === \"string\") {\n return /^\\s*-?0x/i.test(value) ? parseInt(value, 16) : parseInt(value, 10);\n }\n return NaN;\n};\ngoog.string.splitLimit = function(str, separator, limit) {\n const parts = str.split(separator);\n const returnVal = [];\n while (limit > 0 && parts.length) {\n returnVal.push(parts.shift());\n limit--;\n }\n if (parts.length) {\n returnVal.push(parts.join(separator));\n }\n return returnVal;\n};\ngoog.string.lastComponent = function(str, separators) {\n if (!separators) {\n return str;\n } else if (typeof separators == \"string\") {\n separators = [separators];\n }\n let lastSeparatorIndex = -1;\n for (let i = 0; i < separators.length; i++) {\n if (separators[i] == \"\") {\n continue;\n }\n const currentSeparatorIndex = str.lastIndexOf(separators[i]);\n if (currentSeparatorIndex > lastSeparatorIndex) {\n lastSeparatorIndex = currentSeparatorIndex;\n }\n }\n if (lastSeparatorIndex == -1) {\n return str;\n }\n return str.slice(lastSeparatorIndex + 1);\n};\ngoog.string.editDistance = function(a, b) {\n const v0 = [];\n const v1 = [];\n if (a == b) {\n return 0;\n }\n if (!a.length || !b.length) {\n return Math.max(a.length, b.length);\n }\n for (let i = 0; i < b.length + 1; i++) {\n v0[i] = i;\n }\n for (let i = 0; i < a.length; i++) {\n v1[0] = i + 1;\n for (let j = 0; j < b.length; j++) {\n const cost = Number(a[i] != b[j]);\n v1[j + 1] = Math.min(v1[j] + 1, v0[j + 1] + 1, v0[j] + cost);\n }\n for (let j = 0; j < v0.length; j++) {\n v0[j] = v1[j];\n }\n }\n return v1[b.length];\n};\n","~:source","/**\n * @license\n * Copyright The Closure Library Authors.\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * @fileoverview Utilities for string manipulation.\n */\n\n\n/**\n * Namespace for string utilities\n */\ngoog.provide('goog.string');\ngoog.provide('goog.string.Unicode');\n\ngoog.require('goog.dom.safe');\ngoog.require('goog.html.uncheckedconversions');\ngoog.require('goog.string.Const');\ngoog.require('goog.string.internal');\n\n\n/**\n * @define {boolean} Enables HTML escaping of lowercase letter \"e\" which helps\n * with detection of double-escaping as this letter is frequently used.\n */\ngoog.string.DETECT_DOUBLE_ESCAPING =\n goog.define('goog.string.DETECT_DOUBLE_ESCAPING', false);\n\n\n/**\n * @define {boolean} Whether to force non-dom html unescaping.\n */\ngoog.string.FORCE_NON_DOM_HTML_UNESCAPING =\n goog.define('goog.string.FORCE_NON_DOM_HTML_UNESCAPING', false);\n\n\n/**\n * Common Unicode string characters.\n * @enum {string}\n */\ngoog.string.Unicode = {\n NBSP: '\\xa0',\n ZERO_WIDTH_SPACE: '\\u200b' // This is equivalent to <wbr>.\n};\n\n\n/**\n * Fast prefix-checker.\n * @param {string} str The string to check.\n * @param {string} prefix A string to look for at the start of `str`.\n * @return {boolean} True if `str` begins with `prefix`.\n */\ngoog.string.startsWith = goog.string.internal.startsWith;\n\n\n/**\n * Fast suffix-checker.\n * @param {string} str The string to check.\n * @param {string} suffix A string to look for at the end of `str`.\n * @return {boolean} True if `str` ends with `suffix`.\n */\ngoog.string.endsWith = goog.string.internal.endsWith;\n\n\n/**\n * Case-insensitive prefix-checker.\n * @param {string} str The string to check.\n * @param {string} prefix A string to look for at the end of `str`.\n * @return {boolean} True if `str` begins with `prefix` (ignoring\n * case).\n */\ngoog.string.caseInsensitiveStartsWith =\n goog.string.internal.caseInsensitiveStartsWith;\n\n\n/**\n * Case-insensitive suffix-checker.\n * @param {string} str The string to check.\n * @param {string} suffix A string to look for at the end of `str`.\n * @return {boolean} True if `str` ends with `suffix` (ignoring\n * case).\n */\ngoog.string.caseInsensitiveEndsWith =\n goog.string.internal.caseInsensitiveEndsWith;\n\n\n/**\n * Case-insensitive equality checker.\n * @param {string} str1 First string to check.\n * @param {string} str2 Second string to check.\n * @return {boolean} True if `str1` and `str2` are the same string,\n * ignoring case.\n */\ngoog.string.caseInsensitiveEquals = goog.string.internal.caseInsensitiveEquals;\n\n\n/**\n * Does simple python-style string substitution.\n * subs(\"foo%s hot%s\", \"bar\", \"dog\") becomes \"foobar hotdog\".\n * @param {string} str The string containing the pattern.\n * @param {...*} var_args The items to substitute into the pattern.\n * @return {string} A copy of `str` in which each occurrence of\n * {@code %s} has been replaced an argument from `var_args`.\n */\ngoog.string.subs = function(str, var_args) {\n 'use strict';\n const splitParts = str.split('%s');\n let returnString = '';\n\n const subsArguments = Array.prototype.slice.call(arguments, 1);\n while (subsArguments.length &&\n // Replace up to the last split part. We are inserting in the\n // positions between split parts.\n splitParts.length > 1) {\n returnString += splitParts.shift() + subsArguments.shift();\n }\n\n return returnString + splitParts.join('%s'); // Join unused '%s'\n};\n\n\n/**\n * Converts multiple whitespace chars (spaces, non-breaking-spaces, new lines\n * and tabs) to a single space, and strips leading and trailing whitespace.\n * @param {string} str Input string.\n * @return {string} A copy of `str` with collapsed whitespace.\n */\ngoog.string.collapseWhitespace = function(str) {\n 'use strict';\n // Since IE doesn't include non-breaking-space (0xa0) in their \\s character\n // class (as required by section 7.2 of the ECMAScript spec), we explicitly\n // include it in the regexp to enforce consistent cross-browser behavior.\n return str.replace(/[\\s\\xa0]+/g, ' ').replace(/^\\s+|\\s+$/g, '');\n};\n\n\n/**\n * Checks if a string is empty or contains only whitespaces.\n * @param {string} str The string to check.\n * @return {boolean} Whether `str` is empty or whitespace only.\n */\ngoog.string.isEmptyOrWhitespace = goog.string.internal.isEmptyOrWhitespace;\n\n\n/**\n * Checks if a string is empty.\n * @param {string} str The string to check.\n * @return {boolean} Whether `str` is empty.\n */\ngoog.string.isEmptyString = function(str) {\n 'use strict';\n return str.length == 0;\n};\n\n\n/**\n * Checks if a string is empty or contains only whitespaces.\n *\n * @param {string} str The string to check.\n * @return {boolean} Whether `str` is empty or whitespace only.\n * @deprecated Use goog.string.isEmptyOrWhitespace instead.\n */\ngoog.string.isEmpty = goog.string.isEmptyOrWhitespace;\n\n\n/**\n * Checks if a string is null, undefined, empty or contains only whitespaces.\n * @param {*} str The string to check.\n * @return {boolean} Whether `str` is null, undefined, empty, or\n * whitespace only.\n * @deprecated Use goog.string.isEmptyOrWhitespace(goog.string.makeSafe(str))\n * instead.\n */\ngoog.string.isEmptyOrWhitespaceSafe = function(str) {\n 'use strict';\n return goog.string.isEmptyOrWhitespace(goog.string.makeSafe(str));\n};\n\n\n/**\n * Checks if a string is null, undefined, empty or contains only whitespaces.\n *\n * @param {*} str The string to check.\n * @return {boolean} Whether `str` is null, undefined, empty, or\n * whitespace only.\n * @deprecated Use goog.string.isEmptyOrWhitespace instead.\n */\ngoog.string.isEmptySafe = goog.string.isEmptyOrWhitespaceSafe;\n\n\n/**\n * Checks if a string is all breaking whitespace.\n * @param {string} str The string to check.\n * @return {boolean} Whether the string is all breaking whitespace.\n */\ngoog.string.isBreakingWhitespace = function(str) {\n 'use strict';\n return !/[^\\t\\n\\r ]/.test(str);\n};\n\n\n/**\n * Checks if a string contains all letters.\n * @param {string} str string to check.\n * @return {boolean} True if `str` consists entirely of letters.\n */\ngoog.string.isAlpha = function(str) {\n 'use strict';\n return !/[^a-zA-Z]/.test(str);\n};\n\n\n/**\n * Checks if a string contains only numbers.\n * @param {*} str string to check. If not a string, it will be\n * casted to one.\n * @return {boolean} True if `str` is numeric.\n */\ngoog.string.isNumeric = function(str) {\n 'use strict';\n return !/[^0-9]/.test(str);\n};\n\n\n/**\n * Checks if a string contains only numbers or letters.\n * @param {string} str string to check.\n * @return {boolean} True if `str` is alphanumeric.\n */\ngoog.string.isAlphaNumeric = function(str) {\n 'use strict';\n return !/[^a-zA-Z0-9]/.test(str);\n};\n\n\n/**\n * Checks if a character is a space character.\n * @param {string} ch Character to check.\n * @return {boolean} True if `ch` is a space.\n */\ngoog.string.isSpace = function(ch) {\n 'use strict';\n return ch == ' ';\n};\n\n\n/**\n * Checks if a character is a valid unicode character.\n * @param {string} ch Character to check.\n * @return {boolean} True if `ch` is a valid unicode character.\n */\ngoog.string.isUnicodeChar = function(ch) {\n 'use strict';\n return ch.length == 1 && ch >= ' ' && ch <= '~' ||\n ch >= '\\u0080' && ch <= '\\uFFFD';\n};\n\n\n/**\n * Takes a string and replaces newlines with a space. Multiple lines are\n * replaced with a single space.\n * @param {string} str The string from which to strip newlines.\n * @return {string} A copy of `str` stripped of newlines.\n */\ngoog.string.stripNewlines = function(str) {\n 'use strict';\n return str.replace(/(\\r\\n|\\r|\\n)+/g, ' ');\n};\n\n\n/**\n * Replaces Windows and Mac new lines with unix style: \\r or \\r\\n with \\n.\n * @param {string} str The string to in which to canonicalize newlines.\n * @return {string} `str` A copy of {@code} with canonicalized newlines.\n */\ngoog.string.canonicalizeNewlines = function(str) {\n 'use strict';\n return str.replace(/(\\r\\n|\\r|\\n)/g, '\\n');\n};\n\n\n/**\n * Normalizes whitespace in a string, replacing all whitespace chars with\n * a space.\n * @param {string} str The string in which to normalize whitespace.\n * @return {string} A copy of `str` with all whitespace normalized.\n */\ngoog.string.normalizeWhitespace = function(str) {\n 'use strict';\n return str.replace(/\\xa0|\\s/g, ' ');\n};\n\n\n/**\n * Normalizes spaces in a string, replacing all consecutive spaces and tabs\n * with a single space. Replaces non-breaking space with a space.\n * @param {string} str The string in which to normalize spaces.\n * @return {string} A copy of `str` with all consecutive spaces and tabs\n * replaced with a single space.\n */\ngoog.string.normalizeSpaces = function(str) {\n 'use strict';\n return str.replace(/\\xa0|[ \\t]+/g, ' ');\n};\n\n\n/**\n * Removes the breaking spaces from the left and right of the string and\n * collapses the sequences of breaking spaces in the middle into single spaces.\n * The original and the result strings render the same way in HTML.\n * @param {string} str A string in which to collapse spaces.\n * @return {string} Copy of the string with normalized breaking spaces.\n */\ngoog.string.collapseBreakingSpaces = function(str) {\n 'use strict';\n return str.replace(/[\\t\\r\\n ]+/g, ' ')\n .replace(/^[\\t\\r\\n ]+|[\\t\\r\\n ]+$/g, '');\n};\n\n\n/**\n * Trims white spaces to the left and right of a string.\n * @param {string} str The string to trim.\n * @return {string} A trimmed copy of `str`.\n */\ngoog.string.trim = goog.string.internal.trim;\n\n\n/**\n * Trims whitespaces at the left end of a string.\n * @param {string} str The string to left trim.\n * @return {string} A trimmed copy of `str`.\n */\ngoog.string.trimLeft = function(str) {\n 'use strict';\n // Since IE doesn't include non-breaking-space (0xa0) in their \\s character\n // class (as required by section 7.2 of the ECMAScript spec), we explicitly\n // include it in the regexp to enforce consistent cross-browser behavior.\n return str.replace(/^[\\s\\xa0]+/, '');\n};\n\n\n/**\n * Trims whitespaces at the right end of a string.\n * @param {string} str The string to right trim.\n * @return {string} A trimmed copy of `str`.\n */\ngoog.string.trimRight = function(str) {\n 'use strict';\n // Since IE doesn't include non-breaking-space (0xa0) in their \\s character\n // class (as required by section 7.2 of the ECMAScript spec), we explicitly\n // include it in the regexp to enforce consistent cross-browser behavior.\n return str.replace(/[\\s\\xa0]+$/, '');\n};\n\n\n/**\n * A string comparator that ignores case.\n * -1 = str1 less than str2\n * 0 = str1 equals str2\n * 1 = str1 greater than str2\n *\n * @param {string} str1 The string to compare.\n * @param {string} str2 The string to compare `str1` to.\n * @return {number} The comparator result, as described above.\n */\ngoog.string.caseInsensitiveCompare =\n goog.string.internal.caseInsensitiveCompare;\n\n\n/**\n * Compares two strings interpreting their numeric substrings as numbers.\n *\n * @param {string} str1 First string.\n * @param {string} str2 Second string.\n * @param {!RegExp} tokenizerRegExp Splits a string into substrings of\n * non-negative integers, non-numeric characters and optionally fractional\n * numbers starting with a decimal point.\n * @return {number} Negative if str1 < str2, 0 is str1 == str2, positive if\n * str1 > str2.\n * @private\n */\ngoog.string.numberAwareCompare_ = function(str1, str2, tokenizerRegExp) {\n 'use strict';\n if (str1 == str2) {\n return 0;\n }\n if (!str1) {\n return -1;\n }\n if (!str2) {\n return 1;\n }\n\n // Using match to split the entire string ahead of time turns out to be faster\n // for most inputs than using RegExp.exec or iterating over each character.\n const tokens1 = str1.toLowerCase().match(tokenizerRegExp);\n const tokens2 = str2.toLowerCase().match(tokenizerRegExp);\n\n const count = Math.min(tokens1.length, tokens2.length);\n\n for (let i = 0; i < count; i++) {\n const a = tokens1[i];\n const b = tokens2[i];\n\n // Compare pairs of tokens, returning if one token sorts before the other.\n if (a != b) {\n // Only if both tokens are integers is a special comparison required.\n // Decimal numbers are sorted as strings (e.g., '.09' < '.1').\n const num1 = parseInt(a, 10);\n if (!isNaN(num1)) {\n const num2 = parseInt(b, 10);\n if (!isNaN(num2) && num1 - num2) {\n return num1 - num2;\n }\n }\n return a < b ? -1 : 1;\n }\n }\n\n // If one string is a substring of the other, the shorter string sorts first.\n if (tokens1.length != tokens2.length) {\n return tokens1.length - tokens2.length;\n }\n\n // The two strings must be equivalent except for case (perfect equality is\n // tested at the head of the function.) Revert to default ASCII string\n // comparison to stabilize the sort.\n return str1 < str2 ? -1 : 1;\n};\n\n\n/**\n * String comparison function that handles non-negative integer numbers in a\n * way humans might expect. Using this function, the string 'File 2.jpg' sorts\n * before 'File 10.jpg', and 'Version 1.9' before 'Version 1.10'. The comparison\n * is mostly case-insensitive, though strings that are identical except for case\n * are sorted with the upper-case strings before lower-case.\n *\n * This comparison function is up to 50x slower than either the default or the\n * case-insensitive compare. It should not be used in time-critical code, but\n * should be fast enough to sort several hundred short strings (like filenames)\n * with a reasonable delay.\n *\n * @param {string} str1 The string to compare in a numerically sensitive way.\n * @param {string} str2 The string to compare `str1` to.\n * @return {number} less than 0 if str1 < str2, 0 if str1 == str2, greater than\n * 0 if str1 > str2.\n */\ngoog.string.intAwareCompare = function(str1, str2) {\n 'use strict';\n return goog.string.numberAwareCompare_(str1, str2, /\\d+|\\D+/g);\n};\n\n\n/**\n * String comparison function that handles non-negative integer and fractional\n * numbers in a way humans might expect. Using this function, the string\n * 'File 2.jpg' sorts before 'File 10.jpg', and '3.14' before '3.2'. Equivalent\n * to {@link goog.string.intAwareCompare} apart from the way how it interprets\n * dots.\n *\n * @param {string} str1 The string to compare in a numerically sensitive way.\n * @param {string} str2 The string to compare `str1` to.\n * @return {number} less than 0 if str1 < str2, 0 if str1 == str2, greater than\n * 0 if str1 > str2.\n */\ngoog.string.floatAwareCompare = function(str1, str2) {\n 'use strict';\n return goog.string.numberAwareCompare_(str1, str2, /\\d+|\\.\\d+|\\D+/g);\n};\n\n\n/**\n * Alias for {@link goog.string.floatAwareCompare}.\n *\n * @param {string} str1\n * @param {string} str2\n * @return {number}\n */\ngoog.string.numerateCompare = goog.string.floatAwareCompare;\n\n\n/**\n * URL-encodes a string\n * @param {*} str The string to url-encode.\n * @return {string} An encoded copy of `str` that is safe for urls.\n * Note that '#', ':', and other characters used to delimit portions\n * of URLs *will* be encoded.\n */\ngoog.string.urlEncode = function(str) {\n 'use strict';\n return encodeURIComponent(String(str));\n};\n\n\n/**\n * URL-decodes the string. We need to specially handle '+'s because\n * the javascript library doesn't convert them to spaces.\n * @param {string} str The string to url decode.\n * @return {string} The decoded `str`.\n */\ngoog.string.urlDecode = function(str) {\n 'use strict';\n return decodeURIComponent(str.replace(/\\+/g, ' '));\n};\n\n\n/**\n * Converts \\n to <br>s or <br />s.\n * @param {string} str The string in which to convert newlines.\n * @param {boolean=} opt_xml Whether to use XML compatible tags.\n * @return {string} A copy of `str` with converted newlines.\n */\ngoog.string.newLineToBr = goog.string.internal.newLineToBr;\n\n\n/**\n * Escapes double quote '\"' and single quote '\\'' characters in addition to\n * '&', '<', and '>' so that a string can be included in an HTML tag attribute\n * value within double or single quotes.\n *\n * It should be noted that > doesn't need to be escaped for the HTML or XML to\n * be valid, but it has been decided to escape it for consistency with other\n * implementations.\n *\n * With goog.string.DETECT_DOUBLE_ESCAPING, this function escapes also the\n * lowercase letter \"e\".\n *\n * NOTE(user):\n * HtmlEscape is often called during the generation of large blocks of HTML.\n * Using statics for the regular expressions and strings is an optimization\n * that can more than half the amount of time IE spends in this function for\n * large apps, since strings and regexes both contribute to GC allocations.\n *\n * Testing for the presence of a character before escaping increases the number\n * of function calls, but actually provides a speed increase for the average\n * case -- since the average case often doesn't require the escaping of all 4\n * characters and indexOf() is much cheaper than replace().\n * The worst case does suffer slightly from the additional calls, therefore the\n * opt_isLikelyToContainHtmlChars option has been included for situations\n * where all 4 HTML entities are very likely to be present and need escaping.\n *\n * Some benchmarks (times tended to fluctuate +-0.05ms):\n * FireFox IE6\n * (no chars / average (mix of cases) / all 4 chars)\n * no checks 0.13 / 0.22 / 0.22 0.23 / 0.53 / 0.80\n * indexOf 0.08 / 0.17 / 0.26 0.22 / 0.54 / 0.84\n * indexOf + re test 0.07 / 0.17 / 0.28 0.19 / 0.50 / 0.85\n *\n * An additional advantage of checking if replace actually needs to be called\n * is a reduction in the number of object allocations, so as the size of the\n * application grows the difference between the various methods would increase.\n *\n * @param {string} str string to be escaped.\n * @param {boolean=} opt_isLikelyToContainHtmlChars Don't perform a check to see\n * if the character needs replacing - use this option if you expect each of\n * the characters to appear often. Leave false if you expect few html\n * characters to occur in your strings, such as if you are escaping HTML.\n * @return {string} An escaped copy of `str`.\n */\ngoog.string.htmlEscape = function(str, opt_isLikelyToContainHtmlChars) {\n 'use strict';\n str = goog.string.internal.htmlEscape(str, opt_isLikelyToContainHtmlChars);\n if (goog.string.DETECT_DOUBLE_ESCAPING) {\n str = str.replace(goog.string.E_RE_, '&#101;');\n }\n return str;\n};\n\n\n/**\n * Regular expression that matches a lowercase letter \"e\", for use in escaping.\n * @const {!RegExp}\n * @private\n */\ngoog.string.E_RE_ = /e/g;\n\n\n/**\n * Unescapes an HTML string.\n *\n * @param {string} str The string to unescape.\n * @return {string} An unescaped copy of `str`.\n */\ngoog.string.unescapeEntities = function(str) {\n 'use strict';\n if (goog.string.contains(str, '&')) {\n // We are careful not to use a DOM if we do not have one or we explicitly\n // requested non-DOM html unescaping.\n if (!goog.string.FORCE_NON_DOM_HTML_UNESCAPING &&\n 'document' in goog.global) {\n return goog.string.unescapeEntitiesUsingDom_(str);\n } else {\n // Fall back on pure XML entities\n return goog.string.unescapePureXmlEntities_(str);\n }\n }\n return str;\n};\n\n\n/**\n * Unescapes a HTML string using the provided document.\n *\n * @param {string} str The string to unescape.\n * @param {!Document} document A document to use in escaping the string.\n * @return {string} An unescaped copy of `str`.\n */\ngoog.string.unescapeEntitiesWithDocument = function(str, document) {\n 'use strict';\n if (goog.string.contains(str, '&')) {\n return goog.string.unescapeEntitiesUsingDom_(str, document);\n }\n return str;\n};\n\n\n/**\n * Unescapes an HTML string using a DOM to resolve non-XML, non-numeric\n * entities. This function is XSS-safe and whitespace-preserving.\n * @private\n * @param {string} str The string to unescape.\n * @param {Document=} opt_document An optional document to use for creating\n * elements. If this is not specified then the default window.document\n * will be used.\n * @return {string} The unescaped `str` string.\n */\ngoog.string.unescapeEntitiesUsingDom_ = function(str, opt_document) {\n 'use strict';\n /** @type {!Object<string, string>} */\n const seen = {'&amp;': '&', '&lt;': '<', '&gt;': '>', '&quot;': '\"'};\n /** @type {!Element} */\n let div;\n if (opt_document) {\n div = opt_document.createElement('div');\n } else {\n div = goog.global.document.createElement('div');\n }\n // Match as many valid entity characters as possible. If the actual entity\n // happens to be shorter, it will still work as innerHTML will return the\n // trailing characters unchanged. Since the entity characters do not include\n // open angle bracket, there is no chance of XSS from the innerHTML use.\n // Since no whitespace is passed to innerHTML, whitespace is preserved.\n return str.replace(goog.string.HTML_ENTITY_PATTERN_, function(s, entity) {\n 'use strict';\n // Check for cached entity.\n let value = seen[s];\n if (value) {\n return value;\n }\n // Check for numeric entity.\n if (entity.charAt(0) == '#') {\n // Prefix with 0 so that hex entities (e.g. &#x10) parse as hex numbers.\n const n = Number('0' + entity.slice(1));\n if (!isNaN(n)) {\n value = String.fromCharCode(n);\n }\n }\n // Fall back to innerHTML otherwise.\n if (!value) {\n // Append a non-entity character to avoid a bug in Webkit that parses\n // an invalid entity at the end of innerHTML text as the empty string.\n goog.dom.safe.setInnerHtml(\n div,\n goog.html.uncheckedconversions\n .safeHtmlFromStringKnownToSatisfyTypeContract(\n goog.string.Const.from('Single HTML entity.'), s + ' '));\n // Then remove the trailing character from the result.\n value = div.firstChild.nodeValue.slice(0, -1);\n }\n // Cache and return.\n return seen[s] = value;\n });\n};\n\n\n/**\n * Unescapes XML entities.\n * @private\n * @param {string} str The string to unescape.\n * @return {string} An unescaped copy of `str`.\n */\ngoog.string.unescapePureXmlEntities_ = function(str) {\n 'use strict';\n return str.replace(/&([^;]+);/g, function(s, entity) {\n 'use strict';\n switch (entity) {\n case 'amp':\n return '&';\n case 'lt':\n return '<';\n case 'gt':\n return '>';\n case 'quot':\n return '\"';\n default:\n if (entity.charAt(0) == '#') {\n // Prefix with 0 so that hex entities (e.g. &#x10) parse as hex.\n const n = Number('0' + entity.slice(1));\n if (!isNaN(n)) {\n return String.fromCharCode(n);\n }\n }\n // For invalid entities we just return the entity\n return s;\n }\n });\n};\n\n\n/**\n * Regular expression that matches an HTML entity.\n * See also HTML5: Tokenization / Tokenizing character references.\n * @private\n * @type {!RegExp}\n */\ngoog.string.HTML_ENTITY_PATTERN_ = /&([^;\\s<&]+);?/g;\n\n\n/**\n * Do escaping of whitespace to preserve spatial formatting. We use character\n * entity #160 to make it safer for xml.\n * @param {string} str The string in which to escape whitespace.\n * @param {boolean=} opt_xml Whether to use XML compatible tags.\n * @return {string} An escaped copy of `str`.\n */\ngoog.string.whitespaceEscape = function(str, opt_xml) {\n 'use strict';\n // This doesn't use goog.string.preserveSpaces for backwards compatibility.\n return goog.string.newLineToBr(str.replace(/ /g, ' &#160;'), opt_xml);\n};\n\n\n/**\n * Preserve spaces that would be otherwise collapsed in HTML by replacing them\n * with non-breaking space Unicode characters.\n * @param {string} str The string in which to preserve whitespace.\n * @return {string} A copy of `str` with preserved whitespace.\n */\ngoog.string.preserveSpaces = function(str) {\n 'use strict';\n return str.replace(/(^|[\\n ]) /g, '$1' + goog.string.Unicode.NBSP);\n};\n\n\n/**\n * Strip quote characters around a string. The second argument is a string of\n * characters to treat as quotes. This can be a single character or a string of\n * multiple character and in that case each of those are treated as possible\n * quote characters. For example:\n *\n * <pre>\n * goog.string.stripQuotes('\"abc\"', '\"`') --> 'abc'\n * goog.string.stripQuotes('`abc`', '\"`') --> 'abc'\n * </pre>\n *\n * @param {string} str The string to strip.\n * @param {string} quoteChars The quote characters to strip.\n * @return {string} A copy of `str` without the quotes.\n */\ngoog.string.stripQuotes = function(str, quoteChars) {\n 'use strict';\n const length = quoteChars.length;\n for (let i = 0; i < length; i++) {\n const quoteChar = length == 1 ? quoteChars : quoteChars.charAt(i);\n if (str.charAt(0) == quoteChar && str.charAt(str.length - 1) == quoteChar) {\n return str.substring(1, str.length - 1);\n }\n }\n return str;\n};\n\n\n/**\n * Truncates a string to a certain length and adds '...' if necessary. The\n * length also accounts for the ellipsis, so a maximum length of 10 and a string\n * 'Hello World!' produces 'Hello W...'.\n * @param {string} str The string to truncate.\n * @param {number} chars Max number of characters.\n * @param {boolean=} opt_protectEscapedCharacters Whether to protect escaped\n * characters from being cut off in the middle.\n * @return {string} The truncated `str` string.\n */\ngoog.string.truncate = function(str, chars, opt_protectEscapedCharacters) {\n 'use strict';\n if (opt_protectEscapedCharacters) {\n str = goog.string.unescapeEntities(str);\n }\n\n if (str.length > chars) {\n str = str.substring(0, chars - 3) + '...';\n }\n\n if (opt_protectEscapedCharacters) {\n str = goog.string.htmlEscape(str);\n }\n\n return str;\n};\n\n\n/**\n * Truncate a string in the middle, adding \"...\" if necessary,\n * and favoring the beginning of the string.\n * @param {string} str The string to truncate the middle of.\n * @param {number} chars Max number of characters.\n * @param {boolean=} opt_protectEscapedCharacters Whether to protect escaped\n * characters from being cutoff in the middle.\n * @param {number=} opt_trailingChars Optional number of trailing characters to\n * leave at the end of the string, instead of truncating as close to the\n * middle as possible.\n * @return {string} A truncated copy of `str`.\n */\ngoog.string.truncateMiddle = function(\n str, chars, opt_protectEscapedCharacters, opt_trailingChars) {\n 'use strict';\n if (opt_protectEscapedCharacters) {\n str = goog.string.unescapeEntities(str);\n }\n\n if (opt_trailingChars && str.length > chars) {\n if (opt_trailingChars > chars) {\n opt_trailingChars = chars;\n }\n const endPoint = str.length - opt_trailingChars;\n const startPoint = chars - opt_trailingChars;\n str = str.substring(0, startPoint) + '...' + str.substring(endPoint);\n } else if (str.length > chars) {\n // Favor the beginning of the string:\n let half = Math.floor(chars / 2);\n const endPos = str.length - half;\n half += chars % 2;\n str = str.substring(0, half) + '...' + str.substring(endPos);\n }\n\n if (opt_protectEscapedCharacters) {\n str = goog.string.htmlEscape(str);\n }\n\n return str;\n};\n\n\n/**\n * Special chars that need to be escaped for goog.string.quote.\n * @private {!Object<string, string>}\n */\ngoog.string.specialEscapeChars_ = {\n '\\0': '\\\\0',\n '\\b': '\\\\b',\n '\\f': '\\\\f',\n '\\n': '\\\\n',\n '\\r': '\\\\r',\n '\\t': '\\\\t',\n '\\x0B': '\\\\x0B', // '\\v' is not supported in JScript\n '\"': '\\\\\"',\n '\\\\': '\\\\\\\\',\n // To support the use case of embedding quoted strings inside of script\n // tags, we have to make sure HTML comments and opening/closing script tags do\n // not appear in the resulting string. The specific strings that must be\n // escaped are documented at:\n // https://html.spec.whatwg.org/multipage/scripting.html#restrictions-for-contents-of-script-elements\n '<': '\\\\u003C' // NOTE: JSON.parse crashes on '\\\\x3c'.\n};\n\n\n/**\n * Character mappings used internally for goog.string.escapeChar.\n * @private {!Object<string, string>}\n */\ngoog.string.jsEscapeCache_ = {\n '\\'': '\\\\\\''\n};\n\n\n/**\n * Encloses a string in double quotes and escapes characters so that the\n * string is a valid JS string. The resulting string is safe to embed in\n * `<script>` tags as \"<\" is escaped.\n * @param {string} s The string to quote.\n * @return {string} A copy of `s` surrounded by double quotes.\n */\ngoog.string.quote = function(s) {\n 'use strict';\n s = String(s);\n const sb = ['\"'];\n for (let i = 0; i < s.length; i++) {\n const ch = s.charAt(i);\n const cc = ch.charCodeAt(0);\n sb[i + 1] = goog.string.specialEscapeChars_[ch] ||\n ((cc > 31 && cc < 127) ? ch : goog.string.escapeChar(ch));\n }\n sb.push('\"');\n return sb.join('');\n};\n\n\n/**\n * Takes a string and returns the escaped string for that input string.\n * @param {string} str The string to escape.\n * @return {string} An escaped string representing `str`.\n */\ngoog.string.escapeString = function(str) {\n 'use strict';\n const sb = [];\n for (let i = 0; i < str.length; i++) {\n sb[i] = goog.string.escapeChar(str.charAt(i));\n }\n return sb.join('');\n};\n\n\n/**\n * Takes a character and returns the escaped string for that character. For\n * example escapeChar(String.fromCharCode(15)) -> \"\\\\x0E\".\n * @param {string} c The character to escape.\n * @return {string} An escaped string representing `c`.\n */\ngoog.string.escapeChar = function(c) {\n 'use strict';\n if (c in goog.string.jsEscapeCache_) {\n return goog.string.jsEscapeCache_[c];\n }\n\n if (c in goog.string.specialEscapeChars_) {\n return goog.string.jsEscapeCache_[c] = goog.string.specialEscapeChars_[c];\n }\n\n let rv = c;\n const cc = c.charCodeAt(0);\n if (cc > 31 && cc < 127) {\n rv = c;\n } else {\n // tab is 9 but handled above\n if (cc < 256) {\n rv = '\\\\x';\n if (cc < 16 || cc > 256) {\n rv += '0';\n }\n } else {\n rv = '\\\\u';\n if (cc < 4096) { // \\u1000\n rv += '0';\n }\n }\n rv += cc.toString(16).toUpperCase();\n }\n\n return goog.string.jsEscapeCache_[c] = rv;\n};\n\n\n/**\n * Determines whether a string contains a substring.\n * @param {string} str The string to search.\n * @param {string} subString The substring to search for.\n * @return {boolean} Whether `str` contains `subString`.\n */\ngoog.string.contains = goog.string.internal.contains;\n\n\n/**\n * Determines whether a string contains a substring, ignoring case.\n * @param {string} str The string to search.\n * @param {string} subString The substring to search for.\n * @return {boolean} Whether `str` contains `subString`.\n */\ngoog.string.caseInsensitiveContains =\n goog.string.internal.caseInsensitiveContains;\n\n\n/**\n * Returns the non-overlapping occurrences of ss in s.\n * If either s or ss evalutes to false, then returns zero.\n * @param {string} s The string to look in.\n * @param {string} ss The string to look for.\n * @return {number} Number of occurrences of ss in s.\n */\ngoog.string.countOf = function(s, ss) {\n 'use strict';\n return s && ss ? s.split(ss).length - 1 : 0;\n};\n\n\n/**\n * Removes a substring of a specified length at a specific\n * index in a string.\n * @param {string} s The base string from which to remove.\n * @param {number} index The index at which to remove the substring.\n * @param {number} stringLength The length of the substring to remove.\n * @return {string} A copy of `s` with the substring removed or the full\n * string if nothing is removed or the input is invalid.\n */\ngoog.string.removeAt = function(s, index, stringLength) {\n 'use strict';\n let resultStr = s;\n // If the index is greater or equal to 0 then remove substring\n if (index >= 0 && index < s.length && stringLength > 0) {\n resultStr = s.slice(0, index) + s.slice(index + stringLength);\n }\n return resultStr;\n};\n\n\n/**\n * Removes the first occurrence of a substring from a string.\n * @param {string} str The base string from which to remove.\n * @param {string} substr The string to remove.\n * @return {string} A copy of `str` with `substr` removed or the\n * full string if nothing is removed.\n */\ngoog.string.remove = function(str, substr) {\n 'use strict';\n return str.replace(substr, '');\n};\n\n\n/**\n * Removes all occurrences of a substring from a string.\n * @param {string} s The base string from which to remove.\n * @param {string} ss The string to remove.\n * @return {string} A copy of `s` with `ss` removed or the full\n * string if nothing is removed.\n */\ngoog.string.removeAll = function(s, ss) {\n 'use strict';\n const re = new RegExp(goog.string.regExpEscape(ss), 'g');\n return s.replace(re, '');\n};\n\n\n/**\n * Replaces all occurrences of a substring of a string with a new substring.\n * @param {string} s The base string from which to remove.\n * @param {string} ss The string to replace.\n * @param {string} replacement The replacement string.\n * @return {string} A copy of `s` with `ss` replaced by\n * `replacement` or the original string if nothing is replaced.\n */\ngoog.string.replaceAll = function(s, ss, replacement) {\n 'use strict';\n const re = new RegExp(goog.string.regExpEscape(ss), 'g');\n return s.replace(re, replacement.replace(/\\$/g, '$$$$'));\n};\n\n\n/**\n * Escapes characters in the string that are not safe to use in a RegExp.\n * @param {*} s The string to escape. If not a string, it will be casted\n * to one.\n * @return {string} A RegExp safe, escaped copy of `s`.\n */\ngoog.string.regExpEscape = function(s) {\n 'use strict';\n return String(s)\n .replace(/([-()\\[\\]{}+?*.$\\^|,:#<!\\\\])/g, '\\\\$1')\n .replace(/\\x08/g, '\\\\x08');\n};\n\n\n/**\n * Repeats a string n times.\n * @param {string} string The string to repeat.\n * @param {number} length The number of times to repeat.\n * @return {string} A string containing `length` repetitions of\n * `string`.\n */\ngoog.string.repeat = (String.prototype.repeat) ? function(string, length) {\n 'use strict';\n // The native method is over 100 times faster than the alternative.\n return string.repeat(length);\n} : function(string, length) {\n 'use strict';\n return new Array(length + 1).join(string);\n};\n\n\n/**\n * Pads number to given length and optionally rounds it to a given precision.\n * For example:\n * <pre>padNumber(1.25, 2, 3) -> '01.250'\n * padNumber(1.25, 2) -> '01.25'\n * padNumber(1.25, 2, 1) -> '01.3'\n * padNumber(1.25, 0) -> '1.25'</pre>\n *\n * @param {number} num The number to pad.\n * @param {number} length The desired length.\n * @param {number=} opt_precision The desired precision.\n * @return {string} `num` as a string with the given options.\n */\ngoog.string.padNumber = function(num, length, opt_precision) {\n 'use strict';\n if (!Number.isFinite(num)) return String(num);\n let s =\n (opt_precision !== undefined) ? num.toFixed(opt_precision) : String(num);\n let index = s.indexOf('.');\n if (index === -1) {\n index = s.length;\n }\n const sign = s[0] === '-' ? '-' : '';\n if (sign) {\n s = s.substring(1);\n }\n return sign + goog.string.repeat('0', Math.max(0, length - index)) + s;\n};\n\n\n/**\n * Returns a string representation of the given object, with\n * null and undefined being returned as the empty string.\n *\n * @param {*} obj The object to convert.\n * @return {string} A string representation of the `obj`.\n */\ngoog.string.makeSafe = function(obj) {\n 'use strict';\n return obj == null ? '' : String(obj);\n};\n\n/**\n * Returns a string with at least 64-bits of randomness.\n *\n * Doesn't trust JavaScript's random function entirely. Uses a combination of\n * random and current timestamp, and then encodes the string in base-36 to\n * make it shorter.\n *\n * @return {string} A random string, e.g. sn1s7vb4gcic.\n */\ngoog.string.getRandomString = function() {\n 'use strict';\n const x = 2147483648;\n return Math.floor(Math.random() * x).toString(36) +\n Math.abs(Math.floor(Math.random() * x) ^ goog.now()).toString(36);\n};\n\n\n/**\n * Compares two version numbers.\n *\n * @param {string|number} version1 Version of first item.\n * @param {string|number} version2 Version of second item.\n *\n * @return {number} 1 if `version1` is higher.\n * 0 if arguments are equal.\n * -1 if `version2` is higher.\n */\ngoog.string.compareVersions = goog.string.internal.compareVersions;\n\n\n/**\n * String hash function similar to java.lang.String.hashCode().\n * The hash code for a string is computed as\n * s[0] * 31 ^ (n - 1) + s[1] * 31 ^ (n - 2) + ... + s[n - 1],\n * where s[i] is the ith character of the string and n is the length of\n * the string. We mod the result to make it between 0 (inclusive) and 2^32\n * (exclusive).\n * @param {string} str A string.\n * @return {number} Hash value for `str`, between 0 (inclusive) and 2^32\n * (exclusive). The empty string returns 0.\n */\ngoog.string.hashCode = function(str) {\n 'use strict';\n let result = 0;\n for (let i = 0; i < str.length; ++i) {\n // Normalize to 4 byte range, 0 ... 2^32.\n result = (31 * result + str.charCodeAt(i)) >>> 0;\n }\n return result;\n};\n\n\n/**\n * The most recent unique ID. |0 is equivalent to Math.floor in this case.\n * @type {number}\n * @private\n */\ngoog.string.uniqueStringCounter_ = Math.random() * 0x80000000 | 0;\n\n\n/**\n * Generates and returns a string which is unique in the current document.\n * This is useful, for example, to create unique IDs for DOM elements.\n * @return {string} A unique id.\n */\ngoog.string.createUniqueString = function() {\n 'use strict';\n return 'goog_' + goog.string.uniqueStringCounter_++;\n};\n\n\n/**\n * Converts the supplied string to a number, which may be Infinity or NaN.\n * This function strips whitespace: (toNumber(' 123') === 123)\n * This function accepts scientific notation: (toNumber('1e1') === 10)\n *\n * This is better than JavaScript's built-in conversions because, sadly:\n * (Number(' ') === 0) and (parseFloat('123a') === 123)\n *\n * @param {string} str The string to convert.\n * @return {number} The number the supplied string represents, or NaN.\n */\ngoog.string.toNumber = function(str) {\n 'use strict';\n const num = Number(str);\n if (num == 0 && goog.string.isEmptyOrWhitespace(str)) {\n return NaN;\n }\n return num;\n};\n\n\n/**\n * Returns whether the given string is lower camel case (e.g. \"isFooBar\").\n *\n * Note that this assumes the string is entirely letters.\n * @see http://en.wikipedia.org/wiki/CamelCase#Variations_and_synonyms\n *\n * @param {string} str String to test.\n * @return {boolean} Whether the string is lower camel case.\n */\ngoog.string.isLowerCamelCase = function(str) {\n 'use strict';\n return /^[a-z]+([A-Z][a-z]*)*$/.test(str);\n};\n\n\n/**\n * Returns whether the given string is upper camel case (e.g. \"FooBarBaz\").\n *\n * Note that this assumes the string is entirely letters.\n * @see http://en.wikipedia.org/wiki/CamelCase#Variations_and_synonyms\n *\n * @param {string} str String to test.\n * @return {boolean} Whether the string is upper camel case.\n */\ngoog.string.isUpperCamelCase = function(str) {\n 'use strict';\n return /^([A-Z][a-z]*)+$/.test(str);\n};\n\n\n/**\n * Converts a string from selector-case to camelCase (e.g. from\n * \"multi-part-string\" to \"multiPartString\"), useful for converting\n * CSS selectors and HTML dataset keys to their equivalent JS properties.\n * @param {string} str The string in selector-case form.\n * @return {string} The string in camelCase form.\n */\ngoog.string.toCamelCase = function(str) {\n 'use strict';\n return String(str).replace(/\\-([a-z])/g, function(all, match) {\n 'use strict';\n return match.toUpperCase();\n });\n};\n\n\n/**\n * Converts a string from camelCase to selector-case (e.g. from\n * \"multiPartString\" to \"multi-part-string\"), useful for converting JS\n * style and dataset properties to equivalent CSS selectors and HTML keys.\n * @param {string} str The string in camelCase form.\n * @return {string} The string in selector-case form.\n */\ngoog.string.toSelectorCase = function(str) {\n 'use strict';\n return String(str).replace(/([A-Z])/g, '-$1').toLowerCase();\n};\n\n\n/**\n * Converts a string into TitleCase. First character of the string is always\n * capitalized in addition to the first letter of every subsequent word.\n * Words are delimited by one or more whitespaces by default. Custom delimiters\n * can optionally be specified to replace the default, which doesn't preserve\n * whitespace delimiters and instead must be explicitly included if needed.\n *\n * Default delimiter => \" \":\n * goog.string.toTitleCase('oneTwoThree') => 'OneTwoThree'\n * goog.string.toTitleCase('one two three') => 'One Two Three'\n * goog.string.toTitleCase(' one two ') => ' One Two '\n * goog.string.toTitleCase('one_two_three') => 'One_two_three'\n * goog.string.toTitleCase('one-two-three') => 'One-two-three'\n *\n * Custom delimiter => \"_-.\":\n * goog.string.toTitleCase('oneTwoThree', '_-.') => 'OneTwoThree'\n * goog.string.toTitleCase('one two three', '_-.') => 'One two three'\n * goog.string.toTitleCase(' one two ', '_-.') => ' one two '\n * goog.string.toTitleCase('one_two_three', '_-.') => 'One_Two_Three'\n * goog.string.toTitleCase('one-two-three', '_-.') => 'One-Two-Three'\n * goog.string.toTitleCase('one...two...three', '_-.') => 'One...Two...Three'\n * goog.string.toTitleCase('one. two. three', '_-.') => 'One. two. three'\n * goog.string.toTitleCase('one-two.three', '_-.') => 'One-Two.Three'\n *\n * @param {string} str String value in camelCase form.\n * @param {string=} opt_delimiters Custom delimiter character set used to\n * distinguish words in the string value. Each character represents a\n * single delimiter. When provided, default whitespace delimiter is\n * overridden and must be explicitly included if needed.\n * @return {string} String value in TitleCase form.\n */\ngoog.string.toTitleCase = function(str, opt_delimiters) {\n 'use strict';\n let delimiters = (typeof opt_delimiters === 'string') ?\n goog.string.regExpEscape(opt_delimiters) :\n '\\\\s';\n\n // For IE8, we need to prevent using an empty character set. Otherwise,\n // incorrect matching will occur.\n delimiters = delimiters ? '|[' + delimiters + ']+' : '';\n\n const regexp = new RegExp('(^' + delimiters + ')([a-z])', 'g');\n return str.replace(regexp, function(all, p1, p2) {\n 'use strict';\n return p1 + p2.toUpperCase();\n });\n};\n\n\n/**\n * Capitalizes a string, i.e. converts the first letter to uppercase\n * and all other letters to lowercase, e.g.:\n *\n * goog.string.capitalize('one') => 'One'\n * goog.string.capitalize('ONE') => 'One'\n * goog.string.capitalize('one two') => 'One two'\n *\n * Note that this function does not trim initial whitespace.\n *\n * @param {string} str String value to capitalize.\n * @return {string} String value with first letter in uppercase.\n */\ngoog.string.capitalize = function(str) {\n 'use strict';\n return String(str.charAt(0)).toUpperCase() +\n String(str.slice(1)).toLowerCase();\n};\n\n\n/**\n * Parse a string in decimal or hexidecimal ('0xFFFF') form.\n *\n * To parse a particular radix, please use parseInt(string, radix) directly. See\n * https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/parseInt\n *\n * This is a wrapper for the built-in parseInt function that will only parse\n * numbers as base 10 or base 16. Some JS implementations assume strings\n * starting with \"0\" are intended to be octal. ES3 allowed but discouraged\n * this behavior. ES5 forbids it. This function emulates the ES5 behavior.\n *\n * For more information, see Mozilla JS Reference: http://goo.gl/8RiFj\n *\n * @param {string|number|null|undefined} value The value to be parsed.\n * @return {number} The number, parsed. If the string failed to parse, this\n * will be NaN.\n */\ngoog.string.parseInt = function(value) {\n 'use strict';\n // Force finite numbers to strings.\n if (isFinite(value)) {\n value = String(value);\n }\n\n if (typeof value === 'string') {\n // If the string starts with '0x' or '-0x', parse as hex.\n return /^\\s*-?0x/i.test(value) ? parseInt(value, 16) : parseInt(value, 10);\n }\n\n return NaN;\n};\n\n\n/**\n * Splits a string on a separator a limited number of times.\n *\n * This implementation is more similar to Python or Java, where the limit\n * parameter specifies the maximum number of splits rather than truncating\n * the number of results.\n *\n * See http://docs.python.org/2/library/stdtypes.html#str.split\n * See JavaDoc: http://goo.gl/F2AsY\n * See Mozilla reference: http://goo.gl/dZdZs\n *\n * @param {string} str String to split.\n * @param {string} separator The separator.\n * @param {number} limit The limit to the number of splits. The resulting array\n * will have a maximum length of limit+1. Negative numbers are the same\n * as zero.\n * @return {!Array<string>} The string, split.\n */\ngoog.string.splitLimit = function(str, separator, limit) {\n 'use strict';\n const parts = str.split(separator);\n const returnVal = [];\n\n // Only continue doing this while we haven't hit the limit and we have\n // parts left.\n while (limit > 0 && parts.length) {\n returnVal.push(parts.shift());\n limit--;\n }\n\n // If there are remaining parts, append them to the end.\n if (parts.length) {\n returnVal.push(parts.join(separator));\n }\n\n return returnVal;\n};\n\n\n/**\n * Finds the characters to the right of the last instance of any separator\n *\n * This function is similar to goog.string.path.baseName, except it can take a\n * list of characters to split the string on. It will return the rightmost\n * grouping of characters to the right of any separator as a left-to-right\n * oriented string.\n *\n * @see goog.string.path.baseName\n * @param {string} str The string\n * @param {string|!Array<string>} separators A list of separator characters\n * @return {string} The last part of the string with respect to the separators\n */\ngoog.string.lastComponent = function(str, separators) {\n 'use strict';\n if (!separators) {\n return str;\n } else if (typeof separators == 'string') {\n separators = [separators];\n }\n\n let lastSeparatorIndex = -1;\n for (let i = 0; i < separators.length; i++) {\n if (separators[i] == '') {\n continue;\n }\n const currentSeparatorIndex = str.lastIndexOf(separators[i]);\n if (currentSeparatorIndex > lastSeparatorIndex) {\n lastSeparatorIndex = currentSeparatorIndex;\n }\n }\n if (lastSeparatorIndex == -1) {\n return str;\n }\n return str.slice(lastSeparatorIndex + 1);\n};\n\n\n/**\n * Computes the Levenshtein edit distance between two strings.\n * @param {string} a\n * @param {string} b\n * @return {number} The edit distance between the two strings.\n */\ngoog.string.editDistance = function(a, b) {\n 'use strict';\n const v0 = [];\n const v1 = [];\n\n if (a == b) {\n return 0;\n }\n\n if (!a.length || !b.length) {\n return Math.max(a.length, b.length);\n }\n\n for (let i = 0; i < b.length + 1; i++) {\n v0[i] = i;\n }\n\n for (let i = 0; i < a.length; i++) {\n v1[0] = i + 1;\n\n for (let j = 0; j < b.length; j++) {\n const cost = Number(a[i] != b[j]);\n // Cost for the substring is the minimum of adding one character, removing\n // one character, or a swap.\n v1[j + 1] = Math.min(v1[j] + 1, v0[j + 1] + 1, v0[j] + cost);\n }\n\n for (let j = 0; j < v0.length; j++) {\n v0[j] = v1[j];\n }\n }\n\n return v1[b.length];\n};\n","~:compiled-at",1684858197928,"~:source-map-json","{\n\"version\":3,\n\"file\":\"goog.string.string.js\",\n\"lineCount\":456,\n\"mappings\":\"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\",\n\"sources\":[\"goog/string/string.js\"],\n\"sourcesContent\":[\"/**\\n * @license\\n * Copyright The Closure Library Authors.\\n * SPDX-License-Identifier: Apache-2.0\\n */\\n\\n/**\\n * @fileoverview Utilities for string manipulation.\\n */\\n\\n\\n/**\\n * Namespace for string utilities\\n */\\ngoog.provide('goog.string');\\ngoog.provide('goog.string.Unicode');\\n\\ngoog.require('goog.dom.safe');\\ngoog.require('goog.html.uncheckedconversions');\\ngoog.require('goog.string.Const');\\ngoog.require('goog.string.internal');\\n\\n\\n/**\\n * @define {boolean} Enables HTML escaping of lowercase letter \\\"e\\\" which helps\\n * with detection of double-escaping as this letter is frequently used.\\n */\\ngoog.string.DETECT_DOUBLE_ESCAPING =\\n goog.define('goog.string.DETECT_DOUBLE_ESCAPING', false);\\n\\n\\n/**\\n * @define {boolean} Whether to force non-dom html unescaping.\\n */\\ngoog.string.FORCE_NON_DOM_HTML_UNESCAPING =\\n goog.define('goog.string.FORCE_NON_DOM_HTML_UNESCAPING', false);\\n\\n\\n/**\\n * Common Unicode string characters.\\n * @enum {string}\\n */\\ngoog.string.Unicode = {\\n NBSP: '\\\\xa0',\\n ZERO_WIDTH_SPACE: '\\\\u200b' // This is equivalent to <wbr>.\\n};\\n\\n\\n/**\\n * Fast prefix-checker.\\n * @param {string} str The string to check.\\n * @param {string} prefix A string to look for at the start of `str`.\\n * @return {boolean} True if `str` begins with `prefix`.\\n */\\ngoog.string.startsWith = goog.string.internal.startsWith;\\n\\n\\n/**\\n * Fast suffix-checker.\\n * @param {string} str The string to check.\\n * @param {string} suffix A string to look for at the end of `str`.\\n * @return {boolean} True if `str` ends with `suffix`.\\n */\\ngoog.string.endsWith = goog.string.internal.endsWith;\\n\\n\\n/**\\n * Case-insensitive prefix-checker.\\n * @param {string} str The string to check.\\n * @param {string} prefix A string to look for at the end of `str`.\\n * @return {boolean} True if `str` begins with `prefix` (ignoring\\n * case).\\n */\\ngoog.string.caseInsensitiveStartsWith =\\n goog.string.internal.caseInsensitiveStartsWith;\\n\\n\\n/**\\n * Case-insensitive suffix-checker.\\n * @param {string} str The string to check.\\n * @param {string} suffix A string to look for at the end of `str`.\\n * @return {boolean} True if `str` ends with `suffix` (ignoring\\n * case).\\n */\\ngoog.string.caseInsensitiveEndsWith =\\n goog.string.internal.caseInsensitiveEndsWith;\\n\\n\\n/**\\n * Case-insensitive equality checker.\\n * @param {string} str1 First string to check.\\n * @param {string} str2 Second string to check.\\n * @return {boolean} True if `str1` and `str2` are the same string,\\n * ignoring case.\\n */\\ngoog.string.caseInsensitiveEquals = goog.string.internal.caseInsensitiveEquals;\\n\\n\\n/**\\n * Does simple python-style string substitution.\\n * subs(\\\"foo%s hot%s\\\", \\\"bar\\\", \\\"dog\\\") becomes \\\"foobar hotdog\\\".\\n * @param {string} str The string containing the pattern.\\n * @param {...*} var_args The items to substitute into the pattern.\\n * @return {string} A copy of `str` in which each occurrence of\\n * {@code %s} has been replaced an argument from `var_args`.\\n */\\ngoog.string.subs = function(str, var_args) {\\n 'use strict';\\n const splitParts = str.split('%s');\\n let returnString = '';\\n\\n const subsArguments = Array.prototype.slice.call(arguments, 1);\\n while (subsArguments.length &&\\n // Replace up to the last split part. We are inserting in the\\n // positions between split parts.\\n splitParts.length > 1) {\\n returnString += splitParts.shift() + subsArguments.shift();\\n }\\n\\n return returnString + splitParts.join('%s'); // Join unused '%s'\\n};\\n\\n\\n/**\\n * Converts multiple whitespace chars (spaces, non-breaking-spaces, new lines\\n * and tabs) to a single space, and strips leading and trailing whitespace.\\n * @param {string} str Input string.\\n * @return {string} A copy of `str` with collapsed whitespace.\\n */\\ngoog.string.collapseWhitespace = function(str) {\\n 'use strict';\\n // Since IE doesn't include non-breaking-space (0xa0) in their \\\\s character\\n // class (as required by section 7.2 of the ECMAScript spec), we explicitly\\n // include it in the regexp to enforce consistent cross-browser behavior.\\n return str.replace(/[\\\\s\\\\xa0]+/g, ' ').replace(/^\\\\s+|\\\\s+$/g, '');\\n};\\n\\n\\n/**\\n * Checks if a string is empty or contains only whitespaces.\\n * @param {string} str The string to check.\\n * @return {boolean} Whether `str` is empty or whitespace only.\\n */\\ngoog.string.isEmptyOrWhitespace = goog.string.internal.isEmptyOrWhitespace;\\n\\n\\n/**\\n * Checks if a string is empty.\\n * @param {string} str The string to check.\\n * @return {boolean} Whether `str` is empty.\\n */\\ngoog.string.isEmptyString = function(str) {\\n 'use strict';\\n return str.length == 0;\\n};\\n\\n\\n/**\\n * Checks if a string is empty or contains only whitespaces.\\n *\\n * @param {string} str The string to check.\\n * @return {boolean} Whether `str` is empty or whitespace only.\\n * @deprecated Use goog.string.isEmptyOrWhitespace instead.\\n */\\ngoog.string.isEmpty = goog.string.isEmptyOrWhitespace;\\n\\n\\n/**\\n * Checks if a string is null, undefined, empty or contains only whitespaces.\\n * @param {*} str The string to check.\\n * @return {boolean} Whether `str` is null, undefined, empty, or\\n * whitespace only.\\n * @deprecated Use goog.string.isEmptyOrWhitespace(goog.string.makeSafe(str))\\n * instead.\\n */\\ngoog.string.isEmptyOrWhitespaceSafe = function(str) {\\n 'use strict';\\n return goog.string.isEmptyOrWhitespace(goog.string.makeSafe(str));\\n};\\n\\n\\n/**\\n * Checks if a string is null, undefined, empty or contains only whitespaces.\\n *\\n * @param {*} str The string to check.\\n * @return {boolean} Whether `str` is null, undefined, empty, or\\n * whitespace only.\\n * @deprecated Use goog.string.isEmptyOrWhitespace instead.\\n */\\ngoog.string.isEmptySafe = goog.string.isEmptyOrWhitespaceSafe;\\n\\n\\n/**\\n * Checks if a string is all breaking whitespace.\\n * @param {string} str The string to check.\\n * @return {boolean} Whether the string is all breaking whitespace.\\n */\\ngoog.string.isBreakingWhitespace = function(str) {\\n 'use strict';\\n return !/[^\\\\t\\\\n\\\\r ]/.test(str);\\n};\\n\\n\\n/**\\n * Checks if a string contains all letters.\\n * @param {string} str string to check.\\n * @return {boolean} True if `str` consists entirely of letters.\\n */\\ngoog.string.isAlpha = function(str) {\\n 'use strict';\\n return !/[^a-zA-Z]/.test(str);\\n};\\n\\n\\n/**\\n * Checks if a string contains only numbers.\\n * @param {*} str string to check. If not a string, it will be\\n * casted to one.\\n * @return {boolean} True if `str` is numeric.\\n */\\ngoog.string.isNumeric = function(str) {\\n 'use strict';\\n return !/[^0-9]/.test(str);\\n};\\n\\n\\n/**\\n * Checks if a string contains only numbers or letters.\\n * @param {string} str string to check.\\n * @return {boolean} True if `str` is alphanumeric.\\n */\\ngoog.string.isAlphaNumeric = function(str) {\\n 'use strict';\\n return !/[^a-zA-Z0-9]/.test(str);\\n};\\n\\n\\n/**\\n * Checks if a character is a space character.\\n * @param {string} ch Character to check.\\n * @return {boolean} True if `ch` is a space.\\n */\\ngoog.string.isSpace = function(ch) {\\n 'use strict';\\n return ch == ' ';\\n};\\n\\n\\n/**\\n * Checks if a character is a valid unicode character.\\n * @param {string} ch Character to check.\\n * @return {boolean} True if `ch` is a valid unicode character.\\n */\\ngoog.string.isUnicodeChar = function(ch) {\\n 'use strict';\\n return ch.length == 1 && ch >= ' ' && ch <= '~' ||\\n ch >= '\\\\u0080' && ch <= '\\\\uFFFD';\\n};\\n\\n\\n/**\\n * Takes a string and replaces newlines with a space. Multiple lines are\\n * replaced with a single space.\\n * @param {string} str The string from which to strip newlines.\\n * @return {string} A copy of `str` stripped of newlines.\\n */\\ngoog.string.stripNewlines = function(str) {\\n 'use strict';\\n return str.replace(/(\\\\r\\\\n|\\\\r|\\\\n)+/g, ' ');\\n};\\n\\n\\n/**\\n * Replaces Windows and Mac new lines with unix style: \\\\r or \\\\r\\\\n with \\\\n.\\n * @param {string} str The string to in which to canonicalize newlines.\\n * @return {string} `str` A copy of {@code} with canonicalized newlines.\\n */\\ngoog.string.canonicalizeNewlines = function(str) {\\n 'use strict';\\n return str.replace(/(\\\\r\\\\n|\\\\r|\\\\n)/g, '\\\\n');\\n};\\n\\n\\n/**\\n * Normalizes whitespace in a string, replacing all whitespace chars with\\n * a space.\\n * @param {string} str The string in which to normalize whitespace.\\n * @return {string} A copy of `str` with all whitespace normalized.\\n */\\ngoog.string.normalizeWhitespace = function(str) {\\n 'use strict';\\n return str.replace(/\\\\xa0|\\\\s/g, ' ');\\n};\\n\\n\\n/**\\n * Normalizes spaces in a string, replacing all consecutive spaces and tabs\\n * with a single space. Replaces non-breaking space with a space.\\n * @param {string} str The string in which to normalize spaces.\\n * @return {string} A copy of `str` with all consecutive spaces and tabs\\n * replaced with a single space.\\n */\\ngoog.string.normalizeSpaces = function(str) {\\n 'use strict';\\n return str.replace(/\\\\xa0|[ \\\\t]+/g, ' ');\\n};\\n\\n\\n/**\\n * Removes the breaking spaces from the left and right of the string and\\n * collapses the sequences of breaking spaces in the middle into single spaces.\\n * The original and the result strings render the same way in HTML.\\n * @param {string} str A string in which to collapse spaces.\\n * @return {string} Copy of the string with normalized breaking spaces.\\n */\\ngoog.string.collapseBreakingSpaces = function(str) {\\n 'use strict';\\n return str.replace(/[\\\\t\\\\r\\\\n ]+/g, ' ')\\n .replace(/^[\\\\t\\\\r\\\\n ]+|[\\\\t\\\\r\\\\n ]+$/g, '');\\n};\\n\\n\\n/**\\n * Trims white spaces to the left and right of a string.\\n * @param {string} str The string to trim.\\n * @return {string} A trimmed copy of `str`.\\n */\\ngoog.string.trim = goog.string.internal.trim;\\n\\n\\n/**\\n * Trims whitespaces at the left end of a string.\\n * @param {string} str The string to left trim.\\n * @return {string} A trimmed copy of `str`.\\n */\\ngoog.string.trimLeft = function(str) {\\n 'use strict';\\n // Since IE doesn't include non-breaking-space (0xa0) in their \\\\s character\\n // class (as required by section 7.2 of the ECMAScript spec), we explicitly\\n // include it in the regexp to enforce consistent cross-browser behavior.\\n return str.replace(/^[\\\\s\\\\xa0]+/, '');\\n};\\n\\n\\n/**\\n * Trims whitespaces at the right end of a string.\\n * @param {string} str The string to right trim.\\n * @return {string} A trimmed copy of `str`.\\n */\\ngoog.string.trimRight = function(str) {\\n 'use strict';\\n // Since IE doesn't include non-breaking-space (0xa0) in their \\\\s character\\n // class (as required by section 7.2 of the ECMAScript spec), we explicitly\\n // include it in the regexp to enforce consistent cross-browser behavior.\\n return str.replace(/[\\\\s\\\\xa0]+$/, '');\\n};\\n\\n\\n/**\\n * A string comparator that ignores case.\\n * -1 = str1 less than str2\\n * 0 = str1 equals str2\\n * 1 = str1 greater than str2\\n *\\n * @param {string} str1 The string to compare.\\n * @param {string} str2 The string to compare `str1` to.\\n * @return {number} The comparator result, as described above.\\n */\\ngoog.string.caseInsensitiveCompare =\\n goog.string.internal.caseInsensitiveCompare;\\n\\n\\n/**\\n * Compares two strings interpreting their numeric substrings as numbers.\\n *\\n * @param {string} str1 First string.\\n * @param {string} str2 Second string.\\n * @param {!RegExp} tokenizerRegExp Splits a string into substrings of\\n * non-negative integers, non-numeric characters and optionally fractional\\n * numbers starting with a decimal point.\\n * @return {number} Negative if str1 < str2, 0 is str1 == str2, positive if\\n * str1 > str2.\\n * @private\\n */\\ngoog.string.numberAwareCompare_ = function(str1, str2, tokenizerRegExp) {\\n 'use strict';\\n if (str1 == str2) {\\n return 0;\\n }\\n if (!str1) {\\n return -1;\\n }\\n if (!str2) {\\n return 1;\\n }\\n\\n // Using match to split the entire string ahead of time turns out to be faster\\n // for most inputs than using RegExp.exec or iterating over each character.\\n const tokens1 = str1.toLowerCase().match(tokenizerRegExp);\\n const tokens2 = str2.toLowerCase().match(tokenizerRegExp);\\n\\n const count = Math.min(tokens1.length, tokens2.length);\\n\\n for (let i = 0; i < count; i++) {\\n const a = tokens1[i];\\n const b = tokens2[i];\\n\\n // Compare pairs of tokens, returning if one token sorts before the other.\\n if (a != b) {\\n // Only if both tokens are integers is a special comparison required.\\n // Decimal numbers are sorted as strings (e.g., '.09' < '.1').\\n const num1 = parseInt(a, 10);\\n if (!isNaN(num1)) {\\n const num2 = parseInt(b, 10);\\n if (!isNaN(num2) && num1 - num2) {\\n return num1 - num2;\\n }\\n }\\n return a < b ? -1 : 1;\\n }\\n }\\n\\n // If one string is a substring of the other, the shorter string sorts first.\\n if (tokens1.length != tokens2.length) {\\n return tokens1.length - tokens2.length;\\n }\\n\\n // The two strings must be equivalent except for case (perfect equality is\\n // tested at the head of the function.) Revert to default ASCII string\\n // comparison to stabilize the sort.\\n return str1 < str2 ? -1 : 1;\\n};\\n\\n\\n/**\\n * String comparison function that handles non-negative integer numbers in a\\n * way humans might expect. Using this function, the string 'File 2.jpg' sorts\\n * before 'File 10.jpg', and 'Version 1.9' before 'Version 1.10'. The comparison\\n * is mostly case-insensitive, though strings that are identical except for case\\n * are sorted with the upper-case strings before lower-case.\\n *\\n * This comparison function is up to 50x slower than either the default or the\\n * case-insensitive compare. It should not be used in time-critical code, but\\n * should be fast enough to sort several hundred short strings (like filenames)\\n * with a reasonable delay.\\n *\\n * @param {string} str1 The string to compare in a numerically sensitive way.\\n * @param {string} str2 The string to compare `str1` to.\\n * @return {number} less than 0 if str1 < str2, 0 if str1 == str2, greater than\\n * 0 if str1 > str2.\\n */\\ngoog.string.intAwareCompare = function(str1, str2) {\\n 'use strict';\\n return goog.string.numberAwareCompare_(str1, str2, /\\\\d+|\\\\D+/g);\\n};\\n\\n\\n/**\\n * String comparison function that handles non-negative integer and fractional\\n * numbers in a way humans might expect. Using this function, the string\\n * 'File 2.jpg' sorts before 'File 10.jpg', and '3.14' before '3.2'. Equivalent\\n * to {@link goog.string.intAwareCompare} apart from the way how it interprets\\n * dots.\\n *\\n * @param {string} str1 The string to compare in a numerically sensitive way.\\n * @param {string} str2 The string to compare `str1` to.\\n * @return {number} less than 0 if str1 < str2, 0 if str1 == str2, greater than\\n * 0 if str1 > str2.\\n */\\ngoog.string.floatAwareCompare = function(str1, str2) {\\n 'use strict';\\n return goog.string.numberAwareCompare_(str1, str2, /\\\\d+|\\\\.\\\\d+|\\\\D+/g);\\n};\\n\\n\\n/**\\n * Alias for {@link goog.string.floatAwareCompare}.\\n *\\n * @param {string} str1\\n * @param {string} str2\\n * @return {number}\\n */\\ngoog.string.numerateCompare = goog.string.floatAwareCompare;\\n\\n\\n/**\\n * URL-encodes a string\\n * @param {*} str The string to url-encode.\\n * @return {string} An encoded copy of `str` that is safe for urls.\\n * Note that '#', ':', and other characters used to delimit portions\\n * of URLs *will* be encoded.\\n */\\ngoog.string.urlEncode = function(str) {\\n 'use strict';\\n return encodeURIComponent(String(str));\\n};\\n\\n\\n/**\\n * URL-decodes the string. We need to specially handle '+'s because\\n * the javascript library doesn't convert them to spaces.\\n * @param {string} str The string to url decode.\\n * @return {string} The decoded `str`.\\n */\\ngoog.string.urlDecode = function(str) {\\n 'use strict';\\n return decodeURIComponent(str.replace(/\\\\+/g, ' '));\\n};\\n\\n\\n/**\\n * Converts \\\\n to <br>s or <br />s.\\n * @param {string} str The string in which to convert newlines.\\n * @param {boolean=} opt_xml Whether to use XML compatible tags.\\n * @return {string} A copy of `str` with converted newlines.\\n */\\ngoog.string.newLineToBr = goog.string.internal.newLineToBr;\\n\\n\\n/**\\n * Escapes double quote '\\\"' and single quote '\\\\'' characters in addition to\\n * '&', '<', and '>' so that a string can be included in an HTML tag attribute\\n * value within double or single quotes.\\n *\\n * It should be noted that > doesn't need to be escaped for the HTML or XML to\\n * be valid, but it has been decided to escape it for consistency with other\\n * implementations.\\n *\\n * With goog.string.DETECT_DOUBLE_ESCAPING, this function escapes also the\\n * lowercase letter \\\"e\\\".\\n *\\n * NOTE(user):\\n * HtmlEscape is often called during the generation of large blocks of HTML.\\n * Using statics for the regular expressions and strings is an optimization\\n * that can more than half the amount of time IE spends in this function for\\n * large apps, since strings and regexes both contribute to GC allocations.\\n *\\n * Testing for the presence of a character before escaping increases the number\\n * of function calls, but actually provides a speed increase for the average\\n * case -- since the average case often doesn't require the escaping of all 4\\n * characters and indexOf() is much cheaper than replace().\\n * The worst case does suffer slightly from the additional calls, therefore the\\n * opt_isLikelyToContainHtmlChars option has been included for situations\\n * where all 4 HTML entities are very likely to be present and need escaping.\\n *\\n * Some benchmarks (times tended to fluctuate +-0.05ms):\\n * FireFox IE6\\n * (no chars / average (mix of cases) / all 4 chars)\\n * no checks 0.13 / 0.22 / 0.22 0.23 / 0.53 / 0.80\\n * indexOf 0.08 / 0.17 / 0.26 0.22 / 0.54 / 0.84\\n * indexOf + re test 0.07 / 0.17 / 0.28 0.19 / 0.50 / 0.85\\n *\\n * An additional advantage of checking if replace actually needs to be called\\n * is a reduction in the number of object allocations, so as the size of the\\n * application grows the difference between the various methods would increase.\\n *\\n * @param {string} str string to be escaped.\\n * @param {boolean=} opt_isLikelyToContainHtmlChars Don't perform a check to see\\n * if the character needs replacing - use this option if you expect each of\\n * the characters to appear often. Leave false if you expect few html\\n * characters to occur in your strings, such as if you are escaping HTML.\\n * @return {string} An escaped copy of `str`.\\n */\\ngoog.string.htmlEscape = function(str, opt_isLikelyToContainHtmlChars) {\\n 'use strict';\\n str = goog.string.internal.htmlEscape(str, opt_isLikelyToContainHtmlChars);\\n if (goog.string.DETECT_DOUBLE_ESCAPING) {\\n str = str.replace(goog.string.E_RE_, '&#101;');\\n }\\n return str;\\n};\\n\\n\\n/**\\n * Regular expression that matches a lowercase letter \\\"e\\\", for use in escaping.\\n * @const {!RegExp}\\n * @private\\n */\\ngoog.string.E_RE_ = /e/g;\\n\\n\\n/**\\n * Unescapes an HTML string.\\n *\\n * @param {string} str The string to unescape.\\n * @return {string} An unescaped copy of `str`.\\n */\\ngoog.string.unescapeEntities = function(str) {\\n 'use strict';\\n if (goog.string.contains(str, '&')) {\\n // We are careful not to use a DOM if we do not have one or we explicitly\\n // requested non-DOM html unescaping.\\n if (!goog.string.FORCE_NON_DOM_HTML_UNESCAPING &&\\n 'document' in goog.global) {\\n return goog.string.unescapeEntitiesUsingDom_(str);\\n } else {\\n // Fall back on pure XML entities\\n return goog.string.unescapePureXmlEntities_(str);\\n }\\n }\\n return str;\\n};\\n\\n\\n/**\\n * Unescapes a HTML string using the provided document.\\n *\\n * @param {string} str The string to unescape.\\n * @param {!Document} document A document to use in escaping the string.\\n * @return {string} An unescaped copy of `str`.\\n */\\ngoog.string.unescapeEntitiesWithDocument = function(str, document) {\\n 'use strict';\\n if (goog.string.contains(str, '&')) {\\n return goog.string.unescapeEntitiesUsingDom_(str, document);\\n }\\n return str;\\n};\\n\\n\\n/**\\n * Unescapes an HTML string using a DOM to resolve non-XML, non-numeric\\n * entities. This function is XSS-safe and whitespace-preserving.\\n * @private\\n * @param {string} str The string to unescape.\\n * @param {Document=} opt_document An optional document to use for creating\\n * elements. If this is not specified then the default window.document\\n * will be used.\\n * @return {string} The unescaped `str` string.\\n */\\ngoog.string.unescapeEntitiesUsingDom_ = function(str, opt_document) {\\n 'use strict';\\n /** @type {!Object<string, string>} */\\n const seen = {'&amp;': '&', '&lt;': '<', '&gt;': '>', '&quot;': '\\\"'};\\n /** @type {!Element} */\\n let div;\\n if (opt_document) {\\n div = opt_document.createElement('div');\\n } else {\\n div = goog.global.document.createElement('div');\\n }\\n // Match as many valid entity characters as possible. If the actual entity\\n // happens to be shorter, it will still work as innerHTML will return the\\n // trailing characters unchanged. Since the entity characters do not include\\n // open angle bracket, there is no chance of XSS from the innerHTML use.\\n // Since no whitespace is passed to innerHTML, whitespace is preserved.\\n return str.replace(goog.string.HTML_ENTITY_PATTERN_, function(s, entity) {\\n 'use strict';\\n // Check for cached entity.\\n let value = seen[s];\\n if (value) {\\n return value;\\n }\\n // Check for numeric entity.\\n if (entity.charAt(0) == '#') {\\n // Prefix with 0 so that hex entities (e.g. &#x10) parse as hex numbers.\\n const n = Number('0' + entity.slice(1));\\n if (!isNaN(n)) {\\n value = String.fromCharCode(n);\\n }\\n }\\n // Fall back to innerHTML otherwise.\\n if (!value) {\\n // Append a non-entity character to avoid a bug in Webkit that parses\\n // an invalid entity at the end of innerHTML text as the empty string.\\n goog.dom.safe.setInnerHtml(\\n div,\\n goog.html.uncheckedconversions\\n .safeHtmlFromStringKnownToSatisfyTypeContract(\\n goog.string.Const.from('Single HTML entity.'), s + ' '));\\n // Then remove the trailing character from the result.\\n value = div.firstChild.nodeValue.slice(0, -1);\\n }\\n // Cache and return.\\n return seen[s] = value;\\n });\\n};\\n\\n\\n/**\\n * Unescapes XML entities.\\n * @private\\n * @param {string} str The string to unescape.\\n * @return {string} An unescaped copy of `str`.\\n */\\ngoog.string.unescapePureXmlEntities_ = function(str) {\\n 'use strict';\\n return str.replace(/&([^;]+);/g, function(s, entity) {\\n 'use strict';\\n switch (entity) {\\n case 'amp':\\n return '&';\\n case 'lt':\\n return '<';\\n case 'gt':\\n return '>';\\n case 'quot':\\n return '\\\"';\\n default:\\n if (entity.charAt(0) == '#') {\\n // Prefix with 0 so that hex entities (e.g. &#x10) parse as hex.\\n const n = Number('0' + entity.slice(1));\\n if (!isNaN(n)) {\\n return String.fromCharCode(n);\\n }\\n }\\n // For invalid entities we just return the entity\\n return s;\\n }\\n });\\n};\\n\\n\\n/**\\n * Regular expression that matches an HTML entity.\\n * See also HTML5: Tokenization / Tokenizing character references.\\n * @private\\n * @type {!RegExp}\\n */\\ngoog.string.HTML_ENTITY_PATTERN_ = /&([^;\\\\s<&]+);?/g;\\n\\n\\n/**\\n * Do escaping of whitespace to preserve spatial formatting. We use character\\n * entity #160 to make it safer for xml.\\n * @param {string} str The string in which to escape whitespace.\\n * @param {boolean=} opt_xml Whether to use XML compatible tags.\\n * @return {string} An escaped copy of `str`.\\n */\\ngoog.string.whitespaceEscape = function(str, opt_xml) {\\n 'use strict';\\n // This doesn't use goog.string.preserveSpaces for backwards compatibility.\\n return goog.string.newLineToBr(str.replace(/ /g, ' &#160;'), opt_xml);\\n};\\n\\n\\n/**\\n * Preserve spaces that would be otherwise collapsed in HTML by replacing them\\n * with non-breaking space Unicode characters.\\n * @param {string} str The string in which to preserve whitespace.\\n * @return {string} A copy of `str` with preserved whitespace.\\n */\\ngoog.string.preserveSpaces = function(str) {\\n 'use strict';\\n return str.replace(/(^|[\\\\n ]) /g, '$1' + goog.string.Unicode.NBSP);\\n};\\n\\n\\n/**\\n * Strip quote characters around a string. The second argument is a string of\\n * characters to treat as quotes. This can be a single character or a string of\\n * multiple character and in that case each of those are treated as possible\\n * quote characters. For example:\\n *\\n * <pre>\\n * goog.string.stripQuotes('\\\"abc\\\"', '\\\"`') --\\u003e 'abc'\\n * goog.string.stripQuotes('`abc`', '\\\"`') --\\u003e 'abc'\\n * </pre>\\n *\\n * @param {string} str The string to strip.\\n * @param {string} quoteChars The quote characters to strip.\\n * @return {string} A copy of `str` without the quotes.\\n */\\ngoog.string.stripQuotes = function(str, quoteChars) {\\n 'use strict';\\n const length = quoteChars.length;\\n for (let i = 0; i < length; i++) {\\n const quoteChar = length == 1 ? quoteChars : quoteChars.charAt(i);\\n if (str.charAt(0) == quoteChar && str.charAt(str.length - 1) == quoteChar) {\\n return str.substring(1, str.length - 1);\\n }\\n }\\n return str;\\n};\\n\\n\\n/**\\n * Truncates a string to a certain length and adds '...' if necessary. The\\n * length also accounts for the ellipsis, so a maximum length of 10 and a string\\n * 'Hello World!' produces 'Hello W...'.\\n * @param {string} str The string to truncate.\\n * @param {number} chars Max number of characters.\\n * @param {boolean=} opt_protectEscapedCharacters Whether to protect escaped\\n * characters from being cut off in the middle.\\n * @return {string} The truncated `str` string.\\n */\\ngoog.string.truncate = function(str, chars, opt_protectEscapedCharacters) {\\n 'use strict';\\n if (opt_protectEscapedCharacters) {\\n str = goog.string.unescapeEntities(str);\\n }\\n\\n if (str.length > chars) {\\n str = str.substring(0, chars - 3) + '...';\\n }\\n\\n if (opt_protectEscapedCharacters) {\\n str = goog.string.htmlEscape(str);\\n }\\n\\n return str;\\n};\\n\\n\\n/**\\n * Truncate a string in the middle, adding \\\"...\\\" if necessary,\\n * and favoring the beginning of the string.\\n * @param {string} str The string to truncate the middle of.\\n * @param {number} chars Max number of characters.\\n * @param {boolean=} opt_protectEscapedCharacters Whether to protect escaped\\n * characters from being cutoff in the middle.\\n * @param {number=} opt_trailingChars Optional number of trailing characters to\\n * leave at the end of the string, instead of truncating as close to the\\n * middle as possible.\\n * @return {string} A truncated copy of `str`.\\n */\\ngoog.string.truncateMiddle = function(\\n str, chars, opt_protectEscapedCharacters, opt_trailingChars) {\\n 'use strict';\\n if (opt_protectEscapedCharacters) {\\n str = goog.string.unescapeEntities(str);\\n }\\n\\n if (opt_trailingChars && str.length > chars) {\\n if (opt_trailingChars > chars) {\\n opt_trailingChars = chars;\\n }\\n const endPoint = str.length - opt_trailingChars;\\n const startPoint = chars - opt_trailingChars;\\n str = str.substring(0, startPoint) + '...' + str.substring(endPoint);\\n } else if (str.length > chars) {\\n // Favor the beginning of the string:\\n let half = Math.floor(chars / 2);\\n const endPos = str.length - half;\\n half += chars % 2;\\n str = str.substring(0, half) + '...' + str.substring(endPos);\\n }\\n\\n if (opt_protectEscapedCharacters) {\\n str = goog.string.htmlEscape(str);\\n }\\n\\n return str;\\n};\\n\\n\\n/**\\n * Special chars that need to be escaped for goog.string.quote.\\n * @private {!Object<string, string>}\\n */\\ngoog.string.specialEscapeChars_ = {\\n '\\\\0': '\\\\\\\\0',\\n '\\\\b': '\\\\\\\\b',\\n '\\\\f': '\\\\\\\\f',\\n '\\\\n': '\\\\\\\\n',\\n '\\\\r': '\\\\\\\\r',\\n '\\\\t': '\\\\\\\\t',\\n '\\\\x0B': '\\\\\\\\x0B', // '\\\\v' is not supported in JScript\\n '\\\"': '\\\\\\\\\\\"',\\n '\\\\\\\\': '\\\\\\\\\\\\\\\\',\\n // To support the use case of embedding quoted strings inside of script\\n // tags, we have to make sure HTML comments and opening/closing script tags do\\n // not appear in the resulting string. The specific strings that must be\\n // escaped are documented at:\\n // https://html.spec.whatwg.org/multipage/scripting.html#restrictions-for-contents-of-script-elements\\n '<': '\\\\\\\\u003C' // NOTE: JSON.parse crashes on '\\\\\\\\x3c'.\\n};\\n\\n\\n/**\\n * Character mappings used internally for goog.string.escapeChar.\\n * @private {!Object<string, string>}\\n */\\ngoog.string.jsEscapeCache_ = {\\n '\\\\'': '\\\\\\\\\\\\''\\n};\\n\\n\\n/**\\n * Encloses a string in double quotes and escapes characters so that the\\n * string is a valid JS string. The resulting string is safe to embed in\\n * `<script>` tags as \\\"<\\\" is escaped.\\n * @param {string} s The string to quote.\\n * @return {string} A copy of `s` surrounded by double quotes.\\n */\\ngoog.string.quote = function(s) {\\n 'use strict';\\n s = String(s);\\n const sb = ['\\\"'];\\n for (let i = 0; i < s.length; i++) {\\n const ch = s.charAt(i);\\n const cc = ch.charCodeAt(0);\\n sb[i + 1] = goog.string.specialEscapeChars_[ch] ||\\n ((cc > 31 && cc < 127) ? ch : goog.string.escapeChar(ch));\\n }\\n sb.push('\\\"');\\n return sb.join('');\\n};\\n\\n\\n/**\\n * Takes a string and returns the escaped string for that input string.\\n * @param {string} str The string to escape.\\n * @return {string} An escaped string representing `str`.\\n */\\ngoog.string.escapeString = function(str) {\\n 'use strict';\\n const sb = [];\\n for (let i = 0; i < str.length; i++) {\\n sb[i] = goog.string.escapeChar(str.charAt(i));\\n }\\n return sb.join('');\\n};\\n\\n\\n/**\\n * Takes a character and returns the escaped string for that character. For\\n * example escapeChar(String.fromCharCode(15)) -> \\\"\\\\\\\\x0E\\\".\\n * @param {string} c The character to escape.\\n * @return {string} An escaped string representing `c`.\\n */\\ngoog.string.escapeChar = function(c) {\\n 'use strict';\\n if (c in goog.string.jsEscapeCache_) {\\n return goog.string.jsEscapeCache_[c];\\n }\\n\\n if (c in goog.string.specialEscapeChars_) {\\n return goog.string.jsEscapeCache_[c] = goog.string.specialEscapeChars_[c];\\n }\\n\\n let rv = c;\\n const cc = c.charCodeAt(0);\\n if (cc > 31 && cc < 127) {\\n rv = c;\\n } else {\\n // tab is 9 but handled above\\n if (cc < 256) {\\n rv = '\\\\\\\\x';\\n if (cc < 16 || cc > 256) {\\n rv += '0';\\n }\\n } else {\\n rv = '\\\\\\\\u';\\n if (cc < 4096) { // \\\\u1000\\n rv += '0';\\n }\\n }\\n rv += cc.toString(16).toUpperCase();\\n }\\n\\n return goog.string.jsEscapeCache_[c] = rv;\\n};\\n\\n\\n/**\\n * Determines whether a string contains a substring.\\n * @param {string} str The string to search.\\n * @param {string} subString The substring to search for.\\n * @return {boolean} Whether `str` contains `subString`.\\n */\\ngoog.string.contains = goog.string.internal.contains;\\n\\n\\n/**\\n * Determines whether a string contains a substring, ignoring case.\\n * @param {string} str The string to search.\\n * @param {string} subString The substring to search for.\\n * @return {boolean} Whether `str` contains `subString`.\\n */\\ngoog.string.caseInsensitiveContains =\\n goog.string.internal.caseInsensitiveContains;\\n\\n\\n/**\\n * Returns the non-overlapping occurrences of ss in s.\\n * If either s or ss evalutes to false, then returns zero.\\n * @param {string} s The string to look in.\\n * @param {string} ss The string to look for.\\n * @return {number} Number of occurrences of ss in s.\\n */\\ngoog.string.countOf = function(s, ss) {\\n 'use strict';\\n return s && ss ? s.split(ss).length - 1 : 0;\\n};\\n\\n\\n/**\\n * Removes a substring of a specified length at a specific\\n * index in a string.\\n * @param {string} s The base string from which to remove.\\n * @param {number} index The index at which to remove the substring.\\n * @param {number} stringLength The length of the substring to remove.\\n * @return {string} A copy of `s` with the substring removed or the full\\n * string if nothing is removed or the input is invalid.\\n */\\ngoog.string.removeAt = function(s, index, stringLength) {\\n 'use strict';\\n let resultStr = s;\\n // If the index is greater or equal to 0 then remove substring\\n if (index >= 0 && index < s.length && stringLength > 0) {\\n resultStr = s.slice(0, index) + s.slice(index + stringLength);\\n }\\n return resultStr;\\n};\\n\\n\\n/**\\n * Removes the first occurrence of a substring from a string.\\n * @param {string} str The base string from which to remove.\\n * @param {string} substr The string to remove.\\n * @return {string} A copy of `str` with `substr` removed or the\\n * full string if nothing is removed.\\n */\\ngoog.string.remove = function(str, substr) {\\n 'use strict';\\n return str.replace(substr, '');\\n};\\n\\n\\n/**\\n * Removes all occurrences of a substring from a string.\\n * @param {string} s The base string from which to remove.\\n * @param {string} ss The string to remove.\\n * @return {string} A copy of `s` with `ss` removed or the full\\n * string if nothing is removed.\\n */\\ngoog.string.removeAll = function(s, ss) {\\n 'use strict';\\n const re = new RegExp(goog.string.regExpEscape(ss), 'g');\\n return s.replace(re, '');\\n};\\n\\n\\n/**\\n * Replaces all occurrences of a substring of a string with a new substring.\\n * @param {string} s The base string from which to remove.\\n * @param {string} ss The string to replace.\\n * @param {string} replacement The replacement string.\\n * @return {string} A copy of `s` with `ss` replaced by\\n * `replacement` or the original string if nothing is replaced.\\n */\\ngoog.string.replaceAll = function(s, ss, replacement) {\\n 'use strict';\\n const re = new RegExp(goog.string.regExpEscape(ss), 'g');\\n return s.replace(re, replacement.replace(/\\\\$/g, '$$$$'));\\n};\\n\\n\\n/**\\n * Escapes characters in the string that are not safe to use in a RegExp.\\n * @param {*} s The string to escape. If not a string, it will be casted\\n * to one.\\n * @return {string} A RegExp safe, escaped copy of `s`.\\n */\\ngoog.string.regExpEscape = function(s) {\\n 'use strict';\\n return String(s)\\n .replace(/([-()\\\\[\\\\]{}+?*.$\\\\^|,:#<!\\\\\\\\])/g, '\\\\\\\\$1')\\n .replace(/\\\\x08/g, '\\\\\\\\x08');\\n};\\n\\n\\n/**\\n * Repeats a string n times.\\n * @param {string} string The string to repeat.\\n * @param {number} length The number of times to repeat.\\n * @return {string} A string containing `length` repetitions of\\n * `string`.\\n */\\ngoog.string.repeat = (String.prototype.repeat) ? function(string, length) {\\n 'use strict';\\n // The native method is over 100 times faster than the alternative.\\n return string.repeat(length);\\n} : function(string, length) {\\n 'use strict';\\n return new Array(length + 1).join(string);\\n};\\n\\n\\n/**\\n * Pads number to given length and optionally rounds it to a given precision.\\n * For example:\\n * <pre>padNumber(1.25, 2, 3) -> '01.250'\\n * padNumber(1.25, 2) -> '01.25'\\n * padNumber(1.25, 2, 1) -> '01.3'\\n * padNumber(1.25, 0) -> '1.25'</pre>\\n *\\n * @param {number} num The number to pad.\\n * @param {number} length The desired length.\\n * @param {number=} opt_precision The desired precision.\\n * @return {string} `num` as a string with the given options.\\n */\\ngoog.string.padNumber = function(num, length, opt_precision) {\\n 'use strict';\\n if (!Number.isFinite(num)) return String(num);\\n let s =\\n (opt_precision !== undefined) ? num.toFixed(opt_precision) : String(num);\\n let index = s.indexOf('.');\\n if (index === -1) {\\n index = s.length;\\n }\\n const sign = s[0] === '-' ? '-' : '';\\n if (sign) {\\n s = s.substring(1);\\n }\\n return sign + goog.string.repeat('0', Math.max(0, length - index)) + s;\\n};\\n\\n\\n/**\\n * Returns a string representation of the given object, with\\n * null and undefined being returned as the empty string.\\n *\\n * @param {*} obj The object to convert.\\n * @return {string} A string representation of the `obj`.\\n */\\ngoog.string.makeSafe = function(obj) {\\n 'use strict';\\n return obj == null ? '' : String(obj);\\n};\\n\\n/**\\n * Returns a string with at least 64-bits of randomness.\\n *\\n * Doesn't trust JavaScript's random function entirely. Uses a combination of\\n * random and current timestamp, and then encodes the string in base-36 to\\n * make it shorter.\\n *\\n * @return {string} A random string, e.g. sn1s7vb4gcic.\\n */\\ngoog.string.getRandomString = function() {\\n 'use strict';\\n const x = 2147483648;\\n return Math.floor(Math.random() * x).toString(36) +\\n Math.abs(Math.floor(Math.random() * x) ^ goog.now()).toString(36);\\n};\\n\\n\\n/**\\n * Compares two version numbers.\\n *\\n * @param {string|number} version1 Version of first item.\\n * @param {string|number} version2 Version of second item.\\n *\\n * @return {number} 1 if `version1` is higher.\\n * 0 if arguments are equal.\\n * -1 if `version2` is higher.\\n */\\ngoog.string.compareVersions = goog.string.internal.compareVersions;\\n\\n\\n/**\\n * String hash function similar to java.lang.String.hashCode().\\n * The hash code for a string is computed as\\n * s[0] * 31 ^ (n - 1) + s[1] * 31 ^ (n - 2) + ... + s[n - 1],\\n * where s[i] is the ith character of the string and n is the length of\\n * the string. We mod the result to make it between 0 (inclusive) and 2^32\\n * (exclusive).\\n * @param {string} str A string.\\n * @return {number} Hash value for `str`, between 0 (inclusive) and 2^32\\n * (exclusive). The empty string returns 0.\\n */\\ngoog.string.hashCode = function(str) {\\n 'use strict';\\n let result = 0;\\n for (let i = 0; i < str.length; ++i) {\\n // Normalize to 4 byte range, 0 ... 2^32.\\n result = (31 * result + str.charCodeAt(i)) >>> 0;\\n }\\n return result;\\n};\\n\\n\\n/**\\n * The most recent unique ID. |0 is equivalent to Math.floor in this case.\\n * @type {number}\\n * @private\\n */\\ngoog.string.uniqueStringCounter_ = Math.random() * 0x80000000 | 0;\\n\\n\\n/**\\n * Generates and returns a string which is unique in the current document.\\n * This is useful, for example, to create unique IDs for DOM elements.\\n * @return {string} A unique id.\\n */\\ngoog.string.createUniqueString = function() {\\n 'use strict';\\n return 'goog_' + goog.string.uniqueStringCounter_++;\\n};\\n\\n\\n/**\\n * Converts the supplied string to a number, which may be Infinity or NaN.\\n * This function strips whitespace: (toNumber(' 123') === 123)\\n * This function accepts scientific notation: (toNumber('1e1') === 10)\\n *\\n * This is better than JavaScript's built-in conversions because, sadly:\\n * (Number(' ') === 0) and (parseFloat('123a') === 123)\\n *\\n * @param {string} str The string to convert.\\n * @return {number} The number the supplied string represents, or NaN.\\n */\\ngoog.string.toNumber = function(str) {\\n 'use strict';\\n const num = Number(str);\\n if (num == 0 && goog.string.isEmptyOrWhitespace(str)) {\\n return NaN;\\n }\\n return num;\\n};\\n\\n\\n/**\\n * Returns whether the given string is lower camel case (e.g. \\\"isFooBar\\\").\\n *\\n * Note that this assumes the string is entirely letters.\\n * @see http://en.wikipedia.org/wiki/CamelCase#Variations_and_synonyms\\n *\\n * @param {string} str String to test.\\n * @return {boolean} Whether the string is lower camel case.\\n */\\ngoog.string.isLowerCamelCase = function(str) {\\n 'use strict';\\n return /^[a-z]+([A-Z][a-z]*)*$/.test(str);\\n};\\n\\n\\n/**\\n * Returns whether the given string is upper camel case (e.g. \\\"FooBarBaz\\\").\\n *\\n * Note that this assumes the string is entirely letters.\\n * @see http://en.wikipedia.org/wiki/CamelCase#Variations_and_synonyms\\n *\\n * @param {string} str String to test.\\n * @return {boolean} Whether the string is upper camel case.\\n */\\ngoog.string.isUpperCamelCase = function(str) {\\n 'use strict';\\n return /^([A-Z][a-z]*)+$/.test(str);\\n};\\n\\n\\n/**\\n * Converts a string from selector-case to camelCase (e.g. from\\n * \\\"multi-part-string\\\" to \\\"multiPartString\\\"), useful for converting\\n * CSS selectors and HTML dataset keys to their equivalent JS properties.\\n * @param {string} str The string in selector-case form.\\n * @return {string} The string in camelCase form.\\n */\\ngoog.string.toCamelCase = function(str) {\\n 'use strict';\\n return String(str).replace(/\\\\-([a-z])/g, function(all, match) {\\n 'use strict';\\n return match.toUpperCase();\\n });\\n};\\n\\n\\n/**\\n * Converts a string from camelCase to selector-case (e.g. from\\n * \\\"multiPartString\\\" to \\\"multi-part-string\\\"), useful for converting JS\\n * style and dataset properties to equivalent CSS selectors and HTML keys.\\n * @param {string} str The string in camelCase form.\\n * @return {string} The string in selector-case form.\\n */\\ngoog.string.toSelectorCase = function(str) {\\n 'use strict';\\n return String(str).replace(/([A-Z])/g, '-$1').toLowerCase();\\n};\\n\\n\\n/**\\n * Converts a string into TitleCase. First character of the string is always\\n * capitalized in addition to the first letter of every subsequent word.\\n * Words are delimited by one or more whitespaces by default. Custom delimiters\\n * can optionally be specified to replace the default, which doesn't preserve\\n * whitespace delimiters and instead must be explicitly included if needed.\\n *\\n * Default delimiter => \\\" \\\":\\n * goog.string.toTitleCase('oneTwoThree') => 'OneTwoThree'\\n * goog.string.toTitleCase('one two three') => 'One Two Three'\\n * goog.string.toTitleCase(' one two ') => ' One Two '\\n * goog.string.toTitleCase('one_two_three') => 'One_two_three'\\n * goog.string.toTitleCase('one-two-three') => 'One-two-three'\\n *\\n * Custom delimiter => \\\"_-.\\\":\\n * goog.string.toTitleCase('oneTwoThree', '_-.') => 'OneTwoThree'\\n * goog.string.toTitleCase('one two three', '_-.') => 'One two three'\\n * goog.string.toTitleCase(' one two ', '_-.') => ' one two '\\n * goog.string.toTitleCase('one_two_three', '_-.') => 'One_Two_Three'\\n * goog.string.toTitleCase('one-two-three', '_-.') => 'One-Two-Three'\\n * goog.string.toTitleCase('one...two...three', '_-.') => 'One...Two...Three'\\n * goog.string.toTitleCase('one. two. three', '_-.') => 'One. two. three'\\n * goog.string.toTitleCase('one-two.three', '_-.') => 'One-Two.Three'\\n *\\n * @param {string} str String value in camelCase form.\\n * @param {string=} opt_delimiters Custom delimiter character set used to\\n * distinguish words in the string value. Each character represents a\\n * single delimiter. When provided, default whitespace delimiter is\\n * overridden and must be explicitly included if needed.\\n * @return {string} String value in TitleCase form.\\n */\\ngoog.string.toTitleCase = function(str, opt_delimiters) {\\n 'use strict';\\n let delimiters = (typeof opt_delimiters === 'string') ?\\n goog.string.regExpEscape(opt_delimiters) :\\n '\\\\\\\\s';\\n\\n // For IE8, we need to prevent using an empty character set. Otherwise,\\n // incorrect matching will occur.\\n delimiters = delimiters ? '|[' + delimiters + ']+' : '';\\n\\n const regexp = new RegExp('(^' + delimiters + ')([a-z])', 'g');\\n return str.replace(regexp, function(all, p1, p2) {\\n 'use strict';\\n return p1 + p2.toUpperCase();\\n });\\n};\\n\\n\\n/**\\n * Capitalizes a string, i.e. converts the first letter to uppercase\\n * and all other letters to lowercase, e.g.:\\n *\\n * goog.string.capitalize('one') => 'One'\\n * goog.string.capitalize('ONE') => 'One'\\n * goog.string.capitalize('one two') => 'One two'\\n *\\n * Note that this function does not trim initial whitespace.\\n *\\n * @param {string} str String value to capitalize.\\n * @return {string} String value with first letter in uppercase.\\n */\\ngoog.string.capitalize = function(str) {\\n 'use strict';\\n return String(str.charAt(0)).toUpperCase() +\\n String(str.slice(1)).toLowerCase();\\n};\\n\\n\\n/**\\n * Parse a string in decimal or hexidecimal ('0xFFFF') form.\\n *\\n * To parse a particular radix, please use parseInt(string, radix) directly. See\\n * https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/parseInt\\n *\\n * This is a wrapper for the built-in parseInt function that will only parse\\n * numbers as base 10 or base 16. Some JS implementations assume strings\\n * starting with \\\"0\\\" are intended to be octal. ES3 allowed but discouraged\\n * this behavior. ES5 forbids it. This function emulates the ES5 behavior.\\n *\\n * For more information, see Mozilla JS Reference: http://goo.gl/8RiFj\\n *\\n * @param {string|number|null|undefined} value The value to be parsed.\\n * @return {number} The number, parsed. If the string failed to parse, this\\n * will be NaN.\\n */\\ngoog.string.parseInt = function(value) {\\n 'use strict';\\n // Force finite numbers to strings.\\n if (isFinite(value)) {\\n value = String(value);\\n }\\n\\n if (typeof value === 'string') {\\n // If the string starts with '0x' or '-0x', parse as hex.\\n return /^\\\\s*-?0x/i.test(value) ? parseInt(value, 16) : parseInt(value, 10);\\n }\\n\\n return NaN;\\n};\\n\\n\\n/**\\n * Splits a string on a separator a limited number of times.\\n *\\n * This implementation is more similar to Python or Java, where the limit\\n * parameter specifies the maximum number of splits rather than truncating\\n * the number of results.\\n *\\n * See http://docs.python.org/2/library/stdtypes.html#str.split\\n * See JavaDoc: http://goo.gl/F2AsY\\n * See Mozilla reference: http://goo.gl/dZdZs\\n *\\n * @param {string} str String to split.\\n * @param {string} separator The separator.\\n * @param {number} limit The limit to the number of splits. The resulting array\\n * will have a maximum length of limit+1. Negative numbers are the same\\n * as zero.\\n * @return {!Array<string>} The string, split.\\n */\\ngoog.string.splitLimit = function(str, separator, limit) {\\n 'use strict';\\n const parts = str.split(separator);\\n const returnVal = [];\\n\\n // Only continue doing this while we haven't hit the limit and we have\\n // parts left.\\n while (limit > 0 && parts.length) {\\n returnVal.push(parts.shift());\\n limit--;\\n }\\n\\n // If there are remaining parts, append them to the end.\\n if (parts.length) {\\n returnVal.push(parts.join(separator));\\n }\\n\\n return returnVal;\\n};\\n\\n\\n/**\\n * Finds the characters to the right of the last instance of any separator\\n *\\n * This function is similar to goog.string.path.baseName, except it can take a\\n * list of characters to split the string on. It will return the rightmost\\n * grouping of characters to the right of any separator as a left-to-right\\n * oriented string.\\n *\\n * @see goog.string.path.baseName\\n * @param {string} str The string\\n * @param {string|!Array<string>} separators A list of separator characters\\n * @return {string} The last part of the string with respect to the separators\\n */\\ngoog.string.lastComponent = function(str, separators) {\\n 'use strict';\\n if (!separators) {\\n return str;\\n } else if (typeof separators == 'string') {\\n separators = [separators];\\n }\\n\\n let lastSeparatorIndex = -1;\\n for (let i = 0; i < separators.length; i++) {\\n if (separators[i] == '') {\\n continue;\\n }\\n const currentSeparatorIndex = str.lastIndexOf(separators[i]);\\n if (currentSeparatorIndex > lastSeparatorIndex) {\\n lastSeparatorIndex = currentSeparatorIndex;\\n }\\n }\\n if (lastSeparatorIndex == -1) {\\n return str;\\n }\\n return str.slice(lastSeparatorIndex + 1);\\n};\\n\\n\\n/**\\n * Computes the Levenshtein edit distance between two strings.\\n * @param {string} a\\n * @param {string} b\\n * @return {number} The edit distance between the two strings.\\n */\\ngoog.string.editDistance = function(a, b) {\\n 'use strict';\\n const v0 = [];\\n const v1 = [];\\n\\n if (a == b) {\\n return 0;\\n }\\n\\n if (!a.length || !b.length) {\\n return Math.max(a.length, b.length);\\n }\\n\\n for (let i = 0; i < b.length + 1; i++) {\\n v0[i] = i;\\n }\\n\\n for (let i = 0; i < a.length; i++) {\\n v1[0] = i + 1;\\n\\n for (let j = 0; j < b.length; j++) {\\n const cost = Number(a[i] != b[j]);\\n // Cost for the substring is the minimum of adding one character, removing\\n // one character, or a swap.\\n v1[j + 1] = Math.min(v1[j] + 1, v0[j + 1] + 1, v0[j] + cost);\\n }\\n\\n for (let j = 0; j < v0.length; j++) {\\n v0[j] = v1[j];\\n }\\n }\\n\\n return v1[b.length];\\n};\\n\"],\n\"names\":[\"goog\",\"provide\",\"require\",\"string\",\"DETECT_DOUBLE_ESCAPING\",\"define\",\"FORCE_NON_DOM_HTML_UNESCAPING\",\"Unicode\",\"NBSP\",\"ZERO_WIDTH_SPACE\",\"startsWith\",\"internal\",\"endsWith\",\"caseInsensitiveStartsWith\",\"caseInsensitiveEndsWith\",\"caseInsensitiveEquals\",\"subs\",\"goog.string.subs\",\"str\",\"var_args\",\"splitParts\",\"split\",\"returnString\",\"subsArguments\",\"Array\",\"prototype\",\"slice\",\"call\",\"arguments\",\"length\",\"shift\",\"join\",\"collapseWhitespace\",\"goog.string.collapseWhitespace\",\"replace\",\"isEmptyOrWhitespace\",\"isEmptyString\",\"goog.string.isEmptyString\",\"isEmpty\",\"isEmptyOrWhitespaceSafe\",\"goog.string.isEmptyOrWhitespaceSafe\",\"makeSafe\",\"isEmptySafe\",\"isBreakingWhitespace\",\"goog.string.isBreakingWhitespace\",\"test\",\"isAlpha\",\"goog.string.isAlpha\",\"isNumeric\",\"goog.string.isNumeric\",\"isAlphaNumeric\",\"goog.string.isAlphaNumeric\",\"isSpace\",\"goog.string.isSpace\",\"ch\",\"isUnicodeChar\",\"goog.string.isUnicodeChar\",\"stripNewlines\",\"goog.string.stripNewlines\",\"canonicalizeNewlines\",\"goog.string.canonicalizeNewlines\",\"normalizeWhitespace\",\"goog.string.normalizeWhitespace\",\"normalizeSpaces\",\"goog.string.normalizeSpaces\",\"collapseBreakingSpaces\",\"goog.string.collapseBreakingSpaces\",\"trim\",\"trimLeft\",\"goog.string.trimLeft\",\"trimRight\",\"goog.string.trimRight\",\"caseInsensitiveCompare\",\"numberAwareCompare_\",\"goog.string.numberAwareCompare_\",\"str1\",\"str2\",\"tokenizerRegExp\",\"tokens1\",\"toLowerCase\",\"match\",\"tokens2\",\"count\",\"Math\",\"min\",\"i\",\"a\",\"b\",\"num1\",\"parseInt\",\"isNaN\",\"num2\",\"intAwareCompare\",\"goog.string.intAwareCompare\",\"floatAwareCompare\",\"goog.string.floatAwareCompare\",\"numerateCompare\",\"urlEncode\",\"goog.string.urlEncode\",\"encodeURIComponent\",\"String\",\"urlDecode\",\"goog.string.urlDecode\",\"decodeURIComponent\",\"newLineToBr\",\"htmlEscape\",\"goog.string.htmlEscape\",\"opt_isLikelyToContainHtmlChars\",\"E_RE_\",\"unescapeEntities\",\"goog.string.unescapeEntities\",\"contains\",\"global\",\"unescapeEntitiesUsingDom_\",\"unescapePureXmlEntities_\",\"unescapeEntitiesWithDocument\",\"goog.string.unescapeEntitiesWithDocument\",\"document\",\"goog.string.unescapeEntitiesUsingDom_\",\"opt_document\",\"seen\",\"div\",\"createElement\",\"HTML_ENTITY_PATTERN_\",\"s\",\"entity\",\"value\",\"charAt\",\"n\",\"Number\",\"fromCharCode\",\"dom\",\"safe\",\"setInnerHtml\",\"html\",\"uncheckedconversions\",\"safeHtmlFromStringKnownToSatisfyTypeContract\",\"Const\",\"from\",\"firstChild\",\"nodeValue\",\"goog.string.unescapePureXmlEntities_\",\"whitespaceEscape\",\"goog.string.whitespaceEscape\",\"opt_xml\",\"preserveSpaces\",\"goog.string.preserveSpaces\",\"stripQuotes\",\"goog.string.stripQuotes\",\"quoteChars\",\"quoteChar\",\"substring\",\"truncate\",\"goog.string.truncate\",\"chars\",\"opt_protectEscapedCharacters\",\"truncateMiddle\",\"goog.string.truncateMiddle\",\"opt_trailingChars\",\"endPoint\",\"startPoint\",\"half\",\"floor\",\"endPos\",\"specialEscapeChars_\",\"jsEscapeCache_\",\"quote\",\"goog.string.quote\",\"sb\",\"cc\",\"charCodeAt\",\"escapeChar\",\"push\",\"escapeString\",\"goog.string.escapeString\",\"goog.string.escapeChar\",\"c\",\"rv\",\"toString\",\"toUpperCase\",\"caseInsensitiveContains\",\"countOf\",\"goog.string.countOf\",\"ss\",\"removeAt\",\"goog.string.removeAt\",\"index\",\"stringLength\",\"resultStr\",\"remove\",\"goog.string.remove\",\"substr\",\"removeAll\",\"goog.string.removeAll\",\"re\",\"RegExp\",\"regExpEscape\",\"replaceAll\",\"goog.string.replaceAll\",\"replacement\",\"goog.string.regExpEscape\",\"repeat\",\"padNumber\",\"goog.string.padNumber\",\"num\",\"opt_precision\",\"isFinite\",\"undefined\",\"toFixed\",\"indexOf\",\"sign\",\"max\",\"goog.string.makeSafe\",\"obj\",\"getRandomString\",\"goog.string.getRandomString\",\"x\",\"random\",\"abs\",\"now\",\"compareVersions\",\"hashCode\",\"goog.string.hashCode\",\"result\",\"uniqueStringCounter_\",\"createUniqueString\",\"goog.string.createUniqueString\",\"toNumber\",\"goog.string.toNumber\",\"NaN\",\"isLowerCamelCase\",\"goog.string.isLowerCamelCase\",\"isUpperCamelCase\",\"goog.string.isUpperCamelCase\",\"toCamelCase\",\"goog.string.toCamelCase\",\"all\",\"toSelectorCase\",\"goog.string.toSelectorCase\",\"toTitleCase\",\"goog.string.toTitleCase\",\"opt_delimiters\",\"delimiters\",\"regexp\",\"p1\",\"p2\",\"capitalize\",\"goog.string.capitalize\",\"goog.string.parseInt\",\"splitLimit\",\"goog.string.splitLimit\",\"separator\",\"limit\",\"parts\",\"returnVal\",\"lastComponent\",\"goog.string.lastComponent\",\"separators\",\"lastSeparatorIndex\",\"currentSeparatorIndex\",\"lastIndexOf\",\"editDistance\",\"goog.string.editDistance\",\"v0\",\"v1\",\"j\",\"cost\"]\n}\n"]