ut2 1.4.10 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +6 -0
  2. package/dist/ut2.js +75 -71
  3. package/dist/ut2.js.map +1 -1
  4. package/dist/ut2.min.js +1 -1
  5. package/dist/ut2.min.js.map +1 -1
  6. package/es/chunk.js +2 -1
  7. package/es/inRange.js +2 -1
  8. package/es/internals/decimalAdjust.js +2 -1
  9. package/es/internals/getSymbols.js +2 -2
  10. package/es/internals/getTag.js +8 -8
  11. package/es/internals/getTagWithBugfix.js +6 -6
  12. package/es/internals/helpers.js +4 -4
  13. package/es/internals/keys.js +2 -2
  14. package/es/internals/native.js +15 -8
  15. package/es/internals/nodeUtil.js +0 -5
  16. package/es/isArguments.js +3 -3
  17. package/es/isArrayBuffer.js +2 -2
  18. package/es/isBlob.js +2 -2
  19. package/es/isBoolean.js +2 -2
  20. package/es/isDate.js +2 -2
  21. package/es/isEqual.js +3 -3
  22. package/es/isError.js +2 -2
  23. package/es/isFunction.js +2 -2
  24. package/es/isInteger.js +2 -2
  25. package/es/isMatch.js +2 -2
  26. package/es/isNumber.js +2 -2
  27. package/es/isPlainObject.js +4 -4
  28. package/es/isRegExp.js +2 -2
  29. package/es/isSafeInteger.js +2 -2
  30. package/es/isString.js +2 -2
  31. package/es/isSymbol.js +2 -2
  32. package/es/isTypedArray.js +2 -2
  33. package/es/isWeakSet.js +2 -2
  34. package/es/nth.js +3 -3
  35. package/es/random.js +4 -3
  36. package/es/randomInt.js +4 -3
  37. package/es/times.js +2 -2
  38. package/es/unzip.js +2 -1
  39. package/lib/chunk.js +2 -1
  40. package/lib/inRange.js +2 -1
  41. package/lib/internals/decimalAdjust.js +2 -1
  42. package/lib/internals/getSymbols.js +1 -1
  43. package/lib/internals/getTag.js +7 -7
  44. package/lib/internals/getTagWithBugfix.js +5 -5
  45. package/lib/internals/helpers.js +3 -3
  46. package/lib/internals/keys.js +1 -1
  47. package/lib/internals/native.js +14 -7
  48. package/lib/internals/nodeUtil.js +0 -5
  49. package/lib/isArguments.js +2 -2
  50. package/lib/isArrayBuffer.js +1 -1
  51. package/lib/isBlob.js +1 -1
  52. package/lib/isBoolean.js +1 -1
  53. package/lib/isDate.js +1 -1
  54. package/lib/isEqual.js +2 -2
  55. package/lib/isError.js +1 -1
  56. package/lib/isFunction.js +1 -1
  57. package/lib/isInteger.js +1 -1
  58. package/lib/isMatch.js +1 -1
  59. package/lib/isNumber.js +1 -1
  60. package/lib/isPlainObject.js +3 -3
  61. package/lib/isRegExp.js +1 -1
  62. package/lib/isSafeInteger.js +1 -1
  63. package/lib/isString.js +1 -1
  64. package/lib/isSymbol.js +1 -1
  65. package/lib/isTypedArray.js +1 -1
  66. package/lib/isWeakSet.js +1 -1
  67. package/lib/nth.js +2 -2
  68. package/lib/random.js +4 -3
  69. package/lib/randomInt.js +4 -3
  70. package/lib/times.js +1 -1
  71. package/lib/unzip.js +2 -1
  72. package/package.json +4 -1
  73. package/types/internals/native.d.ts +14 -7
package/README.md CHANGED
@@ -12,6 +12,12 @@
12
12
  - 使用 TypeScript 实现,提供类型定义。
13
13
  - 导出 `es`、`cjs`、`umd` 模块格式,支持不同开发环境使用。
14
14
 
15
+ ## 兼容性
16
+
17
+ 兼容现代浏览器 [Firefox](https://www.firefox.com.cn/)、[Chrome](https://www.google.cn/chrome/index.html)、[Safari](https://www.apple.com.cn/safari/)、[Opera](https://www.opera.com/zh-cn),以及 [Node.js >= 10](https://nodejs.org/) 。
18
+
19
+ 如果要兼容 IE 系列浏览器,建议使用 [@babel/preset-env](https://babeljs.io/docs/babel-preset-env) 设置对应的 `targets` 。
20
+
15
21
  ## 使用
16
22
 
17
23
  ### `es` 或 `node` 开发环境
package/dist/ut2.js CHANGED
@@ -4,24 +4,27 @@
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ut2 = {}));
5
5
  })(this, (function (exports) { 'use strict';
6
6
 
7
- function isArray(value) {
8
- return Array.isArray(value);
9
- }
10
-
11
7
  var objectProto = Object.prototype;
12
- var objectToString = objectProto.toString;
8
+ var objectProtoToString = objectProto.toString;
9
+ var objectProtoHasOwnProperty = objectProto.hasOwnProperty;
10
+ var objectProtoPropertyIsEnumerable = objectProto.propertyIsEnumerable;
13
11
  var objectGetOwnPropertySymbols = Object.getOwnPropertySymbols;
14
12
  var objectGetPrototypeOf = Object.getPrototypeOf;
15
13
  var objectKeys = Object.keys;
16
- var hasOwnProperty = objectProto.hasOwnProperty;
17
- var propertyIsEnumerable = objectProto.propertyIsEnumerable;
18
- var functionToString = Function.prototype.toString;
14
+ var functionProto = Function.prototype;
15
+ var functionProtoToString = functionProto.toString;
19
16
  var symbolExisted = typeof Symbol !== 'undefined';
20
17
  var symbolProto = symbolExisted ? Symbol.prototype : undefined;
21
- var symToStringTag = symbolExisted ? Symbol.toStringTag : undefined;
18
+ var symbolToStringTag = symbolExisted ? Symbol.toStringTag : undefined;
22
19
  var arrayProto = Array.prototype;
23
- var arrSlice = arrayProto.slice;
24
- var arrayAt = arrayProto.at;
20
+ var arrayProtoSlice = arrayProto.slice;
21
+ var arrayProtoAt = arrayProto.at;
22
+ var mathMin = Math.min;
23
+ var mathMax = Math.max;
24
+ var mathRandom = Math.random;
25
+ var mathFloor = Math.floor;
26
+ var mathCeil = Math.ceil;
27
+ var mathAbs = Math.abs;
25
28
  var numberIsFinite = Number.isFinite;
26
29
  var numberIsInteger = Number.isInteger;
27
30
  var numberIsSafeInteger = Number.isSafeInteger;
@@ -50,13 +53,17 @@
50
53
  var setTag = '[object Set]';
51
54
  var weakMapTag = '[object WeakMap]';
52
55
 
56
+ function isArray(value) {
57
+ return Array.isArray(value);
58
+ }
59
+
53
60
  function isObject(value) {
54
61
  var type = typeof value;
55
62
  return value != null && (type === 'object' || type === 'function');
56
63
  }
57
64
 
58
65
  function isSymbol(value) {
59
- return typeof value === 'symbol' || objectToString.call(value) === symbolTag;
66
+ return typeof value === 'symbol' || objectProtoToString.call(value) === symbolTag;
60
67
  }
61
68
 
62
69
  var reIsBinary = /^0b[01]+$/i;
@@ -114,7 +121,7 @@
114
121
  return [];
115
122
  }
116
123
  var length = array.length;
117
- var result = Array(Math.ceil(length / size));
124
+ var result = Array(mathCeil(length / size));
118
125
  var resIndex = 0, index = 0;
119
126
  while (index < length) {
120
127
  result[resIndex++] = array.slice(index, (index += size));
@@ -191,7 +198,7 @@
191
198
  if (typeof value === 'function') {
192
199
  return true;
193
200
  }
194
- var tag = objectToString.call(value);
201
+ var tag = objectProtoToString.call(value);
195
202
  return functionTags.some(function (item) { return item === tag; });
196
203
  }
197
204
 
@@ -208,8 +215,8 @@
208
215
  if (!isArrayLike(array)) {
209
216
  return undefined;
210
217
  }
211
- if (typeof arrayAt === 'function') {
212
- return arrayAt.call(array, n);
218
+ if (typeof arrayProtoAt === 'function') {
219
+ return arrayProtoAt.call(array, n);
213
220
  }
214
221
  var index = n < 0 ? n + array.length : n;
215
222
  return array[index];
@@ -233,14 +240,14 @@
233
240
  if (upper === void 0) { upper = 1; }
234
241
  lower = toFinite(lower);
235
242
  upper = toFinite(upper);
236
- var min = Math.ceil(Math.min(lower, upper) || 0);
237
- var max = Math.floor(Math.max(lower, upper) || 0);
243
+ var min = mathCeil(mathMin(lower, upper) || 0);
244
+ var max = mathFloor(mathMax(lower, upper) || 0);
238
245
  if (min > max) {
239
246
  var temp = min;
240
247
  min = max;
241
248
  max = temp;
242
249
  }
243
- return Math.floor(min + Math.random() * (max - min + 1));
250
+ return mathFloor(min + mathRandom() * (max - min + 1));
244
251
  }
245
252
 
246
253
  function shuffle(array) {
@@ -295,7 +302,7 @@
295
302
  var length = 0;
296
303
  array = array.filter(function (group) {
297
304
  if (isArrayLikeObject(group)) {
298
- length = Math.max(group.length, length);
305
+ length = mathMax(group.length, length);
299
306
  return true;
300
307
  }
301
308
  return false;
@@ -475,13 +482,13 @@
475
482
  return value == null || value !== value ? defaultValue : value;
476
483
  }
477
484
 
478
- var VERSION = "1.4.10";
479
- var supportedArgumentsType = objectToString.call((function () { return arguments; })()) === argumentsTag;
485
+ var VERSION = "1.5.1";
486
+ var supportedArgumentsType = objectProtoToString.call((function () { return arguments; })()) === argumentsTag;
480
487
  var FUNC_ERROR_TEXT = 'Expected a function';
481
488
  function toSource(func) {
482
489
  if (func !== null) {
483
490
  try {
484
- return functionToString.call(func);
491
+ return functionProtoToString.call(func);
485
492
  }
486
493
  catch (e) {
487
494
  }
@@ -665,27 +672,19 @@
665
672
 
666
673
  function isArguments(value) {
667
674
  if (supportedArgumentsType) {
668
- return objectToString.call(value) === argumentsTag;
675
+ return objectProtoToString.call(value) === argumentsTag;
669
676
  }
670
- return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
677
+ return isObjectLike(value) && objectProtoHasOwnProperty.call(value, 'callee') && !objectProtoPropertyIsEnumerable.call(value, 'callee');
671
678
  }
672
679
 
673
- var freeGlobalThis = typeof globalThis === 'object' && globalThis && globalThis.Object === Object && globalThis;
674
- var freeGlobal = typeof global === 'object' && global && global.Object === Object && global;
675
- var freeSelf = typeof self === 'object' && self && self.Object === Object && self;
676
- var root = freeGlobalThis || freeGlobal || freeSelf || Function('return this')() || {};
677
-
678
680
  var freeExports = typeof exports === 'object' && exports && !exports.nodeType && exports;
679
681
  var freeModule = freeExports && typeof module === 'object' && module && !module.nodeType && module;
680
- var moduleExports = freeModule && freeModule.exports === freeExports;
681
- var freeProcess = moduleExports && root.process;
682
682
  var nodeUtil = (function () {
683
683
  try {
684
684
  var types = freeModule && freeModule.require && freeModule.require('util').types;
685
685
  if (types) {
686
686
  return types;
687
687
  }
688
- return freeProcess && freeProcess.binding && freeProcess.binding('util');
689
688
  }
690
689
  catch (e) {
691
690
  }
@@ -698,7 +697,7 @@
698
697
  var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray;
699
698
 
700
699
  function isArrayBuffer(value) {
701
- return nodeIsArrayBuffer ? nodeIsArrayBuffer(value) : objectToString.call(value) === arrayBufferTag;
700
+ return nodeIsArrayBuffer ? nodeIsArrayBuffer(value) : objectProtoToString.call(value) === arrayBufferTag;
702
701
  }
703
702
 
704
703
  var blobExisted = typeof Blob !== 'undefined';
@@ -706,11 +705,11 @@
706
705
  if (blobExisted && value instanceof Blob) {
707
706
  return true;
708
707
  }
709
- return objectToString.call(value) === blobTag;
708
+ return objectProtoToString.call(value) === blobTag;
710
709
  }
711
710
 
712
711
  function isBoolean(value) {
713
- return value === true || value === false || objectToString.call(value) === booleanTag;
712
+ return value === true || value === false || objectProtoToString.call(value) === booleanTag;
714
713
  }
715
714
 
716
715
  function isBuffer(value) {
@@ -724,28 +723,28 @@
724
723
  }
725
724
 
726
725
  function getRawTag(value) {
727
- var isOwn = hasOwnProperty.call(value, symToStringTag);
728
- var tag = value[symToStringTag];
726
+ var isOwn = objectProtoHasOwnProperty.call(value, symbolToStringTag);
727
+ var tag = value[symbolToStringTag];
729
728
  var unmasked = false;
730
729
  try {
731
- value[symToStringTag] = undefined;
730
+ value[symbolToStringTag] = undefined;
732
731
  unmasked = true;
733
732
  }
734
733
  catch (e) {
735
734
  }
736
- var result = objectToString.call(value);
735
+ var result = objectProtoToString.call(value);
737
736
  if (unmasked) {
738
737
  if (isOwn) {
739
- value[symToStringTag] = tag;
738
+ value[symbolToStringTag] = tag;
740
739
  }
741
740
  else {
742
- delete value[symToStringTag];
741
+ delete value[symbolToStringTag];
743
742
  }
744
743
  }
745
744
  return result;
746
745
  }
747
746
  function getTag(value) {
748
- return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString.call(value);
747
+ return symbolToStringTag && symbolToStringTag in Object(value) ? getRawTag(value) : objectProtoToString.call(value);
749
748
  }
750
749
 
751
750
  var dataViewExisted = typeof DataView !== 'undefined';
@@ -759,11 +758,11 @@
759
758
  var setCtorString = toSource(Set);
760
759
  var weakMapCtorString = toSource(WeakMap);
761
760
  var getTagWithBugfix = getTag;
762
- if ((dataViewExisted && objectToString.call(new DataView(new ArrayBuffer(1))) !== dataViewTag) ||
763
- (mapExisted && objectToString.call(new Map()) !== mapTag) ||
764
- (promiseExisted && objectToString.call(Promise.resolve()) !== promiseTag) ||
765
- (setExisted && objectToString.call(new Set()) !== setTag) ||
766
- (weakMapExisted && objectToString.call(new WeakMap()) !== weakMapTag)) {
761
+ if ((dataViewExisted && objectProtoToString.call(new DataView(new ArrayBuffer(1))) !== dataViewTag) ||
762
+ (mapExisted && objectProtoToString.call(new Map()) !== mapTag) ||
763
+ (promiseExisted && objectProtoToString.call(Promise.resolve()) !== promiseTag) ||
764
+ (setExisted && objectProtoToString.call(new Set()) !== setTag) ||
765
+ (weakMapExisted && objectProtoToString.call(new WeakMap()) !== weakMapTag)) {
767
766
  getTagWithBugfix = function (value) {
768
767
  var result = getTag(value);
769
768
  var Ctor = result === objectTag ? value.constructor : undefined;
@@ -792,10 +791,10 @@
792
791
  }
793
792
 
794
793
  function isDate(value) {
795
- return nodeIsDate ? nodeIsDate(value) : objectToString.call(value) === dateTag;
794
+ return nodeIsDate ? nodeIsDate(value) : objectProtoToString.call(value) === dateTag;
796
795
  }
797
796
 
798
- var objectCtorString = functionToString.call(Object);
797
+ var objectCtorString = functionProtoToString.call(Object);
799
798
  function isPlainObject(value) {
800
799
  if (!isObjectLike(value) || getTag(value) !== objectTag) {
801
800
  return false;
@@ -804,8 +803,8 @@
804
803
  if (proto === null) {
805
804
  return true;
806
805
  }
807
- var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
808
- return typeof Ctor === 'function' && Ctor instanceof Ctor && functionToString.call(Ctor) === objectCtorString;
806
+ var Ctor = objectProtoHasOwnProperty.call(proto, 'constructor') && proto.constructor;
807
+ return typeof Ctor === 'function' && Ctor instanceof Ctor && functionProtoToString.call(Ctor) === objectCtorString;
809
808
  }
810
809
 
811
810
  function isElement(value) {
@@ -827,7 +826,7 @@
827
826
  }
828
827
  var result = [];
829
828
  for (var key in Object(value)) {
830
- if (hasOwnProperty.call(value, key) && key !== 'constructor') {
829
+ if (objectProtoHasOwnProperty.call(value, key) && key !== 'constructor') {
831
830
  result.push(key);
832
831
  }
833
832
  }
@@ -865,7 +864,7 @@
865
864
  if (!objectGetOwnPropertySymbols || object === null) {
866
865
  return [];
867
866
  }
868
- return objectGetOwnPropertySymbols(object).filter(function (item) { return propertyIsEnumerable.call(object, item); });
867
+ return objectGetOwnPropertySymbols(object).filter(function (item) { return objectProtoPropertyIsEnumerable.call(object, item); });
869
868
  }
870
869
 
871
870
  function allKeys(object) {
@@ -884,7 +883,7 @@
884
883
  return nodeIsTypedArray(value);
885
884
  }
886
885
  if (isObjectLike(value) && isLength(value.length)) {
887
- var tag_1 = objectToString.call(value);
886
+ var tag_1 = objectProtoToString.call(value);
888
887
  return typedArrayTags.some(function (item) { return item === tag_1; });
889
888
  }
890
889
  return false;
@@ -906,7 +905,7 @@
906
905
  return orderBy(result);
907
906
  }
908
907
  function argToArray(arg) {
909
- return arrSlice.call(arg);
908
+ return arrayProtoSlice.call(arg);
910
909
  }
911
910
  function toBufferView(bufferSource) {
912
911
  return new Uint8Array(bufferSource.buffer || bufferSource, bufferSource.byteOffset || 0, bufferSource.byteLength);
@@ -1033,7 +1032,7 @@
1033
1032
  continue;
1034
1033
  }
1035
1034
  }
1036
- if (!(hasOwnProperty.call(other, key) && isEqualDeep(value[key], other[key], customizer, strictCheck, valueStack, otherStack))) {
1035
+ if (!(objectProtoHasOwnProperty.call(other, key) && isEqualDeep(value[key], other[key], customizer, strictCheck, valueStack, otherStack))) {
1037
1036
  return false;
1038
1037
  }
1039
1038
  if (!skipCtor && key === 'constructor') {
@@ -1073,20 +1072,25 @@
1073
1072
  if (value instanceof Error) {
1074
1073
  return true;
1075
1074
  }
1076
- var tag = objectToString.call(value);
1075
+ var tag = objectProtoToString.call(value);
1077
1076
  return tag === errorTag || tag === domExceptionTag;
1078
1077
  }
1079
1078
 
1079
+ var freeGlobalThis = typeof globalThis === 'object' && globalThis && globalThis.Object === Object && globalThis;
1080
+ var freeGlobal = typeof global === 'object' && global && global.Object === Object && global;
1081
+ var freeSelf = typeof self === 'object' && self && self.Object === Object && self;
1082
+ var root = freeGlobalThis || freeGlobal || freeSelf || Function('return this')() || {};
1083
+
1080
1084
  function isFinite(value) {
1081
1085
  return numberIsFinite ? numberIsFinite(value) : typeof value === 'number' && root.isFinite(value);
1082
1086
  }
1083
1087
 
1084
1088
  function isInteger(value) {
1085
- return numberIsInteger ? numberIsInteger(value) : isFinite(value) && Math.floor(value) === value;
1089
+ return numberIsInteger ? numberIsInteger(value) : isFinite(value) && mathFloor(value) === value;
1086
1090
  }
1087
1091
 
1088
1092
  function isDeepComparable(object, source) {
1089
- return objectToString.call(object) === objectTag && objectToString.call(source) === objectTag;
1093
+ return objectProtoToString.call(object) === objectTag && objectProtoToString.call(source) === objectTag;
1090
1094
  }
1091
1095
  function baseIsMatch(object, source, customizer, strictCheck, objStack, srcStack, executedCustomizer) {
1092
1096
  if (executedCustomizer === void 0) { executedCustomizer = false; }
@@ -1152,7 +1156,7 @@
1152
1156
  }
1153
1157
 
1154
1158
  function isNumber(value) {
1155
- return typeof value === 'number' || objectToString.call(value) === numberTag;
1159
+ return typeof value === 'number' || objectProtoToString.call(value) === numberTag;
1156
1160
  }
1157
1161
 
1158
1162
  function isNaN(value) {
@@ -1168,15 +1172,15 @@
1168
1172
  }
1169
1173
 
1170
1174
  function isRegExp(value) {
1171
- return nodeIsRegExp ? nodeIsRegExp(value) : objectToString.call(value) === regExpTag;
1175
+ return nodeIsRegExp ? nodeIsRegExp(value) : objectProtoToString.call(value) === regExpTag;
1172
1176
  }
1173
1177
 
1174
1178
  function isSafeInteger(value) {
1175
- return numberIsSafeInteger ? numberIsSafeInteger(value) : isInteger(value) && Math.abs(value) <= MAX_SAFE_INTEGER;
1179
+ return numberIsSafeInteger ? numberIsSafeInteger(value) : isInteger(value) && mathAbs(value) <= MAX_SAFE_INTEGER;
1176
1180
  }
1177
1181
 
1178
1182
  function isString(value) {
1179
- return typeof value === 'string' || objectToString.call(value) === stringTag;
1183
+ return typeof value === 'string' || objectProtoToString.call(value) === stringTag;
1180
1184
  }
1181
1185
 
1182
1186
  function isUndefined(value) {
@@ -1188,14 +1192,14 @@
1188
1192
  }
1189
1193
 
1190
1194
  function isWeakSet(value) {
1191
- return objectToString.call(value) === weakSetTag;
1195
+ return objectProtoToString.call(value) === weakSetTag;
1192
1196
  }
1193
1197
 
1194
1198
  function decimalAdjust(type, value, precision) {
1195
1199
  if (precision === void 0) { precision = 0; }
1196
1200
  var func = Math[type];
1197
1201
  value = toNumber(value);
1198
- precision = Math.min(toInteger(precision), 292);
1202
+ precision = mathMin(toInteger(precision), 292);
1199
1203
  if (precision === 0 || !isFinite(value)) {
1200
1204
  return func(value);
1201
1205
  }
@@ -1304,7 +1308,7 @@
1304
1308
  number = toNumber(number);
1305
1309
  start = toNumber(start);
1306
1310
  end = toNumber(end);
1307
- return number >= Math.min(start, end) && number < Math.max(start, end);
1311
+ return number >= mathMin(start, end) && number < mathMax(start, end);
1308
1312
  }
1309
1313
 
1310
1314
  function random(lower, upper) {
@@ -1312,9 +1316,9 @@
1312
1316
  if (upper === void 0) { upper = 1; }
1313
1317
  lower = toFinite(lower);
1314
1318
  upper = toFinite(upper);
1315
- var min = Math.min(lower, upper);
1316
- var max = Math.max(lower, upper);
1317
- return min + Math.random() * (max - min);
1319
+ var min = mathMin(lower, upper);
1320
+ var max = mathMax(lower, upper);
1321
+ return min + mathRandom() * (max - min);
1318
1322
  }
1319
1323
 
1320
1324
  function getKeysIn(object) {
@@ -1607,7 +1611,7 @@
1607
1611
  return [];
1608
1612
  }
1609
1613
  var index = 0;
1610
- var length = Math.min(isInteger(n) ? n : Math.floor(isFinite(n) ? n : 0), MAX_ARRAY_LENGTH);
1614
+ var length = mathMin(isInteger(n) ? n : mathFloor(isFinite(n) ? n : 0), MAX_ARRAY_LENGTH);
1611
1615
  var result = Array(length);
1612
1616
  var func = typeof iteratee === 'function' ? iteratee : identity;
1613
1617
  while (index < length) {