["^ ","~:resource-id",["~:shadow.build.classpath/resource","goog/array/array.js"],"~:js","goog.loadModule(function(exports) {\n function peek(array) {\n return array[array.length - 1];\n }\n function forEachRight(arr, f, opt_obj) {\n const l = arr.length;\n const arr2 = typeof arr === \"string\" ? arr.split(\"\") : arr;\n for (let i = l - 1; i >= 0; --i) {\n if (i in arr2) {\n f.call(opt_obj, arr2[i], i, arr);\n }\n }\n }\n function count(arr, f, opt_obj) {\n let count = 0;\n forEach(arr, function(element, index, arr) {\n if (f.call(opt_obj, element, index, arr)) {\n ++count;\n }\n }, opt_obj);\n return count;\n }\n function find(arr, f, opt_obj) {\n const i = findIndex(arr, f, opt_obj);\n return i < 0 ? null : typeof arr === \"string\" ? arr.charAt(i) : arr[i];\n }\n function findIndex(arr, f, opt_obj) {\n const l = arr.length;\n const arr2 = typeof arr === \"string\" ? arr.split(\"\") : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {\n return i;\n }\n }\n return -1;\n }\n function findRight(arr, f, opt_obj) {\n const i = findIndexRight(arr, f, opt_obj);\n return i < 0 ? null : typeof arr === \"string\" ? arr.charAt(i) : arr[i];\n }\n function findIndexRight(arr, f, opt_obj) {\n const l = arr.length;\n const arr2 = typeof arr === \"string\" ? arr.split(\"\") : arr;\n for (let i = l - 1; i >= 0; i--) {\n if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {\n return i;\n }\n }\n return -1;\n }\n function contains(arr, obj) {\n return indexOf(arr, obj) >= 0;\n }\n function isEmpty(arr) {\n return arr.length == 0;\n }\n function clear(arr) {\n if (!Array.isArray(arr)) {\n for (let i = arr.length - 1; i >= 0; i--) {\n delete arr[i];\n }\n }\n arr.length = 0;\n }\n function insert(arr, obj) {\n if (!contains(arr, obj)) {\n arr.push(obj);\n }\n }\n function insertAt(arr, obj, opt_i) {\n splice(arr, opt_i, 0, obj);\n }\n function insertArrayAt(arr, elementsToAdd, opt_i) {\n goog.partial(splice, arr, opt_i, 0).apply(null, elementsToAdd);\n }\n function insertBefore(arr, obj, opt_obj2) {\n let i;\n if (arguments.length == 2 || (i = indexOf(arr, opt_obj2)) < 0) {\n arr.push(obj);\n } else {\n insertAt(arr, obj, i);\n }\n }\n function remove(arr, obj) {\n const i = indexOf(arr, obj);\n let rv;\n if (rv = i >= 0) {\n removeAt(arr, i);\n }\n return rv;\n }\n function removeLast(arr, obj) {\n const i = lastIndexOf(arr, obj);\n if (i >= 0) {\n removeAt(arr, i);\n return true;\n }\n return false;\n }\n function removeAt(arr, i) {\n asserts.assert(arr.length != null);\n return Array.prototype.splice.call(arr, i, 1).length == 1;\n }\n function removeIf(arr, f, opt_obj) {\n const i = findIndex(arr, f, opt_obj);\n if (i >= 0) {\n removeAt(arr, i);\n return true;\n }\n return false;\n }\n function removeAllIf(arr, f, opt_obj) {\n let removedCount = 0;\n forEachRight(arr, function(val, index) {\n if (f.call(opt_obj, val, index, arr)) {\n if (removeAt(arr, index)) {\n removedCount++;\n }\n }\n });\n return removedCount;\n }\n function concat(var_args) {\n return Array.prototype.concat.apply([], arguments);\n }\n function join(var_args) {\n return Array.prototype.concat.apply([], arguments);\n }\n function toArray(object) {\n const length = object.length;\n if (length > 0) {\n const rv = new Array(length);\n for (let i = 0; i < length; i++) {\n rv[i] = object[i];\n }\n return rv;\n }\n return [];\n }\n function extend(arr1, var_args) {\n for (let i = 1; i < arguments.length; i++) {\n const arr2 = arguments[i];\n if (goog.isArrayLike(arr2)) {\n const len1 = arr1.length || 0;\n const len2 = arr2.length || 0;\n arr1.length = len1 + len2;\n for (let j = 0; j < len2; j++) {\n arr1[len1 + j] = arr2[j];\n }\n } else {\n arr1.push(arr2);\n }\n }\n }\n function splice(arr, index, howMany, var_args) {\n asserts.assert(arr.length != null);\n return Array.prototype.splice.apply(arr, slice(arguments, 1));\n }\n function slice(arr, start, opt_end) {\n asserts.assert(arr.length != null);\n if (arguments.length <= 2) {\n return Array.prototype.slice.call(arr, start);\n } else {\n return Array.prototype.slice.call(arr, start, opt_end);\n }\n }\n function removeDuplicates(arr, opt_rv, opt_hashFn) {\n const returnArray = opt_rv || arr;\n const defaultHashFn = function(item) {\n return goog.isObject(item) ? \"o\" + goog.getUid(item) : (typeof item).charAt(0) + item;\n };\n const hashFn = opt_hashFn || defaultHashFn;\n let cursorInsert = 0;\n let cursorRead = 0;\n const seen = {};\n for (; cursorRead < arr.length;) {\n const current = arr[cursorRead++];\n const key = hashFn(current);\n if (!Object.prototype.hasOwnProperty.call(seen, key)) {\n seen[key] = true;\n returnArray[cursorInsert++] = current;\n }\n }\n returnArray.length = cursorInsert;\n }\n function binarySearch(arr, target, opt_compareFn) {\n return binarySearch_(arr, opt_compareFn || defaultCompare, false, target);\n }\n function binarySelect(arr, evaluator, opt_obj) {\n return binarySearch_(arr, evaluator, true, undefined, opt_obj);\n }\n function binarySearch_(arr, compareFn, isEvaluator, opt_target, opt_selfObj) {\n let left = 0;\n let right = arr.length;\n let found;\n for (; left < right;) {\n const middle = left + (right - left >>> 1);\n let compareResult;\n if (isEvaluator) {\n compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr);\n } else {\n compareResult = compareFn(opt_target, arr[middle]);\n }\n if (compareResult > 0) {\n left = middle + 1;\n } else {\n right = middle;\n found = !compareResult;\n }\n }\n return found ? left : -left - 1;\n }\n function sort(arr, opt_compareFn) {\n arr.sort(opt_compareFn || defaultCompare);\n }\n function stableSort(arr, opt_compareFn) {\n function stableCompareFn(obj1, obj2) {\n return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index;\n }\n const compArr = new Array(arr.length);\n for (let i = 0; i < arr.length; i++) {\n compArr[i] = {index:i, value:arr[i]};\n }\n const valueCompareFn = opt_compareFn || defaultCompare;\n sort(compArr, stableCompareFn);\n for (let i = 0; i < arr.length; i++) {\n arr[i] = compArr[i].value;\n }\n }\n function sortByKey(arr, keyFn, opt_compareFn) {\n const keyCompareFn = opt_compareFn || defaultCompare;\n sort(arr, function(a, b) {\n return keyCompareFn(keyFn(a), keyFn(b));\n });\n }\n function sortObjectsByKey(arr, key, opt_compareFn) {\n sortByKey(arr, function(obj) {\n return obj[key];\n }, opt_compareFn);\n }\n function isSorted(arr, opt_compareFn, opt_strict) {\n const compare = opt_compareFn || defaultCompare;\n for (let i = 1; i < arr.length; i++) {\n const compareResult = compare(arr[i - 1], arr[i]);\n if (compareResult > 0 || compareResult == 0 && opt_strict) {\n return false;\n }\n }\n return true;\n }\n function equals(arr1, arr2, opt_equalsFn) {\n if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) || arr1.length != arr2.length) {\n return false;\n }\n const l = arr1.length;\n const equalsFn = opt_equalsFn || defaultCompareEquality;\n for (let i = 0; i < l; i++) {\n if (!equalsFn(arr1[i], arr2[i])) {\n return false;\n }\n }\n return true;\n }\n function compare3(arr1, arr2, opt_compareFn) {\n const compare = opt_compareFn || defaultCompare;\n const l = Math.min(arr1.length, arr2.length);\n for (let i = 0; i < l; i++) {\n const result = compare(arr1[i], arr2[i]);\n if (result != 0) {\n return result;\n }\n }\n return defaultCompare(arr1.length, arr2.length);\n }\n function defaultCompare(a, b) {\n return a > b ? 1 : a < b ? -1 : 0;\n }\n function inverseDefaultCompare(a, b) {\n return -defaultCompare(a, b);\n }\n function defaultCompareEquality(a, b) {\n return a === b;\n }\n function binaryInsert(array, value, opt_compareFn) {\n const index = binarySearch(array, value, opt_compareFn);\n if (index < 0) {\n insertAt(array, value, -(index + 1));\n return true;\n }\n return false;\n }\n function binaryRemove(array, value, opt_compareFn) {\n const index = binarySearch(array, value, opt_compareFn);\n return index >= 0 ? removeAt(array, index) : false;\n }\n function bucket(array, sorter, opt_obj) {\n const buckets = {};\n for (let i = 0; i < array.length; i++) {\n const value = array[i];\n const key = sorter.call(opt_obj, value, i, array);\n if (key !== undefined) {\n const bucket = buckets[key] || (buckets[key] = []);\n bucket.push(value);\n }\n }\n return buckets;\n }\n function bucketToMap(array, sorter) {\n const buckets = new Map();\n for (let i = 0; i < array.length; i++) {\n const value = array[i];\n const key = sorter(value, i, array);\n if (key !== undefined) {\n let bucket = buckets.get(key);\n if (!bucket) {\n bucket = [];\n buckets.set(key, bucket);\n }\n bucket.push(value);\n }\n }\n return buckets;\n }\n function toObject(arr, keyFunc, opt_obj) {\n const ret = {};\n forEach(arr, function(element, index) {\n ret[keyFunc.call(opt_obj, element, index, arr)] = element;\n });\n return ret;\n }\n function toMap(arr, keyFunc) {\n const map = new Map();\n for (let i = 0; i < arr.length; i++) {\n const element = arr[i];\n map.set(keyFunc(element, i, arr), element);\n }\n return map;\n }\n function range(startOrEnd, opt_end, opt_step) {\n const array = [];\n let start = 0;\n let end = startOrEnd;\n const step = opt_step || 1;\n if (opt_end !== undefined) {\n start = startOrEnd;\n end = opt_end;\n }\n if (step * (end - start) < 0) {\n return [];\n }\n if (step > 0) {\n for (let i = start; i < end; i = i + step) {\n array.push(i);\n }\n } else {\n for (let i = start; i > end; i = i + step) {\n array.push(i);\n }\n }\n return array;\n }\n function repeat(value, n) {\n const array = [];\n for (let i = 0; i < n; i++) {\n array[i] = value;\n }\n return array;\n }\n function flatten(var_args) {\n const CHUNK_SIZE = 8192;\n const result = [];\n for (let i = 0; i < arguments.length; i++) {\n const element = arguments[i];\n if (Array.isArray(element)) {\n for (let c = 0; c < element.length; c = c + CHUNK_SIZE) {\n const chunk = slice(element, c, c + CHUNK_SIZE);\n const recurseResult = flatten.apply(null, chunk);\n for (let r = 0; r < recurseResult.length; r++) {\n result.push(recurseResult[r]);\n }\n }\n } else {\n result.push(element);\n }\n }\n return result;\n }\n function rotate(array, n) {\n asserts.assert(array.length != null);\n if (array.length) {\n n = n % array.length;\n if (n > 0) {\n Array.prototype.unshift.apply(array, array.splice(-n, n));\n } else if (n < 0) {\n Array.prototype.push.apply(array, array.splice(0, -n));\n }\n }\n return array;\n }\n function moveItem(arr, fromIndex, toIndex) {\n asserts.assert(fromIndex >= 0 && fromIndex < arr.length);\n asserts.assert(toIndex >= 0 && toIndex < arr.length);\n const removedItems = Array.prototype.splice.call(arr, fromIndex, 1);\n Array.prototype.splice.call(arr, toIndex, 0, removedItems[0]);\n }\n function zip(var_args) {\n if (!arguments.length) {\n return [];\n }\n const result = [];\n let minLen = arguments[0].length;\n for (let i = 1; i < arguments.length; i++) {\n if (arguments[i].length < minLen) {\n minLen = arguments[i].length;\n }\n }\n for (let i = 0; i < minLen; i++) {\n const value = [];\n for (let j = 0; j < arguments.length; j++) {\n value.push(arguments[j][i]);\n }\n result.push(value);\n }\n return result;\n }\n function shuffle(arr, opt_randFn) {\n const randFn = opt_randFn || Math.random;\n for (let i = arr.length - 1; i > 0; i--) {\n const j = Math.floor(randFn() * (i + 1));\n const tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n }\n }\n function copyByIndex(arr, index_arr) {\n const result = [];\n forEach(index_arr, function(index) {\n result.push(arr[index]);\n });\n return result;\n }\n function concatMap(arr, f, opt_obj) {\n return concat.apply([], map(arr, f, opt_obj));\n }\n \"use strict\";\n goog.module(\"goog.array\");\n goog.module.declareLegacyNamespace();\n const asserts = goog.require(\"goog.asserts\");\n goog.NATIVE_ARRAY_PROTOTYPES = goog.define(\"goog.NATIVE_ARRAY_PROTOTYPES\", goog.TRUSTED_SITE);\n const ASSUME_NATIVE_FUNCTIONS = goog.define(\"goog.array.ASSUME_NATIVE_FUNCTIONS\", goog.FEATURESET_YEAR > 2012);\n exports.ASSUME_NATIVE_FUNCTIONS = ASSUME_NATIVE_FUNCTIONS;\n exports.peek = peek;\n exports.last = peek;\n const indexOf = goog.NATIVE_ARRAY_PROTOTYPES && (ASSUME_NATIVE_FUNCTIONS || Array.prototype.indexOf) ? function(arr, obj, opt_fromIndex) {\n asserts.assert(arr.length != null);\n return Array.prototype.indexOf.call(arr, obj, opt_fromIndex);\n } : function(arr, obj, opt_fromIndex) {\n const fromIndex = opt_fromIndex == null ? 0 : opt_fromIndex < 0 ? Math.max(0, arr.length + opt_fromIndex) : opt_fromIndex;\n if (typeof arr === \"string\") {\n if (typeof obj !== \"string\" || obj.length != 1) {\n return -1;\n }\n return arr.indexOf(obj, fromIndex);\n }\n for (let i = fromIndex; i < arr.length; i++) {\n if (i in arr && arr[i] === obj) {\n return i;\n }\n }\n return -1;\n };\n exports.indexOf = indexOf;\n const lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES && (ASSUME_NATIVE_FUNCTIONS || Array.prototype.lastIndexOf) ? function(arr, obj, opt_fromIndex) {\n asserts.assert(arr.length != null);\n const fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;\n return Array.prototype.lastIndexOf.call(arr, obj, fromIndex);\n } : function(arr, obj, opt_fromIndex) {\n let fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;\n if (fromIndex < 0) {\n fromIndex = Math.max(0, arr.length + fromIndex);\n }\n if (typeof arr === \"string\") {\n if (typeof obj !== \"string\" || obj.length != 1) {\n return -1;\n }\n return arr.lastIndexOf(obj, fromIndex);\n }\n for (let i = fromIndex; i >= 0; i--) {\n if (i in arr && arr[i] === obj) {\n return i;\n }\n }\n return -1;\n };\n exports.lastIndexOf = lastIndexOf;\n const forEach = goog.NATIVE_ARRAY_PROTOTYPES && (ASSUME_NATIVE_FUNCTIONS || Array.prototype.forEach) ? function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n Array.prototype.forEach.call(arr, f, opt_obj);\n } : function(arr, f, opt_obj) {\n const l = arr.length;\n const arr2 = typeof arr === \"string\" ? arr.split(\"\") : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2) {\n f.call(opt_obj, arr2[i], i, arr);\n }\n }\n };\n exports.forEach = forEach;\n exports.forEachRight = forEachRight;\n const filter = goog.NATIVE_ARRAY_PROTOTYPES && (ASSUME_NATIVE_FUNCTIONS || Array.prototype.filter) ? function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n return Array.prototype.filter.call(arr, f, opt_obj);\n } : function(arr, f, opt_obj) {\n const l = arr.length;\n const res = [];\n let resLength = 0;\n const arr2 = typeof arr === \"string\" ? arr.split(\"\") : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2) {\n const val = arr2[i];\n if (f.call(opt_obj, val, i, arr)) {\n res[resLength++] = val;\n }\n }\n }\n return res;\n };\n exports.filter = filter;\n const map = goog.NATIVE_ARRAY_PROTOTYPES && (ASSUME_NATIVE_FUNCTIONS || Array.prototype.map) ? function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n return Array.prototype.map.call(arr, f, opt_obj);\n } : function(arr, f, opt_obj) {\n const l = arr.length;\n const res = new Array(l);\n const arr2 = typeof arr === \"string\" ? arr.split(\"\") : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2) {\n res[i] = f.call(opt_obj, arr2[i], i, arr);\n }\n }\n return res;\n };\n exports.map = map;\n const reduce = goog.NATIVE_ARRAY_PROTOTYPES && (ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduce) ? function(arr, f, val, opt_obj) {\n asserts.assert(arr.length != null);\n if (opt_obj) {\n f = goog.bind(f, opt_obj);\n }\n return Array.prototype.reduce.call(arr, f, val);\n } : function(arr, f, val, opt_obj) {\n let rval = val;\n forEach(arr, function(val, index) {\n rval = f.call(opt_obj, rval, val, index, arr);\n });\n return rval;\n };\n exports.reduce = reduce;\n const reduceRight = goog.NATIVE_ARRAY_PROTOTYPES && (ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduceRight) ? function(arr, f, val, opt_obj) {\n asserts.assert(arr.length != null);\n asserts.assert(f != null);\n if (opt_obj) {\n f = goog.bind(f, opt_obj);\n }\n return Array.prototype.reduceRight.call(arr, f, val);\n } : function(arr, f, val, opt_obj) {\n let rval = val;\n forEachRight(arr, function(val, index) {\n rval = f.call(opt_obj, rval, val, index, arr);\n });\n return rval;\n };\n exports.reduceRight = reduceRight;\n const some = goog.NATIVE_ARRAY_PROTOTYPES && (ASSUME_NATIVE_FUNCTIONS || Array.prototype.some) ? function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n return Array.prototype.some.call(arr, f, opt_obj);\n } : function(arr, f, opt_obj) {\n const l = arr.length;\n const arr2 = typeof arr === \"string\" ? arr.split(\"\") : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2 && f.call(opt_obj, arr2[i], i, arr)) {\n return true;\n }\n }\n return false;\n };\n exports.some = some;\n const every = goog.NATIVE_ARRAY_PROTOTYPES && (ASSUME_NATIVE_FUNCTIONS || Array.prototype.every) ? function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n return Array.prototype.every.call(arr, f, opt_obj);\n } : function(arr, f, opt_obj) {\n const l = arr.length;\n const arr2 = typeof arr === \"string\" ? arr.split(\"\") : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2 && !f.call(opt_obj, arr2[i], i, arr)) {\n return false;\n }\n }\n return true;\n };\n exports.every = every;\n exports.count = count;\n exports.find = find;\n exports.findIndex = findIndex;\n exports.findRight = findRight;\n exports.findIndexRight = findIndexRight;\n exports.contains = contains;\n exports.isEmpty = isEmpty;\n exports.clear = clear;\n exports.insert = insert;\n exports.insertAt = insertAt;\n exports.insertArrayAt = insertArrayAt;\n exports.insertBefore = insertBefore;\n exports.remove = remove;\n exports.removeLast = removeLast;\n exports.removeAt = removeAt;\n exports.removeIf = removeIf;\n exports.removeAllIf = removeAllIf;\n exports.concat = concat;\n exports.join = join;\n exports.toArray = toArray;\n const clone = toArray;\n exports.clone = clone;\n exports.extend = extend;\n exports.splice = splice;\n exports.slice = slice;\n exports.removeDuplicates = removeDuplicates;\n exports.binarySearch = binarySearch;\n exports.binarySelect = binarySelect;\n exports.sort = sort;\n exports.stableSort = stableSort;\n exports.sortByKey = sortByKey;\n exports.sortObjectsByKey = sortObjectsByKey;\n exports.isSorted = isSorted;\n exports.equals = equals;\n exports.compare3 = compare3;\n exports.defaultCompare = defaultCompare;\n exports.inverseDefaultCompare = inverseDefaultCompare;\n exports.defaultCompareEquality = defaultCompareEquality;\n exports.binaryInsert = binaryInsert;\n exports.binaryRemove = binaryRemove;\n exports.bucket = bucket;\n exports.bucketToMap = bucketToMap;\n exports.toObject = toObject;\n exports.toMap = toMap;\n exports.range = range;\n exports.repeat = repeat;\n exports.flatten = flatten;\n exports.rotate = rotate;\n exports.moveItem = moveItem;\n exports.zip = zip;\n exports.shuffle = shuffle;\n exports.copyByIndex = copyByIndex;\n exports.concatMap = concatMap;\n return exports;\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 manipulating arrays.\n */\n\n\ngoog.module('goog.array');\ngoog.module.declareLegacyNamespace();\n\nconst asserts = goog.require('goog.asserts');\n\n\n/**\n * @define {boolean} NATIVE_ARRAY_PROTOTYPES indicates whether the code should\n * rely on Array.prototype functions, if available.\n *\n * The Array.prototype functions can be defined by external libraries like\n * Prototype and setting this flag to false forces closure to use its own\n * goog.array implementation.\n *\n * If your javascript can be loaded by a third party site and you are wary about\n * relying on the prototype functions, specify\n * \"--define goog.NATIVE_ARRAY_PROTOTYPES=false\" to the JSCompiler.\n *\n * Setting goog.TRUSTED_SITE to false will automatically set\n * NATIVE_ARRAY_PROTOTYPES to false.\n */\ngoog.NATIVE_ARRAY_PROTOTYPES =\n goog.define('goog.NATIVE_ARRAY_PROTOTYPES', goog.TRUSTED_SITE);\n\n\n/**\n * @define {boolean} If true, JSCompiler will use the native implementation of\n * array functions where appropriate (e.g., `Array#filter`) and remove the\n * unused pure JS implementation.\n */\nconst ASSUME_NATIVE_FUNCTIONS = goog.define(\n 'goog.array.ASSUME_NATIVE_FUNCTIONS', goog.FEATURESET_YEAR > 2012);\nexports.ASSUME_NATIVE_FUNCTIONS = ASSUME_NATIVE_FUNCTIONS;\n\n\n/**\n * Returns the last element in an array without removing it.\n * Same as {@link goog.array.last}.\n * @param {IArrayLike|string} array The array.\n * @return {T} Last item in array.\n * @template T\n */\nfunction peek(array) {\n return array[array.length - 1];\n}\nexports.peek = peek;\n\n\n/**\n * Returns the last element in an array without removing it.\n * Same as {@link goog.array.peek}.\n * @param {IArrayLike|string} array The array.\n * @return {T} Last item in array.\n * @template T\n */\nexports.last = peek;\n\n// NOTE(arv): Since most of the array functions are generic it allows you to\n// pass an array-like object. Strings have a length and are considered array-\n// like. However, the 'in' operator does not work on strings so we cannot just\n// use the array path even if the browser supports indexing into strings. We\n// therefore end up splitting the string.\n\n\n/**\n * Returns the index of the first element of an array with a specified value, or\n * -1 if the element is not present in the array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-indexof}\n *\n * @param {IArrayLike|string} arr The array to be searched.\n * @param {T} obj The object for which we are searching.\n * @param {number=} opt_fromIndex The index at which to start the search. If\n * omitted the search starts at index 0.\n * @return {number} The index of the first matching array element.\n * @template T\n */\nconst indexOf = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.indexOf) ?\n function(arr, obj, opt_fromIndex) {\n asserts.assert(arr.length != null);\n\n return Array.prototype.indexOf.call(arr, obj, opt_fromIndex);\n } :\n function(arr, obj, opt_fromIndex) {\n const fromIndex = opt_fromIndex == null ?\n 0 :\n (opt_fromIndex < 0 ? Math.max(0, arr.length + opt_fromIndex) :\n opt_fromIndex);\n\n if (typeof arr === 'string') {\n // Array.prototype.indexOf uses === so only strings should be found.\n if (typeof obj !== 'string' || obj.length != 1) {\n return -1;\n }\n return arr.indexOf(obj, fromIndex);\n }\n\n for (let i = fromIndex; i < arr.length; i++) {\n if (i in arr && arr[i] === obj) return i;\n }\n return -1;\n };\nexports.indexOf = indexOf;\n\n\n/**\n * Returns the index of the last element of an array with a specified value, or\n * -1 if the element is not present in the array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-lastindexof}\n *\n * @param {!IArrayLike|string} arr The array to be searched.\n * @param {T} obj The object for which we are searching.\n * @param {?number=} opt_fromIndex The index at which to start the search. If\n * omitted the search starts at the end of the array.\n * @return {number} The index of the last matching array element.\n * @template T\n */\nconst lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.lastIndexOf) ?\n function(arr, obj, opt_fromIndex) {\n asserts.assert(arr.length != null);\n\n // Firefox treats undefined and null as 0 in the fromIndex argument which\n // leads it to always return -1\n const fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;\n return Array.prototype.lastIndexOf.call(arr, obj, fromIndex);\n } :\n function(arr, obj, opt_fromIndex) {\n let fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;\n\n if (fromIndex < 0) {\n fromIndex = Math.max(0, arr.length + fromIndex);\n }\n\n if (typeof arr === 'string') {\n // Array.prototype.lastIndexOf uses === so only strings should be found.\n if (typeof obj !== 'string' || obj.length != 1) {\n return -1;\n }\n return arr.lastIndexOf(obj, fromIndex);\n }\n\n for (let i = fromIndex; i >= 0; i--) {\n if (i in arr && arr[i] === obj) return i;\n }\n return -1;\n };\nexports.lastIndexOf = lastIndexOf;\n\n\n/**\n * Calls a function for each element in an array. Skips holes in the array.\n * See {@link http://tinyurl.com/developer-mozilla-org-array-foreach}\n *\n * @param {IArrayLike|string} arr Array or array like object over\n * which to iterate.\n * @param {?function(this: S, T, number, ?): ?} f The function to call for every\n * element. This function takes 3 arguments (the element, the index and the\n * array). The return value is ignored.\n * @param {S=} opt_obj The object to be used as the value of 'this' within f.\n * @template T,S\n */\nconst forEach = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.forEach) ?\n function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n\n Array.prototype.forEach.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2) {\n f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\n }\n }\n };\nexports.forEach = forEach;\n\n\n/**\n * Calls a function for each element in an array, starting from the last\n * element rather than the first.\n *\n * @param {IArrayLike|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this: S, T, number, ?): ?} f The function to call for every\n * element. This function\n * takes 3 arguments (the element, the index and the array). The return\n * value is ignored.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within f.\n * @template T,S\n */\nfunction forEachRight(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = l - 1; i >= 0; --i) {\n if (i in arr2) {\n f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\n }\n }\n}\nexports.forEachRight = forEachRight;\n\n\n/**\n * Calls a function for each element in an array, and if the function returns\n * true adds the element to a new array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-filter}\n *\n * @param {IArrayLike|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?):boolean} f The function to call for\n * every element. This function\n * takes 3 arguments (the element, the index and the array) and must\n * return a Boolean. If the return value is true the element is added to the\n * result array. If it is false the element is not included.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within f.\n * @return {!Array} a new array in which only elements that passed the test\n * are present.\n * @template T,S\n */\nconst filter = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.filter) ?\n function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n\n return Array.prototype.filter.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const res = [];\n let resLength = 0;\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2) {\n const val = arr2[i]; // in case f mutates arr2\n if (f.call(/** @type {?} */ (opt_obj), val, i, arr)) {\n res[resLength++] = val;\n }\n }\n }\n return res;\n };\nexports.filter = filter;\n\n\n/**\n * Calls a function for each element in an array and inserts the result into a\n * new array.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-map}\n *\n * @param {IArrayLike|string} arr Array or array like object\n * over which to iterate.\n * @param {function(this:THIS, VALUE, number, ?): RESULT} f The function to call\n * for every element. This function takes 3 arguments (the element,\n * the index and the array) and should return something. The result will be\n * inserted into a new array.\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within f.\n * @return {!Array} a new array with the results from f.\n * @template THIS, VALUE, RESULT\n */\nconst map = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.map) ?\n function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n\n return Array.prototype.map.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const res = new Array(l);\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2) {\n res[i] = f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\n }\n }\n return res;\n };\nexports.map = map;\n\n\n/**\n * Passes every element of an array into a function and accumulates the result.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-reduce}\n * Note that this implementation differs from the native Array.prototype.reduce\n * in that the initial value is assumed to be defined (the MDN docs linked above\n * recommend not omitting this parameter, although it is technically optional).\n *\n * For example:\n * var a = [1, 2, 3, 4];\n * reduce(a, function(r, v, i, arr) {return r + v;}, 0);\n * returns 10\n *\n * @param {IArrayLike|string} arr Array or array\n * like object over which to iterate.\n * @param {function(this:S, R, T, number, ?) : R} f The function to call for\n * every element. This function\n * takes 4 arguments (the function's previous result or the initial value,\n * the value of the current array element, the current array index, and the\n * array itself)\n * function(previousValue, currentValue, index, array).\n * @param {?} val The initial value to pass into the function on the first call.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within f.\n * @return {R} Result of evaluating f repeatedly across the values of the array.\n * @template T,S,R\n */\nconst reduce = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduce) ?\n function(arr, f, val, opt_obj) {\n asserts.assert(arr.length != null);\n if (opt_obj) {\n f = goog.bind(f, opt_obj);\n }\n return Array.prototype.reduce.call(arr, f, val);\n } :\n function(arr, f, val, opt_obj) {\n let rval = val;\n forEach(arr, function(val, index) {\n rval = f.call(/** @type {?} */ (opt_obj), rval, val, index, arr);\n });\n return rval;\n };\nexports.reduce = reduce;\n\n\n/**\n * Passes every element of an array into a function and accumulates the result,\n * starting from the last element and working towards the first.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-reduceright}\n *\n * For example:\n * var a = ['a', 'b', 'c'];\n * reduceRight(a, function(r, v, i, arr) {return r + v;}, '');\n * returns 'cba'\n *\n * @param {IArrayLike|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, R, T, number, ?) : R} f The function to call for\n * every element. This function\n * takes 4 arguments (the function's previous result or the initial value,\n * the value of the current array element, the current array index, and the\n * array itself)\n * function(previousValue, currentValue, index, array).\n * @param {?} val The initial value to pass into the function on the first call.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within f.\n * @return {R} Object returned as a result of evaluating f repeatedly across the\n * values of the array.\n * @template T,S,R\n */\nconst reduceRight = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduceRight) ?\n function(arr, f, val, opt_obj) {\n asserts.assert(arr.length != null);\n asserts.assert(f != null);\n if (opt_obj) {\n f = goog.bind(f, opt_obj);\n }\n return Array.prototype.reduceRight.call(arr, f, val);\n } :\n function(arr, f, val, opt_obj) {\n let rval = val;\n forEachRight(arr, function(val, index) {\n rval = f.call(/** @type {?} */ (opt_obj), rval, val, index, arr);\n });\n return rval;\n };\nexports.reduceRight = reduceRight;\n\n\n/**\n * Calls f for each element of an array. If any call returns true, some()\n * returns true (without checking the remaining elements). If all calls\n * return false, some() returns false.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-some}\n *\n * @param {IArrayLike|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\n * for every element. This function takes 3 arguments (the element, the\n * index and the array) and should return a boolean.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within f.\n * @return {boolean} true if any element passes the test.\n * @template T,S\n */\nconst some = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.some) ?\n function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n\n return Array.prototype.some.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n return true;\n }\n }\n return false;\n };\nexports.some = some;\n\n\n/**\n * Call f for each element of an array. If all calls return true, every()\n * returns true. If any call returns false, every() returns false and\n * does not continue to check the remaining elements.\n *\n * See {@link http://tinyurl.com/developer-mozilla-org-array-every}\n *\n * @param {IArrayLike|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\n * for every element. This function takes 3 arguments (the element, the\n * index and the array) and should return a boolean.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within f.\n * @return {boolean} false if any element fails the test.\n * @template T,S\n */\nconst every = goog.NATIVE_ARRAY_PROTOTYPES &&\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.every) ?\n function(arr, f, opt_obj) {\n asserts.assert(arr.length != null);\n\n return Array.prototype.every.call(arr, f, opt_obj);\n } :\n function(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2 && !f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n return false;\n }\n }\n return true;\n };\nexports.every = every;\n\n\n/**\n * Counts the array elements that fulfill the predicate, i.e. for which the\n * callback function returns true. Skips holes in the array.\n *\n * @param {!IArrayLike|string} arr Array or array like object\n * over which to iterate.\n * @param {function(this: S, T, number, ?): boolean} f The function to call for\n * every element. Takes 3 arguments (the element, the index and the array).\n * @param {S=} opt_obj The object to be used as the value of 'this' within f.\n * @return {number} The number of the matching elements.\n * @template T,S\n */\nfunction count(arr, f, opt_obj) {\n let count = 0;\n forEach(arr, function(element, index, arr) {\n if (f.call(/** @type {?} */ (opt_obj), element, index, arr)) {\n ++count;\n }\n }, opt_obj);\n return count;\n}\nexports.count = count;\n\n\n/**\n * Search an array for the first element that satisfies a given condition and\n * return that element.\n * @param {IArrayLike|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n * for every element. This function takes 3 arguments (the element, the\n * index and the array) and should return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {T|null} The first array element that passes the test, or null if no\n * element is found.\n * @template T,S\n */\nfunction find(arr, f, opt_obj) {\n const i = findIndex(arr, f, opt_obj);\n return i < 0 ? null : typeof arr === 'string' ? arr.charAt(i) : arr[i];\n}\nexports.find = find;\n\n\n/**\n * Search an array for the first element that satisfies a given condition and\n * return its index.\n * @param {IArrayLike|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\n * every element. This function\n * takes 3 arguments (the element, the index and the array) and should\n * return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {number} The index of the first array element that passes the test,\n * or -1 if no element is found.\n * @template T,S\n */\nfunction findIndex(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = 0; i < l; i++) {\n if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n return i;\n }\n }\n return -1;\n}\nexports.findIndex = findIndex;\n\n\n/**\n * Search an array (in reverse order) for the last element that satisfies a\n * given condition and return that element.\n * @param {IArrayLike|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n * for every element. This function\n * takes 3 arguments (the element, the index and the array) and should\n * return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {T|null} The last array element that passes the test, or null if no\n * element is found.\n * @template T,S\n */\nfunction findRight(arr, f, opt_obj) {\n const i = findIndexRight(arr, f, opt_obj);\n return i < 0 ? null : typeof arr === 'string' ? arr.charAt(i) : arr[i];\n}\nexports.findRight = findRight;\n\n\n/**\n * Search an array (in reverse order) for the last element that satisfies a\n * given condition and return its index.\n * @param {IArrayLike|string} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n * for every element. This function\n * takes 3 arguments (the element, the index and the array) and should\n * return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {number} The index of the last array element that passes the test,\n * or -1 if no element is found.\n * @template T,S\n */\nfunction findIndexRight(arr, f, opt_obj) {\n const l = arr.length; // must be fixed during loop... see docs\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\n for (let i = l - 1; i >= 0; i--) {\n if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\n return i;\n }\n }\n return -1;\n}\nexports.findIndexRight = findIndexRight;\n\n\n/**\n * Whether the array contains the given object.\n * @param {IArrayLike|string} arr The array to test for the presence of the\n * element.\n * @param {*} obj The object for which to test.\n * @return {boolean} true if obj is present.\n */\nfunction contains(arr, obj) {\n return indexOf(arr, obj) >= 0;\n}\nexports.contains = contains;\n\n\n/**\n * Whether the array is empty.\n * @param {IArrayLike|string} arr The array to test.\n * @return {boolean} true if empty.\n */\nfunction isEmpty(arr) {\n return arr.length == 0;\n}\nexports.isEmpty = isEmpty;\n\n\n/**\n * Clears the array.\n * @param {IArrayLike} arr Array or array like object to clear.\n */\nfunction clear(arr) {\n // For non real arrays we don't have the magic length so we delete the\n // indices.\n if (!Array.isArray(arr)) {\n for (let i = arr.length - 1; i >= 0; i--) {\n delete arr[i];\n }\n }\n arr.length = 0;\n}\nexports.clear = clear;\n\n\n/**\n * Pushes an item into an array, if it's not already in the array.\n * @param {Array} arr Array into which to insert the item.\n * @param {T} obj Value to add.\n * @template T\n */\nfunction insert(arr, obj) {\n if (!contains(arr, obj)) {\n arr.push(obj);\n }\n}\nexports.insert = insert;\n\n\n/**\n * Inserts an object at the given index of the array.\n * @param {IArrayLike} arr The array to modify.\n * @param {*} obj The object to insert.\n * @param {number=} opt_i The index at which to insert the object. If omitted,\n * treated as 0. A negative index is counted from the end of the array.\n */\nfunction insertAt(arr, obj, opt_i) {\n splice(arr, opt_i, 0, obj);\n}\nexports.insertAt = insertAt;\n\n\n/**\n * Inserts at the given index of the array, all elements of another array.\n * @param {IArrayLike} arr The array to modify.\n * @param {IArrayLike} elementsToAdd The array of elements to add.\n * @param {number=} opt_i The index at which to insert the object. If omitted,\n * treated as 0. A negative index is counted from the end of the array.\n */\nfunction insertArrayAt(arr, elementsToAdd, opt_i) {\n goog.partial(splice, arr, opt_i, 0).apply(null, elementsToAdd);\n}\nexports.insertArrayAt = insertArrayAt;\n\n\n/**\n * Inserts an object into an array before a specified object.\n * @param {Array} arr The array to modify.\n * @param {T} obj The object to insert.\n * @param {T=} opt_obj2 The object before which obj should be inserted. If obj2\n * is omitted or not found, obj is inserted at the end of the array.\n * @template T\n */\nfunction insertBefore(arr, obj, opt_obj2) {\n let i;\n if (arguments.length == 2 || (i = indexOf(arr, opt_obj2)) < 0) {\n arr.push(obj);\n } else {\n insertAt(arr, obj, i);\n }\n}\nexports.insertBefore = insertBefore;\n\n\n/**\n * Removes the first occurrence of a particular value from an array.\n * @param {IArrayLike} arr Array from which to remove\n * value.\n * @param {T} obj Object to remove.\n * @return {boolean} True if an element was removed.\n * @template T\n */\nfunction remove(arr, obj) {\n const i = indexOf(arr, obj);\n let rv;\n if ((rv = i >= 0)) {\n removeAt(arr, i);\n }\n return rv;\n}\nexports.remove = remove;\n\n\n/**\n * Removes the last occurrence of a particular value from an array.\n * @param {!IArrayLike} arr Array from which to remove value.\n * @param {T} obj Object to remove.\n * @return {boolean} True if an element was removed.\n * @template T\n */\nfunction removeLast(arr, obj) {\n const i = lastIndexOf(arr, obj);\n if (i >= 0) {\n removeAt(arr, i);\n return true;\n }\n return false;\n}\nexports.removeLast = removeLast;\n\n\n/**\n * Removes from an array the element at index i\n * @param {IArrayLike} arr Array or array like object from which to\n * remove value.\n * @param {number} i The index to remove.\n * @return {boolean} True if an element was removed.\n */\nfunction removeAt(arr, i) {\n asserts.assert(arr.length != null);\n\n // use generic form of splice\n // splice returns the removed items and if successful the length of that\n // will be 1\n return Array.prototype.splice.call(arr, i, 1).length == 1;\n}\nexports.removeAt = removeAt;\n\n\n/**\n * Removes the first value that satisfies the given condition.\n * @param {IArrayLike} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n * for every element. This function\n * takes 3 arguments (the element, the index and the array) and should\n * return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {boolean} True if an element was removed.\n * @template T,S\n */\nfunction removeIf(arr, f, opt_obj) {\n const i = findIndex(arr, f, opt_obj);\n if (i >= 0) {\n removeAt(arr, i);\n return true;\n }\n return false;\n}\nexports.removeIf = removeIf;\n\n\n/**\n * Removes all values that satisfy the given condition.\n * @param {IArrayLike} arr Array or array\n * like object over which to iterate.\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\n * for every element. This function\n * takes 3 arguments (the element, the index and the array) and should\n * return a boolean.\n * @param {S=} opt_obj An optional \"this\" context for the function.\n * @return {number} The number of items removed\n * @template T,S\n */\nfunction removeAllIf(arr, f, opt_obj) {\n let removedCount = 0;\n forEachRight(arr, function(val, index) {\n if (f.call(/** @type {?} */ (opt_obj), val, index, arr)) {\n if (removeAt(arr, index)) {\n removedCount++;\n }\n }\n });\n return removedCount;\n}\nexports.removeAllIf = removeAllIf;\n\n\n/**\n * Returns a new array that is the result of joining the arguments. If arrays\n * are passed then their items are added, however, if non-arrays are passed they\n * will be added to the return array as is.\n *\n * Note that ArrayLike objects will be added as is, rather than having their\n * items added.\n *\n * concat([1, 2], [3, 4]) -> [1, 2, 3, 4]\n * concat(0, [1, 2]) -> [0, 1, 2]\n * concat([1, 2], null) -> [1, 2, null]\n *\n * @param {...*} var_args Items to concatenate. Arrays will have each item\n * added, while primitives and objects will be added as is.\n * @return {!Array} The new resultant array.\n */\nfunction concat(var_args) {\n return Array.prototype.concat.apply([], arguments);\n}\nexports.concat = concat;\n\n\n/**\n * Returns a new array that contains the contents of all the arrays passed.\n * @param {...!Array} var_args\n * @return {!Array}\n * @template T\n */\nfunction join(var_args) {\n return Array.prototype.concat.apply([], arguments);\n}\nexports.join = join;\n\n\n/**\n * Converts an object to an array.\n * @param {IArrayLike|string} object The object to convert to an\n * array.\n * @return {!Array} The object converted into an array. If object has a\n * length property, every property indexed with a non-negative number\n * less than length will be included in the result. If object does not\n * have a length property, an empty array will be returned.\n * @template T\n */\nfunction toArray(object) {\n const length = object.length;\n\n // If length is not a number the following is false. This case is kept for\n // backwards compatibility since there are callers that pass objects that are\n // not array like.\n if (length > 0) {\n const rv = new Array(length);\n for (let i = 0; i < length; i++) {\n rv[i] = object[i];\n }\n return rv;\n }\n return [];\n}\nexports.toArray = toArray;\n\n\n/**\n * Does a shallow copy of an array.\n * @param {IArrayLike|string} arr Array or array-like object to\n * clone.\n * @return {!Array} Clone of the input array.\n * @template T\n */\nconst clone = toArray;\nexports.clone = clone;\n\n\n/**\n * Extends an array with another array, element, or \"array like\" object.\n * This function operates 'in-place', it does not create a new Array.\n *\n * Example:\n * var a = [];\n * extend(a, [0, 1]);\n * a; // [0, 1]\n * extend(a, 2);\n * a; // [0, 1, 2]\n *\n * @param {Array} arr1 The array to modify.\n * @param {...(IArrayLike|VALUE)} var_args The elements or arrays of\n * elements to add to arr1.\n * @template VALUE\n */\nfunction extend(arr1, var_args) {\n for (let i = 1; i < arguments.length; i++) {\n const arr2 = arguments[i];\n if (goog.isArrayLike(arr2)) {\n const len1 = arr1.length || 0;\n const len2 = arr2.length || 0;\n arr1.length = len1 + len2;\n for (let j = 0; j < len2; j++) {\n arr1[len1 + j] = arr2[j];\n }\n } else {\n arr1.push(arr2);\n }\n }\n}\nexports.extend = extend;\n\n\n/**\n * Adds or removes elements from an array. This is a generic version of Array\n * splice. This means that it might work on other objects similar to arrays,\n * such as the arguments object.\n *\n * @param {IArrayLike} arr The array to modify.\n * @param {number|undefined} index The index at which to start changing the\n * array. If not defined, treated as 0.\n * @param {number} howMany How many elements to remove (0 means no removal. A\n * value below 0 is treated as zero and so is any other non number. Numbers\n * are floored).\n * @param {...T} var_args Optional, additional elements to insert into the\n * array.\n * @return {!Array} the removed elements.\n * @template T\n */\nfunction splice(arr, index, howMany, var_args) {\n asserts.assert(arr.length != null);\n\n return Array.prototype.splice.apply(arr, slice(arguments, 1));\n}\nexports.splice = splice;\n\n\n/**\n * Returns a new array from a segment of an array. This is a generic version of\n * Array slice. This means that it might work on other objects similar to\n * arrays, such as the arguments object.\n *\n * @param {IArrayLike|string} arr The array from\n * which to copy a segment.\n * @param {number} start The index of the first element to copy.\n * @param {number=} opt_end The index after the last element to copy.\n * @return {!Array} A new array containing the specified segment of the\n * original array.\n * @template T\n */\nfunction slice(arr, start, opt_end) {\n asserts.assert(arr.length != null);\n\n // passing 1 arg to slice is not the same as passing 2 where the second is\n // null or undefined (in that case the second argument is treated as 0).\n // we could use slice on the arguments object and then use apply instead of\n // testing the length\n if (arguments.length <= 2) {\n return Array.prototype.slice.call(arr, start);\n } else {\n return Array.prototype.slice.call(arr, start, opt_end);\n }\n}\nexports.slice = slice;\n\n\n/**\n * Removes all duplicates from an array (retaining only the first\n * occurrence of each array element). This function modifies the\n * array in place and doesn't change the order of the non-duplicate items.\n *\n * For objects, duplicates are identified as having the same unique ID as\n * defined by {@link goog.getUid}.\n *\n * Alternatively you can specify a custom hash function that returns a unique\n * value for each item in the array it should consider unique.\n *\n * Runtime: N,\n * Worstcase space: 2N (no dupes)\n *\n * @param {IArrayLike} arr The array from which to remove\n * duplicates.\n * @param {Array=} opt_rv An optional array in which to return the results,\n * instead of performing the removal inplace. If specified, the original\n * array will remain unchanged.\n * @param {function(T):string=} opt_hashFn An optional function to use to\n * apply to every item in the array. This function should return a unique\n * value for each item in the array it should consider unique.\n * @template T\n */\nfunction removeDuplicates(arr, opt_rv, opt_hashFn) {\n const returnArray = opt_rv || arr;\n const defaultHashFn = function(item) {\n // Prefix each type with a single character representing the type to\n // prevent conflicting keys (e.g. true and 'true').\n return goog.isObject(item) ? 'o' + goog.getUid(item) :\n (typeof item).charAt(0) + item;\n };\n const hashFn = opt_hashFn || defaultHashFn;\n\n let cursorInsert = 0;\n let cursorRead = 0;\n const seen = {};\n\n while (cursorRead < arr.length) {\n const current = arr[cursorRead++];\n const key = hashFn(current);\n if (!Object.prototype.hasOwnProperty.call(seen, key)) {\n seen[key] = true;\n returnArray[cursorInsert++] = current;\n }\n }\n returnArray.length = cursorInsert;\n}\nexports.removeDuplicates = removeDuplicates;\n\n\n/**\n * Searches the specified array for the specified target using the binary\n * search algorithm. If no opt_compareFn is specified, elements are compared\n * using defaultCompare, which compares the elements\n * using the built in < and > operators. This will produce the expected\n * behavior for homogeneous arrays of String(s) and Number(s). The array\n * specified must be sorted in ascending order (as defined by the\n * comparison function). If the array is not sorted, results are undefined.\n * If the array contains multiple instances of the specified target value, the\n * left-most instance will be found.\n *\n * Runtime: O(log n)\n *\n * @param {IArrayLike} arr The array to be searched.\n * @param {TARGET} target The sought value.\n * @param {function(TARGET, VALUE): number=} opt_compareFn Optional comparison\n * function by which the array is ordered. Should take 2 arguments to\n * compare, the target value and an element from your array, and return a\n * negative number, zero, or a positive number depending on whether the\n * first argument is less than, equal to, or greater than the second.\n * @return {number} Lowest index of the target value if found, otherwise\n * (-(insertion point) - 1). The insertion point is where the value should\n * be inserted into arr to preserve the sorted property. Return value >= 0\n * iff target is found.\n * @template TARGET, VALUE\n */\nfunction binarySearch(arr, target, opt_compareFn) {\n return binarySearch_(\n arr, opt_compareFn || defaultCompare, false /* isEvaluator */, target);\n}\nexports.binarySearch = binarySearch;\n\n\n/**\n * Selects an index in the specified array using the binary search algorithm.\n * The evaluator receives an element and determines whether the desired index\n * is before, at, or after it. The evaluator must be consistent (formally,\n * map(map(arr, evaluator, opt_obj), goog.math.sign)\n * must be monotonically non-increasing).\n *\n * Runtime: O(log n)\n *\n * @param {IArrayLike} arr The array to be searched.\n * @param {function(this:THIS, VALUE, number, ?): number} evaluator\n * Evaluator function that receives 3 arguments (the element, the index and\n * the array). Should return a negative number, zero, or a positive number\n * depending on whether the desired index is before, at, or after the\n * element passed to it.\n * @param {THIS=} opt_obj The object to be used as the value of 'this'\n * within evaluator.\n * @return {number} Index of the leftmost element matched by the evaluator, if\n * such exists; otherwise (-(insertion point) - 1). The insertion point is\n * the index of the first element for which the evaluator returns negative,\n * or arr.length if no such element exists. The return value is non-negative\n * iff a match is found.\n * @template THIS, VALUE\n */\nfunction binarySelect(arr, evaluator, opt_obj) {\n return binarySearch_(\n arr, evaluator, true /* isEvaluator */, undefined /* opt_target */,\n opt_obj);\n}\nexports.binarySelect = binarySelect;\n\n\n/**\n * Implementation of a binary search algorithm which knows how to use both\n * comparison functions and evaluators. If an evaluator is provided, will call\n * the evaluator with the given optional data object, conforming to the\n * interface defined in binarySelect. Otherwise, if a comparison function is\n * provided, will call the comparison function against the given data object.\n *\n * This implementation purposefully does not use goog.bind or goog.partial for\n * performance reasons.\n *\n * Runtime: O(log n)\n *\n * @param {IArrayLike} arr The array to be searched.\n * @param {function(?, ?, ?): number | function(?, ?): number} compareFn\n * Either an evaluator or a comparison function, as defined by binarySearch\n * and binarySelect above.\n * @param {boolean} isEvaluator Whether the function is an evaluator or a\n * comparison function.\n * @param {?=} opt_target If the function is a comparison function, then\n * this is the target to binary search for.\n * @param {Object=} opt_selfObj If the function is an evaluator, this is an\n * optional this object for the evaluator.\n * @return {number} Lowest index of the target value if found, otherwise\n * (-(insertion point) - 1). The insertion point is where the value should\n * be inserted into arr to preserve the sorted property. Return value >= 0\n * iff target is found.\n * @private\n */\nfunction binarySearch_(arr, compareFn, isEvaluator, opt_target, opt_selfObj) {\n let left = 0; // inclusive\n let right = arr.length; // exclusive\n let found;\n while (left < right) {\n const middle = left + ((right - left) >>> 1);\n let compareResult;\n if (isEvaluator) {\n compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr);\n } else {\n // NOTE(dimvar): To avoid this cast, we'd have to use function overloading\n // for the type of binarySearch_, which the type system can't express yet.\n compareResult = /** @type {function(?, ?): number} */ (compareFn)(\n opt_target, arr[middle]);\n }\n if (compareResult > 0) {\n left = middle + 1;\n } else {\n right = middle;\n // We are looking for the lowest index so we can't return immediately.\n found = !compareResult;\n }\n }\n // left is the index if found, or the insertion point otherwise.\n // Avoiding bitwise not operator, as that causes a loss in precision for array\n // indexes outside the bounds of a 32-bit signed integer. Array indexes have\n // a maximum value of 2^32-2 https://tc39.es/ecma262/#array-index\n return found ? left : -left - 1;\n}\n\n\n/**\n * Sorts the specified array into ascending order. If no opt_compareFn is\n * specified, elements are compared using\n * defaultCompare, which compares the elements using\n * the built in < and > operators. This will produce the expected behavior\n * for homogeneous arrays of String(s) and Number(s), unlike the native sort,\n * but will give unpredictable results for heterogeneous lists of strings and\n * numbers with different numbers of digits.\n *\n * This sort is not guaranteed to be stable.\n *\n * Runtime: Same as `Array.prototype.sort`\n *\n * @param {Array} arr The array to be sorted.\n * @param {?function(T,T):number=} opt_compareFn Optional comparison\n * function by which the\n * array is to be ordered. Should take 2 arguments to compare, and return a\n * negative number, zero, or a positive number depending on whether the\n * first argument is less than, equal to, or greater than the second.\n * @template T\n */\nfunction sort(arr, opt_compareFn) {\n // TODO(arv): Update type annotation since null is not accepted.\n arr.sort(opt_compareFn || defaultCompare);\n}\nexports.sort = sort;\n\n\n/**\n * Sorts the specified array into ascending order in a stable way. If no\n * opt_compareFn is specified, elements are compared using\n * defaultCompare, which compares the elements using\n * the built in < and > operators. This will produce the expected behavior\n * for homogeneous arrays of String(s) and Number(s).\n *\n * Runtime: Same as `Array.prototype.sort`, plus an additional\n * O(n) overhead of copying the array twice.\n *\n * @param {Array} arr The array to be sorted.\n * @param {?function(T, T): number=} opt_compareFn Optional comparison function\n * by which the array is to be ordered. Should take 2 arguments to compare,\n * and return a negative number, zero, or a positive number depending on\n * whether the first argument is less than, equal to, or greater than the\n * second.\n * @template T\n */\nfunction stableSort(arr, opt_compareFn) {\n const compArr = new Array(arr.length);\n for (let i = 0; i < arr.length; i++) {\n compArr[i] = {index: i, value: arr[i]};\n }\n const valueCompareFn = opt_compareFn || defaultCompare;\n function stableCompareFn(obj1, obj2) {\n return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index;\n }\n sort(compArr, stableCompareFn);\n for (let i = 0; i < arr.length; i++) {\n arr[i] = compArr[i].value;\n }\n}\nexports.stableSort = stableSort;\n\n\n/**\n * Sort the specified array into ascending order based on item keys\n * returned by the specified key function.\n * If no opt_compareFn is specified, the keys are compared in ascending order\n * using defaultCompare.\n *\n * Runtime: O(S(f(n)), where S is runtime of sort\n * and f(n) is runtime of the key function.\n *\n * @param {Array} arr The array to be sorted.\n * @param {function(T): K} keyFn Function taking array element and returning\n * a key used for sorting this element.\n * @param {?function(K, K): number=} opt_compareFn Optional comparison function\n * by which the keys are to be ordered. Should take 2 arguments to compare,\n * and return a negative number, zero, or a positive number depending on\n * whether the first argument is less than, equal to, or greater than the\n * second.\n * @template T,K\n */\nfunction sortByKey(arr, keyFn, opt_compareFn) {\n const keyCompareFn = opt_compareFn || defaultCompare;\n sort(arr, function(a, b) {\n return keyCompareFn(keyFn(a), keyFn(b));\n });\n}\nexports.sortByKey = sortByKey;\n\n\n/**\n * Sorts an array of objects by the specified object key and compare\n * function. If no compare function is provided, the key values are\n * compared in ascending order using defaultCompare.\n * This won't work for keys that get renamed by the compiler. So use\n * {'foo': 1, 'bar': 2} rather than {foo: 1, bar: 2}.\n * @param {Array} arr An array of objects to sort.\n * @param {string} key The object key to sort by.\n * @param {Function=} opt_compareFn The function to use to compare key\n * values.\n */\nfunction sortObjectsByKey(arr, key, opt_compareFn) {\n sortByKey(arr, function(obj) {\n return obj[key];\n }, opt_compareFn);\n}\nexports.sortObjectsByKey = sortObjectsByKey;\n\n\n/**\n * Tells if the array is sorted.\n * @param {!IArrayLike} arr The array.\n * @param {?function(T,T):number=} opt_compareFn Function to compare the\n * array elements.\n * Should take 2 arguments to compare, and return a negative number, zero,\n * or a positive number depending on whether the first argument is less\n * than, equal to, or greater than the second.\n * @param {boolean=} opt_strict If true no equal elements are allowed.\n * @return {boolean} Whether the array is sorted.\n * @template T\n */\nfunction isSorted(arr, opt_compareFn, opt_strict) {\n const compare = opt_compareFn || defaultCompare;\n for (let i = 1; i < arr.length; i++) {\n const compareResult = compare(arr[i - 1], arr[i]);\n if (compareResult > 0 || compareResult == 0 && opt_strict) {\n return false;\n }\n }\n return true;\n}\nexports.isSorted = isSorted;\n\n\n/**\n * Compares two arrays for equality. Two arrays are considered equal if they\n * have the same length and their corresponding elements are equal according to\n * the comparison function.\n *\n * @param {IArrayLike} arr1 The first array to compare.\n * @param {IArrayLike} arr2 The second array to compare.\n * @param {?function(A,B):boolean=} opt_equalsFn Optional comparison function.\n * Should take 2 arguments to compare, and return true if the arguments\n * are equal. Defaults to {@link goog.array.defaultCompareEquality} which\n * compares the elements using the built-in '===' operator.\n * @return {boolean} Whether the two arrays are equal.\n * @template A\n * @template B\n */\nfunction equals(arr1, arr2, opt_equalsFn) {\n if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) ||\n arr1.length != arr2.length) {\n return false;\n }\n const l = arr1.length;\n const equalsFn = opt_equalsFn || defaultCompareEquality;\n for (let i = 0; i < l; i++) {\n if (!equalsFn(arr1[i], arr2[i])) {\n return false;\n }\n }\n return true;\n}\nexports.equals = equals;\n\n\n/**\n * 3-way array compare function.\n * @param {!IArrayLike} arr1 The first array to\n * compare.\n * @param {!IArrayLike} arr2 The second array to\n * compare.\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\n * function by which the array is to be ordered. Should take 2 arguments to\n * compare, and return a negative number, zero, or a positive number\n * depending on whether the first argument is less than, equal to, or\n * greater than the second.\n * @return {number} Negative number, zero, or a positive number depending on\n * whether the first argument is less than, equal to, or greater than the\n * second.\n * @template VALUE\n */\nfunction compare3(arr1, arr2, opt_compareFn) {\n const compare = opt_compareFn || defaultCompare;\n const l = Math.min(arr1.length, arr2.length);\n for (let i = 0; i < l; i++) {\n const result = compare(arr1[i], arr2[i]);\n if (result != 0) {\n return result;\n }\n }\n return defaultCompare(arr1.length, arr2.length);\n}\nexports.compare3 = compare3;\n\n\n/**\n * Compares its two arguments for order, using the built in < and >\n * operators.\n * @param {VALUE} a The first object to be compared.\n * @param {VALUE} b The second object to be compared.\n * @return {number} A negative number, zero, or a positive number as the first\n * argument is less than, equal to, or greater than the second,\n * respectively.\n * @template VALUE\n */\nfunction defaultCompare(a, b) {\n return a > b ? 1 : a < b ? -1 : 0;\n}\nexports.defaultCompare = defaultCompare;\n\n\n/**\n * Compares its two arguments for inverse order, using the built in < and >\n * operators.\n * @param {VALUE} a The first object to be compared.\n * @param {VALUE} b The second object to be compared.\n * @return {number} A negative number, zero, or a positive number as the first\n * argument is greater than, equal to, or less than the second,\n * respectively.\n * @template VALUE\n */\nfunction inverseDefaultCompare(a, b) {\n return -defaultCompare(a, b);\n}\nexports.inverseDefaultCompare = inverseDefaultCompare;\n\n\n/**\n * Compares its two arguments for equality, using the built in === operator.\n * @param {*} a The first object to compare.\n * @param {*} b The second object to compare.\n * @return {boolean} True if the two arguments are equal, false otherwise.\n */\nfunction defaultCompareEquality(a, b) {\n return a === b;\n}\nexports.defaultCompareEquality = defaultCompareEquality;\n\n\n/**\n * Inserts a value into a sorted array. The array is not modified if the\n * value is already present.\n * @param {IArrayLike} array The array to modify.\n * @param {VALUE} value The object to insert.\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\n * function by which the array is ordered. Should take 2 arguments to\n * compare, and return a negative number, zero, or a positive number\n * depending on whether the first argument is less than, equal to, or\n * greater than the second.\n * @return {boolean} True if an element was inserted.\n * @template VALUE\n */\nfunction binaryInsert(array, value, opt_compareFn) {\n const index = binarySearch(array, value, opt_compareFn);\n if (index < 0) {\n insertAt(array, value, -(index + 1));\n return true;\n }\n return false;\n}\nexports.binaryInsert = binaryInsert;\n\n\n/**\n * Removes a value from a sorted array.\n * @param {!IArrayLike} array The array to modify.\n * @param {VALUE} value The object to remove.\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\n * function by which the array is ordered. Should take 2 arguments to\n * compare, and return a negative number, zero, or a positive number\n * depending on whether the first argument is less than, equal to, or\n * greater than the second.\n * @return {boolean} True if an element was removed.\n * @template VALUE\n */\nfunction binaryRemove(array, value, opt_compareFn) {\n const index = binarySearch(array, value, opt_compareFn);\n return (index >= 0) ? removeAt(array, index) : false;\n}\nexports.binaryRemove = binaryRemove;\n\n\n/**\n * Splits an array into disjoint buckets according to a splitting function.\n * @param {IArrayLike} array The array.\n * @param {function(this:S, T, number, !IArrayLike):?} sorter Function to\n * call for every element. This takes 3 arguments (the element, the index\n * and the array) and must return a valid object key (a string, number,\n * etc), or undefined, if that object should not be placed in a bucket.\n * @param {S=} opt_obj The object to be used as the value of 'this' within\n * sorter.\n * @return {!Object>} An object, with keys being all of the unique\n * return values of sorter, and values being arrays containing the items for\n * which the splitter returned that key.\n * @template T,S\n */\nfunction bucket(array, sorter, opt_obj) {\n const buckets = {};\n\n for (let i = 0; i < array.length; i++) {\n const value = array[i];\n const key = sorter.call(/** @type {?} */ (opt_obj), value, i, array);\n if (key !== undefined) {\n // Push the value to the right bucket, creating it if necessary.\n const bucket = buckets[key] || (buckets[key] = []);\n bucket.push(value);\n }\n }\n\n return buckets;\n}\nexports.bucket = bucket;\n\n\n/**\n * Splits an array into disjoint buckets according to a splitting function.\n * @param {!IArrayLike} array The array.\n * @param {function(V, number, !IArrayLike):(K|undefined)} sorter Function to\n * call for every element. This takes 3 arguments (the element, the index,\n * and the array) and must return a value to use as a key, or undefined, if\n * that object should not be placed in a bucket.\n * @return {!Map>} A map, with keys being all of the unique\n * return values of sorter, and values being arrays containing the items for\n * which the splitter returned that key.\n * @template K,V\n */\nfunction bucketToMap(array, sorter) {\n const /** !Map> */ buckets = new Map();\n\n for (let i = 0; i < array.length; i++) {\n const value = array[i];\n const key = sorter(value, i, array);\n if (key !== undefined) {\n // Push the value to the right bucket, creating it if necessary.\n let bucket = buckets.get(key);\n if (!bucket) {\n bucket = [];\n buckets.set(key, bucket);\n }\n bucket.push(value);\n }\n }\n\n return buckets;\n}\nexports.bucketToMap = bucketToMap;\n\n\n/**\n * Creates a new object built from the provided array and the key-generation\n * function.\n * @param {IArrayLike} arr Array or array like object over\n * which to iterate whose elements will be the values in the new object.\n * @param {?function(this:S, T, number, ?) : string} keyFunc The function to\n * call for every element. This function takes 3 arguments (the element, the\n * index and the array) and should return a string that will be used as the\n * key for the element in the new object. If the function returns the same\n * key for more than one element, the value for that key is\n * implementation-defined.\n * @param {S=} opt_obj The object to be used as the value of 'this'\n * within keyFunc.\n * @return {!Object} The new object.\n * @template T,S\n */\nfunction toObject(arr, keyFunc, opt_obj) {\n const ret = {};\n forEach(arr, function(element, index) {\n ret[keyFunc.call(/** @type {?} */ (opt_obj), element, index, arr)] =\n element;\n });\n return ret;\n}\nexports.toObject = toObject;\n\n\n/**\n * Creates a new ES6 Map built from the provided array and the key-generation\n * function.\n * @param {!IArrayLike} arr Array or array like object over which to iterate\n * whose elements will be the values in the new object.\n * @param {?function(V, number, ?) : K} keyFunc The function to call for every\n * element. This function takes 3 arguments (the element, the index, and the\n * array) and should return a value that will be used as the key for the\n * element in the new object. If the function returns the same key for more\n * than one element, the value for that key is implementation-defined.\n * @return {!Map} The new map.\n * @template K,V\n */\nfunction toMap(arr, keyFunc) {\n const /** !Map */ map = new Map();\n\n for (let i = 0; i < arr.length; i++) {\n const element = arr[i];\n map.set(keyFunc(element, i, arr), element);\n }\n\n return map;\n}\nexports.toMap = toMap;\n\n\n/**\n * Creates a range of numbers in an arithmetic progression.\n *\n * Range takes 1, 2, or 3 arguments:\n *
\n * range(5) is the same as range(0, 5, 1) and produces [0, 1, 2, 3, 4]\n * range(2, 5) is the same as range(2, 5, 1) and produces [2, 3, 4]\n * range(-2, -5, -1) produces [-2, -3, -4]\n * range(-2, -5, 1) produces [], since stepping by 1 wouldn't ever reach -5.\n * 
\n *\n * @param {number} startOrEnd The starting value of the range if an end argument\n * is provided. Otherwise, the start value is 0, and this is the end value.\n * @param {number=} opt_end The optional end value of the range.\n * @param {number=} opt_step The step size between range values. Defaults to 1\n * if opt_step is undefined or 0.\n * @return {!Array} An array of numbers for the requested range. May be\n * an empty array if adding the step would not converge toward the end\n * value.\n */\nfunction range(startOrEnd, opt_end, opt_step) {\n const array = [];\n let start = 0;\n let end = startOrEnd;\n const step = opt_step || 1;\n if (opt_end !== undefined) {\n start = startOrEnd;\n end = opt_end;\n }\n\n if (step * (end - start) < 0) {\n // Sign mismatch: start + step will never reach the end value.\n return [];\n }\n\n if (step > 0) {\n for (let i = start; i < end; i += step) {\n array.push(i);\n }\n } else {\n for (let i = start; i > end; i += step) {\n array.push(i);\n }\n }\n return array;\n}\nexports.range = range;\n\n\n/**\n * Returns an array consisting of the given value repeated N times.\n *\n * @param {VALUE} value The value to repeat.\n * @param {number} n The repeat count.\n * @return {!Array} An array with the repeated value.\n * @template VALUE\n */\nfunction repeat(value, n) {\n const array = [];\n for (let i = 0; i < n; i++) {\n array[i] = value;\n }\n return array;\n}\nexports.repeat = repeat;\n\n\n/**\n * Returns an array consisting of every argument with all arrays\n * expanded in-place recursively.\n *\n * @param {...*} var_args The values to flatten.\n * @return {!Array} An array containing the flattened values.\n */\nfunction flatten(var_args) {\n const CHUNK_SIZE = 8192;\n\n const result = [];\n for (let i = 0; i < arguments.length; i++) {\n const element = arguments[i];\n if (Array.isArray(element)) {\n for (let c = 0; c < element.length; c += CHUNK_SIZE) {\n const chunk = slice(element, c, c + CHUNK_SIZE);\n const recurseResult = flatten.apply(null, chunk);\n for (let r = 0; r < recurseResult.length; r++) {\n result.push(recurseResult[r]);\n }\n }\n } else {\n result.push(element);\n }\n }\n return result;\n}\nexports.flatten = flatten;\n\n\n/**\n * Rotates an array in-place. After calling this method, the element at\n * index i will be the element previously at index (i - n) %\n * array.length, for all values of i between 0 and array.length - 1,\n * inclusive.\n *\n * For example, suppose list comprises [t, a, n, k, s]. After invoking\n * rotate(array, 1) (or rotate(array, -4)), array will comprise [s, t, a, n, k].\n *\n * @param {!Array} array The array to rotate.\n * @param {number} n The amount to rotate.\n * @return {!Array} The array.\n * @template T\n */\nfunction rotate(array, n) {\n asserts.assert(array.length != null);\n\n if (array.length) {\n n %= array.length;\n if (n > 0) {\n Array.prototype.unshift.apply(array, array.splice(-n, n));\n } else if (n < 0) {\n Array.prototype.push.apply(array, array.splice(0, -n));\n }\n }\n return array;\n}\nexports.rotate = rotate;\n\n\n/**\n * Moves one item of an array to a new position keeping the order of the rest\n * of the items. Example use case: keeping a list of JavaScript objects\n * synchronized with the corresponding list of DOM elements after one of the\n * elements has been dragged to a new position.\n * @param {!IArrayLike} arr The array to modify.\n * @param {number} fromIndex Index of the item to move between 0 and\n * `arr.length - 1`.\n * @param {number} toIndex Target index between 0 and `arr.length - 1`.\n */\nfunction moveItem(arr, fromIndex, toIndex) {\n asserts.assert(fromIndex >= 0 && fromIndex < arr.length);\n asserts.assert(toIndex >= 0 && toIndex < arr.length);\n // Remove 1 item at fromIndex.\n const removedItems = Array.prototype.splice.call(arr, fromIndex, 1);\n // Insert the removed item at toIndex.\n Array.prototype.splice.call(arr, toIndex, 0, removedItems[0]);\n // We don't use goog.array.insertAt and goog.array.removeAt, because they're\n // significantly slower than splice.\n}\nexports.moveItem = moveItem;\n\n\n/**\n * Creates a new array for which the element at position i is an array of the\n * ith element of the provided arrays. The returned array will only be as long\n * as the shortest array provided; additional values are ignored. For example,\n * the result of zipping [1, 2] and [3, 4, 5] is [[1,3], [2, 4]].\n *\n * This is similar to the zip() function in Python. See {@link\n * http://docs.python.org/library/functions.html#zip}\n *\n * @param {...!IArrayLike} var_args Arrays to be combined.\n * @return {!Array>} A new array of arrays created from\n * provided arrays.\n */\nfunction zip(var_args) {\n if (!arguments.length) {\n return [];\n }\n const result = [];\n let minLen = arguments[0].length;\n for (let i = 1; i < arguments.length; i++) {\n if (arguments[i].length < minLen) {\n minLen = arguments[i].length;\n }\n }\n for (let i = 0; i < minLen; i++) {\n const value = [];\n for (let j = 0; j < arguments.length; j++) {\n value.push(arguments[j][i]);\n }\n result.push(value);\n }\n return result;\n}\nexports.zip = zip;\n\n\n/**\n * Shuffles the values in the specified array using the Fisher-Yates in-place\n * shuffle (also known as the Knuth Shuffle). By default, calls Math.random()\n * and so resets the state of that random number generator. Similarly, may reset\n * the state of any other specified random number generator.\n *\n * Runtime: O(n)\n *\n * @param {!Array} arr The array to be shuffled.\n * @param {function():number=} opt_randFn Optional random function to use for\n * shuffling.\n * Takes no arguments, and returns a random number on the interval [0, 1).\n * Defaults to Math.random() using JavaScript's built-in Math library.\n */\nfunction shuffle(arr, opt_randFn) {\n const randFn = opt_randFn || Math.random;\n\n for (let i = arr.length - 1; i > 0; i--) {\n // Choose a random array index in [0, i] (inclusive with i).\n const j = Math.floor(randFn() * (i + 1));\n\n const tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n }\n}\nexports.shuffle = shuffle;\n\n\n/**\n * Returns a new array of elements from arr, based on the indexes of elements\n * provided by index_arr. For example, the result of index copying\n * ['a', 'b', 'c'] with index_arr [1,0,0,2] is ['b', 'a', 'a', 'c'].\n *\n * @param {!IArrayLike} arr The array to get a indexed copy from.\n * @param {!IArrayLike} index_arr An array of indexes to get from arr.\n * @return {!Array} A new array of elements from arr in index_arr order.\n * @template T\n */\nfunction copyByIndex(arr, index_arr) {\n const result = [];\n forEach(index_arr, function(index) {\n result.push(arr[index]);\n });\n return result;\n}\nexports.copyByIndex = copyByIndex;\n\n\n/**\n * Maps each element of the input array into zero or more elements of the output\n * array.\n *\n * @param {!IArrayLike|string} arr Array or array like object\n * over which to iterate.\n * @param {function(this:THIS, VALUE, number, ?): !Array} f The function\n * to call for every element. This function takes 3 arguments (the element,\n * the index and the array) and should return an array. The result will be\n * used to extend a new array.\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within f.\n * @return {!Array} a new array with the concatenation of all arrays\n * returned from f.\n * @template THIS, VALUE, RESULT\n */\nfunction concatMap(arr, f, opt_obj) {\n return concat.apply([], map(arr, f, opt_obj));\n}\nexports.concatMap = concatMap;\n","~:compiled-at",1730900725400,"~:source-map-json","{\n\"version\":3,\n\"file\":\"goog.array.array.js\",\n\"lineCount\":656,\n\"mappings\":\"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\",\n\"sources\":[\"goog/array/array.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 manipulating arrays.\\n */\\n\\n\\ngoog.module('goog.array');\\ngoog.module.declareLegacyNamespace();\\n\\nconst asserts = goog.require('goog.asserts');\\n\\n\\n/**\\n * @define {boolean} NATIVE_ARRAY_PROTOTYPES indicates whether the code should\\n * rely on Array.prototype functions, if available.\\n *\\n * The Array.prototype functions can be defined by external libraries like\\n * Prototype and setting this flag to false forces closure to use its own\\n * goog.array implementation.\\n *\\n * If your javascript can be loaded by a third party site and you are wary about\\n * relying on the prototype functions, specify\\n * \\\"--define goog.NATIVE_ARRAY_PROTOTYPES=false\\\" to the JSCompiler.\\n *\\n * Setting goog.TRUSTED_SITE to false will automatically set\\n * NATIVE_ARRAY_PROTOTYPES to false.\\n */\\ngoog.NATIVE_ARRAY_PROTOTYPES =\\n goog.define('goog.NATIVE_ARRAY_PROTOTYPES', goog.TRUSTED_SITE);\\n\\n\\n/**\\n * @define {boolean} If true, JSCompiler will use the native implementation of\\n * array functions where appropriate (e.g., `Array#filter`) and remove the\\n * unused pure JS implementation.\\n */\\nconst ASSUME_NATIVE_FUNCTIONS = goog.define(\\n 'goog.array.ASSUME_NATIVE_FUNCTIONS', goog.FEATURESET_YEAR > 2012);\\nexports.ASSUME_NATIVE_FUNCTIONS = ASSUME_NATIVE_FUNCTIONS;\\n\\n\\n/**\\n * Returns the last element in an array without removing it.\\n * Same as {@link goog.array.last}.\\n * @param {IArrayLike|string} array The array.\\n * @return {T} Last item in array.\\n * @template T\\n */\\nfunction peek(array) {\\n return array[array.length - 1];\\n}\\nexports.peek = peek;\\n\\n\\n/**\\n * Returns the last element in an array without removing it.\\n * Same as {@link goog.array.peek}.\\n * @param {IArrayLike|string} array The array.\\n * @return {T} Last item in array.\\n * @template T\\n */\\nexports.last = peek;\\n\\n// NOTE(arv): Since most of the array functions are generic it allows you to\\n// pass an array-like object. Strings have a length and are considered array-\\n// like. However, the 'in' operator does not work on strings so we cannot just\\n// use the array path even if the browser supports indexing into strings. We\\n// therefore end up splitting the string.\\n\\n\\n/**\\n * Returns the index of the first element of an array with a specified value, or\\n * -1 if the element is not present in the array.\\n *\\n * See {@link http://tinyurl.com/developer-mozilla-org-array-indexof}\\n *\\n * @param {IArrayLike|string} arr The array to be searched.\\n * @param {T} obj The object for which we are searching.\\n * @param {number=} opt_fromIndex The index at which to start the search. If\\n * omitted the search starts at index 0.\\n * @return {number} The index of the first matching array element.\\n * @template T\\n */\\nconst indexOf = goog.NATIVE_ARRAY_PROTOTYPES &&\\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.indexOf) ?\\n function(arr, obj, opt_fromIndex) {\\n asserts.assert(arr.length != null);\\n\\n return Array.prototype.indexOf.call(arr, obj, opt_fromIndex);\\n } :\\n function(arr, obj, opt_fromIndex) {\\n const fromIndex = opt_fromIndex == null ?\\n 0 :\\n (opt_fromIndex < 0 ? Math.max(0, arr.length + opt_fromIndex) :\\n opt_fromIndex);\\n\\n if (typeof arr === 'string') {\\n // Array.prototype.indexOf uses === so only strings should be found.\\n if (typeof obj !== 'string' || obj.length != 1) {\\n return -1;\\n }\\n return arr.indexOf(obj, fromIndex);\\n }\\n\\n for (let i = fromIndex; i < arr.length; i++) {\\n if (i in arr && arr[i] === obj) return i;\\n }\\n return -1;\\n };\\nexports.indexOf = indexOf;\\n\\n\\n/**\\n * Returns the index of the last element of an array with a specified value, or\\n * -1 if the element is not present in the array.\\n *\\n * See {@link http://tinyurl.com/developer-mozilla-org-array-lastindexof}\\n *\\n * @param {!IArrayLike|string} arr The array to be searched.\\n * @param {T} obj The object for which we are searching.\\n * @param {?number=} opt_fromIndex The index at which to start the search. If\\n * omitted the search starts at the end of the array.\\n * @return {number} The index of the last matching array element.\\n * @template T\\n */\\nconst lastIndexOf = goog.NATIVE_ARRAY_PROTOTYPES &&\\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.lastIndexOf) ?\\n function(arr, obj, opt_fromIndex) {\\n asserts.assert(arr.length != null);\\n\\n // Firefox treats undefined and null as 0 in the fromIndex argument which\\n // leads it to always return -1\\n const fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;\\n return Array.prototype.lastIndexOf.call(arr, obj, fromIndex);\\n } :\\n function(arr, obj, opt_fromIndex) {\\n let fromIndex = opt_fromIndex == null ? arr.length - 1 : opt_fromIndex;\\n\\n if (fromIndex < 0) {\\n fromIndex = Math.max(0, arr.length + fromIndex);\\n }\\n\\n if (typeof arr === 'string') {\\n // Array.prototype.lastIndexOf uses === so only strings should be found.\\n if (typeof obj !== 'string' || obj.length != 1) {\\n return -1;\\n }\\n return arr.lastIndexOf(obj, fromIndex);\\n }\\n\\n for (let i = fromIndex; i >= 0; i--) {\\n if (i in arr && arr[i] === obj) return i;\\n }\\n return -1;\\n };\\nexports.lastIndexOf = lastIndexOf;\\n\\n\\n/**\\n * Calls a function for each element in an array. Skips holes in the array.\\n * See {@link http://tinyurl.com/developer-mozilla-org-array-foreach}\\n *\\n * @param {IArrayLike|string} arr Array or array like object over\\n * which to iterate.\\n * @param {?function(this: S, T, number, ?): ?} f The function to call for every\\n * element. This function takes 3 arguments (the element, the index and the\\n * array). The return value is ignored.\\n * @param {S=} opt_obj The object to be used as the value of 'this' within f.\\n * @template T,S\\n */\\nconst forEach = goog.NATIVE_ARRAY_PROTOTYPES &&\\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.forEach) ?\\n function(arr, f, opt_obj) {\\n asserts.assert(arr.length != null);\\n\\n Array.prototype.forEach.call(arr, f, opt_obj);\\n } :\\n function(arr, f, opt_obj) {\\n const l = arr.length; // must be fixed during loop... see docs\\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\\n for (let i = 0; i < l; i++) {\\n if (i in arr2) {\\n f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\\n }\\n }\\n };\\nexports.forEach = forEach;\\n\\n\\n/**\\n * Calls a function for each element in an array, starting from the last\\n * element rather than the first.\\n *\\n * @param {IArrayLike|string} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this: S, T, number, ?): ?} f The function to call for every\\n * element. This function\\n * takes 3 arguments (the element, the index and the array). The return\\n * value is ignored.\\n * @param {S=} opt_obj The object to be used as the value of 'this'\\n * within f.\\n * @template T,S\\n */\\nfunction forEachRight(arr, f, opt_obj) {\\n const l = arr.length; // must be fixed during loop... see docs\\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\\n for (let i = l - 1; i >= 0; --i) {\\n if (i in arr2) {\\n f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\\n }\\n }\\n}\\nexports.forEachRight = forEachRight;\\n\\n\\n/**\\n * Calls a function for each element in an array, and if the function returns\\n * true adds the element to a new array.\\n *\\n * See {@link http://tinyurl.com/developer-mozilla-org-array-filter}\\n *\\n * @param {IArrayLike|string} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, T, number, ?):boolean} f The function to call for\\n * every element. This function\\n * takes 3 arguments (the element, the index and the array) and must\\n * return a Boolean. If the return value is true the element is added to the\\n * result array. If it is false the element is not included.\\n * @param {S=} opt_obj The object to be used as the value of 'this'\\n * within f.\\n * @return {!Array} a new array in which only elements that passed the test\\n * are present.\\n * @template T,S\\n */\\nconst filter = goog.NATIVE_ARRAY_PROTOTYPES &&\\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.filter) ?\\n function(arr, f, opt_obj) {\\n asserts.assert(arr.length != null);\\n\\n return Array.prototype.filter.call(arr, f, opt_obj);\\n } :\\n function(arr, f, opt_obj) {\\n const l = arr.length; // must be fixed during loop... see docs\\n const res = [];\\n let resLength = 0;\\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\\n for (let i = 0; i < l; i++) {\\n if (i in arr2) {\\n const val = arr2[i]; // in case f mutates arr2\\n if (f.call(/** @type {?} */ (opt_obj), val, i, arr)) {\\n res[resLength++] = val;\\n }\\n }\\n }\\n return res;\\n };\\nexports.filter = filter;\\n\\n\\n/**\\n * Calls a function for each element in an array and inserts the result into a\\n * new array.\\n *\\n * See {@link http://tinyurl.com/developer-mozilla-org-array-map}\\n *\\n * @param {IArrayLike|string} arr Array or array like object\\n * over which to iterate.\\n * @param {function(this:THIS, VALUE, number, ?): RESULT} f The function to call\\n * for every element. This function takes 3 arguments (the element,\\n * the index and the array) and should return something. The result will be\\n * inserted into a new array.\\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within f.\\n * @return {!Array} a new array with the results from f.\\n * @template THIS, VALUE, RESULT\\n */\\nconst map = goog.NATIVE_ARRAY_PROTOTYPES &&\\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.map) ?\\n function(arr, f, opt_obj) {\\n asserts.assert(arr.length != null);\\n\\n return Array.prototype.map.call(arr, f, opt_obj);\\n } :\\n function(arr, f, opt_obj) {\\n const l = arr.length; // must be fixed during loop... see docs\\n const res = new Array(l);\\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\\n for (let i = 0; i < l; i++) {\\n if (i in arr2) {\\n res[i] = f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr);\\n }\\n }\\n return res;\\n };\\nexports.map = map;\\n\\n\\n/**\\n * Passes every element of an array into a function and accumulates the result.\\n *\\n * See {@link http://tinyurl.com/developer-mozilla-org-array-reduce}\\n * Note that this implementation differs from the native Array.prototype.reduce\\n * in that the initial value is assumed to be defined (the MDN docs linked above\\n * recommend not omitting this parameter, although it is technically optional).\\n *\\n * For example:\\n * var a = [1, 2, 3, 4];\\n * reduce(a, function(r, v, i, arr) {return r + v;}, 0);\\n * returns 10\\n *\\n * @param {IArrayLike|string} arr Array or array\\n * like object over which to iterate.\\n * @param {function(this:S, R, T, number, ?) : R} f The function to call for\\n * every element. This function\\n * takes 4 arguments (the function's previous result or the initial value,\\n * the value of the current array element, the current array index, and the\\n * array itself)\\n * function(previousValue, currentValue, index, array).\\n * @param {?} val The initial value to pass into the function on the first call.\\n * @param {S=} opt_obj The object to be used as the value of 'this'\\n * within f.\\n * @return {R} Result of evaluating f repeatedly across the values of the array.\\n * @template T,S,R\\n */\\nconst reduce = goog.NATIVE_ARRAY_PROTOTYPES &&\\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduce) ?\\n function(arr, f, val, opt_obj) {\\n asserts.assert(arr.length != null);\\n if (opt_obj) {\\n f = goog.bind(f, opt_obj);\\n }\\n return Array.prototype.reduce.call(arr, f, val);\\n } :\\n function(arr, f, val, opt_obj) {\\n let rval = val;\\n forEach(arr, function(val, index) {\\n rval = f.call(/** @type {?} */ (opt_obj), rval, val, index, arr);\\n });\\n return rval;\\n };\\nexports.reduce = reduce;\\n\\n\\n/**\\n * Passes every element of an array into a function and accumulates the result,\\n * starting from the last element and working towards the first.\\n *\\n * See {@link http://tinyurl.com/developer-mozilla-org-array-reduceright}\\n *\\n * For example:\\n * var a = ['a', 'b', 'c'];\\n * reduceRight(a, function(r, v, i, arr) {return r + v;}, '');\\n * returns 'cba'\\n *\\n * @param {IArrayLike|string} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, R, T, number, ?) : R} f The function to call for\\n * every element. This function\\n * takes 4 arguments (the function's previous result or the initial value,\\n * the value of the current array element, the current array index, and the\\n * array itself)\\n * function(previousValue, currentValue, index, array).\\n * @param {?} val The initial value to pass into the function on the first call.\\n * @param {S=} opt_obj The object to be used as the value of 'this'\\n * within f.\\n * @return {R} Object returned as a result of evaluating f repeatedly across the\\n * values of the array.\\n * @template T,S,R\\n */\\nconst reduceRight = goog.NATIVE_ARRAY_PROTOTYPES &&\\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.reduceRight) ?\\n function(arr, f, val, opt_obj) {\\n asserts.assert(arr.length != null);\\n asserts.assert(f != null);\\n if (opt_obj) {\\n f = goog.bind(f, opt_obj);\\n }\\n return Array.prototype.reduceRight.call(arr, f, val);\\n } :\\n function(arr, f, val, opt_obj) {\\n let rval = val;\\n forEachRight(arr, function(val, index) {\\n rval = f.call(/** @type {?} */ (opt_obj), rval, val, index, arr);\\n });\\n return rval;\\n };\\nexports.reduceRight = reduceRight;\\n\\n\\n/**\\n * Calls f for each element of an array. If any call returns true, some()\\n * returns true (without checking the remaining elements). If all calls\\n * return false, some() returns false.\\n *\\n * See {@link http://tinyurl.com/developer-mozilla-org-array-some}\\n *\\n * @param {IArrayLike|string} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\\n * for every element. This function takes 3 arguments (the element, the\\n * index and the array) and should return a boolean.\\n * @param {S=} opt_obj The object to be used as the value of 'this'\\n * within f.\\n * @return {boolean} true if any element passes the test.\\n * @template T,S\\n */\\nconst some = goog.NATIVE_ARRAY_PROTOTYPES &&\\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.some) ?\\n function(arr, f, opt_obj) {\\n asserts.assert(arr.length != null);\\n\\n return Array.prototype.some.call(arr, f, opt_obj);\\n } :\\n function(arr, f, opt_obj) {\\n const l = arr.length; // must be fixed during loop... see docs\\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\\n for (let i = 0; i < l; i++) {\\n if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\\n return true;\\n }\\n }\\n return false;\\n };\\nexports.some = some;\\n\\n\\n/**\\n * Call f for each element of an array. If all calls return true, every()\\n * returns true. If any call returns false, every() returns false and\\n * does not continue to check the remaining elements.\\n *\\n * See {@link http://tinyurl.com/developer-mozilla-org-array-every}\\n *\\n * @param {IArrayLike|string} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\\n * for every element. This function takes 3 arguments (the element, the\\n * index and the array) and should return a boolean.\\n * @param {S=} opt_obj The object to be used as the value of 'this'\\n * within f.\\n * @return {boolean} false if any element fails the test.\\n * @template T,S\\n */\\nconst every = goog.NATIVE_ARRAY_PROTOTYPES &&\\n (ASSUME_NATIVE_FUNCTIONS || Array.prototype.every) ?\\n function(arr, f, opt_obj) {\\n asserts.assert(arr.length != null);\\n\\n return Array.prototype.every.call(arr, f, opt_obj);\\n } :\\n function(arr, f, opt_obj) {\\n const l = arr.length; // must be fixed during loop... see docs\\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\\n for (let i = 0; i < l; i++) {\\n if (i in arr2 && !f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\\n return false;\\n }\\n }\\n return true;\\n };\\nexports.every = every;\\n\\n\\n/**\\n * Counts the array elements that fulfill the predicate, i.e. for which the\\n * callback function returns true. Skips holes in the array.\\n *\\n * @param {!IArrayLike|string} arr Array or array like object\\n * over which to iterate.\\n * @param {function(this: S, T, number, ?): boolean} f The function to call for\\n * every element. Takes 3 arguments (the element, the index and the array).\\n * @param {S=} opt_obj The object to be used as the value of 'this' within f.\\n * @return {number} The number of the matching elements.\\n * @template T,S\\n */\\nfunction count(arr, f, opt_obj) {\\n let count = 0;\\n forEach(arr, function(element, index, arr) {\\n if (f.call(/** @type {?} */ (opt_obj), element, index, arr)) {\\n ++count;\\n }\\n }, opt_obj);\\n return count;\\n}\\nexports.count = count;\\n\\n\\n/**\\n * Search an array for the first element that satisfies a given condition and\\n * return that element.\\n * @param {IArrayLike|string} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\\n * for every element. This function takes 3 arguments (the element, the\\n * index and the array) and should return a boolean.\\n * @param {S=} opt_obj An optional \\\"this\\\" context for the function.\\n * @return {T|null} The first array element that passes the test, or null if no\\n * element is found.\\n * @template T,S\\n */\\nfunction find(arr, f, opt_obj) {\\n const i = findIndex(arr, f, opt_obj);\\n return i < 0 ? null : typeof arr === 'string' ? arr.charAt(i) : arr[i];\\n}\\nexports.find = find;\\n\\n\\n/**\\n * Search an array for the first element that satisfies a given condition and\\n * return its index.\\n * @param {IArrayLike|string} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call for\\n * every element. This function\\n * takes 3 arguments (the element, the index and the array) and should\\n * return a boolean.\\n * @param {S=} opt_obj An optional \\\"this\\\" context for the function.\\n * @return {number} The index of the first array element that passes the test,\\n * or -1 if no element is found.\\n * @template T,S\\n */\\nfunction findIndex(arr, f, opt_obj) {\\n const l = arr.length; // must be fixed during loop... see docs\\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\\n for (let i = 0; i < l; i++) {\\n if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\\n return i;\\n }\\n }\\n return -1;\\n}\\nexports.findIndex = findIndex;\\n\\n\\n/**\\n * Search an array (in reverse order) for the last element that satisfies a\\n * given condition and return that element.\\n * @param {IArrayLike|string} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\\n * for every element. This function\\n * takes 3 arguments (the element, the index and the array) and should\\n * return a boolean.\\n * @param {S=} opt_obj An optional \\\"this\\\" context for the function.\\n * @return {T|null} The last array element that passes the test, or null if no\\n * element is found.\\n * @template T,S\\n */\\nfunction findRight(arr, f, opt_obj) {\\n const i = findIndexRight(arr, f, opt_obj);\\n return i < 0 ? null : typeof arr === 'string' ? arr.charAt(i) : arr[i];\\n}\\nexports.findRight = findRight;\\n\\n\\n/**\\n * Search an array (in reverse order) for the last element that satisfies a\\n * given condition and return its index.\\n * @param {IArrayLike|string} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\\n * for every element. This function\\n * takes 3 arguments (the element, the index and the array) and should\\n * return a boolean.\\n * @param {S=} opt_obj An optional \\\"this\\\" context for the function.\\n * @return {number} The index of the last array element that passes the test,\\n * or -1 if no element is found.\\n * @template T,S\\n */\\nfunction findIndexRight(arr, f, opt_obj) {\\n const l = arr.length; // must be fixed during loop... see docs\\n const arr2 = (typeof arr === 'string') ? arr.split('') : arr;\\n for (let i = l - 1; i >= 0; i--) {\\n if (i in arr2 && f.call(/** @type {?} */ (opt_obj), arr2[i], i, arr)) {\\n return i;\\n }\\n }\\n return -1;\\n}\\nexports.findIndexRight = findIndexRight;\\n\\n\\n/**\\n * Whether the array contains the given object.\\n * @param {IArrayLike|string} arr The array to test for the presence of the\\n * element.\\n * @param {*} obj The object for which to test.\\n * @return {boolean} true if obj is present.\\n */\\nfunction contains(arr, obj) {\\n return indexOf(arr, obj) >= 0;\\n}\\nexports.contains = contains;\\n\\n\\n/**\\n * Whether the array is empty.\\n * @param {IArrayLike|string} arr The array to test.\\n * @return {boolean} true if empty.\\n */\\nfunction isEmpty(arr) {\\n return arr.length == 0;\\n}\\nexports.isEmpty = isEmpty;\\n\\n\\n/**\\n * Clears the array.\\n * @param {IArrayLike} arr Array or array like object to clear.\\n */\\nfunction clear(arr) {\\n // For non real arrays we don't have the magic length so we delete the\\n // indices.\\n if (!Array.isArray(arr)) {\\n for (let i = arr.length - 1; i >= 0; i--) {\\n delete arr[i];\\n }\\n }\\n arr.length = 0;\\n}\\nexports.clear = clear;\\n\\n\\n/**\\n * Pushes an item into an array, if it's not already in the array.\\n * @param {Array} arr Array into which to insert the item.\\n * @param {T} obj Value to add.\\n * @template T\\n */\\nfunction insert(arr, obj) {\\n if (!contains(arr, obj)) {\\n arr.push(obj);\\n }\\n}\\nexports.insert = insert;\\n\\n\\n/**\\n * Inserts an object at the given index of the array.\\n * @param {IArrayLike} arr The array to modify.\\n * @param {*} obj The object to insert.\\n * @param {number=} opt_i The index at which to insert the object. If omitted,\\n * treated as 0. A negative index is counted from the end of the array.\\n */\\nfunction insertAt(arr, obj, opt_i) {\\n splice(arr, opt_i, 0, obj);\\n}\\nexports.insertAt = insertAt;\\n\\n\\n/**\\n * Inserts at the given index of the array, all elements of another array.\\n * @param {IArrayLike} arr The array to modify.\\n * @param {IArrayLike} elementsToAdd The array of elements to add.\\n * @param {number=} opt_i The index at which to insert the object. If omitted,\\n * treated as 0. A negative index is counted from the end of the array.\\n */\\nfunction insertArrayAt(arr, elementsToAdd, opt_i) {\\n goog.partial(splice, arr, opt_i, 0).apply(null, elementsToAdd);\\n}\\nexports.insertArrayAt = insertArrayAt;\\n\\n\\n/**\\n * Inserts an object into an array before a specified object.\\n * @param {Array} arr The array to modify.\\n * @param {T} obj The object to insert.\\n * @param {T=} opt_obj2 The object before which obj should be inserted. If obj2\\n * is omitted or not found, obj is inserted at the end of the array.\\n * @template T\\n */\\nfunction insertBefore(arr, obj, opt_obj2) {\\n let i;\\n if (arguments.length == 2 || (i = indexOf(arr, opt_obj2)) < 0) {\\n arr.push(obj);\\n } else {\\n insertAt(arr, obj, i);\\n }\\n}\\nexports.insertBefore = insertBefore;\\n\\n\\n/**\\n * Removes the first occurrence of a particular value from an array.\\n * @param {IArrayLike} arr Array from which to remove\\n * value.\\n * @param {T} obj Object to remove.\\n * @return {boolean} True if an element was removed.\\n * @template T\\n */\\nfunction remove(arr, obj) {\\n const i = indexOf(arr, obj);\\n let rv;\\n if ((rv = i >= 0)) {\\n removeAt(arr, i);\\n }\\n return rv;\\n}\\nexports.remove = remove;\\n\\n\\n/**\\n * Removes the last occurrence of a particular value from an array.\\n * @param {!IArrayLike} arr Array from which to remove value.\\n * @param {T} obj Object to remove.\\n * @return {boolean} True if an element was removed.\\n * @template T\\n */\\nfunction removeLast(arr, obj) {\\n const i = lastIndexOf(arr, obj);\\n if (i >= 0) {\\n removeAt(arr, i);\\n return true;\\n }\\n return false;\\n}\\nexports.removeLast = removeLast;\\n\\n\\n/**\\n * Removes from an array the element at index i\\n * @param {IArrayLike} arr Array or array like object from which to\\n * remove value.\\n * @param {number} i The index to remove.\\n * @return {boolean} True if an element was removed.\\n */\\nfunction removeAt(arr, i) {\\n asserts.assert(arr.length != null);\\n\\n // use generic form of splice\\n // splice returns the removed items and if successful the length of that\\n // will be 1\\n return Array.prototype.splice.call(arr, i, 1).length == 1;\\n}\\nexports.removeAt = removeAt;\\n\\n\\n/**\\n * Removes the first value that satisfies the given condition.\\n * @param {IArrayLike} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\\n * for every element. This function\\n * takes 3 arguments (the element, the index and the array) and should\\n * return a boolean.\\n * @param {S=} opt_obj An optional \\\"this\\\" context for the function.\\n * @return {boolean} True if an element was removed.\\n * @template T,S\\n */\\nfunction removeIf(arr, f, opt_obj) {\\n const i = findIndex(arr, f, opt_obj);\\n if (i >= 0) {\\n removeAt(arr, i);\\n return true;\\n }\\n return false;\\n}\\nexports.removeIf = removeIf;\\n\\n\\n/**\\n * Removes all values that satisfy the given condition.\\n * @param {IArrayLike} arr Array or array\\n * like object over which to iterate.\\n * @param {?function(this:S, T, number, ?) : boolean} f The function to call\\n * for every element. This function\\n * takes 3 arguments (the element, the index and the array) and should\\n * return a boolean.\\n * @param {S=} opt_obj An optional \\\"this\\\" context for the function.\\n * @return {number} The number of items removed\\n * @template T,S\\n */\\nfunction removeAllIf(arr, f, opt_obj) {\\n let removedCount = 0;\\n forEachRight(arr, function(val, index) {\\n if (f.call(/** @type {?} */ (opt_obj), val, index, arr)) {\\n if (removeAt(arr, index)) {\\n removedCount++;\\n }\\n }\\n });\\n return removedCount;\\n}\\nexports.removeAllIf = removeAllIf;\\n\\n\\n/**\\n * Returns a new array that is the result of joining the arguments. If arrays\\n * are passed then their items are added, however, if non-arrays are passed they\\n * will be added to the return array as is.\\n *\\n * Note that ArrayLike objects will be added as is, rather than having their\\n * items added.\\n *\\n * concat([1, 2], [3, 4]) -> [1, 2, 3, 4]\\n * concat(0, [1, 2]) -> [0, 1, 2]\\n * concat([1, 2], null) -> [1, 2, null]\\n *\\n * @param {...*} var_args Items to concatenate. Arrays will have each item\\n * added, while primitives and objects will be added as is.\\n * @return {!Array} The new resultant array.\\n */\\nfunction concat(var_args) {\\n return Array.prototype.concat.apply([], arguments);\\n}\\nexports.concat = concat;\\n\\n\\n/**\\n * Returns a new array that contains the contents of all the arrays passed.\\n * @param {...!Array} var_args\\n * @return {!Array}\\n * @template T\\n */\\nfunction join(var_args) {\\n return Array.prototype.concat.apply([], arguments);\\n}\\nexports.join = join;\\n\\n\\n/**\\n * Converts an object to an array.\\n * @param {IArrayLike|string} object The object to convert to an\\n * array.\\n * @return {!Array} The object converted into an array. If object has a\\n * length property, every property indexed with a non-negative number\\n * less than length will be included in the result. If object does not\\n * have a length property, an empty array will be returned.\\n * @template T\\n */\\nfunction toArray(object) {\\n const length = object.length;\\n\\n // If length is not a number the following is false. This case is kept for\\n // backwards compatibility since there are callers that pass objects that are\\n // not array like.\\n if (length > 0) {\\n const rv = new Array(length);\\n for (let i = 0; i < length; i++) {\\n rv[i] = object[i];\\n }\\n return rv;\\n }\\n return [];\\n}\\nexports.toArray = toArray;\\n\\n\\n/**\\n * Does a shallow copy of an array.\\n * @param {IArrayLike|string} arr Array or array-like object to\\n * clone.\\n * @return {!Array} Clone of the input array.\\n * @template T\\n */\\nconst clone = toArray;\\nexports.clone = clone;\\n\\n\\n/**\\n * Extends an array with another array, element, or \\\"array like\\\" object.\\n * This function operates 'in-place', it does not create a new Array.\\n *\\n * Example:\\n * var a = [];\\n * extend(a, [0, 1]);\\n * a; // [0, 1]\\n * extend(a, 2);\\n * a; // [0, 1, 2]\\n *\\n * @param {Array} arr1 The array to modify.\\n * @param {...(IArrayLike|VALUE)} var_args The elements or arrays of\\n * elements to add to arr1.\\n * @template VALUE\\n */\\nfunction extend(arr1, var_args) {\\n for (let i = 1; i < arguments.length; i++) {\\n const arr2 = arguments[i];\\n if (goog.isArrayLike(arr2)) {\\n const len1 = arr1.length || 0;\\n const len2 = arr2.length || 0;\\n arr1.length = len1 + len2;\\n for (let j = 0; j < len2; j++) {\\n arr1[len1 + j] = arr2[j];\\n }\\n } else {\\n arr1.push(arr2);\\n }\\n }\\n}\\nexports.extend = extend;\\n\\n\\n/**\\n * Adds or removes elements from an array. This is a generic version of Array\\n * splice. This means that it might work on other objects similar to arrays,\\n * such as the arguments object.\\n *\\n * @param {IArrayLike} arr The array to modify.\\n * @param {number|undefined} index The index at which to start changing the\\n * array. If not defined, treated as 0.\\n * @param {number} howMany How many elements to remove (0 means no removal. A\\n * value below 0 is treated as zero and so is any other non number. Numbers\\n * are floored).\\n * @param {...T} var_args Optional, additional elements to insert into the\\n * array.\\n * @return {!Array} the removed elements.\\n * @template T\\n */\\nfunction splice(arr, index, howMany, var_args) {\\n asserts.assert(arr.length != null);\\n\\n return Array.prototype.splice.apply(arr, slice(arguments, 1));\\n}\\nexports.splice = splice;\\n\\n\\n/**\\n * Returns a new array from a segment of an array. This is a generic version of\\n * Array slice. This means that it might work on other objects similar to\\n * arrays, such as the arguments object.\\n *\\n * @param {IArrayLike|string} arr The array from\\n * which to copy a segment.\\n * @param {number} start The index of the first element to copy.\\n * @param {number=} opt_end The index after the last element to copy.\\n * @return {!Array} A new array containing the specified segment of the\\n * original array.\\n * @template T\\n */\\nfunction slice(arr, start, opt_end) {\\n asserts.assert(arr.length != null);\\n\\n // passing 1 arg to slice is not the same as passing 2 where the second is\\n // null or undefined (in that case the second argument is treated as 0).\\n // we could use slice on the arguments object and then use apply instead of\\n // testing the length\\n if (arguments.length <= 2) {\\n return Array.prototype.slice.call(arr, start);\\n } else {\\n return Array.prototype.slice.call(arr, start, opt_end);\\n }\\n}\\nexports.slice = slice;\\n\\n\\n/**\\n * Removes all duplicates from an array (retaining only the first\\n * occurrence of each array element). This function modifies the\\n * array in place and doesn't change the order of the non-duplicate items.\\n *\\n * For objects, duplicates are identified as having the same unique ID as\\n * defined by {@link goog.getUid}.\\n *\\n * Alternatively you can specify a custom hash function that returns a unique\\n * value for each item in the array it should consider unique.\\n *\\n * Runtime: N,\\n * Worstcase space: 2N (no dupes)\\n *\\n * @param {IArrayLike} arr The array from which to remove\\n * duplicates.\\n * @param {Array=} opt_rv An optional array in which to return the results,\\n * instead of performing the removal inplace. If specified, the original\\n * array will remain unchanged.\\n * @param {function(T):string=} opt_hashFn An optional function to use to\\n * apply to every item in the array. This function should return a unique\\n * value for each item in the array it should consider unique.\\n * @template T\\n */\\nfunction removeDuplicates(arr, opt_rv, opt_hashFn) {\\n const returnArray = opt_rv || arr;\\n const defaultHashFn = function(item) {\\n // Prefix each type with a single character representing the type to\\n // prevent conflicting keys (e.g. true and 'true').\\n return goog.isObject(item) ? 'o' + goog.getUid(item) :\\n (typeof item).charAt(0) + item;\\n };\\n const hashFn = opt_hashFn || defaultHashFn;\\n\\n let cursorInsert = 0;\\n let cursorRead = 0;\\n const seen = {};\\n\\n while (cursorRead < arr.length) {\\n const current = arr[cursorRead++];\\n const key = hashFn(current);\\n if (!Object.prototype.hasOwnProperty.call(seen, key)) {\\n seen[key] = true;\\n returnArray[cursorInsert++] = current;\\n }\\n }\\n returnArray.length = cursorInsert;\\n}\\nexports.removeDuplicates = removeDuplicates;\\n\\n\\n/**\\n * Searches the specified array for the specified target using the binary\\n * search algorithm. If no opt_compareFn is specified, elements are compared\\n * using defaultCompare, which compares the elements\\n * using the built in < and > operators. This will produce the expected\\n * behavior for homogeneous arrays of String(s) and Number(s). The array\\n * specified must be sorted in ascending order (as defined by the\\n * comparison function). If the array is not sorted, results are undefined.\\n * If the array contains multiple instances of the specified target value, the\\n * left-most instance will be found.\\n *\\n * Runtime: O(log n)\\n *\\n * @param {IArrayLike} arr The array to be searched.\\n * @param {TARGET} target The sought value.\\n * @param {function(TARGET, VALUE): number=} opt_compareFn Optional comparison\\n * function by which the array is ordered. Should take 2 arguments to\\n * compare, the target value and an element from your array, and return a\\n * negative number, zero, or a positive number depending on whether the\\n * first argument is less than, equal to, or greater than the second.\\n * @return {number} Lowest index of the target value if found, otherwise\\n * (-(insertion point) - 1). The insertion point is where the value should\\n * be inserted into arr to preserve the sorted property. Return value >= 0\\n * iff target is found.\\n * @template TARGET, VALUE\\n */\\nfunction binarySearch(arr, target, opt_compareFn) {\\n return binarySearch_(\\n arr, opt_compareFn || defaultCompare, false /* isEvaluator */, target);\\n}\\nexports.binarySearch = binarySearch;\\n\\n\\n/**\\n * Selects an index in the specified array using the binary search algorithm.\\n * The evaluator receives an element and determines whether the desired index\\n * is before, at, or after it. The evaluator must be consistent (formally,\\n * map(map(arr, evaluator, opt_obj), goog.math.sign)\\n * must be monotonically non-increasing).\\n *\\n * Runtime: O(log n)\\n *\\n * @param {IArrayLike} arr The array to be searched.\\n * @param {function(this:THIS, VALUE, number, ?): number} evaluator\\n * Evaluator function that receives 3 arguments (the element, the index and\\n * the array). Should return a negative number, zero, or a positive number\\n * depending on whether the desired index is before, at, or after the\\n * element passed to it.\\n * @param {THIS=} opt_obj The object to be used as the value of 'this'\\n * within evaluator.\\n * @return {number} Index of the leftmost element matched by the evaluator, if\\n * such exists; otherwise (-(insertion point) - 1). The insertion point is\\n * the index of the first element for which the evaluator returns negative,\\n * or arr.length if no such element exists. The return value is non-negative\\n * iff a match is found.\\n * @template THIS, VALUE\\n */\\nfunction binarySelect(arr, evaluator, opt_obj) {\\n return binarySearch_(\\n arr, evaluator, true /* isEvaluator */, undefined /* opt_target */,\\n opt_obj);\\n}\\nexports.binarySelect = binarySelect;\\n\\n\\n/**\\n * Implementation of a binary search algorithm which knows how to use both\\n * comparison functions and evaluators. If an evaluator is provided, will call\\n * the evaluator with the given optional data object, conforming to the\\n * interface defined in binarySelect. Otherwise, if a comparison function is\\n * provided, will call the comparison function against the given data object.\\n *\\n * This implementation purposefully does not use goog.bind or goog.partial for\\n * performance reasons.\\n *\\n * Runtime: O(log n)\\n *\\n * @param {IArrayLike} arr The array to be searched.\\n * @param {function(?, ?, ?): number | function(?, ?): number} compareFn\\n * Either an evaluator or a comparison function, as defined by binarySearch\\n * and binarySelect above.\\n * @param {boolean} isEvaluator Whether the function is an evaluator or a\\n * comparison function.\\n * @param {?=} opt_target If the function is a comparison function, then\\n * this is the target to binary search for.\\n * @param {Object=} opt_selfObj If the function is an evaluator, this is an\\n * optional this object for the evaluator.\\n * @return {number} Lowest index of the target value if found, otherwise\\n * (-(insertion point) - 1). The insertion point is where the value should\\n * be inserted into arr to preserve the sorted property. Return value >= 0\\n * iff target is found.\\n * @private\\n */\\nfunction binarySearch_(arr, compareFn, isEvaluator, opt_target, opt_selfObj) {\\n let left = 0; // inclusive\\n let right = arr.length; // exclusive\\n let found;\\n while (left < right) {\\n const middle = left + ((right - left) >>> 1);\\n let compareResult;\\n if (isEvaluator) {\\n compareResult = compareFn.call(opt_selfObj, arr[middle], middle, arr);\\n } else {\\n // NOTE(dimvar): To avoid this cast, we'd have to use function overloading\\n // for the type of binarySearch_, which the type system can't express yet.\\n compareResult = /** @type {function(?, ?): number} */ (compareFn)(\\n opt_target, arr[middle]);\\n }\\n if (compareResult > 0) {\\n left = middle + 1;\\n } else {\\n right = middle;\\n // We are looking for the lowest index so we can't return immediately.\\n found = !compareResult;\\n }\\n }\\n // left is the index if found, or the insertion point otherwise.\\n // Avoiding bitwise not operator, as that causes a loss in precision for array\\n // indexes outside the bounds of a 32-bit signed integer. Array indexes have\\n // a maximum value of 2^32-2 https://tc39.es/ecma262/#array-index\\n return found ? left : -left - 1;\\n}\\n\\n\\n/**\\n * Sorts the specified array into ascending order. If no opt_compareFn is\\n * specified, elements are compared using\\n * defaultCompare, which compares the elements using\\n * the built in < and > operators. This will produce the expected behavior\\n * for homogeneous arrays of String(s) and Number(s), unlike the native sort,\\n * but will give unpredictable results for heterogeneous lists of strings and\\n * numbers with different numbers of digits.\\n *\\n * This sort is not guaranteed to be stable.\\n *\\n * Runtime: Same as `Array.prototype.sort`\\n *\\n * @param {Array} arr The array to be sorted.\\n * @param {?function(T,T):number=} opt_compareFn Optional comparison\\n * function by which the\\n * array is to be ordered. Should take 2 arguments to compare, and return a\\n * negative number, zero, or a positive number depending on whether the\\n * first argument is less than, equal to, or greater than the second.\\n * @template T\\n */\\nfunction sort(arr, opt_compareFn) {\\n // TODO(arv): Update type annotation since null is not accepted.\\n arr.sort(opt_compareFn || defaultCompare);\\n}\\nexports.sort = sort;\\n\\n\\n/**\\n * Sorts the specified array into ascending order in a stable way. If no\\n * opt_compareFn is specified, elements are compared using\\n * defaultCompare, which compares the elements using\\n * the built in < and > operators. This will produce the expected behavior\\n * for homogeneous arrays of String(s) and Number(s).\\n *\\n * Runtime: Same as `Array.prototype.sort`, plus an additional\\n * O(n) overhead of copying the array twice.\\n *\\n * @param {Array} arr The array to be sorted.\\n * @param {?function(T, T): number=} opt_compareFn Optional comparison function\\n * by which the array is to be ordered. Should take 2 arguments to compare,\\n * and return a negative number, zero, or a positive number depending on\\n * whether the first argument is less than, equal to, or greater than the\\n * second.\\n * @template T\\n */\\nfunction stableSort(arr, opt_compareFn) {\\n const compArr = new Array(arr.length);\\n for (let i = 0; i < arr.length; i++) {\\n compArr[i] = {index: i, value: arr[i]};\\n }\\n const valueCompareFn = opt_compareFn || defaultCompare;\\n function stableCompareFn(obj1, obj2) {\\n return valueCompareFn(obj1.value, obj2.value) || obj1.index - obj2.index;\\n }\\n sort(compArr, stableCompareFn);\\n for (let i = 0; i < arr.length; i++) {\\n arr[i] = compArr[i].value;\\n }\\n}\\nexports.stableSort = stableSort;\\n\\n\\n/**\\n * Sort the specified array into ascending order based on item keys\\n * returned by the specified key function.\\n * If no opt_compareFn is specified, the keys are compared in ascending order\\n * using defaultCompare.\\n *\\n * Runtime: O(S(f(n)), where S is runtime of sort\\n * and f(n) is runtime of the key function.\\n *\\n * @param {Array} arr The array to be sorted.\\n * @param {function(T): K} keyFn Function taking array element and returning\\n * a key used for sorting this element.\\n * @param {?function(K, K): number=} opt_compareFn Optional comparison function\\n * by which the keys are to be ordered. Should take 2 arguments to compare,\\n * and return a negative number, zero, or a positive number depending on\\n * whether the first argument is less than, equal to, or greater than the\\n * second.\\n * @template T,K\\n */\\nfunction sortByKey(arr, keyFn, opt_compareFn) {\\n const keyCompareFn = opt_compareFn || defaultCompare;\\n sort(arr, function(a, b) {\\n return keyCompareFn(keyFn(a), keyFn(b));\\n });\\n}\\nexports.sortByKey = sortByKey;\\n\\n\\n/**\\n * Sorts an array of objects by the specified object key and compare\\n * function. If no compare function is provided, the key values are\\n * compared in ascending order using defaultCompare.\\n * This won't work for keys that get renamed by the compiler. So use\\n * {'foo': 1, 'bar': 2} rather than {foo: 1, bar: 2}.\\n * @param {Array} arr An array of objects to sort.\\n * @param {string} key The object key to sort by.\\n * @param {Function=} opt_compareFn The function to use to compare key\\n * values.\\n */\\nfunction sortObjectsByKey(arr, key, opt_compareFn) {\\n sortByKey(arr, function(obj) {\\n return obj[key];\\n }, opt_compareFn);\\n}\\nexports.sortObjectsByKey = sortObjectsByKey;\\n\\n\\n/**\\n * Tells if the array is sorted.\\n * @param {!IArrayLike} arr The array.\\n * @param {?function(T,T):number=} opt_compareFn Function to compare the\\n * array elements.\\n * Should take 2 arguments to compare, and return a negative number, zero,\\n * or a positive number depending on whether the first argument is less\\n * than, equal to, or greater than the second.\\n * @param {boolean=} opt_strict If true no equal elements are allowed.\\n * @return {boolean} Whether the array is sorted.\\n * @template T\\n */\\nfunction isSorted(arr, opt_compareFn, opt_strict) {\\n const compare = opt_compareFn || defaultCompare;\\n for (let i = 1; i < arr.length; i++) {\\n const compareResult = compare(arr[i - 1], arr[i]);\\n if (compareResult > 0 || compareResult == 0 && opt_strict) {\\n return false;\\n }\\n }\\n return true;\\n}\\nexports.isSorted = isSorted;\\n\\n\\n/**\\n * Compares two arrays for equality. Two arrays are considered equal if they\\n * have the same length and their corresponding elements are equal according to\\n * the comparison function.\\n *\\n * @param {IArrayLike} arr1 The first array to compare.\\n * @param {IArrayLike} arr2 The second array to compare.\\n * @param {?function(A,B):boolean=} opt_equalsFn Optional comparison function.\\n * Should take 2 arguments to compare, and return true if the arguments\\n * are equal. Defaults to {@link goog.array.defaultCompareEquality} which\\n * compares the elements using the built-in '===' operator.\\n * @return {boolean} Whether the two arrays are equal.\\n * @template A\\n * @template B\\n */\\nfunction equals(arr1, arr2, opt_equalsFn) {\\n if (!goog.isArrayLike(arr1) || !goog.isArrayLike(arr2) ||\\n arr1.length != arr2.length) {\\n return false;\\n }\\n const l = arr1.length;\\n const equalsFn = opt_equalsFn || defaultCompareEquality;\\n for (let i = 0; i < l; i++) {\\n if (!equalsFn(arr1[i], arr2[i])) {\\n return false;\\n }\\n }\\n return true;\\n}\\nexports.equals = equals;\\n\\n\\n/**\\n * 3-way array compare function.\\n * @param {!IArrayLike} arr1 The first array to\\n * compare.\\n * @param {!IArrayLike} arr2 The second array to\\n * compare.\\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\\n * function by which the array is to be ordered. Should take 2 arguments to\\n * compare, and return a negative number, zero, or a positive number\\n * depending on whether the first argument is less than, equal to, or\\n * greater than the second.\\n * @return {number} Negative number, zero, or a positive number depending on\\n * whether the first argument is less than, equal to, or greater than the\\n * second.\\n * @template VALUE\\n */\\nfunction compare3(arr1, arr2, opt_compareFn) {\\n const compare = opt_compareFn || defaultCompare;\\n const l = Math.min(arr1.length, arr2.length);\\n for (let i = 0; i < l; i++) {\\n const result = compare(arr1[i], arr2[i]);\\n if (result != 0) {\\n return result;\\n }\\n }\\n return defaultCompare(arr1.length, arr2.length);\\n}\\nexports.compare3 = compare3;\\n\\n\\n/**\\n * Compares its two arguments for order, using the built in < and >\\n * operators.\\n * @param {VALUE} a The first object to be compared.\\n * @param {VALUE} b The second object to be compared.\\n * @return {number} A negative number, zero, or a positive number as the first\\n * argument is less than, equal to, or greater than the second,\\n * respectively.\\n * @template VALUE\\n */\\nfunction defaultCompare(a, b) {\\n return a > b ? 1 : a < b ? -1 : 0;\\n}\\nexports.defaultCompare = defaultCompare;\\n\\n\\n/**\\n * Compares its two arguments for inverse order, using the built in < and >\\n * operators.\\n * @param {VALUE} a The first object to be compared.\\n * @param {VALUE} b The second object to be compared.\\n * @return {number} A negative number, zero, or a positive number as the first\\n * argument is greater than, equal to, or less than the second,\\n * respectively.\\n * @template VALUE\\n */\\nfunction inverseDefaultCompare(a, b) {\\n return -defaultCompare(a, b);\\n}\\nexports.inverseDefaultCompare = inverseDefaultCompare;\\n\\n\\n/**\\n * Compares its two arguments for equality, using the built in === operator.\\n * @param {*} a The first object to compare.\\n * @param {*} b The second object to compare.\\n * @return {boolean} True if the two arguments are equal, false otherwise.\\n */\\nfunction defaultCompareEquality(a, b) {\\n return a === b;\\n}\\nexports.defaultCompareEquality = defaultCompareEquality;\\n\\n\\n/**\\n * Inserts a value into a sorted array. The array is not modified if the\\n * value is already present.\\n * @param {IArrayLike} array The array to modify.\\n * @param {VALUE} value The object to insert.\\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\\n * function by which the array is ordered. Should take 2 arguments to\\n * compare, and return a negative number, zero, or a positive number\\n * depending on whether the first argument is less than, equal to, or\\n * greater than the second.\\n * @return {boolean} True if an element was inserted.\\n * @template VALUE\\n */\\nfunction binaryInsert(array, value, opt_compareFn) {\\n const index = binarySearch(array, value, opt_compareFn);\\n if (index < 0) {\\n insertAt(array, value, -(index + 1));\\n return true;\\n }\\n return false;\\n}\\nexports.binaryInsert = binaryInsert;\\n\\n\\n/**\\n * Removes a value from a sorted array.\\n * @param {!IArrayLike} array The array to modify.\\n * @param {VALUE} value The object to remove.\\n * @param {function(VALUE, VALUE): number=} opt_compareFn Optional comparison\\n * function by which the array is ordered. Should take 2 arguments to\\n * compare, and return a negative number, zero, or a positive number\\n * depending on whether the first argument is less than, equal to, or\\n * greater than the second.\\n * @return {boolean} True if an element was removed.\\n * @template VALUE\\n */\\nfunction binaryRemove(array, value, opt_compareFn) {\\n const index = binarySearch(array, value, opt_compareFn);\\n return (index >= 0) ? removeAt(array, index) : false;\\n}\\nexports.binaryRemove = binaryRemove;\\n\\n\\n/**\\n * Splits an array into disjoint buckets according to a splitting function.\\n * @param {IArrayLike} array The array.\\n * @param {function(this:S, T, number, !IArrayLike):?} sorter Function to\\n * call for every element. This takes 3 arguments (the element, the index\\n * and the array) and must return a valid object key (a string, number,\\n * etc), or undefined, if that object should not be placed in a bucket.\\n * @param {S=} opt_obj The object to be used as the value of 'this' within\\n * sorter.\\n * @return {!Object>} An object, with keys being all of the unique\\n * return values of sorter, and values being arrays containing the items for\\n * which the splitter returned that key.\\n * @template T,S\\n */\\nfunction bucket(array, sorter, opt_obj) {\\n const buckets = {};\\n\\n for (let i = 0; i < array.length; i++) {\\n const value = array[i];\\n const key = sorter.call(/** @type {?} */ (opt_obj), value, i, array);\\n if (key !== undefined) {\\n // Push the value to the right bucket, creating it if necessary.\\n const bucket = buckets[key] || (buckets[key] = []);\\n bucket.push(value);\\n }\\n }\\n\\n return buckets;\\n}\\nexports.bucket = bucket;\\n\\n\\n/**\\n * Splits an array into disjoint buckets according to a splitting function.\\n * @param {!IArrayLike} array The array.\\n * @param {function(V, number, !IArrayLike):(K|undefined)} sorter Function to\\n * call for every element. This takes 3 arguments (the element, the index,\\n * and the array) and must return a value to use as a key, or undefined, if\\n * that object should not be placed in a bucket.\\n * @return {!Map>} A map, with keys being all of the unique\\n * return values of sorter, and values being arrays containing the items for\\n * which the splitter returned that key.\\n * @template K,V\\n */\\nfunction bucketToMap(array, sorter) {\\n const /** !Map> */ buckets = new Map();\\n\\n for (let i = 0; i < array.length; i++) {\\n const value = array[i];\\n const key = sorter(value, i, array);\\n if (key !== undefined) {\\n // Push the value to the right bucket, creating it if necessary.\\n let bucket = buckets.get(key);\\n if (!bucket) {\\n bucket = [];\\n buckets.set(key, bucket);\\n }\\n bucket.push(value);\\n }\\n }\\n\\n return buckets;\\n}\\nexports.bucketToMap = bucketToMap;\\n\\n\\n/**\\n * Creates a new object built from the provided array and the key-generation\\n * function.\\n * @param {IArrayLike} arr Array or array like object over\\n * which to iterate whose elements will be the values in the new object.\\n * @param {?function(this:S, T, number, ?) : string} keyFunc The function to\\n * call for every element. This function takes 3 arguments (the element, the\\n * index and the array) and should return a string that will be used as the\\n * key for the element in the new object. If the function returns the same\\n * key for more than one element, the value for that key is\\n * implementation-defined.\\n * @param {S=} opt_obj The object to be used as the value of 'this'\\n * within keyFunc.\\n * @return {!Object} The new object.\\n * @template T,S\\n */\\nfunction toObject(arr, keyFunc, opt_obj) {\\n const ret = {};\\n forEach(arr, function(element, index) {\\n ret[keyFunc.call(/** @type {?} */ (opt_obj), element, index, arr)] =\\n element;\\n });\\n return ret;\\n}\\nexports.toObject = toObject;\\n\\n\\n/**\\n * Creates a new ES6 Map built from the provided array and the key-generation\\n * function.\\n * @param {!IArrayLike} arr Array or array like object over which to iterate\\n * whose elements will be the values in the new object.\\n * @param {?function(V, number, ?) : K} keyFunc The function to call for every\\n * element. This function takes 3 arguments (the element, the index, and the\\n * array) and should return a value that will be used as the key for the\\n * element in the new object. If the function returns the same key for more\\n * than one element, the value for that key is implementation-defined.\\n * @return {!Map} The new map.\\n * @template K,V\\n */\\nfunction toMap(arr, keyFunc) {\\n const /** !Map */ map = new Map();\\n\\n for (let i = 0; i < arr.length; i++) {\\n const element = arr[i];\\n map.set(keyFunc(element, i, arr), element);\\n }\\n\\n return map;\\n}\\nexports.toMap = toMap;\\n\\n\\n/**\\n * Creates a range of numbers in an arithmetic progression.\\n *\\n * Range takes 1, 2, or 3 arguments:\\n *
\\n * range(5) is the same as range(0, 5, 1) and produces [0, 1, 2, 3, 4]\\n * range(2, 5) is the same as range(2, 5, 1) and produces [2, 3, 4]\\n * range(-2, -5, -1) produces [-2, -3, -4]\\n * range(-2, -5, 1) produces [], since stepping by 1 wouldn't ever reach -5.\\n * 
\\n *\\n * @param {number} startOrEnd The starting value of the range if an end argument\\n * is provided. Otherwise, the start value is 0, and this is the end value.\\n * @param {number=} opt_end The optional end value of the range.\\n * @param {number=} opt_step The step size between range values. Defaults to 1\\n * if opt_step is undefined or 0.\\n * @return {!Array} An array of numbers for the requested range. May be\\n * an empty array if adding the step would not converge toward the end\\n * value.\\n */\\nfunction range(startOrEnd, opt_end, opt_step) {\\n const array = [];\\n let start = 0;\\n let end = startOrEnd;\\n const step = opt_step || 1;\\n if (opt_end !== undefined) {\\n start = startOrEnd;\\n end = opt_end;\\n }\\n\\n if (step * (end - start) < 0) {\\n // Sign mismatch: start + step will never reach the end value.\\n return [];\\n }\\n\\n if (step > 0) {\\n for (let i = start; i < end; i += step) {\\n array.push(i);\\n }\\n } else {\\n for (let i = start; i > end; i += step) {\\n array.push(i);\\n }\\n }\\n return array;\\n}\\nexports.range = range;\\n\\n\\n/**\\n * Returns an array consisting of the given value repeated N times.\\n *\\n * @param {VALUE} value The value to repeat.\\n * @param {number} n The repeat count.\\n * @return {!Array} An array with the repeated value.\\n * @template VALUE\\n */\\nfunction repeat(value, n) {\\n const array = [];\\n for (let i = 0; i < n; i++) {\\n array[i] = value;\\n }\\n return array;\\n}\\nexports.repeat = repeat;\\n\\n\\n/**\\n * Returns an array consisting of every argument with all arrays\\n * expanded in-place recursively.\\n *\\n * @param {...*} var_args The values to flatten.\\n * @return {!Array} An array containing the flattened values.\\n */\\nfunction flatten(var_args) {\\n const CHUNK_SIZE = 8192;\\n\\n const result = [];\\n for (let i = 0; i < arguments.length; i++) {\\n const element = arguments[i];\\n if (Array.isArray(element)) {\\n for (let c = 0; c < element.length; c += CHUNK_SIZE) {\\n const chunk = slice(element, c, c + CHUNK_SIZE);\\n const recurseResult = flatten.apply(null, chunk);\\n for (let r = 0; r < recurseResult.length; r++) {\\n result.push(recurseResult[r]);\\n }\\n }\\n } else {\\n result.push(element);\\n }\\n }\\n return result;\\n}\\nexports.flatten = flatten;\\n\\n\\n/**\\n * Rotates an array in-place. After calling this method, the element at\\n * index i will be the element previously at index (i - n) %\\n * array.length, for all values of i between 0 and array.length - 1,\\n * inclusive.\\n *\\n * For example, suppose list comprises [t, a, n, k, s]. After invoking\\n * rotate(array, 1) (or rotate(array, -4)), array will comprise [s, t, a, n, k].\\n *\\n * @param {!Array} array The array to rotate.\\n * @param {number} n The amount to rotate.\\n * @return {!Array} The array.\\n * @template T\\n */\\nfunction rotate(array, n) {\\n asserts.assert(array.length != null);\\n\\n if (array.length) {\\n n %= array.length;\\n if (n > 0) {\\n Array.prototype.unshift.apply(array, array.splice(-n, n));\\n } else if (n < 0) {\\n Array.prototype.push.apply(array, array.splice(0, -n));\\n }\\n }\\n return array;\\n}\\nexports.rotate = rotate;\\n\\n\\n/**\\n * Moves one item of an array to a new position keeping the order of the rest\\n * of the items. Example use case: keeping a list of JavaScript objects\\n * synchronized with the corresponding list of DOM elements after one of the\\n * elements has been dragged to a new position.\\n * @param {!IArrayLike} arr The array to modify.\\n * @param {number} fromIndex Index of the item to move between 0 and\\n * `arr.length - 1`.\\n * @param {number} toIndex Target index between 0 and `arr.length - 1`.\\n */\\nfunction moveItem(arr, fromIndex, toIndex) {\\n asserts.assert(fromIndex >= 0 && fromIndex < arr.length);\\n asserts.assert(toIndex >= 0 && toIndex < arr.length);\\n // Remove 1 item at fromIndex.\\n const removedItems = Array.prototype.splice.call(arr, fromIndex, 1);\\n // Insert the removed item at toIndex.\\n Array.prototype.splice.call(arr, toIndex, 0, removedItems[0]);\\n // We don't use goog.array.insertAt and goog.array.removeAt, because they're\\n // significantly slower than splice.\\n}\\nexports.moveItem = moveItem;\\n\\n\\n/**\\n * Creates a new array for which the element at position i is an array of the\\n * ith element of the provided arrays. The returned array will only be as long\\n * as the shortest array provided; additional values are ignored. For example,\\n * the result of zipping [1, 2] and [3, 4, 5] is [[1,3], [2, 4]].\\n *\\n * This is similar to the zip() function in Python. See {@link\\n * http://docs.python.org/library/functions.html#zip}\\n *\\n * @param {...!IArrayLike} var_args Arrays to be combined.\\n * @return {!Array>} A new array of arrays created from\\n * provided arrays.\\n */\\nfunction zip(var_args) {\\n if (!arguments.length) {\\n return [];\\n }\\n const result = [];\\n let minLen = arguments[0].length;\\n for (let i = 1; i < arguments.length; i++) {\\n if (arguments[i].length < minLen) {\\n minLen = arguments[i].length;\\n }\\n }\\n for (let i = 0; i < minLen; i++) {\\n const value = [];\\n for (let j = 0; j < arguments.length; j++) {\\n value.push(arguments[j][i]);\\n }\\n result.push(value);\\n }\\n return result;\\n}\\nexports.zip = zip;\\n\\n\\n/**\\n * Shuffles the values in the specified array using the Fisher-Yates in-place\\n * shuffle (also known as the Knuth Shuffle). By default, calls Math.random()\\n * and so resets the state of that random number generator. Similarly, may reset\\n * the state of any other specified random number generator.\\n *\\n * Runtime: O(n)\\n *\\n * @param {!Array} arr The array to be shuffled.\\n * @param {function():number=} opt_randFn Optional random function to use for\\n * shuffling.\\n * Takes no arguments, and returns a random number on the interval [0, 1).\\n * Defaults to Math.random() using JavaScript's built-in Math library.\\n */\\nfunction shuffle(arr, opt_randFn) {\\n const randFn = opt_randFn || Math.random;\\n\\n for (let i = arr.length - 1; i > 0; i--) {\\n // Choose a random array index in [0, i] (inclusive with i).\\n const j = Math.floor(randFn() * (i + 1));\\n\\n const tmp = arr[i];\\n arr[i] = arr[j];\\n arr[j] = tmp;\\n }\\n}\\nexports.shuffle = shuffle;\\n\\n\\n/**\\n * Returns a new array of elements from arr, based on the indexes of elements\\n * provided by index_arr. For example, the result of index copying\\n * ['a', 'b', 'c'] with index_arr [1,0,0,2] is ['b', 'a', 'a', 'c'].\\n *\\n * @param {!IArrayLike} arr The array to get a indexed copy from.\\n * @param {!IArrayLike} index_arr An array of indexes to get from arr.\\n * @return {!Array} A new array of elements from arr in index_arr order.\\n * @template T\\n */\\nfunction copyByIndex(arr, index_arr) {\\n const result = [];\\n forEach(index_arr, function(index) {\\n result.push(arr[index]);\\n });\\n return result;\\n}\\nexports.copyByIndex = copyByIndex;\\n\\n\\n/**\\n * Maps each element of the input array into zero or more elements of the output\\n * array.\\n *\\n * @param {!IArrayLike|string} arr Array or array like object\\n * over which to iterate.\\n * @param {function(this:THIS, VALUE, number, ?): !Array} f The function\\n * to call for every element. This function takes 3 arguments (the element,\\n * the index and the array) and should return an array. The result will be\\n * used to extend a new array.\\n * @param {THIS=} opt_obj The object to be used as the value of 'this' within f.\\n * @return {!Array} a new array with the concatenation of all arrays\\n * returned from f.\\n * @template THIS, VALUE, RESULT\\n */\\nfunction concatMap(arr, f, opt_obj) {\\n return concat.apply([], map(arr, f, opt_obj));\\n}\\nexports.concatMap = concatMap;\\n\"],\n\"names\":[\"peek\",\"array\",\"length\",\"forEachRight\",\"arr\",\"f\",\"opt_obj\",\"l\",\"arr2\",\"split\",\"i\",\"call\",\"count\",\"forEach\",\"element\",\"index\",\"find\",\"findIndex\",\"charAt\",\"findRight\",\"findIndexRight\",\"contains\",\"obj\",\"indexOf\",\"isEmpty\",\"clear\",\"Array\",\"isArray\",\"insert\",\"push\",\"insertAt\",\"opt_i\",\"splice\",\"insertArrayAt\",\"elementsToAdd\",\"goog\",\"partial\",\"apply\",\"insertBefore\",\"opt_obj2\",\"arguments\",\"remove\",\"rv\",\"removeAt\",\"removeLast\",\"lastIndexOf\",\"asserts\",\"assert\",\"prototype\",\"removeIf\",\"removeAllIf\",\"removedCount\",\"val\",\"concat\",\"var_args\",\"join\",\"toArray\",\"object\",\"extend\",\"arr1\",\"isArrayLike\",\"len1\",\"len2\",\"j\",\"howMany\",\"slice\",\"start\",\"opt_end\",\"removeDuplicates\",\"opt_rv\",\"opt_hashFn\",\"returnArray\",\"defaultHashFn\",\"item\",\"isObject\",\"getUid\",\"hashFn\",\"cursorInsert\",\"cursorRead\",\"seen\",\"current\",\"key\",\"Object\",\"hasOwnProperty\",\"binarySearch\",\"target\",\"opt_compareFn\",\"binarySearch_\",\"defaultCompare\",\"binarySelect\",\"evaluator\",\"undefined\",\"compareFn\",\"isEvaluator\",\"opt_target\",\"opt_selfObj\",\"left\",\"right\",\"found\",\"middle\",\"compareResult\",\"sort\",\"stableSort\",\"stableCompareFn\",\"obj1\",\"obj2\",\"valueCompareFn\",\"value\",\"compArr\",\"sortByKey\",\"keyFn\",\"keyCompareFn\",\"a\",\"b\",\"sortObjectsByKey\",\"isSorted\",\"opt_strict\",\"compare\",\"equals\",\"opt_equalsFn\",\"equalsFn\",\"defaultCompareEquality\",\"compare3\",\"Math\",\"min\",\"result\",\"inverseDefaultCompare\",\"binaryInsert\",\"binaryRemove\",\"bucket\",\"sorter\",\"buckets\",\"bucketToMap\",\"Map\",\"get\",\"set\",\"toObject\",\"keyFunc\",\"ret\",\"toMap\",\"map\",\"range\",\"startOrEnd\",\"opt_step\",\"end\",\"step\",\"repeat\",\"n\",\"flatten\",\"CHUNK_SIZE\",\"c\",\"chunk\",\"recurseResult\",\"r\",\"rotate\",\"unshift\",\"moveItem\",\"fromIndex\",\"toIndex\",\"removedItems\",\"zip\",\"minLen\",\"shuffle\",\"opt_randFn\",\"randFn\",\"random\",\"floor\",\"tmp\",\"copyByIndex\",\"index_arr\",\"concatMap\",\"module\",\"declareLegacyNamespace\",\"require\",\"NATIVE_ARRAY_PROTOTYPES\",\"define\",\"TRUSTED_SITE\",\"ASSUME_NATIVE_FUNCTIONS\",\"FEATURESET_YEAR\",\"exports\",\"last\",\"opt_fromIndex\",\"max\",\"filter\",\"res\",\"resLength\",\"reduce\",\"bind\",\"rval\",\"reduceRight\",\"some\",\"every\",\"clone\"]\n}\n"]